nix run: Fix chroot execution
Running "nix run" with a diverted store, e.g.
$ nix run --store local?root=/tmp/nix nixpkgs.hello
stopped working when Nix became multithreaded, because
unshare(CLONE_NEWUSER) doesn't work in multithreaded processes. The
obvious solution is to terminate all other threads first, but 1) there
is no way to terminate Boehm GC marker threads; and 2) it appears that
the kernel has a race where unshare(CLONE_NEWUSER) will still fail for
some indeterminate amount of time after joining other threads.
So instead, "nix run" will now exec() a single-threaded helper ("nix
__run_in_chroot") that performs the actual unshare()/chroot()/exec().
This commit is contained in:
parent
1c58e13bee
commit
93a5ef0516
2 changed files with 110 additions and 60 deletions
|
|
@ -9,6 +9,10 @@
|
|||
#include "store-api.hh"
|
||||
#include "progress-bar.hh"
|
||||
|
||||
extern std::string chrootHelperName;
|
||||
|
||||
void chrootHelper(int argc, char * * argv);
|
||||
|
||||
namespace nix {
|
||||
|
||||
struct NixArgs : virtual MultiCommand, virtual MixCommonArgs
|
||||
|
|
@ -57,6 +61,13 @@ void mainWrapped(int argc, char * * argv)
|
|||
verbosity = lvlError;
|
||||
settings.verboseBuild = false;
|
||||
|
||||
/* The chroot helper needs to be run before any threads have been
|
||||
started. */
|
||||
if (argc > 0 && argv[0] == chrootHelperName) {
|
||||
chrootHelper(argc, argv);
|
||||
return;
|
||||
}
|
||||
|
||||
initNix();
|
||||
initGC();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue