aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2021-12-13 19:55:32 +0100
committerGitHub <noreply@github.com>2021-12-13 19:55:32 +0100
commit6ae5f39ea07f67b0dc746860ddf25e5659c94d81 (patch)
treec0e81edcdf789db71428024a4ca1176499b33ce7
parente2e5f3a78f31e4e72170ebfe48cbbb082860cc24 (diff)
parentd17d46cfc2e38efb63565270a1fba7b03b37de16 (diff)
Merge pull request #5770 from edolstra/gc-fixes
Fix macOS GC failures
-rw-r--r--src/libstore/gc.cc25
-rw-r--r--tests/gc-non-blocking.sh2
2 files changed, 24 insertions, 3 deletions
diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc
index 7a414da6b..e35199b3d 100644
--- a/src/libstore/gc.cc
+++ b/src/libstore/gc.cc
@@ -126,7 +126,17 @@ void LocalStore::addTempRoot(const StorePath & path)
auto socketPath = stateDir.get() + gcSocketPath;
debug("connecting to '%s'", socketPath);
state->fdRootsSocket = createUnixDomainSocket();
- nix::connect(state->fdRootsSocket.get(), socketPath);
+ try {
+ nix::connect(state->fdRootsSocket.get(), socketPath);
+ } catch (SysError & e) {
+ /* The garbage collector may have exited, so we need to
+ restart. */
+ if (e.errNo == ECONNREFUSED) {
+ debug("GC socket connection refused");
+ state->fdRootsSocket.close();
+ goto restart;
+ }
+ }
}
try {
@@ -523,6 +533,8 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
AutoCloseFD fdClient = accept(fdServer.get(), nullptr, nullptr);
if (!fdClient) continue;
+ debug("GC roots server accepted new client");
+
/* Process the connection in a separate thread. */
auto fdClient_ = fdClient.get();
std::thread clientThread([&, fdClient = std::move(fdClient)]() {
@@ -535,6 +547,12 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
}
});
+ /* On macOS, accepted sockets inherit the
+ non-blocking flag from the server socket, so
+ explicitly make it blocking. */
+ if (fcntl(fdServer.get(), F_SETFL, fcntl(fdServer.get(), F_GETFL) & ~O_NONBLOCK) == -1)
+ abort();
+
while (true) {
try {
auto path = readLine(fdClient.get());
@@ -559,7 +577,10 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
} else
printError("received garbage instead of a root from client");
writeFull(fdClient.get(), "1", false);
- } catch (Error &) { break; }
+ } catch (Error & e) {
+ debug("reading GC root from client: %s", e.msg());
+ break;
+ }
}
});
diff --git a/tests/gc-non-blocking.sh b/tests/gc-non-blocking.sh
index 8b21c6f1c..0d781485d 100644
--- a/tests/gc-non-blocking.sh
+++ b/tests/gc-non-blocking.sh
@@ -19,7 +19,7 @@ pid=$!
sleep 2
-outPath=$(nix-build -o "$TEST_ROOT/result" -E "
+outPath=$(nix-build --max-silent-time 60 -o "$TEST_ROOT/result" -E "
with import ./config.nix;
mkDerivation {
name = \"non-blocking\";