aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libstore/db.cc6
-rw-r--r--src/libstore/store.cc27
2 files changed, 26 insertions, 7 deletions
diff --git a/src/libstore/db.cc b/src/libstore/db.cc
index 82211bd1d..6740d6865 100644
--- a/src/libstore/db.cc
+++ b/src/libstore/db.cc
@@ -194,9 +194,9 @@ void Database::open(const string & path)
number, then run db_recover on the database to remove the
existing DB environment (since changes only take effect on
new environments). */
- env->set_lk_max_locks(4000);
- env->set_lk_max_lockers(4000);
- env->set_lk_max_objects(4000);
+ env->set_lk_max_locks(10000);
+ env->set_lk_max_lockers(10000);
+ env->set_lk_max_objects(10000);
env->set_lk_detect(DB_LOCK_DEFAULT);
/* Dangerous, probably, but from the docs it *seems* that BDB
diff --git a/src/libstore/store.cc b/src/libstore/store.cc
index 9f50e597e..4b9e807d2 100644
--- a/src/libstore/store.cc
+++ b/src/libstore/store.cc
@@ -319,6 +319,9 @@ void setReferences(const Transaction & txn, const Path & storePath,
Paths oldReferences;
nixDB.queryStrings(txn, dbReferences, storePath, oldReferences);
+
+ PathSet oldReferences2(oldReferences.begin(), oldReferences.end());
+ if (oldReferences2 == references) return;
nixDB.setStrings(txn, dbReferences, storePath,
Paths(references.begin(), references.end()));
@@ -454,6 +457,9 @@ void registerSubstitute(const Transaction & txn,
Substitutes subs = readSubstitutes(txn, srcPath);
+ if (find(subs.begin(), subs.end(), sub) != subs.end())
+ return;
+
/* New substitutes take precedence over old ones. If the
substitute is already present, it's moved to the front. */
remove(subs.begin(), subs.end(), sub);
@@ -469,6 +475,9 @@ Substitutes querySubstitutes(const Transaction & txn, const Path & srcPath)
}
+static void invalidatePath(Transaction & txn, const Path & path);
+
+
void clearSubstitutes()
{
Transaction txn(nixDB);
@@ -477,10 +486,20 @@ void clearSubstitutes()
Paths subKeys;
nixDB.enumTable(txn, dbSubstitutes, subKeys);
for (Paths::iterator i = subKeys.begin(); i != subKeys.end(); ++i) {
+
/* Delete all substitutes for path *i. */
nixDB.delPair(txn, dbSubstitutes, *i);
+
+ /* Maintain the cleanup invariant. */
+ if (!isValidPathTxn(txn, *i))
+ invalidatePath(txn, *i);
}
+ /* !!! there should be no referers to any of the invalid
+ substitutable paths. This should be the case by construction
+ (the only referers can be other invalid substitutable paths,
+ which have all been removed now). */
+
txn.commit();
}
@@ -541,7 +560,7 @@ void registerValidPath(const Transaction & txn,
/* Invalidate a path. The caller is responsible for checking that
there are no referers. */
-static void invalidatePath(const Path & path, Transaction & txn)
+static void invalidatePath(Transaction & txn, const Path & path)
{
debug(format("unregistering path `%1%'") % path);
@@ -673,7 +692,7 @@ void deleteFromStore(const Path & _path)
(referers.size() == 1 &&
*referers.begin() != path))
throw Error(format("cannot delete path `%1%' because it is in use") % path);
- invalidatePath(path, txn);
+ invalidatePath(txn, path);
}
txn.commit();
@@ -692,10 +711,10 @@ void verifyStore(bool checkContents)
for (Paths::iterator i = paths.begin(); i != paths.end(); ++i) {
if (!pathExists(*i)) {
printMsg(lvlError, format("path `%1%' disappeared") % *i);
- invalidatePath(*i, txn);
+ invalidatePath(txn, *i);
} else if (!isStorePath(*i)) {
printMsg(lvlError, format("path `%1%' is not in the Nix store") % *i);
- invalidatePath(*i, txn);
+ invalidatePath(txn, *i);
} else {
if (checkContents) {
Hash expected = queryHash(txn, *i);