Author: eelco
Date: Mon Dec  6 15:29:38 2010
New Revision: 25004
URL: https://svn.nixos.org/websvn/nix/?rev=25004&sc=1

Log:
* `nix-store --verify --check-contents': don't hold the global GC lock
  while checking the contents, since this operation can take a very
  long time to finish.  Also, fill in missing narSize fields in the DB
  while doing this.

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

Modified: nix/branches/sqlite/src/libstore/local-store.cc
==============================================================================
--- nix/branches/sqlite/src/libstore/local-store.cc     Mon Dec  6 14:25:58 
2010        (r25003)
+++ nix/branches/sqlite/src/libstore/local-store.cc     Mon Dec  6 15:29:38 
2010        (r25004)
@@ -353,6 +353,8 @@
     /* Prepare SQL statements. */
     stmtRegisterValidPath.create(db,
         "insert into ValidPaths (path, hash, registrationTime, deriver, 
narSize) values (?, ?, ?, ?, ?);");
+    stmtUpdatePathInfo.create(db,
+        "update ValidPaths set narSize = ? where path = ?;");
     stmtAddReference.create(db,
         "insert or replace into Refs (referrer, reference) values (?, ?);");
     stmtQueryPathInfo.create(db,
@@ -645,6 +647,21 @@
 }
 
 
+/* Update path info in the database.  Currently only updated the
+   narSize field. */
+void LocalStore::updatePathInfo(const ValidPathInfo & info)
+{
+    SQLiteStmtUse use(stmtUpdatePathInfo);
+    if (info.narSize != 0)
+        stmtUpdatePathInfo.bind64(info.narSize);
+    else
+        stmtUpdatePathInfo.bind(); // null
+    stmtUpdatePathInfo.bind(info.path);
+    if (sqlite3_step(stmtUpdatePathInfo) != SQLITE_DONE)
+        throwSQLiteError(db, format("updating info of path `%1%' in database") 
% info.path);
+}
+
+
 unsigned long long LocalStore::queryValidPathId(const Path & path)
 {
     SQLiteStmtUse use(stmtQueryPathInfo);
@@ -1305,23 +1322,41 @@
     foreach (PathSet::iterator, i, validPaths2)
         verifyPath(*i, store, done, validPaths);
 
+    /* Release the GC lock so that checking content hashes (which can
+       take ages) doesn't block the GC or builds. */
+    fdGCLock.close();
+
     /* Optionally, check the content hashes (slow). */
     if (checkContents) {
         printMsg(lvlInfo, "checking hashes...");
 
         foreach (PathSet::iterator, i, validPaths) {
-            ValidPathInfo info = queryPathInfo(*i);
+            try {
+                ValidPathInfo info = queryPathInfo(*i);
 
-            /* Check the content hash (optionally - slow). */
-            printMsg(lvlTalkative, format("checking contents of `%1%'") % *i);
-            Hash current = hashPath(info.hash.type, *i).first;
-            if (current != info.hash) {
-                printMsg(lvlError, format("path `%1%' was modified! "
-                        "expected hash `%2%', got `%3%'")
-                    % *i % printHash(info.hash) % printHash(current));
-            }
+                /* Check the content hash (optionally - slow). */
+                printMsg(lvlTalkative, format("checking contents of `%1%'") % 
*i);
+                HashResult current = hashPath(info.hash.type, *i);
+                
+                if (current.first != info.hash) {
+                    printMsg(lvlError, format("path `%1%' was modified! "
+                            "expected hash `%2%', got `%3%'")
+                        % *i % printHash(info.hash) % 
printHash(current.first));
+                } else {
+                    /* Fill in missing narSize fields (from old stores). */
+                    if (info.narSize == 0) {
+                        printMsg(lvlError, format("updating size field on 
`%1%' to %2%") % *i % current.second);
+                        info.narSize = current.second;
+                        updatePathInfo(info);
+                    }
+                }
             
-            /* !!! Check info.narSize */
+            } catch (Error & e) {
+                /* It's possible that the path got GC'ed, so ignore
+                   errors on invalid paths. */
+                if (isValidPath(*i)) throw;
+                printMsg(lvlError, format("warning: %1%") % e.msg());
+            }
         }
     }
 }

Modified: nix/branches/sqlite/src/libstore/local-store.hh
==============================================================================
--- nix/branches/sqlite/src/libstore/local-store.hh     Mon Dec  6 14:25:58 
2010        (r25003)
+++ nix/branches/sqlite/src/libstore/local-store.hh     Mon Dec  6 15:29:38 
2010        (r25004)
@@ -203,6 +203,7 @@
 
     /* Some precompiled SQLite statements. */
     SQLiteStmt stmtRegisterValidPath;
+    SQLiteStmt stmtUpdatePathInfo;
     SQLiteStmt stmtAddReference;
     SQLiteStmt stmtQueryPathInfo;
     SQLiteStmt stmtQueryReferences;
@@ -235,6 +236,8 @@
     void verifyPath(const Path & path, const PathSet & store,
         PathSet & done, PathSet & validPaths);
 
+    void updatePathInfo(const ValidPathInfo & info);
+
     void upgradeStore6();
     PathSet queryValidPathsOld();
     ValidPathInfo queryPathInfoOld(const Path & path);
_______________________________________________
nix-commits mailing list
[email protected]
http://mail.cs.uu.nl/mailman/listinfo/nix-commits

Reply via email to