NixOS / nix

Nix, the purely functional package manager
https://nixos.org/
GNU Lesser General Public License v2.1
12.85k stars 1.52k forks source link

Builders inherit ignored signals #2803

Open hvdijk opened 5 years ago

hvdijk commented 5 years ago

When a systemd service does not contain

[Service]
IgnoreSIGPIPE=no

systemd will cause SIGPIPE to be ignored, and Nix does nothing to restore this in builders. As a result, builds behave subtly differently depending on whether nix-daemon is used or not, and whether nix-daemon is launched from systemd or launched manually.

This showed up when running diffutils 3.7's test suite inside a builder, which tests that in a specific situation, diff correctly fails with SIGPIPE. This test failed, because diff exited with a regular exit code instead, until I stopped the nix-daemon service and launched nix-daemon manually.

After modifying nix-daemon.service as described, diffutils's tests do pass.

Is adding IgnoreSIGPIPE=no the right solution, or should Nix fix this up itself, for all signals no matter how it's started? The former solves the immediate problem the simplest way, the latter would take more work but would potentially fix more cases.

hvdijk commented 5 years ago

Had to look a bit for how to create a simple standalone testcase, but:

nix-build --expr 'with builtins; derivation {
  name = "test";
  system = currentSystem;
  __noChroot = true;
  PATH = "/bin:/usr/bin";
  builder = "/bin/bash";
  args = ["-c" "set -o pipefail; cat /bin/bash | head -c1 >/dev/null; echo $?"];
}'

Paths may need to be adjusted. This should print "141", but depending on how nix-daemon was started, may actually print "cat: write error: Broken pipe", followed by "1". This can be modified to conditionally create $out, if desired.

luke-clifton commented 4 years ago

This causes me endless number of headaches. I think nix itself needs to actually fix the issues itself. I can't control how other people have started their daemon.

stale[bot] commented 3 years ago

I marked this as stale due to inactivity. → More info

hvdijk commented 3 years ago

I forgot about this when setting up Nix on a new system and spent time again digging into the same failing test in diffutils 3.8. While it would be nice to fix this in Nix itself so that it is guaranteed to work well for everybody, the systemd service file is provided by Nix itself, could at least that be updated so that a default installation will just work?

ju1m commented 2 years ago

After a puzzling inquiry, where a test of public-inbox was hanging in nix build but succeeding when entering manually the stalled sandbox, @martinetd found that the masking of SIGPIPE was the culprit. @hvdijk's suggested fix (IgnoreSIGPIPE=no) made the test succeed.

ju1m commented 2 years ago

For the record, public-inbox's author opted for reenabling SIGPIPE:

Yes, blocking SIGPIPE makes sense for most daemons so I think systemd is being reasonable, here. However, this lei test is for simulating an interactive environment, so re-enabling SIGPIPE under t/lei-sigpipe.t seems best...