1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-11 04:56:01 +01:00

nix store delete: Show the first root that prevents deletion

Examples:

  error: Cannot delete path '/nix/store/6fcrjgfjip2ww3sx51rrmmghfsf60jvi-patchelf-0.14.3' because it's referenced by the GC root '/home/eelco/Dev/nix-master/build/result'.

  error: Cannot delete path '/nix/store/rn0qyn3kmky26xgpr2n10vr787g57lff-cowsay-3.8.4' because it's referenced by the GC root '/proc/3600568/environ'.
This commit is contained in:
Eelco Dolstra 2025-06-27 15:08:17 +02:00
parent 1929d84f9e
commit 59700c0978

View file

@ -458,7 +458,8 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
bool gcKeepOutputs = settings.gcKeepOutputs; bool gcKeepOutputs = settings.gcKeepOutputs;
bool gcKeepDerivations = settings.gcKeepDerivations; bool gcKeepDerivations = settings.gcKeepDerivations;
std::unordered_set<StorePath> roots, dead, alive; Roots roots;
std::unordered_set<StorePath> dead, alive;
struct Shared struct Shared
{ {
@ -612,11 +613,8 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
/* 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. */
printInfo("finding garbage collector roots..."); printInfo("finding garbage collector roots...");
Roots rootMap;
if (!options.ignoreLiveness) if (!options.ignoreLiveness)
findRootsNoTemp(rootMap, true); findRootsNoTemp(roots, true);
for (auto & i : rootMap) roots.insert(i.first);
/* Read the temporary roots created before we acquired the global /* Read the temporary roots created before we acquired the global
GC root. Any new roots will be sent to our socket. */ GC root. Any new roots will be sent to our socket. */
@ -715,11 +713,12 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
}; };
/* If this is a root, bail out. */ /* If this is a root, bail out. */
if (roots.count(*path)) { if (auto i = roots.find(*path); i != roots.end()) {
if (options.action == GCOptions::gcDeleteSpecific) if (options.action == GCOptions::gcDeleteSpecific)
throw Error( throw Error(
"Cannot delete path '%s' because it's a GC root.", "Cannot delete path '%s' because it's referenced by the GC root '%s'.",
printStorePath(start)); printStorePath(start),
*i->second.begin());
debug("cannot delete '%s' because it's a root", printStorePath(*path)); debug("cannot delete '%s' because it's a root", printStorePath(*path));
return markAlive(); return markAlive();
} }