aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libstore/store.cc16
-rw-r--r--src/libstore/store.hh10
-rw-r--r--src/nix-store/main.cc2
3 files changed, 24 insertions, 4 deletions
diff --git a/src/libstore/store.cc b/src/libstore/store.cc
index 9c68c3392..25e2d6e36 100644
--- a/src/libstore/store.cc
+++ b/src/libstore/store.cc
@@ -76,11 +76,25 @@ static void upgradeStore07();
static void upgradeStore09();
-void openDB()
+void openDB(bool reserveSpace)
{
if (readOnlyMode) return;
try {
+ Path reservedPath = nixDBPath + "/reserved";
+ off_t reservedSize = 1024 * 1024;
+ if (reserveSpace) {
+ struct stat st;
+ if (stat(reservedPath.c_str(), &st) == -1 ||
+ st.st_size != reservedSize)
+ writeFile(reservedPath, string(1024 * 1024, 'X'));
+ }
+ else
+ deletePath(reservedPath);
+ } catch (SysError & e) { /* don't care about errors */
+ }
+
+ try {
nixDB.open(nixDBPath);
} catch (DbNoPermission & e) {
printMsg(lvlTalkative, "cannot access Nix database; continuing anyway");
diff --git a/src/libstore/store.hh b/src/libstore/store.hh
index 2d8018d5f..c617585ba 100644
--- a/src/libstore/store.hh
+++ b/src/libstore/store.hh
@@ -37,8 +37,14 @@ struct Substitute
typedef list<Substitute> Substitutes;
-/* Open the database environment. */
-void openDB();
+/* Open the database environment. If `reserveSpace' is true, make
+ sure that a big empty file exists in /nix/var/nix/db/reserved. If
+ `reserveSpace' is false, delete this file if it exists. The idea
+ is that on normal operation, the file exists; but when we run the
+ garbage collector, it is deleted. This is to ensure that the
+ garbage collector has a small amount of disk space available, which
+ is required to open the Berkeley DB environment. */
+void openDB(bool reserveSpace = true);
/* Create the required database tables. */
void initDB();
diff --git a/src/nix-store/main.cc b/src/nix-store/main.cc
index 88e6720c0..0ee7b0a7e 100644
--- a/src/nix-store/main.cc
+++ b/src/nix-store/main.cc
@@ -686,7 +686,7 @@ void run(Strings args)
if (!op) throw UsageError("no operation specified");
if (op != opDump && op != opRestore) /* !!! hack */
- openDB();
+ openDB(op != opGC);
op(opFlags, opArgs);
}