Reserve some disk space for the garbage collector

We can't open a SQLite database if the disk is full.  Since this
prevents the garbage collector from running when it's most needed, we
reserve some dummy space that we can free just before doing a garbage
collection.  This actually revives some old code from the Berkeley DB
days.

Fixes #27.
This commit is contained in:
Eelco Dolstra 2012-05-29 22:59:12 -04:00
parent 2c26985835
commit 4bc4da331a
9 changed files with 35 additions and 11 deletions

View file

@ -195,7 +195,7 @@ void checkStoreNotSymlink()
}
LocalStore::LocalStore()
LocalStore::LocalStore(bool reserveSpace)
{
substitutablePathsLoaded = false;
@ -221,6 +221,24 @@ LocalStore::LocalStore()
checkStoreNotSymlink();
/* We can't open a SQLite database if the disk is full. Since
this prevents the garbage collector from running when it's most
needed, we reserve some dummy space that we can free just
before doing a garbage collection. */
try {
Path reservedPath = nixDBPath + "/reserved";
if (reserveSpace) {
int reservedSize = queryIntSetting("gc-reserved-space", 1024 * 1024);
struct stat st;
if (stat(reservedPath.c_str(), &st) == -1 ||
st.st_size != reservedSize)
writeFile(reservedPath, string(reservedSize, 'X'));
}
else
deletePath(reservedPath);
} catch (SysError & e) { /* don't care about errors */
}
/* Acquire the big fat lock in shared mode to make sure that no
schema upgrade is in progress. */
try {