Fix auto-gc

This commit is contained in:
Eelco Dolstra 2021-08-19 22:43:43 +02:00
parent 8614cf1334
commit ff453b06f9
3 changed files with 19 additions and 5 deletions

View file

@ -112,6 +112,9 @@ void LocalStore::addTempRoot(const StorePath & path)
} }
if (!state->fdGCLock)
state->fdGCLock = openGCLock();
restart: restart:
FdLock gcLock(state->fdGCLock.get(), ltRead, false, ""); FdLock gcLock(state->fdGCLock.get(), ltRead, false, "");
@ -653,8 +656,11 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
if (state.shouldDelete) if (state.shouldDelete)
deletePath(reservedPath); deletePath(reservedPath);
/* Acquire the global GC root. */ /* Acquire the global GC root. Note: we don't use state->fdGCLock
FdLock gcLock(_state.lock()->fdGCLock.get(), ltWrite, true, "waiting for the big garbage collector lock..."); here because then in auto-gc mode, another thread could
downgrade our exclusive lock. */
auto fdGCLock = openGCLock();
FdLock gcLock(fdGCLock.get(), ltWrite, true, "waiting for the big garbage collector lock...");
/* Start the server for receiving new roots. */ /* Start the server for receiving new roots. */
auto socketPath = stateDir.get() + gcSocketPath; auto socketPath = stateDir.get() + gcSocketPath;

View file

@ -382,11 +382,16 @@ LocalStore::LocalStore(const Params & params)
(select id from Realisations where drvPath = ? and outputName = ?)); (select id from Realisations where drvPath = ? and outputName = ?));
)"); )");
} }
}
AutoCloseFD LocalStore::openGCLock()
{
Path fnGCLock = stateDir + "/gc.lock"; Path fnGCLock = stateDir + "/gc.lock";
state->fdGCLock = open(fnGCLock.c_str(), O_RDWR | O_CREAT | O_CLOEXEC, 0600); auto fdGCLock = open(fnGCLock.c_str(), O_RDWR | O_CREAT | O_CLOEXEC, 0600);
if (!state->fdGCLock) if (!fdGCLock)
throw SysError("opening global GC lock '%1%'", fnGCLock); throw SysError("opening global GC lock '%1%'", fnGCLock);
return fdGCLock;
} }
@ -1509,7 +1514,8 @@ bool LocalStore::verifyStore(bool checkContents, RepairFlag repair)
/* Acquire the global GC lock to get a consistent snapshot of /* Acquire the global GC lock to get a consistent snapshot of
existing and valid paths. */ existing and valid paths. */
FdLock gcLock(_state.lock()->fdGCLock.get(), ltWrite, true, "waiting for the big garbage collector lock..."); auto fdGCLock = openGCLock();
FdLock gcLock(fdGCLock.get(), ltRead, true, "waiting for the big garbage collector lock...");
StringSet store; StringSet store;
for (auto & i : readDirectory(realStoreDir)) store.insert(i.name); for (auto & i : readDirectory(realStoreDir)) store.insert(i.name);

View file

@ -158,6 +158,8 @@ private:
void findTempRoots(Roots & roots, bool censor); void findTempRoots(Roots & roots, bool censor);
AutoCloseFD openGCLock();
public: public:
Roots findRoots(bool censor) override; Roots findRoots(bool censor) override;