Merge pull request #5770 from edolstra/gc-fixes

Fix macOS GC failures
This commit is contained in:
Eelco Dolstra 2021-12-13 19:55:32 +01:00 committed by GitHub
commit 6ae5f39ea0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 24 additions and 3 deletions

View file

@ -126,7 +126,17 @@ void LocalStore::addTempRoot(const StorePath & path)
auto socketPath = stateDir.get() + gcSocketPath; auto socketPath = stateDir.get() + gcSocketPath;
debug("connecting to '%s'", socketPath); debug("connecting to '%s'", socketPath);
state->fdRootsSocket = createUnixDomainSocket(); state->fdRootsSocket = createUnixDomainSocket();
try {
nix::connect(state->fdRootsSocket.get(), socketPath); 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 { try {
@ -523,6 +533,8 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
AutoCloseFD fdClient = accept(fdServer.get(), nullptr, nullptr); AutoCloseFD fdClient = accept(fdServer.get(), nullptr, nullptr);
if (!fdClient) continue; if (!fdClient) continue;
debug("GC roots server accepted new client");
/* Process the connection in a separate thread. */ /* Process the connection in a separate thread. */
auto fdClient_ = fdClient.get(); auto fdClient_ = fdClient.get();
std::thread clientThread([&, fdClient = std::move(fdClient)]() { 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) { while (true) {
try { try {
auto path = readLine(fdClient.get()); auto path = readLine(fdClient.get());
@ -559,7 +577,10 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
} else } else
printError("received garbage instead of a root from client"); printError("received garbage instead of a root from client");
writeFull(fdClient.get(), "1", false); writeFull(fdClient.get(), "1", false);
} catch (Error &) { break; } } catch (Error & e) {
debug("reading GC root from client: %s", e.msg());
break;
}
} }
}); });

View file

@ -19,7 +19,7 @@ pid=$!
sleep 2 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; with import ./config.nix;
mkDerivation { mkDerivation {
name = \"non-blocking\"; name = \"non-blocking\";