From 6a41dae49a91059d5996124717042c1b657b05b7 Mon Sep 17 00:00:00 2001 From: Raito Bezarius Date: Sun, 19 Jan 2025 11:58:57 +0100 Subject: [PATCH] fix(gc): log sudden "path in use" exceptions and recover during GC gracefully Original-Author: picnoir Inspired from https://github.com/NixOS/nix/pull/11922/commits/ced8d311a593fcf9c3823e4e118474ac132d8e60 and adapted for Lix needs. TL;DR: The topological sort should ensure that it is possible to delete the path iterated upon. Nonetheless, in some cases, `invalidatePathChecked` can still throw `PathInUse`, the exception bubbles up and cancel the garbage collection procedure, leaving the rest of the paths untouched. This change ensure that the error is logged for further investigation but doesn't prevent the GC to continue when it can. After code review, we decided to make it a `printInfo` to inform the user about sudden "in use" dependencies during garbage collection and let them re-run garbage collection if they care about this. References: https://github.com/NixOS/nix/issues/11923 References: https://git.lix.systems/lix-project/lix/issues/621 Change-Id: I5606c9afd16b5faa747b713fde2dc24016990ba3 Signed-off-by: Raito Bezarius --- lix/libstore/gc.cc | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/lix/libstore/gc.cc b/lix/libstore/gc.cc index 750bdbc1d..a32f77dda 100644 --- a/lix/libstore/gc.cc +++ b/lix/libstore/gc.cc @@ -746,9 +746,16 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results) for (auto & path : topoSortPaths(visited)) { if (!dead.insert(path).second) continue; if (shouldDelete) { - invalidatePathChecked(path); - deleteFromStore(path.to_string()); - referrersCache.erase(path); + try { + invalidatePathChecked(path); + deleteFromStore(path.to_string()); + referrersCache.erase(path); + } catch (PathInUse &) { + // References to upstream "bugs": + // https://github.com/NixOS/nix/issues/11923 + // https://git.lix.systems/lix-project/lix/issues/621 + printInfo("Skipping deletion of path '%1%' because it is now in use, preventing its removal.", printStorePath(path)); + } } } };