1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-07-03 06:11:46 +02:00

* Revived the old "nix-store --delete" operation that deletes the

specified paths from the Nix store.  However, this operation is
  safe: it refuses to delete anything that the garbage collector
  wouldn't delete.
This commit is contained in:
Eelco Dolstra 2005-12-23 21:08:42 +00:00
parent 3c5619c7e4
commit 4b9e7f59ca
4 changed files with 45 additions and 11 deletions

View file

@ -303,8 +303,8 @@ static Paths topoSort(const PathSet & paths)
}
void collectGarbage(GCAction action, PathSet & result,
unsigned long long & bytesFreed)
void collectGarbage(GCAction action, const PathSet & pathsToDelete,
PathSet & result, unsigned long long & bytesFreed)
{
result.clear();
bytesFreed = 0;
@ -398,17 +398,26 @@ void collectGarbage(GCAction action, PathSet & result,
/* Read the Nix store directory to find all currently existing
paths. */
Paths storePaths = readDirectory(nixStore);
PathSet storePaths2;
for (Paths::iterator i = storePaths.begin(); i != storePaths.end(); ++i)
storePaths2.insert(canonPath(nixStore + "/" + *i));
PathSet storePathSet;
if (action != gcDeleteSpecific) {
Paths entries = readDirectory(nixStore);
for (Paths::iterator i = entries.begin(); i != entries.end(); ++i)
storePathSet.insert(canonPath(nixStore + "/" + *i));
} else {
for (PathSet::iterator i = pathsToDelete.begin();
i != pathsToDelete.end(); ++i)
{
assertStorePath(*i);
storePathSet.insert(*i);
}
}
/* Topologically sort them under the `referrers' relation. That
is, a < b iff a is in referrers(b). This gives us the order in
which things can be deleted safely. */
/* !!! when we have multiple output paths per derivation, this
will not work anymore because we get cycles. */
storePaths = topoSort(storePaths2);
Paths storePaths = topoSort(storePathSet);
/* Try to delete store paths in the topologically sorted order. */
for (Paths::iterator i = storePaths.begin(); i != storePaths.end(); ++i) {
@ -416,6 +425,8 @@ void collectGarbage(GCAction action, PathSet & result,
debug(format("considering deletion of `%1%'") % *i);
if (livePaths.find(*i) != livePaths.end()) {
if (action == gcDeleteSpecific)
throw Error(format("cannot delete path `%1%' since it is still alive") % *i);
debug(format("live path `%1%'") % *i);
continue;
}
@ -430,7 +441,7 @@ void collectGarbage(GCAction action, PathSet & result,
AutoCloseFD fdLock;
if (action == gcDeleteDead) {
if (action == gcDeleteDead || action == gcDeleteSpecific) {
/* Only delete a lock file if we can acquire a write lock
on it. That means that it's either stale, or the

View file

@ -10,6 +10,7 @@ typedef enum {
gcReturnLive,
gcReturnDead,
gcDeleteDead,
gcDeleteSpecific,
} GCAction;
/* If `action' is set to `gcReturnRoots', find and return the set of
@ -19,8 +20,8 @@ typedef enum {
closure of) the roots. If `action' is `gcReturnDead', return the
set of paths not reachable from the roots. If `action' is
`gcDeleteDead', actually delete the latter set. */
void collectGarbage(GCAction action, PathSet & result,
unsigned long long & bytesFreed);
void collectGarbage(GCAction action, const PathSet & pathsToDelete,
PathSet & result, unsigned long long & bytesFreed);
/* Register a temporary GC root. This root will automatically
disappear when this process exits. WARNING: this function should