libstore/gc: restore deletion of referrers
Fixes: 8614cf1334
Fixes #495
Change-Id: I4d8d655c6254786ba1222a5b37551c68d9e370ee
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
---
|
||||
synopsis: "Fix nix-store --delete on paths with remaining referrers"
|
||||
cls: [2783]
|
||||
category: "Fixes"
|
||||
credits: lheckemann
|
||||
---
|
||||
|
||||
Nix 2.5 introduced a regression whereby `nix-store --delete` and `nix
|
||||
store delete` started to fail when trying to delete a path that was
|
||||
still referenced by other paths, even if the referrers were not
|
||||
reachable from any GC roots. The old behaviour, where attempting to
|
||||
delete a store path would also delete its referrer closure, is now
|
||||
restored.
|
||||
@@ -749,10 +749,6 @@ try {
|
||||
co_return result::success();
|
||||
}
|
||||
|
||||
if (options.action == GCOptions::gcDeleteSpecific
|
||||
&& !options.pathsToDelete.count(*path))
|
||||
co_return result::success();
|
||||
|
||||
if (!gcServer.markPendingIfPresent(std::string(path->hashPart()))) {
|
||||
debug("cannot delete '%s' because it's a temporary root", printStorePath(*path));
|
||||
TRY_AWAIT(markAlive());
|
||||
|
||||
+19
-11
@@ -2,12 +2,16 @@ source common.sh
|
||||
|
||||
clearStore
|
||||
|
||||
drvPath=$(nix-instantiate dependencies.nix)
|
||||
outPath=$(nix-store -rvv "$drvPath")
|
||||
createAndRootPaths() {
|
||||
drvPath=$(nix-instantiate dependencies.nix)
|
||||
outPath=$(nix-store -rvv "$drvPath")
|
||||
|
||||
# Set a GC root.
|
||||
rm -f "$NIX_STATE_DIR"/gcroots/foo
|
||||
ln -sf $outPath "$NIX_STATE_DIR"/gcroots/foo
|
||||
# Set a GC root.
|
||||
rm -f "$NIX_STATE_DIR"/gcroots/foo
|
||||
ln -sf $outPath "$NIX_STATE_DIR"/gcroots/foo
|
||||
}
|
||||
|
||||
createAndRootPaths
|
||||
|
||||
[ "$(nix-store -q --roots $outPath)" = "$NIX_STATE_DIR/gcroots/foo -> $outPath" ]
|
||||
|
||||
@@ -18,9 +22,9 @@ if nix-store --gc --print-dead | grep -E $outPath$; then false; fi
|
||||
|
||||
nix-store --gc --print-dead
|
||||
|
||||
inUse=$(readLink $outPath/reference-to-input-2)
|
||||
if nix-store --delete $inUse; then false; fi
|
||||
test -e $inUse
|
||||
input2=$(readLink $outPath/reference-to-input-2)
|
||||
if nix-store --delete $input2; then false; fi
|
||||
test -e $input2
|
||||
|
||||
if nix-store --delete $outPath; then false; fi
|
||||
test -e $outPath
|
||||
@@ -42,10 +46,14 @@ if test -e $drvPath; then false; fi
|
||||
|
||||
rm "$NIX_STATE_DIR"/gcroots/foo
|
||||
|
||||
nix-collect-garbage
|
||||
# Deleting the dependency should now be possible, and delete the referrer as well
|
||||
nix-store --delete $input2
|
||||
! test -e $outPath
|
||||
! test -e $input2
|
||||
|
||||
# Check that the output has been GC'd.
|
||||
if test -e $outPath/foobar; then false; fi
|
||||
createAndRootPaths
|
||||
rm "$NIX_STATE_DIR"/gcroots/foo
|
||||
nix-collect-garbage
|
||||
|
||||
# Check that the store is empty.
|
||||
rmdir $NIX_STORE_DIR/.links
|
||||
|
||||
Reference in New Issue
Block a user