local-derivation-goal.cc: improve error messages when sandboxing fails

The failure modes for nix's sandboxing setup are pretty complicated.
When nix is unable to set up the sandbox, let's provide more detail
about what went wrong.  Specifically:

* Make sure the error message includes the word "sandbox" so the user
  knows that the failure was related to sandboxing.

* If `--option sandbox-fallback false` was provided, and removing it
  would have allowed further attempts to make progress, let the user
  know.
This commit is contained in:
Adam Joseph 2022-07-16 14:39:22 -07:00
parent 59764eb842
commit 8ea3a911aa

View file

@ -850,13 +850,23 @@ void LocalDerivationGoal::startBuilder()
flags &= ~CLONE_NEWUSER; flags &= ~CLONE_NEWUSER;
child = clone(childEntry, stack + stackSize, flags, this); child = clone(childEntry, stack + stackSize, flags, this);
} }
if (child == -1)
switch(errno) {
case EPERM:
case EINVAL: {
/* Otherwise exit with EPERM so we can handle this in the /* Otherwise exit with EPERM so we can handle this in the
parent. This is only done when sandbox-fallback is set parent. This is only done when sandbox-fallback is set
to true (the default). */ to true (the default). */
if (child == -1 && (errno == EPERM || errno == EINVAL) && settings.sandboxFallback) if (settings.sandboxFallback)
_exit(1); _exit(1);
if (child == -1) throw SysError("cloning builder process"); /* Mention sandbox-fallback in the error message so the user
knows that having it disabled contributed to the
unrecoverability of this failure */
throw SysError("creating sandboxed builder process using clone(), without sandbox-fallback");
}
default:
throw SysError("creating sandboxed builder process using clone()");
}
writeFull(builderOut.writeSide.get(), writeFull(builderOut.writeSide.get(),
fmt("%d %d\n", usingUserNamespace, child)); fmt("%d %d\n", usingUserNamespace, child));
_exit(0); _exit(0);