diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc index 5d9dfdc00..b0a1b320d 100644 --- a/src/libstore/gc.cc +++ b/src/libstore/gc.cc @@ -412,7 +412,7 @@ static void dfsVisit(const PathSet & paths, const Path & path, PathSet references; if (store->isValidPath(path)) - store->queryStoreReferences(path, references, 0); //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!! + store->queryStoreReferences(path, references, 0); for (PathSet::iterator i = references.begin(); i != references.end(); ++i) @@ -424,6 +424,8 @@ static void dfsVisit(const PathSet & paths, const Path & path, sorted.push_front(path); } +//TODO maybe? stateTopoSortPaths(const PathSet & paths) + Paths topoSortPaths(const PathSet & paths) { @@ -446,9 +448,6 @@ void LocalStore::collectGarbage(GCAction action, const PathSet & pathsToDelete, bool gcKeepDerivations = queryBoolSetting("gc-keep-derivations", true); - gcKeepDerivations = true; //TODO for now. we always keep drvs in the state branch since we - //need some of them to lookup info - /* Acquire the global GC root. This prevents a) New roots from being added. b) Processes from creating new temporary root files. */ @@ -479,7 +478,7 @@ void LocalStore::collectGarbage(GCAction action, const PathSet & pathsToDelete, roots under the `references' relation. */ PathSet livePaths; for (PathSet::const_iterator i = roots.begin(); i != roots.end(); ++i){ - printMsg(lvlError, format("CHECK '%1%'") % *i); + //printMsg(lvlError, format("CHECK '%1%'") % *i); computeFSClosure(canonPath(*i), livePaths, true, true, 0); } @@ -490,7 +489,8 @@ void LocalStore::collectGarbage(GCAction action, const PathSet & pathsToDelete, i != livePaths.end(); ++i) { if (store->isStateComponent(*i)){ - printMsg(lvlError, format("CHECK-STATE-STORE '%1%'") % *i); + //printMsg(lvlError, format("Live state store '%1%'") % *i); + //we select ALL state Derivations here PathSet derivers = store->queryDerivers(*i, "*", "*"); @@ -500,22 +500,27 @@ void LocalStore::collectGarbage(GCAction action, const PathSet & pathsToDelete, computeFSClosure(*j, livePaths, true, true, 0); } else if (store->isValidPath(*i)){ - printMsg(lvlError, format("CHECK-STORE '%1%'") % *i); - Path deriver = store->queryDeriver(*i); - //printMsg(lvlError, format("CHECK-STORE DRV '%1%'") % deriver); + //printMsg(lvlError, format("Live Store '%1%'") % *i); + Path deriver = store->queryDeriver(*i); /* Note that the deriver need not be valid (e.g., if we previously ran the collector with `gcKeepDerivations' turned off). */ if (deriver != "" && store->isValidPath(deriver)) computeFSClosure(deriver, livePaths, true, true, 0); + } + else if (store->isValidStatePath(*i)){ + //printMsg(lvlError, format("Live State '%1%'") % *i); + Path deriver = queryStatePathDrvTxn(noTxn, *i); + + if(!store->isValidPath(deriver)) + throw Error(format("deriver `%1%' of state-store component `%2%' in GC is not valid") % deriver % *i); + + computeFSClosure(deriver, livePaths, true, true, 0); } else{ - printMsg(lvlError, format("CHECK-STATE '%1%'") % *i); - - //TODO also get its deriver???? for if its component is gone !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - } +// //throw error? ( check trunk? + } } } @@ -526,12 +531,14 @@ void LocalStore::collectGarbage(GCAction action, const PathSet & pathsToDelete, for (PathSet::iterator i = livePaths.begin(); i != livePaths.end(); ++i) if (isDerivation(*i)) { - printMsg(lvlError, format("CHECK3 '%1%'") % *i); + //printMsg(lvlError, format("CHECK3 '%1%'") % *i); Derivation drv = derivationFromPathTxn(noTxn, *i); for (DerivationOutputs::iterator j = drv.outputs.begin(); j != drv.outputs.end(); ++j) if (store->isValidPath(j->second.path)) - computeFSClosure(j->second.path, livePaths, true, true, 0); //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!! WHAT ARE (STATE) OUTPUTS ???????????? + computeFSClosure(j->second.path, livePaths, true, true, 0); //TODO Check? + else if (store->isValidStatePath(j->second.path)) + computeFSClosure(j->second.path, livePaths, true, true, 0); } } @@ -556,7 +563,9 @@ void LocalStore::collectGarbage(GCAction action, const PathSet & pathsToDelete, PathSet tempRootsClosed; for (PathSet::iterator i = tempRoots.begin(); i != tempRoots.end(); ++i) if (store->isValidPath(*i)) - computeFSClosure(*i, tempRootsClosed, true, false, 0); //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!! WE (MAY) ALSO NEED TO .... STATE + computeFSClosure(*i, tempRootsClosed, true, true, 0); //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!! WE (MAY) ALSO NEED TO .... STATE + else if(store->isValidStatePath(*i)) + computeFSClosure(*i, tempRootsClosed, true, true, 0); //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!! WE (MAY) ALSO NEED TO .... STATE else tempRootsClosed.insert(*i); @@ -569,9 +578,38 @@ void LocalStore::collectGarbage(GCAction action, const PathSet & pathsToDelete, that is not currently in in `livePaths' or `tempRootsClosed' can be deleted. */ - ///TODO Calc get shared paths //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - //for: livePaths, tempRootsClosed - PathSet sharedWith_livePaths_tempRootsClosed; + /* + * We lookup all shared paths for: livePaths, tempRootsClosed + */ + PathSet allLiveStatePaths; + + for (PathSet::iterator i = livePaths.begin(); i != livePaths.end(); ++i) + if(store->isValidStatePath(*i)){ + allLiveStatePaths.insert(*i); + allLiveStatePaths = pathSets_union(getSharedWithPathSetRecTxn(noTxn, *i), allLiveStatePaths); + } + for (PathSet::iterator i = tempRootsClosed.begin(); i != tempRootsClosed.end(); ++i) + if(store->isValidStatePath(*i)){ + allLiveStatePaths.insert(*i); + allLiveStatePaths = pathSets_union(getSharedWithPathSetRecTxn(noTxn, *i), allLiveStatePaths); + } + + /* + * Lookup all derivations, of all state paths, because they need to be kept for comitting + */ + PathSet allStatePathDerivations; + for (PathSet::iterator i = allLiveStatePaths.begin(); i != allLiveStatePaths.end(); ++i){ + printMsg(lvlError, format("Live state path `%1%'") % *i); + + //allStatePathDerivations + + //GET DERIVER AND COMPUTE CLOSURE HERE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + //if (deriver != "" && store->isValidPath(deriver)) + // computeFSClosure(deriver, livePaths, true, true, 0); + } + + + /* Read the Nix store and state directory's to find all currently existing paths. */ @@ -651,7 +689,7 @@ void LocalStore::collectGarbage(GCAction action, const PathSet & pathsToDelete, if (!pathExists(*i)) continue; - printMsg(lvlInfo, format("deleting `%1%'") % *i); + //printMsg(lvlInfo, format("deleting `%1%'") % *i); //TODO /* Okay, it's safe to delete. */ try { @@ -686,21 +724,9 @@ void LocalStore::collectGarbage(GCAction action, const PathSet & pathsToDelete, for (Paths::iterator i = statePaths.begin(); i != statePaths.end(); ++i) { debug(format("considering deletion of state path `%1%'") % *i); - - if (livePaths.find(*i) != livePaths.end()) { - if (action == gcDeleteSpecific) - throw Error(format("cannot delete state path `%1%' since it is still alive") % *i); - debug(format("live state path `%1%'") % *i); - continue; - } - if (tempRootsClosed.find(*i) != tempRootsClosed.end()) { - debug(format("temporary root `%1%'") % *i); - continue; - } - - if (sharedWith_livePaths_tempRootsClosed.find(*i) != sharedWith_livePaths_tempRootsClosed.end()) { - debug(format("State path `%1%' is shared with another live path") % *i); + if (allLiveStatePaths.find(*i) != allLiveStatePaths.end()) { + debug(format("State path `%1%' is alive (possibyly shared with another live path)") % *i); continue; } diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index 514ac2222..a6ab99594 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -237,11 +237,11 @@ LocalStore::LocalStore(bool reserveSpace) throw Error(format("`%1%' is corrupt") % schemaFN); } - if (curSchema > nixSchemaVersion && curSchema != 4) //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! MAJOR HACK, I SHOULD MERGE WITH THE TRUNK + if (curSchema > nixSchemaVersion) throw Error(format("current Nix store schema is version %1%, but I only support %2%") % curSchema % nixSchemaVersion); - if (curSchema < nixSchemaVersion && curSchema != 4) { //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! MAJOR HACK, I SHOULD MERGE WITH THE TRUNK + if (curSchema < nixSchemaVersion) { if (curSchema <= 1) upgradeStore07(); if (curSchema == 2) @@ -756,14 +756,12 @@ static Path queryDeriver(const Transaction & txn, const Path & storePath) previously ran the garbage collector with `gcKeepDerivations' turned off). */ if(deriver == ""){ - printMsg(lvlTalkative, format("WARNING: Path '%1%' has no deriver anymore") % storePath); + //printMsg(lvlTalkative, format("WARNING: Path '%1%' has no deriver anymore") % storePath); return ""; } - //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - //Derivation drv = derivationFromPathTxn(txn, deriver); //We cant do this (at this point) since the drv might not exist .... - //if (isStateDrv(drv)) - // throw Error(format("This deriver `%1%' is a state deriver, u should use queryDerivers instead of queryDeriver") % deriver); + if (isStateComponentTxn(txn, storePath)) + throw Error(format("This path `%1%' is a store-state path, u should use queryDerivers instead of queryDeriver") % storePath); if (b) return deriver; @@ -892,9 +890,9 @@ Hash LocalStore::queryPathHash(const Path & path) return queryHash(noTxn, path); } -Path queryStatePathDrvTxn(const Transaction & txn, const Path & statePath) //TODO !!!!!!!!!!!!!!!!!!!!!! A STATEPATH CAN HAVE MORE THEN JUST ONE DRV!!!!!!!!!!!!!!!!!!!!!!! -{ //SOLUTION: make dbValidStatePaths :: statepath --> storepath - string s; //query includes username and identifier ....?? +Path queryStatePathDrvTxn(const Transaction & txn, const Path & statePath) +{ + string s; nixDB.queryString(txn, dbValidStatePaths, statePath, s); return s; } @@ -964,7 +962,7 @@ void registerValidPaths(const Transaction & txn, const ValidPathInfos & infos) setDeriver(txn, i->path, i->deriver); } - //TODO maybe also set a state deriver into dbStateDerivers .... well state is already linked to a drvpath in dbValidStatePaths .... + //State is already linked to a drvpath in dbValidStatePaths } } @@ -1038,7 +1036,7 @@ Path LocalStore::addToStore(const Path & _srcPath, bool fixed, canonicalisePathMetaData(dstPath); Transaction txn(nixDB); - registerValidPath(txn, dstPath, h, PathSet(), PathSet(), "", -1); //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!! CHECK (probabyly ok?) + registerValidPath(txn, dstPath, h, PathSet(), PathSet(), "", 0); //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!! CHECK (probabyly ok?) txn.commit(); } @@ -1214,7 +1212,7 @@ Path LocalStore::importPath(bool requireSignature, Source & source) PathSet references = readStorePaths(hashAndReadSource); - //TODO TODO also ..??!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + //TODO TODO also ..??!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! PathSet stateReferences; Path deriver = readString(hashAndReadSource); @@ -1635,7 +1633,7 @@ bool querySolidStateReferencesTxn(const Transaction & txn, const Path & statePat return notempty; } -void unShareStateTxn(const Transaction & txn, const Path & path, const bool branch, const bool restoreOld) //TODO ADD BOOL YES/NO TO RESTORE OLD STATE (LAST REV.) +void unShareStateTxn(const Transaction & txn, const Path & path, const bool branch, const bool restoreOld) { //Check if is statePath if(!isValidStatePathTxn(txn, path)) @@ -1785,7 +1783,7 @@ void setStateStateReferencesTxn(const Transaction & txn, const Path & statePath, setStateReferences(nixDB, txn, dbStateStateReferences, dbStateRevisions, statePath, references, revision, timestamp); } -//Lookups which statePaths directy share (point to) statePath +//Lookup which statePaths directy share (point to) statePath PathSet getDirectlySharedWithPathSetTxn(const Transaction & txn, const Path & statePath) { PathSet statePaths; @@ -1822,6 +1820,7 @@ PathSet getSharedWithPathSetRecTxn_private(const Transaction & txn, const Path & return statePaths; } +//Lookup recursively which statePaths (in)directy share (point to) statePath PathSet getSharedWithPathSetRecTxn(const Transaction & txn, const Path & statePath) { //To no shared state path diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh index 626545c74..0eb36ca42 100644 --- a/src/libstore/store-api.hh +++ b/src/libstore/store-api.hh @@ -229,6 +229,7 @@ public: /* TODO */ virtual void unShareState(const Path & path, const bool branch, const bool restoreOld) = 0; + }; diff --git a/src/nix-worker/nix-worker.cc b/src/nix-worker/nix-worker.cc index ea52a0758..e2b3641c2 100644 --- a/src/nix-worker/nix-worker.cc +++ b/src/nix-worker/nix-worker.cc @@ -704,10 +704,15 @@ static void processConnection() try { int oppp = readInt(from); op = (WorkerOp) oppp; + + /* Use for debugging*/ + /* if(oppp == 14){ printMsg(lvlError, format("Sleeping 10")); sleep(10); } + */ + } catch (EndOfFile & e) { break; }