-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
Add Linux-specific pidfd process extensions (take 2) #81825
Merged
Merged
Commits on Jul 21, 2021
-
Add Linux-specific pidfd process extensions
Background: Over the last year, pidfd support was added to the Linux kernel. This allows interacting with other processes. In particular, this allows waiting on a child process with a timeout in a race-free way, bypassing all of the awful signal-handler tricks that are usually required. Pidfds can be obtained for a child process (as well as any other process) via the `pidfd_open` syscall. Unfortunately, this requires several conditions to hold in order to be race-free (i.e. the pid is not reused). Per `man pidfd_open`: ``` · the disposition of SIGCHLD has not been explicitly set to SIG_IGN (see sigaction(2)); · the SA_NOCLDWAIT flag was not specified while establishing a han‐ dler for SIGCHLD or while setting the disposition of that signal to SIG_DFL (see sigaction(2)); and · the zombie process was not reaped elsewhere in the program (e.g., either by an asynchronously executed signal handler or by wait(2) or similar in another thread). If any of these conditions does not hold, then the child process (along with a PID file descriptor that refers to it) should instead be created using clone(2) with the CLONE_PIDFD flag. ``` Sadly, these conditions are impossible to guarantee once any libraries are used. For example, C code runnng in a different thread could call `wait()`, which is impossible to detect from Rust code trying to open a pidfd. While pid reuse issues should (hopefully) be rare in practice, we can do better. By passing the `CLONE_PIDFD` flag to `clone()` or `clone3()`, we can obtain a pidfd for the child process in a guaranteed race-free manner. This PR: This PR adds Linux-specific process extension methods to allow obtaining pidfds for processes spawned via the standard `Command` API. Other than being made available to user code, the standard library does not make use of these pidfds in any way. In particular, the implementation of `Child::wait` is completely unchanged. Two Linux-specific helper methods are added: `CommandExt::create_pidfd` and `ChildExt::pidfd`. These methods are intended to serve as a building block for libraries to build higher-level abstractions - in particular, waiting on a process with a timeout. I've included a basic test, which verifies that pidfds are created iff the `create_pidfd` method is used. This test is somewhat special - it should always succeed on systems with the `clone3` system call available, and always fail on systems without `clone3` available. I'm not sure how to best ensure this programatically. This PR relies on the newer `clone3` system call to pass the `CLONE_FD`, rather than the older `clone` system call. `clone3` was added to Linux in the same release as pidfds, so this shouldn't unnecessarily limit the kernel versions that this code supports. Unresolved questions: * What should the name of the feature gate be for these newly added methods? * Should the `pidfd` method distinguish between an error occurring and `create_pidfd` not being called?
Configuration menu - View commit details
-
Copy full SHA for 694be09 - Browse repository at this point
Copy the full SHA 694be09View commit details -
Co-authored-by: bjorn3 <bjorn3@users.noreply.github.com>
Configuration menu - View commit details
-
Copy full SHA for ef03de2 - Browse repository at this point
Copy the full SHA ef03de2View commit details -
Add PidFd type and seal traits
Improve docs Split do_fork into two Make do_fork unsafe Add target attribute to create_pidfd field in Command Add method to get create_pidfd value
Configuration menu - View commit details
-
Copy full SHA for 619fd96 - Browse repository at this point
Copy the full SHA 619fd96View commit details -
Configuration menu - View commit details
-
Copy full SHA for c3321d3 - Browse repository at this point
Copy the full SHA c3321d3View commit details
Commits on Aug 1, 2021
-
Do not call getpid wrapper after fork in tests
The test calls libc::getpid() in the pre_exec hook and asserts that the returned value is different from the PID of the parent. However, libc::getpid() returns the wrong value. Before version 2.25, glibc caches the PID of the current process with the goal of avoiding additional syscalls. The cached value is only updated when the wrapper functions for fork or clone are called. In PR rust-lang#81825 we switch to directly using the clone3 syscall. Thus, the cache is not updated and getpid returns the PID of the parent. source: https://man7.org/linux/man-pages/man2/getpid.2.html#NOTES
Configuration menu - View commit details
-
Copy full SHA for 12fbabd - Browse repository at this point
Copy the full SHA 12fbabdView commit details -
Configuration menu - View commit details
-
Copy full SHA for 2a4d012 - Browse repository at this point
Copy the full SHA 2a4d012View commit details -
Configuration menu - View commit details
-
Copy full SHA for 4a832d3 - Browse repository at this point
Copy the full SHA 4a832d3View commit details
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.