From 02873bd3ca51fa82017e3eb5686e49b70893b000 Mon Sep 17 00:00:00 2001 From: Rain Date: Tue, 2 Apr 2024 12:38:28 -0700 Subject: [PATCH] [oxlog] add sigpipe::reset (#5358) We have a number of CLI tools that panic when piped to things like `head` instead of quietly exiting. There's a long history about this within the Rust community (see https://github.com/rust-lang/rust/issues/62569), but the long and short of it is that SIGPIPE really should be set to its default handler (`SIG_DFL`, terminate the process) for CLI tools. Because oxlog doesn't make any network requests, reset the SIGPIPE handler to `SIG_DFL`. I looked at also potentially doing this for some of our other CLI tools that wait on network services. This should be fine to do if and only if whenever we send data over a socket, the `MSG_NOSIGNAL` flag is set. (This causes an `EPIPE` error to be returned, but no `SIGPIPE` signal to be generated.) Rust does set this flag [here]. **However, as of Rust 1.77 this flag is not set on illumos.** That's a bug and I'll fix it in Rust upstream. [here]: https://github.com/rust-lang/rust/blob/877d36b1928b5a4f7d193517b48290ecbe404d71/library/std/src/sys_common/net.rs#L32 --- Cargo.lock | 10 ++++++++++ Cargo.toml | 1 + dev-tools/oxlog/Cargo.toml | 1 + dev-tools/oxlog/src/bin/oxlog.rs | 2 ++ 4 files changed, 14 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 8f37c0de72..d2f1bf4df2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6302,6 +6302,7 @@ dependencies = [ "chrono", "clap 4.5.1", "omicron-workspace-hack", + "sigpipe", "uuid 1.7.0", ] @@ -8676,6 +8677,15 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "sigpipe" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5584bfb3e0d348139d8210285e39f6d2f8a1902ac06de343e06357d1d763d8e6" +dependencies = [ + "libc", +] + [[package]] name = "similar" version = "2.4.0" diff --git a/Cargo.toml b/Cargo.toml index 56ffd7eb38..7a0bcd93aa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -378,6 +378,7 @@ sha3 = "0.10.8" shell-words = "1.1.0" signal-hook = "0.3" signal-hook-tokio = { version = "0.3", features = [ "futures-v0_3" ] } +sigpipe = "0.1.3" similar-asserts = "1.5.0" sled = "0.34" sled-agent-client = { path = "clients/sled-agent-client" } diff --git a/dev-tools/oxlog/Cargo.toml b/dev-tools/oxlog/Cargo.toml index 5d7cfaf5c1..3c3d983d09 100644 --- a/dev-tools/oxlog/Cargo.toml +++ b/dev-tools/oxlog/Cargo.toml @@ -9,6 +9,7 @@ anyhow.workspace = true camino.workspace = true chrono.workspace = true clap.workspace = true +sigpipe.workspace = true uuid.workspace = true omicron-workspace-hack.workspace = true diff --git a/dev-tools/oxlog/src/bin/oxlog.rs b/dev-tools/oxlog/src/bin/oxlog.rs index 88e067c382..ceeb98b3bd 100644 --- a/dev-tools/oxlog/src/bin/oxlog.rs +++ b/dev-tools/oxlog/src/bin/oxlog.rs @@ -57,6 +57,8 @@ struct FilterArgs { } fn main() -> Result<(), anyhow::Error> { + sigpipe::reset(); + let cli = Cli::parse(); match cli.command {