aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2010-12-06 15:29:38 +0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2010-12-06 15:29:38 +0000
commit8062d3af30b27eb4d617c14856d4f3a173f8012e (patch)
treea1ab6dceb03955ec348092fd739d0fef4972e5e2 /src
parentde79d23f76c13da820f7167cd980264b2de28bd2 (diff)
* `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.
Diffstat (limited to 'src')
-rw-r--r--src/libstore/local-store.cc57
-rw-r--r--src/libstore/local-store.hh3
2 files changed, 49 insertions, 11 deletions
diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc
index 88548706b..3782d1b16 100644
--- a/src/libstore/local-store.cc
+++ b/src/libstore/local-store.cc
@@ -353,6 +353,8 @@ void LocalStore::openDB(bool create)
/* 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 @@ ValidPathInfo LocalStore::queryPathInfo(const Path & path)
}
+/* 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 @@ void LocalStore::verifyStore(bool checkContents)
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);
-
- /* 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));
- }
+ try {
+ ValidPathInfo info = queryPathInfo(*i);
+
+ /* 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());
+ }
}
}
}
diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh
index 4076e5957..f270fb723 100644
--- a/src/libstore/local-store.hh
+++ b/src/libstore/local-store.hh
@@ -203,6 +203,7 @@ private:
/* Some precompiled SQLite statements. */
SQLiteStmt stmtRegisterValidPath;
+ SQLiteStmt stmtUpdatePathInfo;
SQLiteStmt stmtAddReference;
SQLiteStmt stmtQueryPathInfo;
SQLiteStmt stmtQueryReferences;
@@ -235,6 +236,8 @@ private:
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);