Rclone mount - progrmatic umount under windows

Hi,

I am trying to bring rclone-browser to full glory and have one unresolved bug on Windows platform.

How to umount drive mounted with "rclone mount"? It seems there is no option like under linux/macOS to use fusermount/umount. So I have an issue how to do this from within the app. Does not seem Qt can sent ctrl-C signal.

Rgds

Dariusz

As far as I remember the only way to unmount a drive on Windows with rclone is to kill the rclone process.

You can get the PID of rclone from the API.

Do you maintain an API connection to spawned rclones?

I saw some ideas here https://forum.rclone.org/t/unmount-in-windows/9057/3

I could maintain API connection with "rclone rc" - but what is command to close it? "rclone rc core/quit" suggested in other thread is not implemented.
Of course I will have to use ports as many instances can be running but this is not an issue.

I tried killing it but results are not good. Rclone dies but does not seem that WinFsp-FUSE likes it. Hanging drives in undefined state etc..

when done from command line with ctrl-C it work perfectly

on microsoft windows, here is a way to do it; without the need to maintain the PID of the API.
perhaps it might be helpful to spark some ideas.

and this gets around the problem mentioned in


"While this does the unmount, it has other quirks, such as I cannot use /B (no window) because then I cannot kill the window"

as you can see here i am using the /b flag

run commands:

start /b rclone.exe mount wasabiwest01:vserver03-bjv.h.vserver03.g.ampe01\ b:\test01\
start /b rclone.exe mount wasabiwest01:vserver03-bjv.h.vserver03.g.ampe01\ b:\test02\

get the stdout of this command:

wmic process where caption="rclone.exe" get processid,commandline

which would look like:

rclone.exe mount wasabiwest01:test01\ b:\test01\ 19364
rclone.exe mount wasabiwest01:test02\ b:\test02\ 5044

and from that output, you can easily determine which rclone.exe to kill.
let's say i want to kill the mount b:\test01\, then I would run this command:

taskkill /pid 19364 /F

Thx for your suggestion. I have tried and as mentioned before results are not as expected. I kill rclone but WinFsp-FUSE rclone is using does not behave the same way as with simple ctrl-C on rclone. Leaves "hanging" drives in weird state etc.

sure, just trying to help.

and i am curious as to what this weird state is?

i have re-mounted the exact same mounts and then taskkill those mounts 10 times over and over.
and from an end-user perspective, i have not experienced any problems.

It could be very easily...

how should I start the process of implementing it:)? It would be ideal way without brutally killing rclone. My objective is to have well behaving rclone-browser across all major platforms.

I understand that rclone would behave exactly in the same way as after receiving ctrl-C? passig whatever signals it normally does to Fuse?

Having an RC command would obviously be the cleanest but, under the assumption that we don't have that option to use...

Using my "jank skillz" in batch I think something like this would work:

start /b rclone mount ... (it run in background)
title ULC Upload ... (sets window title)

below that in the same script run a loop like this:

:loop1
tasklist /fi "windowtitle eq Upload ULC*" |find "cmd.exe" >nul && echo ""| set /p dummyName=. && timeout /t 1 >nul && exit
goto :loop1

This searches for windows (starting with) title "Upload ULC" in this case, and when it finds one it proceeds (and does an exit in this case). This would close down the window from inside and should have the same result as a manual CTRL+C , ie. a soft kill not a hard one. Hopefully that should work more smoothly in terms of closing down the mount properly.

That would allow any other script to effectively signal the mount to exit by spawning a window with the correct title.

Is this jank? yes
Would it work? quite likely
I use (a variant of) this myself whenever I need to make "mulithreaded" code in batch to do maintenance stuff on several different components.
I did not test these scripts as I edited them just now, so minor mistakes might exist. I could test and make sure it worked - but I won't spend time on it unless you say you want to test it.

Be aware that if you ever need to run this as SYSTEM (for service ect.) the code will need to be altered at the very least, because it automatically appends "Administrator: " to the start of all windows spawned by system or elevated admin.

I'm still a padawan in batch so there is almost certainly a more elegant way to do this, but at the very leaast this mgiht give you some ideas on how to work around the issue.

Actually, I just remembered - I recently found a much better and more robust way of doing the same as described above using lock-files. This sidesteps much of the quirky behavior and limitations that may follow from using window titles (like when you run windowless scripts, on SYSTEM-level ect.) should also just be much more solid as a true pseudo-mutex (much less vulnerable to timing problems).

here is an example of how to use a lock-file as a mutex:

:: Note - this extra call is to avoid a bug with %~f0 when the script
:: is executed with quotes around the script name.
call :getLock
exit /b

:getLock
:: The CALL will fail if another process already has a write lock on the script
call :main 9>>"%~f0"
exit /b

:main
:: Body of your script goes here. Only one process can ever get here
:: at a time. The lock will be released upon return from this routine,
:: or when the script terminates for any reason

So the way this would be relevant to your problem is that you could use a very simple wrapper-script to launch the mount script. Before it does, the wrapper script locks down exclusive access to some some arbitrary file (the scripts themselves may be those files themselves in some cases - for example the wrapper-script could be used here maybe).

Then you still launch mount as
start /b rclone mount ...
[a loop goes here]
exit

Just as the example above...

But the loop at the end of the mount-script - instead of continually checking for windows with a certain name like in previous example would loop and continually try to get write-lock on that same file as the wrapper did (and fail until the wrapper releases it). This is very robust because the OS assures that no matter what causes the wrapper script to stop running, the write-lock is released. Feel free to brutally murderize it by any means you want :smiley:
The OS will also never allow 2 thinks to write-lock the same file ever - so it's a garantueed mutex by Microsoft, not some hacky solution (like above) that might fail in rare edge-cases and be vulnerable to strange timings.

So to end the mount gracefully - you'd hard-kill the wrapper-script by any means you want. The OS then will automatically release the write-lock. The loop in the mount-script then can get past the hurdle and hit the "exit" at the end which then makes it soft-exit gracefully.

Disclaimer: The write-lock mutex example code is not mine. I shamelessly stole it from stackoverflow.

Again - if you are interested in something like this I can add more detail - but if you want to go the ideal route of integrating this into rclone (which I by all means encourage you to do since we can all benefit from it) then I won't waste time doing it in advance :smiley:

(Now if you'll excuse me this just reminded me I have to go re-work my own scripts to use this more robust mutex lock on my existing multithreaded functions =P )

@thestigma, that is some scary code, i would not want to trust .cmd files for pseudo write lock mutexes.

for me, the goal, is always to avoid a mutex, unless absolutely needed and it is rarely needed.
and not to rely on multi-threading, using dos command line.
no way to really debug and test that dos pseudo mutex script.

better to run the start /b commands and exit quickly.
and if need be use taskkill as needed to kill rclone.
a few lines of python would solve the problem easily and reliably.

that is why i gave up complex, unreliable command line batch files and use python.

but i do understand @kapitainsky need for clean code across platforms.

Well that's really the good part about this - the mutex is handled by Windows, not the batch script.

The reason mutexes can be scary is they can cause (and prevent) deadlocks if not handled well - but in these simple uses that's not really a concern. It's not really being used as a mutex in this context - simply as a reliable cross-process signal (because batch as far as I know batch has no support for proper signaling - or much of anything else :stuck_out_tongue: ).

If you just start the mount with /b and then exit then it will just shut down the mount - so that's not an option. If you know of a way to make a window wait for all background processes to complete before closing then by all means share - because that could greatly simplify some of my threaded scripts. I just don't think that's how CMD works though.

Nothing is ideal to write in batch, and anything complicated will rely on some tricks and hacks. That said, as long as you aren't fundamentally compromising stability (which I don't really think is a risk for this simple use-case) then it's nice to be able to run it on any windows system without prerequisites.

But could pyhon or basically any modern scripting language do this more cleanly? lol ... obvious answer is obvious :stuck_out_tongue:

i respectfully disagree, start /b rclone mount works just fine.

Well darnit - now I have to re-test it don't I? :stuck_out_tongue:
But if I was mistaken about this then I'd be very happy to be wrong...

EDIT: Indeed it does work hmm... and I still have this exact setup in my previous version of scripts I decided to discard.

I think there must have been some other reason why I found out that I could not use this because this was actually my original plan - but I would not have abandoned it for no reason.
But I definitely mis-attributed the cause. My bad. Something got mixed up in the old brain-bank there.

I'm still not sure that solves the OPs problem though, as if you don't have any code to trigger anything then it's just going to run forever and you are back tothe same problem of having to hard-kill it.

i agree that in either example, mine or yours, a hard kill is needed.
and i stated that in my last post.

my point is that mutex based on a scary dos batch file is not needed.

do a start /b rclone mount
and if and when needed do a taskkill on that rclone mount.

no mutex needed.

But the mount exiting messily on a hard-kill is the whole problem in the first place... if we weren't trying to solve that problem and just gave up then I agree no fancy code is needed :stuck_out_tongue:

and running the mount with /b or not will have no impact on that as far as a hard-kill goes (at least I don't see why that would matter).

A hard-kill should not be needed - or at least it is possible to simulate a CTRL-C, which I assume acts as a soft-kill. I've at least never experienced bad mount terminations using that (and I've been doing that a LOT during various testing).
At least one way to do it:
https://www.dostips.com/forum/viewtopic.php?t=5859

I assumed we coul use a simple EXIT in my examples - which clearly was a mistake on my part. We have to use a simulated CTRL-C instead, but other than that it should work the same. What action we choose to trigger on detecting the signal is up to us.

we agree, but sometimes a hardkill is the way to go and works just fine.

i am working on a way to simulate a ctrl-c soft kill for start /b

often, a hardkill is not so hard, as the process is still is notified and can itself up.
and in this case it seems a hardkill does not corrupt anything.

run this code for 10 minutes and you will see no problems

:looper
start /b rclone.exe mount wasabiwest01:vserver03-bjv.h.vserver03.g.ampe01\ x:
ping localhost -n 5 -w 1000
taskkill /im rclone.exe /f
goto looper

I will trust you if you say so - as I haven't really had much reason to hard-kill my mounts - so I don't really know how they usually react to that.

I was just taking OP as his word when he said it didn't seem to work so well for him to taskkill.

Unrelated:
Why ping localhost -n 5 -w 1000
instead of
timeout /t 5 >nul
?

Just being oldschool or some form of backwards compatibility consideration?
(I know both work fine - just asking why the preference for the more archaic version)

yes, in this post, up above, i did ask OP for details but so far, s/he/it has not replied.