You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Ensure that rust's std sets MSG_NOSIGNAL for send(2) on illumos #148
On Unix systems, by default, writing to a pipe that is broken causes two things to happen:
A SIGPIPE signal is raised.
An EPIPE error is returned.
The default disposition of SIGPIPE is to terminate the program. This is why things like ls | head terminate cleanly. But Rust sets the SIGPIPE disposition to SIG_IGN by default. There's a long history behind this: see rust-lang/rust#62569 for more.
The upshot of this is that Rust binaries fail with errors like:
BRM42220014 # /opt/oxide/oxlog/oxlog logs --archived oxz_switch | head -n1
/pool/ext/0c4ef358-5533-43db-ad38-a8eff716e53a/crypt/debug/oxz_switch/oxide-dendrite:default.log.1693451383
thread 'main' panicked at library/std/src/io/stdio.rs:1021:9:
failed printing to stdout: Broken pipe (os error 32)
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
What we can do, from the perspective of shipping binaries written in Rust, is to simply set SIGPIPE to SIG_DFL for them. But there is a wrinkle: the same logic about broken pipes applies not just to writes to local pipes, but also network connections. While sending data, if there's a connection reset for some reason, SIGPIPE will be raised as well.
The good news is that many modern Unix platforms recognize this fundamental mismatch between what CLI tools want and what network services should do. They address it in one of two ways:
Support a flag to send(2) called MSG_NOSIGNAL (Linux, several BSDs, and illumos).
At socket creation time, set a flag called SO_NOSIGPIPE (Apple platforms, example use).
Focusing on 1 since that's what's relevant to illumos, I spent some time looking at the rustc source code, and saw that rustc does pass in MSG_NOSIGNAL where supported. However, the conditional doesn't include illumos, and so this flag isn't passed in on illumos even though it is supported.
Overall, this means that for a tool like oxlog, setting SIGPIPE to SIG_DFL is fine to do because it doesn't make any network requests (oxidecomputer/omicron#5358 does so). But other CLI tools like wicket, omdb and oxdb do make network requests -- and just exiting if a connection reset happens wouldn't be great.
It would be good to get this fixed in Rust upstream. There are likely tests for this behavior too, which we should ensure are enabled on illumos.
changed the title [-]Ensure that rustc sets MSG_NOSIGNAL for send(2) on illumos[/-][+]Ensure that rust's std sets MSG_NOSIGNAL for send(2) on illumos[/+]on Apr 3, 2024
Activity
[-]Ensure that rustc sets MSG_NOSIGNAL for send(2) on illumos[/-][+]Ensure that rust's std sets MSG_NOSIGNAL for send(2) on illumos[/+]sunshowers commentedon Jul 27, 2024
Addressed by rust-lang/rust#128259.
sunshowers commentedon Jul 27, 2024
rust-lang/rust#128259 has landed -- expected to be part of Rust 1.82.