diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/libstore/build/local-derivation-goal.cc | 6 | ||||
-rw-r--r-- | src/libutil/filesystem.cc | 6 | ||||
-rw-r--r-- | src/libutil/util.hh | 7 |
3 files changed, 19 insertions, 0 deletions
diff --git a/src/libstore/build/local-derivation-goal.cc b/src/libstore/build/local-derivation-goal.cc index 1fc966951..8e5ab7594 100644 --- a/src/libstore/build/local-derivation-goal.cc +++ b/src/libstore/build/local-derivation-goal.cc @@ -2528,6 +2528,12 @@ SingleDrvOutputs LocalDerivationGoal::registerOutputs() [&](const DerivationOutput::CAFixed & dof) { auto & wanted = dof.ca.hash; + // Replace the output by a fresh copy of itself to make sure + // that there's no stale file descriptor pointing to it + Path tmpOutput = actualPath + ".tmp"; + movePath(actualPath, tmpOutput); + copyFile(tmpOutput, actualPath, true); + auto newInfo0 = newInfoFromCA(DerivationOutput::CAFloating { .method = dof.ca.method, .hashType = wanted.type, diff --git a/src/libutil/filesystem.cc b/src/libutil/filesystem.cc index 11cc0c0e7..2a7787c0e 100644 --- a/src/libutil/filesystem.cc +++ b/src/libutil/filesystem.cc @@ -133,6 +133,12 @@ void copy(const fs::directory_entry & from, const fs::path & to, bool andDelete) } } + +void copyFile(const Path & oldPath, const Path & newPath, bool andDelete) +{ + return copy(fs::directory_entry(fs::path(oldPath)), fs::path(newPath), andDelete); +} + void renameFile(const Path & oldName, const Path & newName) { fs::rename(oldName, newName); diff --git a/src/libutil/util.hh b/src/libutil/util.hh index bcee42327..acd77ee33 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -275,6 +275,13 @@ void renameFile(const Path & src, const Path & dst); */ void moveFile(const Path & src, const Path & dst); +/** + * Recursively copy the content of `oldPath` to `newPath`. If `andDelete` is + * `true`, then also remove `oldPath` (making this equivalent to `moveFile`, but + * with the guaranty that the destination will be “fresh”, with no stale inode + * or file descriptor pointing to it). + */ +void copyFile(const Path & oldPath, const Path & newPath, bool andDelete); /** * Wrappers arount read()/write() that read/write exactly the |