mirror of
https://github.com/NixOS/nix.git
synced 2025-11-26 04:00:59 +01:00
Added some state-specific garbage collection code (not complete yet)
This commit is contained in:
parent
43d93e5e64
commit
d69dd855d5
18 changed files with 199 additions and 103 deletions
|
|
@ -1083,7 +1083,7 @@ static string makeValidityRegistration(const PathSet & paths,
|
||||||
s += deriver + "\n";
|
s += deriver + "\n";
|
||||||
|
|
||||||
PathSet references;
|
PathSet references;
|
||||||
store->queryReferences(*i, references, 0); //TODO check if this is ok
|
store->queryStoreReferences(*i, references, 0); //TODO check if this is ok
|
||||||
|
|
||||||
s += (format("%1%\n") % references.size()).str();
|
s += (format("%1%\n") % references.size()).str();
|
||||||
|
|
||||||
|
|
@ -2058,7 +2058,7 @@ void SubstitutionGoal::init()
|
||||||
|
|
||||||
/* To maintain the closure invariant, we first have to realise the
|
/* To maintain the closure invariant, we first have to realise the
|
||||||
paths referenced by this one. */
|
paths referenced by this one. */
|
||||||
store->queryReferences(storePath, references, 0);
|
store->queryStoreReferences(storePath, references, 0);
|
||||||
|
|
||||||
for (PathSet::iterator i = references.begin();
|
for (PathSet::iterator i = references.begin();
|
||||||
i != references.end(); ++i)
|
i != references.end(); ++i)
|
||||||
|
|
|
||||||
|
|
@ -406,7 +406,7 @@ static void dfsVisit(const PathSet & paths, const Path & path,
|
||||||
|
|
||||||
PathSet references;
|
PathSet references;
|
||||||
if (store->isValidPath(path))
|
if (store->isValidPath(path))
|
||||||
store->queryReferences(path, references, 0); //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
store->queryStoreReferences(path, references, 0); //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
|
||||||
for (PathSet::iterator i = references.begin();
|
for (PathSet::iterator i = references.begin();
|
||||||
i != references.end(); ++i)
|
i != references.end(); ++i)
|
||||||
|
|
@ -447,7 +447,7 @@ void LocalStore::collectGarbage(GCAction action, const PathSet & pathsToDelete,
|
||||||
|
|
||||||
/* Find the roots. Since we've grabbed the GC lock, the set of
|
/* Find the roots. Since we've grabbed the GC lock, the set of
|
||||||
permanent roots cannot increase now. */
|
permanent roots cannot increase now. */
|
||||||
Roots rootMap = ignoreLiveness ? Roots() : nix::findRoots(true);
|
Roots rootMap = ignoreLiveness ? Roots() : nix::findRoots(true); //TODO Also find state roots?
|
||||||
|
|
||||||
PathSet roots;
|
PathSet roots;
|
||||||
for (Roots::iterator i = rootMap.begin(); i != rootMap.end(); ++i)
|
for (Roots::iterator i = rootMap.begin(); i != rootMap.end(); ++i)
|
||||||
|
|
@ -468,13 +468,17 @@ void LocalStore::collectGarbage(GCAction action, const PathSet & pathsToDelete,
|
||||||
/* Determine the live paths which is just the closure of the
|
/* Determine the live paths which is just the closure of the
|
||||||
roots under the `references' relation. */
|
roots under the `references' relation. */
|
||||||
PathSet livePaths;
|
PathSet livePaths;
|
||||||
for (PathSet::const_iterator i = roots.begin(); i != roots.end(); ++i)
|
for (PathSet::const_iterator i = roots.begin(); i != roots.end(); ++i){
|
||||||
|
printMsg(lvlError, format("CHECK '%1%'") % *i);
|
||||||
computeFSClosure(canonPath(*i), livePaths, true, false, 0); //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!! WE (MAY) ALSO NEED TO DELETE STATE??
|
computeFSClosure(canonPath(*i), livePaths, true, false, 0); //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!! WE (MAY) ALSO NEED TO DELETE STATE??
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (gcKeepDerivations) {
|
if (gcKeepDerivations) {
|
||||||
for (PathSet::iterator i = livePaths.begin();
|
for (PathSet::iterator i = livePaths.begin();
|
||||||
i != livePaths.end(); ++i)
|
i != livePaths.end(); ++i)
|
||||||
{
|
{
|
||||||
|
printMsg(lvlError, format("CHECK2 '%1%'") % *i);
|
||||||
/* Note that the deriver need not be valid (e.g., if we
|
/* Note that the deriver need not be valid (e.g., if we
|
||||||
previously ran the collector with `gcKeepDerivations'
|
previously ran the collector with `gcKeepDerivations'
|
||||||
turned off). */
|
turned off). */
|
||||||
|
|
@ -489,6 +493,7 @@ void LocalStore::collectGarbage(GCAction action, const PathSet & pathsToDelete,
|
||||||
for (PathSet::iterator i = livePaths.begin();
|
for (PathSet::iterator i = livePaths.begin();
|
||||||
i != livePaths.end(); ++i)
|
i != livePaths.end(); ++i)
|
||||||
if (isDerivation(*i)) {
|
if (isDerivation(*i)) {
|
||||||
|
printMsg(lvlError, format("CHECK3 '%1%'") % *i);
|
||||||
Derivation drv = derivationFromPathTxn(noTxn, *i);
|
Derivation drv = derivationFromPathTxn(noTxn, *i);
|
||||||
for (DerivationOutputs::iterator j = drv.outputs.begin();
|
for (DerivationOutputs::iterator j = drv.outputs.begin();
|
||||||
j != drv.outputs.end(); ++j)
|
j != drv.outputs.end(); ++j)
|
||||||
|
|
|
||||||
|
|
@ -33,16 +33,17 @@ static Database nixDB;
|
||||||
|
|
||||||
/* Database tables. */
|
/* Database tables. */
|
||||||
|
|
||||||
/* dbValidPaths :: Path -> ()
|
/* dbValidPaths :: Path -> sha256 Hash
|
||||||
|
|
||||||
The existence of a key $p$ indicates that path $p$ is valid (that
|
The existence of a key $p$ indicates that path $p$ is valid (that
|
||||||
is, produced by a succesful build). */
|
is, produced by a succesful build). */
|
||||||
static TableId dbValidPaths = 0;
|
static TableId dbValidPaths = 0;
|
||||||
|
|
||||||
/* dbValidStatePaths :: Path -> ()
|
/* dbValidStatePaths :: statePath -> DrvPath
|
||||||
|
|
||||||
The existence of a key $p$ indicates that state path $p$ is valid (that
|
The existence of a key $p$ indicates that state path $p$ is valid (that
|
||||||
is, produced by a succesful build). */
|
is, produced by a succesful build).
|
||||||
|
*/
|
||||||
static TableId dbValidStatePaths = 0;
|
static TableId dbValidStatePaths = 0;
|
||||||
|
|
||||||
/* dbReferences :: Path -> [Path]
|
/* dbReferences :: Path -> [Path]
|
||||||
|
|
@ -445,6 +446,9 @@ static string stripPrefix(const string & prefix, const string & s)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The revision can be omitted for normal store paths
|
||||||
|
*/
|
||||||
void setReferences(const Transaction & txn, const Path & store_or_statePath,
|
void setReferences(const Transaction & txn, const Path & store_or_statePath,
|
||||||
const PathSet & references, const PathSet & stateReferences, const unsigned int revision)
|
const PathSet & references, const PathSet & stateReferences, const unsigned int revision)
|
||||||
{
|
{
|
||||||
|
|
@ -529,7 +533,7 @@ void queryXReferencesTxn(const Transaction & txn, const Path & store_or_statePat
|
||||||
references.insert(references2.begin(), references2.end());
|
references.insert(references2.begin(), references2.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalStore::queryReferences(const Path & storePath, PathSet & references, const unsigned int revision)
|
void LocalStore::queryStoreReferences(const Path & storePath, PathSet & references, const unsigned int revision)
|
||||||
{
|
{
|
||||||
nix::queryXReferencesTxn(noTxn, storePath, references, revision, true);
|
nix::queryXReferencesTxn(noTxn, storePath, references, revision, true);
|
||||||
}
|
}
|
||||||
|
|
@ -539,6 +543,7 @@ void LocalStore::queryStateReferences(const Path & componentOrstatePath, PathSet
|
||||||
nix::queryXReferencesTxn(noTxn, componentOrstatePath, stateReferences, revision, false);
|
nix::queryXReferencesTxn(noTxn, componentOrstatePath, stateReferences, revision, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Private
|
||||||
static PathSet getXReferrers(const Transaction & txn, const Path & store_or_statePath, const bool component_or_state, const unsigned int revision)
|
static PathSet getXReferrers(const Transaction & txn, const Path & store_or_statePath, const bool component_or_state, const unsigned int revision)
|
||||||
{
|
{
|
||||||
TableId table = 0;
|
TableId table = 0;
|
||||||
|
|
@ -633,7 +638,7 @@ static PathSet getXReferrers(const Transaction & txn, const Path & store_or_stat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static PathSet getReferrersTxn(const Transaction & txn, const Path & store_or_statePath, const unsigned int revision)
|
static PathSet getStoreReferrersTxn(const Transaction & txn, const Path & store_or_statePath, const unsigned int revision)
|
||||||
{
|
{
|
||||||
return getXReferrers(txn, store_or_statePath, true, revision);
|
return getXReferrers(txn, store_or_statePath, true, revision);
|
||||||
}
|
}
|
||||||
|
|
@ -643,19 +648,19 @@ static PathSet getStateReferrersTxn(const Transaction & txn, const Path & store_
|
||||||
return getXReferrers(txn, store_or_statePath, false, revision);
|
return getXReferrers(txn, store_or_statePath, false, revision);
|
||||||
}
|
}
|
||||||
|
|
||||||
void queryReferrersTxn(const Transaction & txn,
|
void queryStoreReferrersTxn(const Transaction & txn,
|
||||||
const Path & storePath, PathSet & referrers, const unsigned int revision)
|
const Path & storePath, PathSet & referrers, const unsigned int revision)
|
||||||
{
|
{
|
||||||
if (!isRealisableComponentOrStatePath(txn, storePath))
|
if (!isRealisableComponentOrStatePath(txn, storePath))
|
||||||
throw Error(format("path `%1%' is not valid") % storePath);
|
throw Error(format("path `%1%' is not valid") % storePath);
|
||||||
PathSet referrers2 = getReferrersTxn(txn, storePath, revision);
|
PathSet referrers2 = getStoreReferrersTxn(txn, storePath, revision);
|
||||||
referrers.insert(referrers2.begin(), referrers2.end());
|
referrers.insert(referrers2.begin(), referrers2.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalStore::queryReferrers(const Path & storePath,
|
void LocalStore::queryStoreReferrers(const Path & storePath,
|
||||||
PathSet & referrers, const unsigned int revision)
|
PathSet & referrers, const unsigned int revision)
|
||||||
{
|
{
|
||||||
nix::queryReferrersTxn(noTxn, storePath, referrers, revision);
|
nix::queryStoreReferrersTxn(noTxn, storePath, referrers, revision);
|
||||||
}
|
}
|
||||||
|
|
||||||
void queryStateReferrersTxn(const Transaction & txn, const Path & storePath, PathSet & stateReferrers, const unsigned int revision)
|
void queryStateReferrersTxn(const Transaction & txn, const Path & storePath, PathSet & stateReferrers, const unsigned int revision)
|
||||||
|
|
@ -944,10 +949,10 @@ Substitutes LocalStore::querySubstitutes(const Path & path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void invalidatePath(Transaction & txn, const Path & path);
|
static void invalidateStorePath(Transaction & txn, const Path & path);
|
||||||
|
|
||||||
|
|
||||||
void clearSubstitutes()
|
void clearSubstitutes() //TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ALSO FOR STATE
|
||||||
{
|
{
|
||||||
Transaction txn(nixDB);
|
Transaction txn(nixDB);
|
||||||
|
|
||||||
|
|
@ -961,7 +966,7 @@ void clearSubstitutes()
|
||||||
|
|
||||||
/* Maintain the cleanup invariant. */
|
/* Maintain the cleanup invariant. */
|
||||||
if (!isValidPathTxn(txn, *i))
|
if (!isValidPathTxn(txn, *i))
|
||||||
invalidatePath(txn, *i);
|
invalidateStorePath(txn, *i);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* !!! there should be no referrers to any of the invalid
|
/* !!! there should be no referrers to any of the invalid
|
||||||
|
|
@ -1084,23 +1089,39 @@ void registerValidPaths(const Transaction & txn, const ValidPathInfos & infos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void invalidatexPath(Transaction & txn, const Path & path, const bool component_or_state)
|
||||||
/* Invalidate a path. The caller is responsible for checking that
|
|
||||||
there are no referrers. */
|
|
||||||
static void invalidatePath(Transaction & txn, const Path & path) //TODO Adjust for state paths????
|
|
||||||
{
|
{
|
||||||
debug(format("unregistering path `%1%'") % path);
|
debug(format("invalidating %2% path `%1%'") % path % (component_or_state ? "store" : "state"));
|
||||||
|
|
||||||
/* Clear the `references' entry for this path, as well as the
|
/* Clear the `references' entry for this path, as well as the
|
||||||
inverse `referrers' entries, and the `derivers' entry; but only
|
inverse `referrers' entries, and the `derivers' entry. */
|
||||||
if there are no substitutes for this path. This maintains the
|
|
||||||
cleanup invariant. */
|
|
||||||
if (querySubstitutes(txn, path).size() == 0) {
|
|
||||||
setReferences(txn, path, PathSet(), PathSet(), -1); //Set last references empty (TODO is this ok?)
|
|
||||||
nixDB.delPair(txn, dbDerivers, path); //TODO!!!!! also for state Derivers!!!!!!!!!!!!!!!
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if(component_or_state)
|
||||||
|
setReferences(txn, path, PathSet(), PathSet(), 0); //This is a store path so the revision doenst matter
|
||||||
|
else
|
||||||
|
setReferences(txn, path, PathSet(), PathSet(), 0); //For now.... we only delete clear references for the new revision (TODO !!!!!!!!!!!!!!!! CHECK IF WE REALLY SET IT FOR A NEW OR LAST REVISION)
|
||||||
|
|
||||||
|
nixDB.delPair(txn, dbDerivers, path);
|
||||||
|
|
||||||
|
if(component_or_state)
|
||||||
nixDB.delPair(txn, dbValidPaths, path);
|
nixDB.delPair(txn, dbValidPaths, path);
|
||||||
|
else
|
||||||
|
nixDB.delPair(txn, dbValidStatePaths, path);
|
||||||
|
|
||||||
|
if(component_or_state)
|
||||||
|
nixDB.delPair(txn, dbStateInfo, path); //We (may) need to delete if this key if path is a state-store path
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Invalidate a store or state path. The caller is responsible for checking that
|
||||||
|
there are no referrers. */
|
||||||
|
static void invalidateStorePath(Transaction & txn, const Path & path)
|
||||||
|
{
|
||||||
|
invalidatexPath(txn, path, true);
|
||||||
|
}
|
||||||
|
static void invalidateStatePath(Transaction & txn, const Path & path)
|
||||||
|
{
|
||||||
|
invalidatexPath(txn, path, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1391,36 +1412,54 @@ Path LocalStore::importPath(bool requireSignature, Source & source)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void deleteFromStore(const Path & _path, unsigned long long & bytesFreed)
|
void deleteXFromStore(const Path & _path, unsigned long long & bytesFreed, const bool component_or_state)
|
||||||
{
|
{
|
||||||
bytesFreed = 0;
|
bytesFreed = 0;
|
||||||
Path path(canonPath(_path));
|
Path path(canonPath(_path));
|
||||||
|
|
||||||
|
if(component_or_state)
|
||||||
assertStorePath(path);
|
assertStorePath(path);
|
||||||
|
else
|
||||||
|
assertStatePath(path);
|
||||||
|
|
||||||
Transaction txn(nixDB);
|
Transaction txn(nixDB);
|
||||||
if (isValidPathTxn(txn, path)) {
|
if (isValidPathTxn(txn, path) || isValidStatePathTxn(txn, path))
|
||||||
PathSet referrers = getReferrersTxn(txn, path, -1); //delete latest referrers (TODO?)
|
{
|
||||||
for (PathSet::iterator i = referrers.begin();
|
PathSet storeReferrers = getStoreReferrersTxn(txn, path, 0);
|
||||||
i != referrers.end(); ++i)
|
PathSet stateReferrers = getStateReferrersTxn(txn, path, 0);
|
||||||
if (*i != path && isValidPathTxn(txn, *i))
|
|
||||||
throw PathInUse(format("cannot delete path `%1%' because it is in use by path `%2%'") % path % *i);
|
|
||||||
invalidatePath(txn, path);
|
|
||||||
|
|
||||||
//TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Also delete/invalidate stateReferrers?????
|
for (PathSet::iterator i = storeReferrers.begin(); i != storeReferrers.end(); ++i)
|
||||||
|
if (*i != path && isValidPathTxn(txn, *i))
|
||||||
|
throw PathInUse(format("cannot delete %3% path `%1%' because it is in use by store path `%2%'") % path % *i % (component_or_state ? "store" : "state"));
|
||||||
|
for (PathSet::iterator i = stateReferrers.begin(); i != stateReferrers.end(); ++i)
|
||||||
|
if (*i != path && isValidPathTxn(txn, *i))
|
||||||
|
throw PathInUse(format("cannot delete %3% path `%1%' because it is in use by state path `%2%'") % path % *i % (component_or_state ? "store" : "state"));
|
||||||
|
|
||||||
|
|
||||||
|
if(component_or_state)
|
||||||
|
invalidateStorePath(txn, path);
|
||||||
|
else
|
||||||
|
invalidateStatePath(txn, path);
|
||||||
}
|
}
|
||||||
txn.commit();
|
txn.commit();
|
||||||
|
|
||||||
deletePathWrapped(path, bytesFreed);
|
deletePathWrapped(path, bytesFreed);
|
||||||
}
|
}
|
||||||
|
void deleteFromStore(const Path & _path, unsigned long long & bytesFreed)
|
||||||
|
{
|
||||||
|
deleteXFromStore(_path, bytesFreed, true);
|
||||||
|
}
|
||||||
|
void deleteFromState(const Path & _path, unsigned long long & bytesFreed)
|
||||||
|
{
|
||||||
|
deleteXFromStore(_path, bytesFreed, false);
|
||||||
|
}
|
||||||
|
|
||||||
void verifyStore(bool checkContents)
|
void verifyStore(bool checkContents)
|
||||||
{
|
{
|
||||||
Transaction txn(nixDB);
|
Transaction txn(nixDB);
|
||||||
|
|
||||||
|
|
||||||
printMsg(lvlInfo, "checking path existence");
|
printMsg(lvlInfo, "checking store path existence");
|
||||||
|
|
||||||
Paths paths;
|
Paths paths;
|
||||||
PathSet validPaths;
|
PathSet validPaths;
|
||||||
|
|
@ -1428,18 +1467,18 @@ void verifyStore(bool checkContents)
|
||||||
|
|
||||||
for (Paths::iterator i = paths.begin(); i != paths.end(); ++i) {
|
for (Paths::iterator i = paths.begin(); i != paths.end(); ++i) {
|
||||||
if (!pathExists(*i)) {
|
if (!pathExists(*i)) {
|
||||||
printMsg(lvlError, format("path `%1%' disappeared") % *i);
|
printMsg(lvlError, format("store path `%1%' disappeared") % *i);
|
||||||
invalidatePath(txn, *i);
|
invalidateStorePath(txn, *i);
|
||||||
} else if (!isStorePath(*i)) {
|
} else if (!isStorePath(*i)) {
|
||||||
printMsg(lvlError, format("path `%1%' is not in the Nix store") % *i);
|
printMsg(lvlError, format("store path `%1%' is not in the Nix store") % *i);
|
||||||
invalidatePath(txn, *i);
|
invalidateStorePath(txn, *i);
|
||||||
} else {
|
} else {
|
||||||
if (checkContents) {
|
if (checkContents) {
|
||||||
debug(format("checking contents of `%1%'") % *i);
|
debug(format("checking contents of `%1%'") % *i);
|
||||||
Hash expected = queryHash(txn, *i);
|
Hash expected = queryHash(txn, *i);
|
||||||
Hash current = hashPath(expected.type, *i);
|
Hash current = hashPath(expected.type, *i);
|
||||||
if (current != expected) {
|
if (current != expected) {
|
||||||
printMsg(lvlError, format("path `%1%' was modified! "
|
printMsg(lvlError, format("store path `%1%' was modified! "
|
||||||
"expected hash `%2%', got `%3%'")
|
"expected hash `%2%', got `%3%'")
|
||||||
% *i % printHash(expected) % printHash(current));
|
% *i % printHash(expected) % printHash(current));
|
||||||
}
|
}
|
||||||
|
|
@ -1448,6 +1487,24 @@ void verifyStore(bool checkContents)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printMsg(lvlInfo, "checking state path existence");
|
||||||
|
|
||||||
|
Paths statePaths;
|
||||||
|
PathSet validStatePaths;
|
||||||
|
nixDB.enumTable(txn, dbValidStatePaths, statePaths);
|
||||||
|
|
||||||
|
for (Paths::iterator i = statePaths.begin(); i != statePaths.end(); ++i) {
|
||||||
|
if (!pathExists(*i)) {
|
||||||
|
printMsg(lvlError, format("state path `%1%' disappeared") % *i);
|
||||||
|
invalidateStatePath(txn, *i);
|
||||||
|
} else if (!isStatePath(*i)) {
|
||||||
|
printMsg(lvlError, format("state path `%1%' is not in the Nix state-store") % *i);
|
||||||
|
invalidateStatePath(txn, *i);
|
||||||
|
} else {
|
||||||
|
validStatePaths.insert(*i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
printMsg(lvlInfo, "checking path realisability");
|
printMsg(lvlInfo, "checking path realisability");
|
||||||
|
|
||||||
|
|
@ -1456,7 +1513,8 @@ void verifyStore(bool checkContents)
|
||||||
PathSet realisablePaths(validPaths);
|
PathSet realisablePaths(validPaths);
|
||||||
|
|
||||||
|
|
||||||
//TODO Do also for validStatePaths
|
//TODO !!!!!!!!!!!!!!!!!!!!!!!!! Do also for validStatePaths
|
||||||
|
|
||||||
|
|
||||||
/* Check that the values of the substitute mappings are valid
|
/* Check that the values of the substitute mappings are valid
|
||||||
paths. */
|
paths. */
|
||||||
|
|
@ -1752,7 +1810,7 @@ void unShareStateTxn(const Transaction & txn, const Path & path, const bool bran
|
||||||
|
|
||||||
//Copy if necessary
|
//Copy if necessary
|
||||||
if(branch){
|
if(branch){
|
||||||
copyContents(sharedWithOldPath, path);
|
rsyncPaths(sharedWithOldPath, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Restore the latest snapshot (non-recursive) made on this statepath
|
//Restore the latest snapshot (non-recursive) made on this statepath
|
||||||
|
|
|
||||||
|
|
@ -51,11 +51,11 @@ public:
|
||||||
|
|
||||||
Path queryStatePathDrv(const Path & statePath);
|
Path queryStatePathDrv(const Path & statePath);
|
||||||
|
|
||||||
void queryReferences(const Path & path, PathSet & references, const unsigned int revision);
|
void queryStoreReferences(const Path & path, PathSet & references, const unsigned int revision);
|
||||||
|
|
||||||
void queryStateReferences(const Path & storePath, PathSet & stateReferences, const unsigned int revision);
|
void queryStateReferences(const Path & storePath, PathSet & stateReferences, const unsigned int revision);
|
||||||
|
|
||||||
void queryReferrers(const Path & path, PathSet & referrers, const unsigned int revision);
|
void queryStoreReferrers(const Path & path, PathSet & referrers, const unsigned int revision);
|
||||||
|
|
||||||
void queryStateReferrers(const Path & path, PathSet & stateReferrers, const unsigned int revision);
|
void queryStateReferrers(const Path & path, PathSet & stateReferrers, const unsigned int revision);
|
||||||
|
|
||||||
|
|
@ -177,7 +177,7 @@ bool isValidPathTxn(const Transaction & txn, const Path & path);
|
||||||
/* Sets the set of outgoing FS (also state) references for a store path. Use with
|
/* Sets the set of outgoing FS (also state) references for a store path. Use with
|
||||||
care!
|
care!
|
||||||
|
|
||||||
-1 for revision means overwrite the last revision
|
0 for revision means overwrite the last revision
|
||||||
*/
|
*/
|
||||||
void setReferences(const Transaction & txn, const Path & store_or_statePath,
|
void setReferences(const Transaction & txn, const Path & store_or_statePath,
|
||||||
const PathSet & references, const PathSet & stateReferences, const unsigned int revision);
|
const PathSet & references, const PathSet & stateReferences, const unsigned int revision);
|
||||||
|
|
@ -192,6 +192,9 @@ PathSet queryDerivers(const Transaction & txn, const Path & storePath, const str
|
||||||
/* Delete a value from the nixStore directory. */
|
/* Delete a value from the nixStore directory. */
|
||||||
void deleteFromStore(const Path & path, unsigned long long & bytesFreed);
|
void deleteFromStore(const Path & path, unsigned long long & bytesFreed);
|
||||||
|
|
||||||
|
/* Delete a value from the nixState directory. */
|
||||||
|
void deleteFromState(const Path & _path, unsigned long long & bytesFreed);
|
||||||
|
|
||||||
MakeError(PathInUse, Error);
|
MakeError(PathInUse, Error);
|
||||||
|
|
||||||
void verifyStore(bool checkContents);
|
void verifyStore(bool checkContents);
|
||||||
|
|
@ -232,7 +235,7 @@ void queryXReferencesTxn(const Transaction & txn, const Path & path, PathSet & r
|
||||||
void setStateComponentReferencesTxn(const Transaction & txn, const Path & statePath, const Strings & references, const unsigned int revision, const unsigned int timestamp);
|
void setStateComponentReferencesTxn(const Transaction & txn, const Path & statePath, const Strings & references, const unsigned int revision, const unsigned int timestamp);
|
||||||
void setStateStateReferencesTxn(const Transaction & txn, const Path & statePath, const Strings & references, const unsigned int revision, const unsigned int timestamp);
|
void setStateStateReferencesTxn(const Transaction & txn, const Path & statePath, const Strings & references, const unsigned int revision, const unsigned int timestamp);
|
||||||
|
|
||||||
void queryReferrersTxn(const Transaction & txn, const Path & storePath, PathSet & referrers, const unsigned int revision);
|
void queryStoreReferrersTxn(const Transaction & txn, const Path & storePath, PathSet & referrers, const unsigned int revision);
|
||||||
void queryStateReferrersTxn(const Transaction & txn, const Path & storePath, PathSet & stateReferrers, const unsigned int revision);
|
void queryStateReferrersTxn(const Transaction & txn, const Path & storePath, PathSet & stateReferrers, const unsigned int revision);
|
||||||
|
|
||||||
Path queryStatePathDrvTxn(const Transaction & txn, const Path & statePath);
|
Path queryStatePathDrvTxn(const Transaction & txn, const Path & statePath);
|
||||||
|
|
@ -263,6 +266,7 @@ bool queryStateRevisionsTxn(const Transaction & txn, const Path & statePath, Rev
|
||||||
void setStatePathsIntervalTxn(const Transaction & txn, const PathSet & statePath, const IntVector & intervals, bool allZero = false);
|
void setStatePathsIntervalTxn(const Transaction & txn, const PathSet & statePath, const IntVector & intervals, bool allZero = false);
|
||||||
bool querySharedStateTxn(const Transaction & txn, const Path & statePath, Path & shared_with);
|
bool querySharedStateTxn(const Transaction & txn, const Path & statePath, Path & shared_with);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -73,13 +73,15 @@ void computeFSClosureRecTxn(const Transaction & txn, const Path & path, PathSet
|
||||||
if (paths.find(path) != paths.end()) //takes care of double entries
|
if (paths.find(path) != paths.end()) //takes care of double entries
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
//printMsg(lvlError, format("ComputeFSClosureRec '%1%'") % path);
|
||||||
|
|
||||||
paths.insert(path);
|
paths.insert(path);
|
||||||
|
|
||||||
PathSet references;
|
PathSet references;
|
||||||
PathSet stateReferences;
|
PathSet stateReferences;
|
||||||
|
|
||||||
if (flipDirection){
|
if (flipDirection){
|
||||||
queryReferrersTxn(txn, path, references, revision);
|
queryStoreReferrersTxn(txn, path, references, revision);
|
||||||
queryStateReferrersTxn(txn, path, stateReferences, revision);
|
queryStateReferrersTxn(txn, path, stateReferences, revision);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
|
@ -143,7 +145,7 @@ void queryMissing(const PathSet & targets,
|
||||||
if (store->hasSubstitutes(p))
|
if (store->hasSubstitutes(p))
|
||||||
willSubstitute.insert(p);
|
willSubstitute.insert(p);
|
||||||
PathSet refs;
|
PathSet refs;
|
||||||
store->queryReferences(p, todo, 0); //TODO?
|
store->queryStoreReferences(p, todo, 0); //TODO?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -215,10 +215,10 @@ Path RemoteStore::queryStatePathDrv(const Path & statePath)
|
||||||
return readString(from);
|
return readString(from);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteStore::queryReferences(const Path & path,
|
void RemoteStore::queryStoreReferences(const Path & path,
|
||||||
PathSet & references, const unsigned int revision)
|
PathSet & references, const unsigned int revision)
|
||||||
{
|
{
|
||||||
writeInt(wopQueryReferences, to);
|
writeInt(wopQueryStoreReferences, to);
|
||||||
writeString(path, to);
|
writeString(path, to);
|
||||||
writeBigUnsignedInt(revision, to);
|
writeBigUnsignedInt(revision, to);
|
||||||
processStderr();
|
processStderr();
|
||||||
|
|
@ -238,10 +238,10 @@ void RemoteStore::queryStateReferences(const Path & path,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RemoteStore::queryReferrers(const Path & path,
|
void RemoteStore::queryStoreReferrers(const Path & path,
|
||||||
PathSet & referrers, const unsigned int revision)
|
PathSet & referrers, const unsigned int revision)
|
||||||
{
|
{
|
||||||
writeInt(wopQueryReferrers, to);
|
writeInt(wopQueryStoreReferrers, to);
|
||||||
writeString(path, to);
|
writeString(path, to);
|
||||||
writeBigUnsignedInt(revision, to);
|
writeBigUnsignedInt(revision, to);
|
||||||
processStderr();
|
processStderr();
|
||||||
|
|
|
||||||
|
|
@ -39,11 +39,11 @@ public:
|
||||||
|
|
||||||
Path queryStatePathDrv(const Path & statePath);
|
Path queryStatePathDrv(const Path & statePath);
|
||||||
|
|
||||||
void queryReferences(const Path & path, PathSet & references, const unsigned int revision);
|
void queryStoreReferences(const Path & path, PathSet & references, const unsigned int revision);
|
||||||
|
|
||||||
void queryStateReferences(const Path & storePath, PathSet & stateReferences, const unsigned int revision);
|
void queryStateReferences(const Path & storePath, PathSet & stateReferences, const unsigned int revision);
|
||||||
|
|
||||||
void queryReferrers(const Path & path, PathSet & referrers, const unsigned int revision);
|
void queryStoreReferrers(const Path & path, PathSet & referrers, const unsigned int revision);
|
||||||
|
|
||||||
void queryStateReferrers(const Path & path, PathSet & stateReferrers, const unsigned int revision);
|
void queryStateReferrers(const Path & path, PathSet & stateReferrers, const unsigned int revision);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@ public:
|
||||||
|
|
||||||
/* Queries the set of outgoing FS references for a store path.
|
/* Queries the set of outgoing FS references for a store path.
|
||||||
The result is not cleared. */
|
The result is not cleared. */
|
||||||
virtual void queryReferences(const Path & path,
|
virtual void queryStoreReferences(const Path & path,
|
||||||
PathSet & references, const unsigned int revision) = 0;
|
PathSet & references, const unsigned int revision) = 0;
|
||||||
|
|
||||||
/* Queries the set of outgoing FS state-references for a store path.
|
/* Queries the set of outgoing FS state-references for a store path.
|
||||||
|
|
@ -89,7 +89,7 @@ public:
|
||||||
|
|
||||||
/* Queries the set of incoming FS references for a store path.
|
/* Queries the set of incoming FS references for a store path.
|
||||||
The result is not cleared. */
|
The result is not cleared. */
|
||||||
virtual void queryReferrers(const Path & path,
|
virtual void queryStoreReferrers(const Path & path,
|
||||||
PathSet & referrers, const unsigned int revision) = 0;
|
PathSet & referrers, const unsigned int revision) = 0;
|
||||||
|
|
||||||
/* Queries the set of incoming FS state-references for a store path.
|
/* Queries the set of incoming FS state-references for a store path.
|
||||||
|
|
|
||||||
|
|
@ -108,10 +108,18 @@ void revertToRevisionTxn(const Transaction & txn, const Path & statePath, const
|
||||||
RevisionClosureTS getTimestamps;
|
RevisionClosureTS getTimestamps;
|
||||||
queryStateRevisionsTxn(txn, statePath_ns, getRivisions, getTimestamps, revision_arg);
|
queryStateRevisionsTxn(txn, statePath_ns, getRivisions, getTimestamps, revision_arg);
|
||||||
|
|
||||||
//TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
||||||
//include recursive
|
|
||||||
//lookup 0 (latest) to the real revision
|
|
||||||
|
|
||||||
|
//If not recursive: filter out all paths execpt statePath_ns
|
||||||
|
if(!recursive)
|
||||||
|
{
|
||||||
|
Snapshots currentSS = getRivisions[statePath_ns]; //save SS of statePath_ns
|
||||||
|
getRivisions.clear(); //clear all
|
||||||
|
getRivisions[statePath_ns] = currentSS; //insert
|
||||||
|
|
||||||
|
unsigned int currentTS = getTimestamps[statePath_ns]; //same as above
|
||||||
|
getTimestamps.clear();
|
||||||
|
getTimestamps[statePath_ns] = currentTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//Revert each statePath in the list
|
//Revert each statePath in the list
|
||||||
|
|
@ -145,6 +153,7 @@ void revertToRevisionTxn(const Transaction & txn, const Path & statePath, const
|
||||||
Strings p_args;
|
Strings p_args;
|
||||||
p_args.push_back("-c"); //we use the shell to execute the cp command becuase the shell expands the '*'
|
p_args.push_back("-c"); //we use the shell to execute the cp command becuase the shell expands the '*'
|
||||||
string cpcommand = "cp";
|
string cpcommand = "cp";
|
||||||
|
|
||||||
if(revertPathOrFile.substr(revertPathOrFile.length() -1 , revertPathOrFile.length()) == "/"){ //is dir
|
if(revertPathOrFile.substr(revertPathOrFile.length() -1 , revertPathOrFile.length()) == "/"){ //is dir
|
||||||
string revert_to_path = revertPathOrFile.substr(0, revertPathOrFile.length() -1) + "@" + unsignedInt2String(epoch);
|
string revert_to_path = revertPathOrFile.substr(0, revertPathOrFile.length() -1) + "@" + unsignedInt2String(epoch);
|
||||||
cpcommand += " -R " + revert_to_path + "/*";
|
cpcommand += " -R " + revert_to_path + "/*";
|
||||||
|
|
@ -186,7 +195,7 @@ void revertToRevisionTxn(const Transaction & txn, const Path & statePath, const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//*** Now also revert _state references_ to the specific revision (the revision is already converted to a timestamp here)
|
//*** Now also revert state _references_ to the specific revision (the revision is already converted to a timestamp here)
|
||||||
|
|
||||||
//Query the references of the old revision (already converted to a timestamp)
|
//Query the references of the old revision (already converted to a timestamp)
|
||||||
PathSet state_references;
|
PathSet state_references;
|
||||||
|
|
@ -198,6 +207,9 @@ void revertToRevisionTxn(const Transaction & txn, const Path & statePath, const
|
||||||
setStateComponentReferencesTxn(txn, statePath, Strings(state_references.begin(), state_references.end()), 0, newTimestamp);
|
setStateComponentReferencesTxn(txn, statePath, Strings(state_references.begin(), state_references.end()), 0, newTimestamp);
|
||||||
setStateStateReferencesTxn(txn, statePath, Strings(state_stateReferences.begin(), state_stateReferences.end()), 0, newTimestamp);
|
setStateStateReferencesTxn(txn, statePath, Strings(state_stateReferences.begin(), state_stateReferences.end()), 0, newTimestamp);
|
||||||
|
|
||||||
|
if(revision_arg == 0)
|
||||||
|
printMsg(lvlError, format("Reverted state of '%1%' to the latest revision") % statePath); //TODO lookup the number
|
||||||
|
else
|
||||||
printMsg(lvlError, format("Reverted state of '%1%' to revision '%2%'") % statePath % revision_arg);
|
printMsg(lvlError, format("Reverted state of '%1%' to revision '%2%'") % statePath % revision_arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -293,6 +305,8 @@ void scanAndUpdateAllReferencesTxn(const Transaction & txn, const Path & statePa
|
||||||
|
|
||||||
//TODO check if path is not a shared path !
|
//TODO check if path is not a shared path !
|
||||||
//TODO
|
//TODO
|
||||||
|
//TODO Unshare the path:
|
||||||
|
//TODO Path statePath_ns = toNonSharedPathTxn(txn, statePath);
|
||||||
|
|
||||||
//get all possible state and component references
|
//get all possible state and component references
|
||||||
PathSet allComponentPaths;
|
PathSet allComponentPaths;
|
||||||
|
|
@ -714,7 +728,7 @@ bool queryAvailableStateRevisions(Database & nixDB, const Transaction & txn, Tab
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void copyContents(const Path & from, const Path & to) //TODO bool shellexpansion, bool failure for nix-env
|
void rsyncPaths(const Path & from, const Path & to) //TODO bool shellexpansion, bool failure for nix-env
|
||||||
{
|
{
|
||||||
//TODO Could be a symlink (to a non-existing dir)
|
//TODO Could be a symlink (to a non-existing dir)
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ namespace nix {
|
||||||
const Path & statePath, RevisionInfos & revisions);
|
const Path & statePath, RevisionInfos & revisions);
|
||||||
|
|
||||||
/* Copy all files and folders recursively (also the hidden ones) from the dir from/... to the dir to/... and delete the rest in to/ (Rsync) */
|
/* Copy all files and folders recursively (also the hidden ones) from the dir from/... to the dir to/... and delete the rest in to/ (Rsync) */
|
||||||
void copyContents(const Path & from, const Path & to);
|
void rsyncPaths(const Path & from, const Path & to);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,9 @@ typedef enum {
|
||||||
wopHasSubstitutes,
|
wopHasSubstitutes,
|
||||||
wopQueryPathHash,
|
wopQueryPathHash,
|
||||||
wopQueryStatePathDrv,
|
wopQueryStatePathDrv,
|
||||||
wopQueryReferences,
|
wopQueryStoreReferences,
|
||||||
wopQueryStateReferences,
|
wopQueryStateReferences,
|
||||||
wopQueryReferrers, //10
|
wopQueryStoreReferrers, //10
|
||||||
wopQueryStateReferrers,
|
wopQueryStateReferrers,
|
||||||
wopAddToStore,
|
wopAddToStore,
|
||||||
wopAddTextToStore,
|
wopAddTextToStore,
|
||||||
|
|
|
||||||
|
|
@ -641,10 +641,10 @@ static void installDerivations(Globals & globals,
|
||||||
comparePaths.insert(statePath);
|
comparePaths.insert(statePath);
|
||||||
comparePaths.insert(read_statePath);
|
comparePaths.insert(read_statePath);
|
||||||
if(store->toNonSharedPathSet(comparePaths).size() != 1) //TODO !!!!!!!!!!!!!??
|
if(store->toNonSharedPathSet(comparePaths).size() != 1) //TODO !!!!!!!!!!!!!??
|
||||||
copyContents(externalState, statePath);
|
rsyncPaths(externalState, statePath);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
copyContents(externalState, statePath);
|
rsyncPaths(externalState, statePath);
|
||||||
|
|
||||||
deletePath(externalState);
|
deletePath(externalState);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,13 +23,13 @@ Information:
|
||||||
--version: output version information
|
--version: output version information
|
||||||
--help: display help
|
--help: display help
|
||||||
|
|
||||||
Share state Operations:
|
(Un)Share state Operations:
|
||||||
|
|
||||||
--unshare: unshare this path
|
--unshare: unshare this path
|
||||||
--share-with=a b: make the statepath b point to a
|
--share-with=a b: make the statepath b point to a
|
||||||
--copy-from=a b: make the contents of statepath b equal to the contents of a
|
--rsync-from=a b: make the contents of statepath b equal to the contents of a
|
||||||
|
|
||||||
Share state Options:
|
Unshare state Options:
|
||||||
|
|
||||||
--unshare-and-branch-state:
|
--unshare-and-branch-state:
|
||||||
--unshare-and-restore-old-state: (default)
|
--unshare-and-restore-old-state: (default)
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -279,17 +279,19 @@ static void opUnshare(Strings opFlags, Strings opArgs)
|
||||||
static void opShareWith(Strings opFlags, Strings opArgs)
|
static void opShareWith(Strings opFlags, Strings opArgs)
|
||||||
{
|
{
|
||||||
Path statePath = *(opArgs.begin());
|
Path statePath = *(opArgs.begin());
|
||||||
if(!store->isValidStatePath(statePath))
|
if(!store->isValidStatePath(statePath) || !store->isValidStatePath(share_with))
|
||||||
throw UsageError(format("Path '%1%' is not a valid state path.") % statePath);
|
throw UsageError(format("Path '%1%' or '%2%' is not a valid state path.") % statePath % share_with);
|
||||||
|
|
||||||
store->shareState(statePath, share_with, false);
|
store->shareState(statePath, share_with, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void opCopyFrom(Strings opFlags, Strings opArgs)
|
static void opCopyFrom(Strings opFlags, Strings opArgs)
|
||||||
{
|
{
|
||||||
//TODO !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
Path statePath = *(opArgs.begin());
|
||||||
//copy_from
|
if(!store->isValidStatePath(statePath) || !store->isValidStatePath(copy_from))
|
||||||
throw UsageError(format("TODO !!!!!!!!!!!!"));
|
throw UsageError(format("Path '%1%' or '%2%' is not a valid state path.") % statePath % copy_from);
|
||||||
|
|
||||||
|
rsyncPaths(copy_from, statePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -522,7 +524,7 @@ void run(Strings args)
|
||||||
printMsg(lvlError, format("NOW: '%1%'") % FileExist("/nix/store/65c7p6c8j0vy6b8fjgq8") );
|
printMsg(lvlError, format("NOW: '%1%'") % FileExist("/nix/store/65c7p6c8j0vy6b8fjgq8") );
|
||||||
printMsg(lvlError, format("NOW: '%1%'") % DirectoryExist("/nix/store/65c7p6c8j0vy6b8fjg") );
|
printMsg(lvlError, format("NOW: '%1%'") % DirectoryExist("/nix/store/65c7p6c8j0vy6b8fjg") );
|
||||||
|
|
||||||
store = openStore();
|
|
||||||
|
|
||||||
// /nix/state/g8vby0bjfrs85qpf1jfajrcrmlawn442-hellohardcodedstateworld-1.0-
|
// /nix/state/g8vby0bjfrs85qpf1jfajrcrmlawn442-hellohardcodedstateworld-1.0-
|
||||||
// /nix/state/6l93ff3bn1mk61jbdd34diafmb4aq7c6-hellohardcodedstateworld-1.0-
|
// /nix/state/6l93ff3bn1mk61jbdd34diafmb4aq7c6-hellohardcodedstateworld-1.0-
|
||||||
|
|
@ -572,8 +574,19 @@ void run(Strings args)
|
||||||
printMsg(lvlError, format("Rsync: '%1%'") % nixRsync);
|
printMsg(lvlError, format("Rsync: '%1%'") % nixRsync);
|
||||||
|
|
||||||
copyContents("/nix/state/fwir6jlqygy90zadnx95zryfa8918qac-hellohardcodedstateworld-1.0-test/", "/home/wouterdb/tmp/aa/"); //TODO !!!!!!!!!!!!!!!!!!!
|
copyContents("/nix/state/fwir6jlqygy90zadnx95zryfa8918qac-hellohardcodedstateworld-1.0-test/", "/home/wouterdb/tmp/aa/"); //TODO !!!!!!!!!!!!!!!!!!!
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
store = openStore();
|
||||||
|
Hash hash;
|
||||||
|
PathSet references;
|
||||||
|
PathSet stateReferences;
|
||||||
|
registerValidPath(noTxn, "/nix/store/sjnaisdpqyckc75c3mjz4msi9s1662cw-hellohardcodedstateworld-1.0", hash, references, stateReferences, "/nix/store/y7abzzpiknzps5kjb4qvdxvlhvxl6slj-hellohardcodedstateworld_import-1.0.drv", 0);
|
||||||
return;
|
return;
|
||||||
*/
|
|
||||||
|
//*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* test */
|
/* test */
|
||||||
|
|
||||||
|
|
@ -647,9 +660,9 @@ void run(Strings args)
|
||||||
op = opShareWith;
|
op = opShareWith;
|
||||||
share_with = arg.substr(13,arg.length());
|
share_with = arg.substr(13,arg.length());
|
||||||
}
|
}
|
||||||
else if (arg.substr(0,12) == "--copy-from="){
|
else if (arg.substr(0,13) == "--rsync-from="){
|
||||||
op = opCopyFrom;
|
op = opCopyFrom;
|
||||||
copy_from = arg.substr(12,arg.length());
|
copy_from = arg.substr(13,arg.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,7 @@ void printDotGraph(const PathSet & roots)
|
||||||
//Lookup all references
|
//Lookup all references
|
||||||
PathSet references;
|
PathSet references;
|
||||||
PathSet stateReferences;
|
PathSet stateReferences;
|
||||||
store->queryReferences(path, references, 0);
|
store->queryStoreReferences(path, references, 0);
|
||||||
store->queryStateReferences(path, stateReferences, 0);
|
store->queryStateReferences(path, stateReferences, 0);
|
||||||
PathSet allReferences = pathSets_union(references, stateReferences);
|
PathSet allReferences = pathSets_union(references, stateReferences);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -214,7 +214,7 @@ static void printTree(const Path & path,
|
||||||
//Lookup all references
|
//Lookup all references
|
||||||
PathSet references;
|
PathSet references;
|
||||||
PathSet stateReferences;
|
PathSet stateReferences;
|
||||||
store->queryReferences(path, references, 0);
|
store->queryStoreReferences(path, references, 0);
|
||||||
store->queryStateReferences(path, stateReferences, 0);
|
store->queryStateReferences(path, stateReferences, 0);
|
||||||
PathSet allReferences = pathSets_union(references, stateReferences);
|
PathSet allReferences = pathSets_union(references, stateReferences);
|
||||||
|
|
||||||
|
|
@ -317,9 +317,9 @@ static void opQuery(Strings opFlags, Strings opArgs)
|
||||||
if (query == qRequisites) store->storePathRequisites(path, includeOutputs, paths, true, false, revision);
|
if (query == qRequisites) store->storePathRequisites(path, includeOutputs, paths, true, false, revision);
|
||||||
else if (query == qRequisitesState) store->storePathRequisites(path, includeOutputs, paths, false, true, revision);
|
else if (query == qRequisitesState) store->storePathRequisites(path, includeOutputs, paths, false, true, revision);
|
||||||
else if (query == qRequisitesFull) store->storePathRequisites(path, includeOutputs, paths, true, true, revision);
|
else if (query == qRequisitesFull) store->storePathRequisites(path, includeOutputs, paths, true, true, revision);
|
||||||
else if (query == qReferences) store->queryReferences(path, paths, revision);
|
else if (query == qReferences) store->queryStoreReferences(path, paths, revision);
|
||||||
else if (query == qStateReferences) store->queryStateReferences(path, paths, revision);
|
else if (query == qStateReferences) store->queryStateReferences(path, paths, revision);
|
||||||
else if (query == qReferrers) store->queryReferrers(path, paths, revision);
|
else if (query == qReferrers) store->queryStoreReferrers(path, paths, revision);
|
||||||
else if (query == qStateReferrers) store->queryStateReferrers(path, paths, revision);
|
else if (query == qStateReferrers) store->queryStateReferrers(path, paths, revision);
|
||||||
else if (query == qReferrersClosure) computeFSClosure(path, paths, true, false, revision, true);
|
else if (query == qReferrersClosure) computeFSClosure(path, paths, true, false, revision, true);
|
||||||
else if (query == qReferrersClosureWithState) computeFSClosure(path, paths, true, true, revision, true);
|
else if (query == qReferrersClosureWithState) computeFSClosure(path, paths, true, true, revision, true);
|
||||||
|
|
@ -453,7 +453,7 @@ static void opRegisterSubstitutes(Strings opFlags, Strings opArgs)
|
||||||
}
|
}
|
||||||
if (!cin || cin.eof()) throw Error("missing input");
|
if (!cin || cin.eof()) throw Error("missing input");
|
||||||
registerSubstitute(txn, srcPath, sub);
|
registerSubstitute(txn, srcPath, sub);
|
||||||
setReferences(txn, srcPath, references, stateReferences, 0); //state revision 0, e.g. first commit
|
setReferences(txn, srcPath, references, stateReferences, 1); //state revision 1, e.g. first commit
|
||||||
}
|
}
|
||||||
|
|
||||||
txn.commit();
|
txn.commit();
|
||||||
|
|
|
||||||
|
|
@ -294,16 +294,16 @@ static void performOp(Source & from, Sink & to, unsigned int op)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case wopQueryReferences:
|
case wopQueryStoreReferences:
|
||||||
case wopQueryReferrers: {
|
case wopQueryStoreReferrers: {
|
||||||
Path path = readStorePath(from);
|
Path path = readStorePath(from);
|
||||||
unsigned int revision = readBigUnsignedInt(from);
|
unsigned int revision = readBigUnsignedInt(from);
|
||||||
startWork();
|
startWork();
|
||||||
PathSet paths;
|
PathSet paths;
|
||||||
if (op == wopQueryReferences)
|
if (op == wopQueryStoreReferences)
|
||||||
store->queryReferences(path, paths, revision);
|
store->queryStoreReferences(path, paths, revision);
|
||||||
else
|
else
|
||||||
store->queryReferrers(path, paths, revision);
|
store->queryStoreReferrers(path, paths, revision);
|
||||||
stopWork();
|
stopWork();
|
||||||
writeStringSet(paths, to);
|
writeStringSet(paths, to);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue