diff --git a/src/libstore/db.cc b/src/libstore/db.cc index bb5eecf6e..d886b3f7a 100644 --- a/src/libstore/db.cc +++ b/src/libstore/db.cc @@ -664,6 +664,13 @@ void Database::setStateRevisions(const Transaction & txn, TableId revisions_tabl //get all paths that point to the same state (using shareing) and check if one of them equals the rootStatePath PathSet sharedWith = getSharedWithPathSetRecTxn(txn, statePath); + + /* + printMsg(lvlError, format("SP RootSP '%1%' - '%2%'") % statePath % rootStatePath); + for (PathSet::const_iterator j = sharedWith.begin(); j != sharedWith.end(); ++j) + printMsg(lvlError, format("SP SW '%1%'") % *j); + */ + if(statePath == rootStatePath || sharedWith.find(rootStatePath) != sharedWith.end()) metadata.push_back(comment); else diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index c4bc60d42..d2e977f5d 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -1791,7 +1791,7 @@ void setStateStateReferencesTxn(const Transaction & txn, const Path & statePath, } //Lookups which statePaths directy share (point to) statePath -PathSet getSharedWithPathSetTxn(const Transaction & txn, const Path & statePath) +PathSet getDirectlySharedWithPathSetTxn(const Transaction & txn, const Path & statePath) { PathSet statePaths; @@ -1812,31 +1812,51 @@ PathSet getSharedWithPathSetTxn(const Transaction & txn, const Path & statePath) PathSet getSharedWithPathSetRecTxn_private(const Transaction & txn, const Path & statePath, PathSet & statePaths) { //Get all paths pointing to statePath - PathSet newStatePaths = getSharedWithPathSetTxn(txn, statePath); + PathSet newStatePaths = getDirectlySharedWithPathSetTxn(txn, statePath); + /* + printMsg(lvlError, format("getSharedWithPathSetRecTxn_private: '%1%'") % statePath); + for (PathSet::const_iterator j = newStatePaths.begin(); j != newStatePaths.end(); ++j) + printMsg(lvlError, format("newStatePaths '%1%'") % *j); + */ + //go into recursion to see if there are more paths indirectly pointing to statePath - for (PathSet::iterator i = newStatePaths.begin(); i != newStatePaths.end(); ++i) + for (PathSet::iterator i = newStatePaths.begin(); i != newStatePaths.end(); ++i){ //Only recurse on the really new statePaths to prevent infinite recursion - if(statePaths.find(*i) == statePaths.end()) - statePaths = pathSets_union(statePaths, getSharedWithPathSetRecTxn_private(txn, *i, statePaths)); + if(statePaths.find(*i) == statePaths.end()) + { + statePaths.insert(*i); + statePaths = pathSets_union(statePaths, getSharedWithPathSetRecTxn_private(txn, *i, statePaths)); //TODO !!!!!!!!!!!!!!!!!!!!!! + } + } return statePaths; } -//Note: Also returns statePath in the PathSet PathSet getSharedWithPathSetRecTxn(const Transaction & txn, const Path & statePath) { //To no shared state path Path statePath_ns = toNonSharedPathTxn(txn, statePath); - PathSet empty; - return getSharedWithPathSetRecTxn_private(txn, statePath_ns, empty); + + //Also insert non-shared state path if it doenst equal statePath + PathSet statePaths; + if(statePath_ns != statePath) + statePaths.insert(statePath_ns); + + //Make the call to get all shared with paths + PathSet result = getSharedWithPathSetRecTxn_private(txn, statePath_ns, statePaths); + + //Remove yourself from the list eventually + result.erase(statePath); + + return result; } -void LocalStore::revertToRevision(const Path & componentPath, const Path & derivationPath, const Path & statePath, const unsigned int revision_arg, const bool recursive) +void LocalStore::revertToRevision(const Path & statePath, const unsigned int revision_arg, const bool recursive) { Transaction txn(nixDB); - revertToRevisionTxn(txn, componentPath, derivationPath, statePath, revision_arg, recursive); + revertToRevisionTxn(txn, statePath, revision_arg, recursive); txn.commit(); } diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh index cbe09be3f..41e46e022 100644 --- a/src/libstore/local-store.hh +++ b/src/libstore/local-store.hh @@ -112,7 +112,7 @@ public: PathSet toNonSharedPathSet(const PathSet & statePaths); - void revertToRevision(const Path & componentPath, const Path & derivationPath, const Path & statePath, const unsigned int revision_arg, const bool recursive); + void revertToRevision(const Path & statePath, const unsigned int revision_arg, const bool recursive); void setSharedState(const Path & fromExisting, const Path & toNew); }; @@ -243,6 +243,10 @@ bool querySolidStateReferencesTxn(const Transaction & txn, const Path & statePat void setSharedStateTxn(const Transaction & txn, const Path & fromExisting, const Path & toNew); PathSet toNonSharedPathSetTxn(const Transaction & txn, const PathSet & statePaths); Path toNonSharedPathTxn(const Transaction & txn, const Path & statePath); + +/* + * Returns a pathset with all paths (including itself) that eventually share the same statePath + */ PathSet getSharedWithPathSetRecTxn(const Transaction & txn, const Path & statePath); void ensurePathTxn(const Transaction & txn, const Path & path); diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index 210546829..b5d3f31e3 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -513,11 +513,9 @@ PathSet RemoteStore::toNonSharedPathSet(const PathSet & statePaths) return readStringSet(from); //TODO !!!!!!!!!!!!!!! create a readStatePaths just like readStorePaths } -void RemoteStore::revertToRevision(const Path & componentPath, const Path & derivationPath, const Path & statePath, const unsigned int revision_arg, const bool recursive) +void RemoteStore::revertToRevision(const Path & statePath, const unsigned int revision_arg, const bool recursive) { writeInt(wopRevertToRevision, to); - writeString(componentPath, to); - writeString(derivationPath, to); writeString(statePath, to); writeBigUnsignedInt(revision_arg, to); writeInt(recursive ? 1 : 0, to); diff --git a/src/libstore/remote-store.hh b/src/libstore/remote-store.hh index 2e2957ce4..2e77360c2 100644 --- a/src/libstore/remote-store.hh +++ b/src/libstore/remote-store.hh @@ -98,7 +98,7 @@ public: PathSet toNonSharedPathSet(const PathSet & statePaths); - void revertToRevision(const Path & componentPath, const Path & derivationPath, const Path & statePath, const unsigned int revision_arg, const bool recursive); + void revertToRevision(const Path & statePath, const unsigned int revision_arg, const bool recursive); void setSharedState(const Path & fromExisting, const Path & toNew); diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh index 3cedb08d9..fd325f26e 100644 --- a/src/libstore/store-api.hh +++ b/src/libstore/store-api.hh @@ -241,7 +241,7 @@ public: virtual PathSet toNonSharedPathSet(const PathSet & statePaths) = 0; /* TODO */ - virtual void revertToRevision(const Path & componentPath, const Path & derivationPath, const Path & statePath, const unsigned int revision_arg, const bool recursive) = 0; + virtual void revertToRevision(const Path & statePath, const unsigned int revision_arg, const bool recursive) = 0; /* TODO */ virtual void setSharedState(const Path & fromExisting, const Path & toNew) = 0; diff --git a/src/libstore/store-state.cc b/src/libstore/store-state.cc index 5f09aa8ac..979d87442 100644 --- a/src/libstore/store-state.cc +++ b/src/libstore/store-state.cc @@ -93,22 +93,18 @@ PathSet getAllStateDerivationsRecursivelyTxn(const Transaction & txn, const Path -void revertToRevisionTxn(const Transaction & txn, const Path & componentPath, const Path & derivationPath, const Path & statePath, const int revision_arg, const bool recursive) +void revertToRevisionTxn(const Transaction & txn, const Path & statePath, const int revision_arg, const bool recursive) { - - PathSet statePaths; - if(recursive) - PathSet statePaths = getAllStateDerivationsRecursivelyTxn(txn, componentPath, revision_arg); //get dependecies (if neccecary | recusively) of all state components that need to be updated - else - statePaths.insert(derivationPath); //Insert direct state path - + //Unshare the path + Path statePath_ns = toNonSharedPathTxn(txn, statePath); + //get a new timestamp for the references update unsigned int newTimestamp = getTimeStamp(); //Get the revisions recursively to also roll them back RevisionClosure getRivisions; RevisionClosureTS getTimestamps; - queryStateRevisionsTxn(txn, statePath, getRivisions, getTimestamps, revision_arg); + queryStateRevisionsTxn(txn, statePath_ns, getRivisions, getTimestamps, revision_arg); //Revert each statePath in the list for (RevisionClosure::iterator i = getRivisions.begin(); i != getRivisions.end(); ++i){ diff --git a/src/libstore/store-state.hh b/src/libstore/store-state.hh index 0120b3541..3ef6fcb32 100644 --- a/src/libstore/store-state.hh +++ b/src/libstore/store-state.hh @@ -25,7 +25,7 @@ void scanAndUpdateAllReferencesTxn(const Transaction & txn, const Path & statePa void scanAndUpdateAllReferencesRecusivelyTxn(const Transaction & txn, const Path & statePath); -void revertToRevisionTxn(const Transaction & txn, const Path & componentPath, const Path & derivationPath, const Path & statePath, const int revision_arg, const bool recursive); +void revertToRevisionTxn(const Transaction & txn, const Path & statePath, const int revision_arg, const bool recursive); } diff --git a/src/nix-state/nix-state.cc b/src/nix-state/nix-state.cc index b7e328885..c33ecb0d1 100644 --- a/src/nix-state/nix-state.cc +++ b/src/nix-state/nix-state.cc @@ -177,7 +177,7 @@ static void revertToRevision(Strings opFlags, Strings opArgs) bool recursive = revert_recursively; - store->revertToRevision(componentPath, derivationPath, statePath, revision_arg, recursive); + store->revertToRevision(statePath, revision_arg, recursive); } @@ -486,8 +486,23 @@ void run(Strings args) RevisionClosureTS timestamps; bool b = store->queryStateRevisions("/nix/state/aacs4qpi9jzg4vmhj09d0ichframh22x-hellohardcodedstateworld-1.0-test", revisions, timestamps, 0); - return; */ + + store = openStore(); + + /* + PathSet sharedWith = getSharedWithPathSetRecTxn(noTxn, "/nix/state/1kjxymaxf0i6qp5k8ggacc06bzbi4b82-hellohardcodedstateworld-1.0-test"); + for (PathSet::const_iterator j = sharedWith.begin(); j != sharedWith.end(); ++j) + printMsg(lvlError, format("RootSP SW '%1%'") % *j); + printMsg(lvlError, format("------------")); + sharedWith = getSharedWithPathSetRecTxn(noTxn, "/nix/state/7c9azkk6qfk18hsvw4a5d8vk1p6qryk0-hellohardcodedstateworld-1.0-test"); + for (PathSet::const_iterator j = sharedWith.begin(); j != sharedWith.end(); ++j) + printMsg(lvlError, format("RootSP SW '%1%'") % *j); + + return; + + */ + /* test */ for (Strings::iterator i = args.begin(); i != args.end(); ) { diff --git a/src/nix-worker/nix-worker.cc b/src/nix-worker/nix-worker.cc index 40dc8a737..8eaa74a82 100644 --- a/src/nix-worker/nix-worker.cc +++ b/src/nix-worker/nix-worker.cc @@ -579,13 +579,11 @@ static void performOp(Source & from, Sink & to, unsigned int op) } case wopRevertToRevision: { - Path componentPath = readString(from); - Path derivationPath = readString(from); Path statePath = readString(from); unsigned int revision_arg = readBigUnsignedInt(from); bool recursive = readInt(from) == 1; startWork(); - store->revertToRevision(componentPath, derivationPath, statePath, revision_arg, recursive); + store->revertToRevision(statePath, revision_arg, recursive); stopWork(); writeInt(1, to); break;