diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc index d82118ba7..cc50f6ae4 100644 --- a/src/libstore/gc.cc +++ b/src/libstore/gc.cc @@ -407,12 +407,13 @@ static void addAdditionalRoots(PathSet & roots) static void dfsVisit(const PathSet & paths, const Path & path, PathSet & visited, Paths & sorted) { - if (visited.find(path) != visited.end()) return; + if (visited.find(path) != visited.end()) + return; visited.insert(path); PathSet references; if (store->isValidPath(path)) - store->queryStoreReferences(path, references, 0); + store->queryStoreReferences(path, references, 0); for (PathSet::iterator i = references.begin(); i != references.end(); ++i) @@ -634,6 +635,21 @@ void LocalStore::collectGarbage(GCAction action, const PathSet & pathsToDelete, will not work anymore because we get cycles. */ Paths storePaths = topoSortPaths(storePathSet); + for (Paths::iterator i = storePaths.begin(); i != storePaths.end(); ++i) { + + if(*i != "/nix/store/zg8x9wdhcs4j0hvf33vg34c7m65adrpa-env-manifest") + continue; + + printMsg(lvlError, format("Consider DEL `%1%'") % *i); + + PathSet references; + store->queryStoreReferences(*i, references, 0); + for (PathSet::iterator j = references.begin(); j != references.end(); ++j) { + printMsg(lvlError, format("REF `%1%'") % *j); + } + + } + /* Try to delete store paths in the topologically sorted order. */ for (Paths::iterator i = storePaths.begin(); i != storePaths.end(); ++i) { diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc index 23a23c25c..18bd17c43 100644 --- a/src/libstore/globals.cc +++ b/src/libstore/globals.cc @@ -36,6 +36,7 @@ static bool settingsRead = false; uid_t callingUID = 0; //A root user will not set this value, so the default uid is 0 bool singleThreaded = false; //TODO Gives an error: cannot start worker (environment already open) / waiting for process X: No child processes bool sendOutput = true; +bool sleepForGDB = false; static std::map settings; diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh index b163f127e..252a8cf38 100644 --- a/src/libstore/globals.hh +++ b/src/libstore/globals.hh @@ -104,8 +104,10 @@ string queryCallingUsername(); /* get the username based on the UID of the user currently runs the process */ string queryCurrentUsername(); +/* Debugging variables */ extern bool singleThreaded; -extern bool sendOutput; +extern bool sendOutput; +extern bool sleepForGDB; } diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index 30e1e5e37..b278344b0 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -401,12 +401,10 @@ bool LocalStore::isValidComponentOrStatePath(const Path & path) void setReferences(const Transaction & txn, const Path & store_or_statePath, const PathSet & references, const PathSet & stateReferences, const unsigned int revision) { - /* For unrealisable paths, we can only clear the references. */ if (references.size() > 0 && !isValidComponentOrStatePathTxn(txn, store_or_statePath)) throw Error(format("cannot set references for path `%1%' which is invalid and has no substitutes") % store_or_statePath); - /* for (PathSet::iterator i = references.begin(); i != references.end(); ++i) printMsg(lvlError, format("'%2%' has references: %1%") % *i % store_or_statePath); @@ -483,14 +481,14 @@ void queryXReferencesTxn(const Transaction & txn, const Path & store_or_statePat references.insert(references2.begin(), references2.end()); } -void LocalStore::queryStoreReferences(const Path & storePath, PathSet & references, const unsigned int revision) +void LocalStore::queryStoreReferences(const Path & componentOrstatePath, PathSet & references, const unsigned int revision) { - nix::queryXReferencesTxn(noTxn, storePath, references, revision, true); + nix::queryXReferencesTxn(noTxn, componentOrstatePath, references, true, revision); } void LocalStore::queryStateReferences(const Path & componentOrstatePath, PathSet & stateReferences, const unsigned int revision) { - nix::queryXReferencesTxn(noTxn, componentOrstatePath, stateReferences, revision, false); + nix::queryXReferencesTxn(noTxn, componentOrstatePath, stateReferences, false, revision); } //Private diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index 07f4be0b9..81e6b0a4c 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -18,21 +18,54 @@ namespace nix { -Path readStorePath(Source & from) +Path readXPath(Source & from, const bool canBeStore, const bool canBeState) { Path path = readString(from); - assertStorePath(path); + + if(canBeStore && canBeState) + assertStoreOrStatePath(path); + else if(canBeStore) + assertStorePath(path); + else if(canBeState) + assertStatePath(path); + return path; } +Path readStorePath(Source & from) +{ + return readXPath(from, true, false); +} +Path readStatePath(Source & from) +{ + return readXPath(from, false, true); +} +Path readStoreOrStatePath(Source & from) +{ + return readXPath(from, true, true); +} - -PathSet readStorePaths(Source & from) +PathSet readXPaths(Source & from, const bool canBeStore, const bool canBeState) { PathSet paths = readStringSet(from); - for (PathSet::iterator i = paths.begin(); i != paths.end(); ++i) - assertStorePath(*i); + for (PathSet::iterator i = paths.begin(); i != paths.end(); ++i){ + if(canBeStore && canBeState) + assertStoreOrStatePath(*i); + else if(canBeStore) + assertStorePath(*i); + else if(canBeState) + assertStatePath(*i); + } return paths; } +PathSet readStorePaths(Source & from) +{ + return readXPaths(from, true, false); +} +PathSet readStatePaths(Source & from) +{ + return readXPaths(from, false, true); +} + RemoteStore::RemoteStore() @@ -246,7 +279,7 @@ void RemoteStore::queryStateReferences(const Path & path, writeString(path, to); writeBigUnsignedInt(revision, to); processStderr(); - PathSet stateReferences2 = readStorePaths(from); + PathSet stateReferences2 = readStatePaths(from); stateReferences.insert(stateReferences2.begin(), stateReferences2.end()); } @@ -270,7 +303,7 @@ void RemoteStore::queryStateReferrers(const Path & path, writeString(path, to); writeBigUnsignedInt(revision, to); processStderr(); - PathSet stateReferrers2 = readStorePaths(from); + PathSet stateReferrers2 = readStatePaths(from); stateReferrers.insert(stateReferrers2.begin(), stateReferrers2.end()); } diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc index d10e496ea..f8aa927eb 100644 --- a/src/libstore/store-api.cc +++ b/src/libstore/store-api.cc @@ -53,6 +53,13 @@ void assertStatePath(const Path & path) throw Error(format("state path `%1%' is not in the Nix state-store") % path); } +void assertStoreOrStatePath(const Path & path) +{ + if (!isStorePath(path) && !isStatePath(path)) + throw Error(format("path `%1%' is not a store or state path") % path); +} + + Path toStorePath(const Path & path) { diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh index 0eb36ca42..877d99cda 100644 --- a/src/libstore/store-api.hh +++ b/src/libstore/store-api.hh @@ -56,7 +56,8 @@ public: /* Queries the set of outgoing FS state-references for a store path. The result is not cleared. */ - virtual void queryStateReferences(const Path & storePath, PathSet & stateReferences, const unsigned int revision) = 0; + virtual void queryStateReferences(const Path & path, + PathSet & stateReferences, const unsigned int revision) = 0; /* Queries the set of incoming FS references for a store path. The result is not cleared. */ @@ -238,6 +239,7 @@ public: /* Throw an exception if `path' is not directly in the Nix store. */ void assertStorePath(const Path & path); void assertStatePath(const Path & path); +void assertStoreOrStatePath(const Path & path); bool isInStore(const Path & path); bool isStorePath(const Path & path); diff --git a/src/libstore/store-state.cc b/src/libstore/store-state.cc index 52a56aad2..bd7867aa8 100644 --- a/src/libstore/store-state.cc +++ b/src/libstore/store-state.cc @@ -128,13 +128,6 @@ void revertToRevisionTxn(const Transaction & txn, const Path & statePath, const Snapshots revisioned_paths = (*i).second; unsigned int timestamp = getTimestamps[statePath]; - - //get its derivation-state-items - //Derivation statePath_drv = derivationFromPathTxn(txn, queryStatePathDrvTxn(txn, statePath)); - //DerivationStateOutputDirs stateOutputDirs = statePath_drv.stateOutputDirs; - - //TODO Sort snapshots??? eg first restore root, then the subdirs?? - for (Snapshots::iterator j = revisioned_paths.begin(); j != revisioned_paths.end(); ++j){ Path revertPathOrFile = (*j).first; unsigned int epoch = (*j).second; diff --git a/src/libstore/worker-protocol.hh b/src/libstore/worker-protocol.hh index 5725598e7..a69711fd2 100644 --- a/src/libstore/worker-protocol.hh +++ b/src/libstore/worker-protocol.hh @@ -71,7 +71,11 @@ typedef enum { Path readStorePath(Source & from); +Path readStatePath(Source & from); +Path readStoreOrStatePath(Source & from); + PathSet readStorePaths(Source & from); +PathSet readStatePaths(Source & from); } diff --git a/src/nix-state/nix-state.cc b/src/nix-state/nix-state.cc index 75a6245e7..8c6f91660 100644 --- a/src/nix-state/nix-state.cc +++ b/src/nix-state/nix-state.cc @@ -20,7 +20,6 @@ using namespace nix; using std::cin; using std::cout; - typedef void (* Operation) (Strings opFlags, Strings opArgs); //two global variables @@ -73,7 +72,7 @@ Derivation getDerivation(const string & fullPath, const Strings & program_args, //printMsg(lvlError, format("'%1%' - '%2%' - '%3%' - '%4%' - '%5%'") % componentPath % state_identifier % binary % username % bool2string(isStateComponent)); if(isStateComponent) - derivers = store->queryDerivers(componentPath, state_identifier, username); + derivers = store->queryDerivers(componentPath, state_identifier, username); //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! needed ??? else derivers.insert(store->queryDeriver(componentPath)); @@ -594,13 +593,38 @@ void run(Strings args) throw Error(format("aaa")); return; - */ - /* - store = openStore(); store->isStateComponent("/nix/state/rrki0fgjc42sfszgk95cg0bpchbc5xp7-hellohardcodedstateworld-1.0-test"); + + store = openStore(); + + PathSet p; + p.insert("/nix/store/zg8x9wdhcs4j0hvf33vg34c7m65adrpa-env-manifest"); + p.insert("/nix/store/zwm6lwydkh84wmzhffvcgazmcrmamqw7-hellohardcodedstateworld-1.0"); + for (PathSet::iterator i = p.begin(); i != p.end(); ++i) { + printMsg(lvlError, format("Path p has references `%1%'") % *i); + PathSet references; + store->queryStoreReferences(*i, references, 0); + for (PathSet::iterator j = references.begin(); j != references.end(); ++j) { + printMsg(lvlError, format("REF `%1%'") % *j); + } + } + + PathSet p2; + p2.insert("/nix/store/zg8x9wdhcs4j0hvf33vg34c7m65adrpa-env-manifest"); + p2.insert("/nix/store/zwm6lwydkh84wmzhffvcgazmcrmamqw7-hellohardcodedstateworld-1.0"); + for (PathSet::iterator i = p.begin(); i != p.end(); ++i) { + printMsg(lvlError, format("Path p has referrers `%1%'") % *i); + PathSet referrers; + store->queryStoreReferrers(*i, referrers, 0); + for (PathSet::iterator j = referrers.begin(); j != referrers.end(); ++j) { + printMsg(lvlError, format("REF `%1%'") % *j); + } + } + + return; - */ + */ /* test */ if(args.size() == 1 && ( *(args.begin()) == "--help" || *(args.begin()) == "--statehelp")){ diff --git a/src/nix-worker/nix-worker.cc b/src/nix-worker/nix-worker.cc index 270b4fb5e..8f8219eae 100644 --- a/src/nix-worker/nix-worker.cc +++ b/src/nix-worker/nix-worker.cc @@ -250,7 +250,7 @@ static void performOp(Source & from, Sink & to, unsigned int op) } case wopIsValidStatePath: { - Path path = readString(from); //TODO readStatePath + Path path = readStatePath(from); startWork(); bool result = store->isValidStatePath(path); stopWork(); @@ -259,7 +259,7 @@ static void performOp(Source & from, Sink & to, unsigned int op) } case wopIsValidComponentOrStatePath: { - Path path = readStorePath(from); + Path path = readStoreOrStatePath(from); startWork(); bool result = store->isValidComponentOrStatePath(path); stopWork(); @@ -286,7 +286,7 @@ static void performOp(Source & from, Sink & to, unsigned int op) } case wopQueryStatePathDrv: { - Path path = readString(from); //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! make a readStatePath... + Path path = readStatePath(from); startWork(); Path p = store->queryStatePathDrv(path); stopWork(); @@ -296,7 +296,7 @@ static void performOp(Source & from, Sink & to, unsigned int op) case wopQueryStoreReferences: case wopQueryStoreReferrers: { - Path path = readStorePath(from); + Path path = readStoreOrStatePath(from); unsigned int revision = readBigUnsignedInt(from); startWork(); PathSet paths; @@ -311,7 +311,7 @@ static void performOp(Source & from, Sink & to, unsigned int op) case wopQueryStateReferences: case wopQueryStateReferrers: { - Path path = readStorePath(from); + Path path = readStoreOrStatePath(from); unsigned int revision = readBigUnsignedInt(from); startWork(); PathSet paths; @@ -493,7 +493,7 @@ static void performOp(Source & from, Sink & to, unsigned int op) } case wopIsStateComponent: { - Path path = readString(from); + Path path = readStorePath(from); startWork(); bool result = store->isStateComponent(path); stopWork(); @@ -502,7 +502,7 @@ static void performOp(Source & from, Sink & to, unsigned int op) } case wopStorePathRequisites: { - Path storeOrstatePath = readString(from); + Path storeOrstatePath = readStoreOrStatePath(from); bool includeOutputs = readInt(from) == 1; PathSet paths = readStringSet(from); bool withComponents = readInt(from) == 1; @@ -528,7 +528,7 @@ static void performOp(Source & from, Sink & to, unsigned int op) case wopQueryStateRevisions: { printMsg(lvlError, format("queryStateRevisions nix-worker")); - Path statePath = readString(from); + Path statePath = readStatePath(from); unsigned int revision = readBigUnsignedInt(from); RevisionClosure revisions; RevisionClosureTS timestamps; @@ -542,7 +542,7 @@ static void performOp(Source & from, Sink & to, unsigned int op) } case wopQueryAvailableStateRevisions: { - Path statePath = readString(from); + Path statePath = readStatePath(from); RevisionInfos revisions; startWork(); bool result = store->queryAvailableStateRevisions(statePath, revisions); @@ -553,7 +553,7 @@ static void performOp(Source & from, Sink & to, unsigned int op) } case wopCommitStatePath: { - Path statePath = readString(from); + Path statePath = readStatePath(from); startWork(); Snapshots ss = store->commitStatePath(statePath); stopWork(); @@ -562,7 +562,7 @@ static void performOp(Source & from, Sink & to, unsigned int op) } case wopScanAndUpdateAllReferences: { - Path statePath = readString(from); + Path statePath = readStatePath(from); bool recursive = readInt(from) == 1; startWork(); store->scanAndUpdateAllReferences(statePath, recursive); @@ -572,7 +572,7 @@ static void performOp(Source & from, Sink & to, unsigned int op) } case wopGetSharedWith: { - Path statePath1 = readString(from); + Path statePath1 = readStatePath(from); Path statePath2; startWork(); bool result = store->getSharedWith(statePath1, statePath2); @@ -583,7 +583,7 @@ static void performOp(Source & from, Sink & to, unsigned int op) } case wopToNonSharedPathSet: { - PathSet statePaths = readStringSet(from); + PathSet statePaths = readStatePaths(from); startWork(); PathSet statePaths_ns = store->toNonSharedPathSet(statePaths); stopWork(); @@ -592,7 +592,7 @@ static void performOp(Source & from, Sink & to, unsigned int op) } case wopRevertToRevision: { - Path statePath = readString(from); + Path statePath = readStatePath(from); unsigned int revision_arg = readBigUnsignedInt(from); bool recursive = readInt(from) == 1; startWork(); @@ -603,8 +603,8 @@ static void performOp(Source & from, Sink & to, unsigned int op) } case wopShareState: { - Path from_arg = readString(from); - Path to_arg = readString(from); + Path from_arg = readStatePath(from); + Path to_arg = readStatePath(from); bool snapshot = readInt(from) == 1; startWork(); store->shareState(from_arg, to_arg, snapshot); @@ -614,7 +614,7 @@ static void performOp(Source & from, Sink & to, unsigned int op) } case wopUnShareState: { - Path path = readString(from); + Path path = readStatePath(from); bool branch = readInt(from) == 1; bool restoreOld = readInt(from) == 1; startWork(); @@ -706,12 +706,11 @@ static void processConnection() op = (WorkerOp) oppp; /* Use for debugging with gdb --pid=myPid */ - /* - if(oppp == 39){ - printMsg(lvlError, format("Sleeping 10 before op '%1%' with pid '%2%'") % op % myPid); - sleep(10); - } - */ + if(sleepForGDB) + if(oppp == 39){ + printMsg(lvlError, format("Sleeping 10 before op '%1%' with pid '%2%'") % op % myPid); + sleep(10); + } } catch (EndOfFile & e) { break;