Open hvdijk opened 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.
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.
I marked this as stale due to inactivity. → More info
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?
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.
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...
When a systemd service does not contain
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.