Description
Overview
During self update, rustup needs to replace rustup and the various proxies for cargo, rustc etc.
If it cannot do this, then respectively:
- future invocations of rustup will be still be running the older version and it will attempt to self-update again
- any improvements made to the proxy code paths will not be reflected in the live proxies on disk (and conversely any bugs will remain)
However, on Windows, when a binary is executed, it gets a read lock taken out on it. This prevents deleting (or replacing) the file until the process has exited. Renaming seems possible.
Today we have code to spawn a separate process from rustup to perform these replacements, but this will fail if any rust or rustup process is running concurrent with the self-update.
Specifically the following cases cause errors:
- processes that are already running like rls running under an IDE
- rust processes started immediately after 'rustup self update' exits
What do these errors look like?
There are two cases:
A) Failed updates of rustup.exe / proxies
error: could not copy file from 'C:\Users\<username>\.cargo\bin\rustup-init.exe' to 'C:\Users\<username>\.cargo\bin\rustup.exe'
info: caused by: Access is denied. (os error 5)
B) Failed removal of the updater binary
error: could not remove 'setup' file: 'C:\Users\<username>\.cargo\bin/rustup-init.exe'
error: caused by: Access is denied. (os error 5)
Design space
We need to cater for processes that are already running - they need to be shut down before the updates in step A can proceed.
We need to cater for processes that start up after parent process exits: short lived ones (e.g. rustc
, rustup version
) can be allowed to complete, but long running processes (e.g. rls
) need to be shut down just like processes that were already running.
We can't prevent the OS starting the processes (not even by renaming, since even a rename may race with that), so its more a matter of tolerating processes that startup and having a way to tell them to exit rapidly. Whatever 'process should exit' mechanism will act to guard against case B.
Finally, we need to cater for file locks coming from other utilities like mcafee or various endpoint security products that may (hopefully temporarily) lock any of these files that we need to manipulate; but the same retry mechanisms should provide some resilience; but possibly having some interface to signal that a given process is holding a lock will be needed: that can be left for a separate ticket though, as it will, unlike this ticket, not be a systemic problem.
Final finally we need to deal with having two instances of the installer executing at once - but perhaps that can be a separate enhancement.