1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-26 12:10:59 +01:00

Added more state garbage collection code

This commit is contained in:
Wouter den Breejen 2007-10-12 17:18:39 +00:00
parent 60a32fcbf3
commit ef37776094
4 changed files with 81 additions and 50 deletions

View file

@ -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,21 +500,26 @@ 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);
//printMsg(lvlError, format("Live Store '%1%'") % *i);
Path deriver = store->queryDeriver(*i);
//printMsg(lvlError, format("CHECK-STORE DRV '%1%'") % deriver);
/* 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 {
@ -687,20 +725,8 @@ void LocalStore::collectGarbage(GCAction action, const PathSet & pathsToDelete,
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;
}

View file

@ -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

View file

@ -229,6 +229,7 @@ public:
/* TODO */
virtual void unShareState(const Path & path, const bool branch, const bool restoreOld) = 0;
};

View file

@ -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;
}