From b33fefcb92e02725fc77b6adfabab1c1f43e9aa1 Mon Sep 17 00:00:00 2001 From: Daiderd Jordan Date: Sat, 4 Jan 2020 17:47:52 +0100 Subject: [PATCH 1/2] build: recover store path when replacing fails This shouldn't happen in normal circumstances, but just in case attempt to move the temporary path back if possible. --- src/libstore/build.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 78f39fed1..257d70ca9 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -1513,8 +1513,10 @@ void replaceValidPath(const Path & storePath, const Path tmpPath) Path oldPath = (format("%1%.old-%2%-%3%") % storePath % getpid() % random()).str(); if (pathExists(storePath)) rename(storePath.c_str(), oldPath.c_str()); - if (rename(tmpPath.c_str(), storePath.c_str()) == -1) + if (rename(tmpPath.c_str(), storePath.c_str()) == -1) { + rename(oldPath.c_str(), storePath.c_str()); // attempt to recover throw SysError("moving '%s' to '%s'", tmpPath, storePath); + } deletePath(oldPath); } From 7d448bc966021e63e9c7b96530cee885f3dcd68d Mon Sep 17 00:00:00 2001 From: Daiderd Jordan Date: Sat, 4 Jan 2020 20:23:59 +0100 Subject: [PATCH 2/2] build: fix path repairing when hash rewriting is required Handle store path repairing on darwin when sandboxing is enabled. Unlike on linux sandboxing on darwin still requires hash rewriting. --- src/libstore/build.cc | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 257d70ca9..0674f936b 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -3567,19 +3567,6 @@ void DerivationGoal::registerOutputs() if (!missingPaths.count(i.second.path)) continue; Path actualPath = path; - if (useChroot) { - actualPath = chrootRootDir + path; - if (pathExists(actualPath)) { - /* Move output paths from the chroot to the Nix store. */ - if (buildMode == bmRepair) - replaceValidPath(path, actualPath); - else - if (buildMode != bmCheck && rename(actualPath.c_str(), worker.store.toRealPath(path).c_str()) == -1) - throw SysError(format("moving build output '%1%' from the sandbox to the Nix store") % path); - } - if (buildMode != bmCheck) actualPath = worker.store.toRealPath(path); - } - if (needsHashRewrite()) { auto r = redirectedOutputs.find(i.second.path); if (r != redirectedOutputs.end()) { @@ -3591,6 +3578,17 @@ void DerivationGoal::registerOutputs() if (buildMode == bmCheck) actualPath = redirected; } + } else if (useChroot) { + actualPath = chrootRootDir + path; + if (pathExists(actualPath)) { + /* Move output paths from the chroot to the Nix store. */ + if (buildMode == bmRepair) + replaceValidPath(path, actualPath); + else + if (buildMode != bmCheck && rename(actualPath.c_str(), worker.store.toRealPath(path).c_str()) == -1) + throw SysError(format("moving build output '%1%' from the sandbox to the Nix store") % path); + } + if (buildMode != bmCheck) actualPath = worker.store.toRealPath(path); } struct stat st;