Skip to content
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

Close non-stdio file handles when daemonizing #2314

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

ntrrgc
Copy link

@ntrrgc ntrrgc commented Jan 8, 2025

Otherwise, when the compiler wrapper spawns the sccache server, the server may end up with unintended file descriptors, which can lead to unexpected problems.

This is particularly problematic if any of those file descriptors that accidentally end up in the server process is a pipe, as the pipe will only be closed when all the processes with that file descriptor close it or exit.

This was causing sccache to hang ninja, as ninja uses the EOF of a pipe given to the subprocess to detect when that subprocess has exited: ninja-build/ninja#2444 (comment)

This patch adds a dependency on the
close_fds crate, which automatically chooses an appropriate mechanism to close a range of file descriptors. On Linux 5.9+ that mechanism will be libc::close_range().

Fixes #2313

@ntrrgc
Copy link
Author

ntrrgc commented Jan 9, 2025

The test test_rust_cargo_cmd_readonly_preemtive_block was failing. After investigation, I found the reason:

if env::var("SCCACHE_ERROR_LOG").is_ok() {
    let f = create_error_log()?;
    // Can't report failure here, we're already daemonized.
    daemonize()?;
    redirect_error_log(f)?;

That code was opening a log file, daemonizing, then swapping stderr with it. We could pass the file descriptor of f to the list of exceptions of close_open_fds(), but in this particular case there is no need, as swapping stderr with a file is already a built-in feature of Daemonize.

I'm updating the patch to make daemonize accept a log file as argument and do the file handle swap at that point, which also removes the need for the redirect_stderr() and redirect_error_log() functions in sccache.

Otherwise, when the compiler wrapper spawns the sccache server, the
server may end up with unintended file descriptors, which can lead to
unexpected problems.

This is particularly problematic if any of those file descriptors that
accidentally end up in the server process is a pipe, as the pipe will
only be closed when all the processes with that file descriptor close it
or exit.

This was causing sccache to hang ninja, as ninja uses the EOF of a pipe
given to the subprocess to detect when that subprocess has exited:
ninja-build/ninja#2444 (comment)

This patch adds a dependency on the
[close_fds](https://crates.io/crates/close_fds) crate, which
automatically chooses an appropriate mechanism to close a range of file
descriptors. On Linux 5.9+ that mechanism will be libc::close_range().

Fixes mozilla#2313
@ntrrgc ntrrgc force-pushed the 2025-01-08-close-fds branch from 0fc0c5a to 2c22e92 Compare January 9, 2025 23:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

sccache could be more zealous closing file descriptors when daemonizing
1 participant