-
Notifications
You must be signed in to change notification settings - Fork 985
Lock download file to avoid races #4606
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
4b0e0d9 to
19c23a7
Compare
See #TBD for details. This is one of two possible implementations, the easier one is using a temporary directory or a unique filename to ensure processes don't collide. Using locks has less platform support, but OTOH means that we don't create stray temp files that don't get cleaned up (because we never know if one of those files is actually used by another process). This does not fix #TBD completely. It only fixed the downloaded, parallel `rustup-init` calls still fail at the transaction stage. This PR introduces a `LockedFile` primitive that's modeled after the uv type of the same name. It's currently very simple and locks forever. We can extend it with a timeout that makes rustup exit after a certain duration and print an error message, instead of an inscrutable waiting without any message.
19c23a7 to
e69fb23
Compare
| // Otherwise, create a temporary file with 777 permissions, to handle races between | ||
| // processes running under different UIDs (e.g., in Docker containers). We must set | ||
| // permissions _after_ creating the file, to override the `umask`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting. I guess Cargo's file locks also have the same issue?
Would be great if you can a link to it :) |
|
The uv type: https://github.com/astral-sh/uv/blob/fc0cf90795dbfa961f22fc0934a53afc9c13c349/crates/uv-fs/src/lib.rs#L672. I have a branch that adds async timeouts, but that's in review still. |
| }; | ||
| if let Err(err) = file | ||
| .as_file() | ||
| .set_permissions(std::fs::Permissions::from_mode(0o777)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can the permissions be cached in a static variable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The method is a no-op constructor.
See #4607 for details.
This is one of two possible implementations, the easier one is using a temporary directory or a unique filename to ensure processes don't collide. Using locks has less platform support, but OTOH means that we don't create stray temp files that don't get cleaned up (because we never know if one of those files is actually used by another process).
This does not fix #4607 completely. It only fixed the downloaded, parallel
rustup-initcalls still fail at the transaction stage.This PR introduces a
LockedFileprimitive that's modeled after the uv type of the same name. It's currently very simple and locks forever. We can extend it with a timeout that makes rustup exit after a certain duration and print an error message, instead of an inscrutable waiting without any message.