forked from lix-project/lix
* `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.
This commit is contained in:
parent
de79d23f76
commit
8062d3af30
|
@ -353,6 +353,8 @@ void LocalStore::openDB(bool create)
|
||||||
/* Prepare SQL statements. */
|
/* Prepare SQL statements. */
|
||||||
stmtRegisterValidPath.create(db,
|
stmtRegisterValidPath.create(db,
|
||||||
"insert into ValidPaths (path, hash, registrationTime, deriver, narSize) values (?, ?, ?, ?, ?);");
|
"insert into ValidPaths (path, hash, registrationTime, deriver, narSize) values (?, ?, ?, ?, ?);");
|
||||||
|
stmtUpdatePathInfo.create(db,
|
||||||
|
"update ValidPaths set narSize = ? where path = ?;");
|
||||||
stmtAddReference.create(db,
|
stmtAddReference.create(db,
|
||||||
"insert or replace into Refs (referrer, reference) values (?, ?);");
|
"insert or replace into Refs (referrer, reference) values (?, ?);");
|
||||||
stmtQueryPathInfo.create(db,
|
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)
|
unsigned long long LocalStore::queryValidPathId(const Path & path)
|
||||||
{
|
{
|
||||||
SQLiteStmtUse use(stmtQueryPathInfo);
|
SQLiteStmtUse use(stmtQueryPathInfo);
|
||||||
|
@ -1305,23 +1322,41 @@ void LocalStore::verifyStore(bool checkContents)
|
||||||
foreach (PathSet::iterator, i, validPaths2)
|
foreach (PathSet::iterator, i, validPaths2)
|
||||||
verifyPath(*i, store, done, validPaths);
|
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). */
|
/* Optionally, check the content hashes (slow). */
|
||||||
if (checkContents) {
|
if (checkContents) {
|
||||||
printMsg(lvlInfo, "checking hashes...");
|
printMsg(lvlInfo, "checking hashes...");
|
||||||
|
|
||||||
foreach (PathSet::iterator, i, validPaths) {
|
foreach (PathSet::iterator, i, validPaths) {
|
||||||
ValidPathInfo info = queryPathInfo(*i);
|
try {
|
||||||
|
ValidPathInfo info = queryPathInfo(*i);
|
||||||
|
|
||||||
/* Check the content hash (optionally - slow). */
|
/* Check the content hash (optionally - slow). */
|
||||||
printMsg(lvlTalkative, format("checking contents of `%1%'") % *i);
|
printMsg(lvlTalkative, format("checking contents of `%1%'") % *i);
|
||||||
Hash current = hashPath(info.hash.type, *i).first;
|
HashResult current = hashPath(info.hash.type, *i);
|
||||||
if (current != info.hash) {
|
|
||||||
printMsg(lvlError, format("path `%1%' was modified! "
|
if (current.first != info.hash) {
|
||||||
"expected hash `%2%', got `%3%'")
|
printMsg(lvlError, format("path `%1%' was modified! "
|
||||||
% *i % printHash(info.hash) % printHash(current));
|
"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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -203,6 +203,7 @@ private:
|
||||||
|
|
||||||
/* Some precompiled SQLite statements. */
|
/* Some precompiled SQLite statements. */
|
||||||
SQLiteStmt stmtRegisterValidPath;
|
SQLiteStmt stmtRegisterValidPath;
|
||||||
|
SQLiteStmt stmtUpdatePathInfo;
|
||||||
SQLiteStmt stmtAddReference;
|
SQLiteStmt stmtAddReference;
|
||||||
SQLiteStmt stmtQueryPathInfo;
|
SQLiteStmt stmtQueryPathInfo;
|
||||||
SQLiteStmt stmtQueryReferences;
|
SQLiteStmt stmtQueryReferences;
|
||||||
|
@ -235,6 +236,8 @@ private:
|
||||||
void verifyPath(const Path & path, const PathSet & store,
|
void verifyPath(const Path & path, const PathSet & store,
|
||||||
PathSet & done, PathSet & validPaths);
|
PathSet & done, PathSet & validPaths);
|
||||||
|
|
||||||
|
void updatePathInfo(const ValidPathInfo & info);
|
||||||
|
|
||||||
void upgradeStore6();
|
void upgradeStore6();
|
||||||
PathSet queryValidPathsOld();
|
PathSet queryValidPathsOld();
|
||||||
ValidPathInfo queryPathInfoOld(const Path & path);
|
ValidPathInfo queryPathInfoOld(const Path & path);
|
||||||
|
|
Loading…
Reference in a new issue