[Nix-dev] [PATCH] t/verify-selected-store-paths-only

Marc Weber marco-oweber at gmx.de
Mon Jul 12 05:42:43 CEST 2010


running nix-store --verify --check-contents takes very long.
Too long if you only want to check a couple of paths

This patch allows passing store paths limiting the number of paths
being checked. Example:

  nix-store --verify --check-contents /nix/store/00290kmd3f6cd3i01xxqbb9qdzqv56cl-openvpn-2.1.1

implementation details:
  store paths passed via command line arguments are intersected with the existing
  valid store paths list. Thus passing invalid strings can't cause damage.
  A error message is print in that case

Signed-off-by: Marc Weber <marco-oweber at gmx.de>
---
 doc/manual/nix-store.xml    |    3 ++-
 src/libstore/local-store.cc |   30 +++++++++++++++++++++++++-----
 src/libstore/local-store.hh |    2 +-
 src/nix-store/nix-store.cc  |    4 +---
 4 files changed, 29 insertions(+), 10 deletions(-)

diff --git a/doc/manual/nix-store.xml b/doc/manual/nix-store.xml
index 10bb3ed..03fc398 100644
--- a/doc/manual/nix-store.xml
+++ b/doc/manual/nix-store.xml
@@ -731,6 +731,7 @@ $ nix-store -q --roots $(which svn)
     <command>nix-store</command>
     <arg choice='plain'><option>--verify</option></arg>
     <arg><option>--check-contents</option></arg>
+    <arg choice='plain' rep='repeat'><replaceable>paths</replaceable></arg>
   </cmdsynopsis>
 </refsection>
 
@@ -741,7 +742,7 @@ consistency of the Nix database, and the consistency between the Nix
 database and the Nix store.  Any inconsistencies encountered are
 automatically repaired.  Inconsistencies are generally the result of
 the Nix store or database being modified by non-Nix tools, or of bugs
-in Nix itself.</para>
+in Nix itself. If store paths are given only those will be checked.</para>
 
 <para>There is one option:
 
diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc
index 2c0aa35..f8e469b 100644
--- a/src/libstore/local-store.cc
+++ b/src/libstore/local-store.cc
@@ -1039,12 +1039,20 @@ void LocalStore::deleteFromStore(const Path & path, unsigned long long & bytesFr
 }
 
 
-void LocalStore::verifyStore(bool checkContents)
+// if storePaths is empty check all valid store paths.
+// otherwise check subset of valid store paths only.
+void LocalStore::verifyStore(bool checkContents, Strings checkOnlyThese)
 {
     /* Check whether all valid paths actually exist. */
     printMsg(lvlInfo, "checking path existence");
 
-    PathSet validPaths2 = queryValidPaths(), validPaths;
+    PathSet validPaths2 = queryValidPaths(), validPaths, pathsToCheck, storePathsSet;
+
+    // Strings -> PathSet
+    for (Strings::iterator i = checkOnlyThese.begin();
+         i != checkOnlyThese.end(); ++i){
+        storePathsSet.insert(*i);
+    }
     
     foreach (PathSet::iterator, i, validPaths2) {
         checkInterrupt();
@@ -1064,17 +1072,29 @@ void LocalStore::verifyStore(bool checkContents)
                 if (unlink(infoFile.c_str()) == -1)
                     throw SysError(format("unlinking `%1%'") % infoFile);
             }
-            else validPaths.insert(*i);
+            else {
+                validPaths.insert(*i);
+                if (storePathsSet.empty() || storePathsSet.find(*i) != storePathsSet.end() )
+                    pathsToCheck.insert(*i);
+            }
         }
     }
 
+    // warn user if he passed strings which are not contained in validPaths
+    // thus were not added to pathsToCheck
+    for (Strings::iterator i = checkOnlyThese.begin();
+         i != checkOnlyThese.end(); ++i){
+        if (pathsToCheck.find(*i) == pathsToCheck.end())
+            printMsg(lvlError, format("path `%1%' is no valid store path - maybe it disappeared") % *i);
+    }
+
 
     /* Check the store path meta-information. */
     printMsg(lvlInfo, "checking path meta-information");
 
     std::map<Path, PathSet> referrersCache;
     
-    foreach (PathSet::iterator, i, validPaths) {
+    foreach (PathSet::iterator, i, pathsToCheck) {
         bool update = false;
         ValidPathInfo info = queryPathInfo(*i, true);
 
@@ -1124,7 +1144,7 @@ void LocalStore::verifyStore(bool checkContents)
     referrersCache.clear();
     
 
-    /* Check the referrers. */
+    /* Check the referrers. storePaths is ignored. This is fast enough */
     printMsg(lvlInfo, "checking referrers");
 
     std::map<Path, PathSet> referencesCache;
diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh
index 31f8d91..b322232 100644
--- a/src/libstore/local-store.hh
+++ b/src/libstore/local-store.hh
@@ -124,7 +124,7 @@ public:
     void optimiseStore(bool dryRun, OptimiseStats & stats);
 
     /* Check the integrity of the Nix store. */
-    void verifyStore(bool checkContents);
+    void verifyStore(bool checkContents, Strings storePaths);
 
     /* Register the validity of a path, i.e., that `path' exists, that
        the paths referenced by it exists, and in the case of an output
diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc
index 22effc6..cf0947e 100644
--- a/src/nix-store/nix-store.cc
+++ b/src/nix-store/nix-store.cc
@@ -617,8 +617,6 @@ static void opInit(Strings opFlags, Strings opArgs)
 /* Verify the consistency of the Nix environment. */
 static void opVerify(Strings opFlags, Strings opArgs)
 {
-    if (!opArgs.empty())
-        throw UsageError("no arguments expected");
 
     bool checkContents = false;
     
@@ -627,7 +625,7 @@ static void opVerify(Strings opFlags, Strings opArgs)
         if (*i == "--check-contents") checkContents = true;
         else throw UsageError(format("unknown flag `%1%'") % *i);
     
-    ensureLocalStore().verifyStore(checkContents);
+    ensureLocalStore().verifyStore(checkContents, opArgs);
 }
 
 
-- 
1.7.1




More information about the nix-dev mailing list