Handle EPERM when creating a hard link for the chroot

There is a race condition when doing parallel builds with chroots and
the immutable bit enabled.  One process may call makeImmutable()
before the other has called link(), in which case link() will fail
with EPERM.  We could retry or wrap the operation in a lock, but since
this condition is rare and I'm lazy, we just use the existing copy
fallback.

Fixes #9.
This commit is contained in:
Eelco Dolstra 2012-04-30 10:58:04 -04:00
parent c722193a91
commit 46cdc6ad51

View file

@ -1708,8 +1708,11 @@ void DerivationGoal::startBuilder()
/* Hard-linking fails if we exceed the maximum /* Hard-linking fails if we exceed the maximum
link count on a file (e.g. 32000 of ext3), link count on a file (e.g. 32000 of ext3),
which is quite possible after a `nix-store which is quite possible after a `nix-store
--optimise'. Make a copy instead. */ --optimise'. It can also fail if another
if (errno != EMLINK) process called makeImmutable() on *i after we
did makeMutable(). In those cases, make a copy
instead. */
if (errno != EMLINK && errno != EPERM)
throw SysError(format("linking `%1%' to `%2%'") % p % *i); throw SysError(format("linking `%1%' to `%2%'") % p % *i);
StringSink sink; StringSink sink;
dumpPath(*i, sink); dumpPath(*i, sink);