From b33fefcb92e02725fc77b6adfabab1c1f43e9aa1 Mon Sep 17 00:00:00 2001
From: Daiderd Jordan <daiderd@gmail.com>
Date: Sat, 4 Jan 2020 17:47:52 +0100
Subject: [PATCH] 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);
 }