Fix chroots builds
Chroots are initialised by hard-linking inputs from the Nix store to the chroot. This doesn't work if the input has its immutable bit set, because it's forbidden to create hard links to immutable files. So temporarily clear the immutable bit when creating and destroying the chroot. Note that making regular files in the Nix store immutable isn't very reliable, since the bit can easily become cleared: for instance, if we run the garbage collector after running ‘nix-store --optimise’. So maybe we should only make directories immutable.
This commit is contained in:
parent
bd013b6f98
commit
6fe13e6aba
1 changed files with 16 additions and 0 deletions
|
@ -7,6 +7,7 @@
|
||||||
#include "local-store.hh"
|
#include "local-store.hh"
|
||||||
#include "util.hh"
|
#include "util.hh"
|
||||||
#include "archive.hh"
|
#include "archive.hh"
|
||||||
|
#include "immutable.hh"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -771,6 +772,9 @@ private:
|
||||||
/* RAII object to delete the chroot directory. */
|
/* RAII object to delete the chroot directory. */
|
||||||
boost::shared_ptr<AutoDelete> autoDelChroot;
|
boost::shared_ptr<AutoDelete> autoDelChroot;
|
||||||
|
|
||||||
|
/* All inputs that are regular files. */
|
||||||
|
PathSet regularInputPaths;
|
||||||
|
|
||||||
/* Whether this is a fixed-output derivation. */
|
/* Whether this is a fixed-output derivation. */
|
||||||
bool fixedOutput;
|
bool fixedOutput;
|
||||||
|
|
||||||
|
@ -1291,6 +1295,11 @@ void DerivationGoal::buildDone()
|
||||||
|
|
||||||
/* Delete the chroot (if we were using one). */
|
/* Delete the chroot (if we were using one). */
|
||||||
autoDelChroot.reset(); /* this runs the destructor */
|
autoDelChroot.reset(); /* this runs the destructor */
|
||||||
|
|
||||||
|
/* Deleting the chroot will have caused the immutable bits on
|
||||||
|
hard-linked inputs to be cleared. So set them again. */
|
||||||
|
foreach (PathSet::iterator, i, regularInputPaths)
|
||||||
|
makeImmutable(*i);
|
||||||
|
|
||||||
/* Compute the FS closure of the outputs and register them as
|
/* Compute the FS closure of the outputs and register them as
|
||||||
being valid. */
|
being valid. */
|
||||||
|
@ -1687,6 +1696,10 @@ void DerivationGoal::startBuilder()
|
||||||
if (S_ISDIR(st.st_mode))
|
if (S_ISDIR(st.st_mode))
|
||||||
dirsInChroot.insert(*i);
|
dirsInChroot.insert(*i);
|
||||||
else {
|
else {
|
||||||
|
/* Creating a hard link to *i is impossible if its
|
||||||
|
immutable bit is set. So clear it first. */
|
||||||
|
makeMutable(*i);
|
||||||
|
|
||||||
Path p = chrootRootDir + *i;
|
Path p = chrootRootDir + *i;
|
||||||
if (link(i->c_str(), p.c_str()) == -1) {
|
if (link(i->c_str(), p.c_str()) == -1) {
|
||||||
/* Hard-linking fails if we exceed the maximum
|
/* Hard-linking fails if we exceed the maximum
|
||||||
|
@ -1700,6 +1713,9 @@ void DerivationGoal::startBuilder()
|
||||||
StringSource source(sink.s);
|
StringSource source(sink.s);
|
||||||
restorePath(p, source);
|
restorePath(p, source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
makeImmutable(*i);
|
||||||
|
regularInputPaths.insert(*i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue