Skip to content

Commit

Permalink
Close input/output handles when running in background (#489)
Browse files Browse the repository at this point in the history
When we run in background mode, the child process inherits the
stdin/stdout/stderr of the parent. That's good because we can print
mount errors from the child and have them reach the parent. But once
we're mounted and the parent exits, the child still holds onto those
handles. This is bad if those handles are pipes, which are often used
when trying to launch a daemon (e.g. Python subprocess.check_output). In
that case, the pipes will never close and the caller will keep waiting
for output on them forever.

We need to close these handles once we're successfully daemonized. This
will prevent us from seeing anything the process prints after they're
closed, but from that point we should be logging anyway, so shouldn't be
printing. Printing still works (doesn't panic or anything), just doesn't
go anywhere.

With this change, a Python script like

    import subprocess
    subprocess.check_output(['mount-s3', 'doc-example-bucket', '/bucket'])

works correctly: once the mount has succeeded, it returns. Without this
change, this program blocks until the bucket is unmounted.

Signed-off-by: James Bornholt <[email protected]>
  • Loading branch information
jamesbornholt authored Aug 31, 2023
1 parent 5626e20 commit 5e8d834
Showing 1 changed file with 7 additions and 0 deletions.
7 changes: 7 additions & 0 deletions mountpoint-s3/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::env;
use std::fs::File;
use std::io::{Read, Write};
use std::os::fd::AsRawFd;
use std::os::unix::prelude::FromRawFd;
use std::path::{Path, PathBuf};
use std::time::Duration;
Expand Down Expand Up @@ -309,6 +310,12 @@ fn main() -> anyhow::Result<()> {
.context("Failed to write data to the pipe")?;
drop(pipe_file);

// Logging is set up and the mount succeeded, so we can hang up
// stdin/out/err now to cleanly daemonize ourselves
nix::unistd::close(std::io::stdin().as_raw_fd()).context("couldn't close stdin")?;
nix::unistd::close(std::io::stdout().as_raw_fd()).context("couldn't close stdout")?;
nix::unistd::close(std::io::stderr().as_raw_fd()).context("couldn't close stderr")?;

session.join().context("failed to join session")?;
}
Err(e) => {
Expand Down

0 comments on commit 5e8d834

Please sign in to comment.