Author: eelco
Date: Thu Oct 14 15:55:51 2010
New Revision: 24293
URL: https://svn.nixos.org/websvn/nix/?rev=24293&sc=1

Log:
* Wrap deleteFromStore() in a transaction.  Otherwise there might be a
  race with other processes that add new referrers to a path,
  resulting in the garbage collector crashing with "foreign key
  constraint failed".  (Nix/4)
* Make --gc --print-dead etc. interruptible.

Modified:
   nix/branches/sqlite/src/libstore/gc.cc
   nix/branches/sqlite/src/libstore/local-store.cc

Modified: nix/branches/sqlite/src/libstore/gc.cc
==============================================================================
--- nix/branches/sqlite/src/libstore/gc.cc      Thu Oct 14 15:44:58 2010        
(r24292)
+++ nix/branches/sqlite/src/libstore/gc.cc      Thu Oct 14 15:55:51 2010        
(r24293)
@@ -421,7 +421,7 @@
 };
 
 
-static bool doDelete(GCOptions::GCAction action)
+static bool shouldDelete(GCOptions::GCAction action)
 {
     return action == GCOptions::gcDeleteDead
         || action == GCOptions::gcDeleteSpecific;
@@ -438,6 +438,8 @@
     
 bool LocalStore::tryToDelete(GCState & state, const Path & path)
 {
+    checkInterrupt();
+    
     if (!pathExists(path)) return true;
     if (state.deleted.find(path) != state.deleted.end()) return true;
     if (state.live.find(path) != state.live.end()) return false;
@@ -516,7 +518,7 @@
     }
 
     /* The path is garbage, so delete it. */
-    if (doDelete(state.options.action)) {
+    if (shouldDelete(state.options.action)) {
         printMsg(lvlInfo, format("deleting `%1%'") % path);
 
         unsigned long long bytesFreed, blocksFreed;
@@ -625,7 +627,7 @@
         vector<Path> entries_(entries.begin(), entries.end());
         random_shuffle(entries_.begin(), entries_.end());
 
-        if (doDelete(state.options.action))
+        if (shouldDelete(state.options.action))
             printMsg(lvlError, format("deleting garbage..."));
         else
             printMsg(lvlError, format("determining live/dead paths..."));

Modified: nix/branches/sqlite/src/libstore/local-store.cc
==============================================================================
--- nix/branches/sqlite/src/libstore/local-store.cc     Thu Oct 14 15:44:58 
2010        (r24292)
+++ nix/branches/sqlite/src/libstore/local-store.cc     Thu Oct 14 15:55:51 
2010        (r24293)
@@ -298,11 +298,10 @@
     if (sqlite3_exec(db, ("pragma synchronous = " + syncMode + ";").c_str(), 
0, 0, 0) != SQLITE_OK)
         throw SQLiteError(db, "setting synchronous mode");
 
-    /* Set the SQLite journal mode.  The default is write-ahead
-       logging since it's the fastest and supports more concurrency.
-       The downside is that it doesn't work over NFS, so allow
-       truncate mode alternatively. */
-    string mode = queryBoolSetting("use-sqlite-wal", true) ? "wal" : 
"truncate";
+    /* Set the SQLite journal mode.  WAL mode is fastest, but doesn't
+       seem entirely stable at the moment (Oct. 2010).  Thus, use
+       truncate mode by default. */
+    string mode = queryBoolSetting("use-sqlite-wal", false) ? "wal" : 
"truncate";
     string prevMode;
     {
         SQLiteStmt stmt;
@@ -1220,6 +1219,8 @@
 
     assertStorePath(path);
 
+    SQLiteTxn txn(db);
+
     if (isValidPath(path)) {
         PathSet referrers; queryReferrers(path, referrers);
         referrers.erase(path); /* ignore self-references */
@@ -1230,6 +1231,8 @@
     }
 
     deletePathWrapped(path, bytesFreed, blocksFreed);
+
+    txn.commit();
 }
 
 
_______________________________________________
nix-commits mailing list
[email protected]
http://mail.cs.uu.nl/mailman/listinfo/nix-commits

Reply via email to