Skip to content

Commit

Permalink
Merge pull request #10 from NixLayeredStore/delete
Browse files Browse the repository at this point in the history
Fix and test deleting when lower store references
  • Loading branch information
Ericson2314 committed Jul 26, 2023
2 parents c2d5449 + 621bdbd commit 31112fd
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 5 deletions.
2 changes: 1 addition & 1 deletion src/libstore/gc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -741,7 +741,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
auto i = referrersCache.find(*path);
if (i == referrersCache.end()) {
StorePathSet referrers;
queryReferrers(*path, referrers);
queryGCReferrers(*path, referrers);
referrersCache.emplace(*path, std::move(referrers));
i = referrersCache.find(*path);
}
Expand Down
6 changes: 6 additions & 0 deletions src/libstore/local-overlay-store.cc
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,12 @@ void LocalOverlayStore::queryReferrers(const StorePath & path, StorePathSet & re
}


void LocalOverlayStore::queryGCReferrers(const StorePath & path, StorePathSet & referrers)
{
LocalStore::queryReferrers(path, referrers);
}


StorePathSet LocalOverlayStore::queryValidDerivers(const StorePath & path)
{
auto res = LocalStore::queryValidDerivers(path);
Expand Down
9 changes: 9 additions & 0 deletions src/libstore/local-overlay-store.hh
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,17 @@ private:

void optimiseStore() override;

/**
* For lower-store paths, we used the lower store location. This avoids the
* wasteful "copying up" that would otherwise happen.
*/
Path toRealPathForHardLink(const StorePath & storePath) override;

/**
* Deletion only effects the upper layer, so we ignore lower-layer referrers.
*/
void queryGCReferrers(const StorePath & path, StorePathSet & referrers) override;

void remountIfNecessary();

std::atomic_bool _remountRequired = false;
Expand Down
12 changes: 12 additions & 0 deletions src/libstore/local-store.hh
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,18 @@ public:

void collectGarbage(const GCOptions & options, GCResults & results) override;

/**
* Called by `collectGarbage` to trace in reverse.
*
* Using this rather than `queryReferrers` directly allows us to
* fine-tune which referrers we consider for garbage collection;
* some store implementations take advantage of this.
*/
virtual void queryGCReferrers(const StorePath & path, StorePathSet & referrers)
{
return queryReferrers(path, referrers);
}

/**
* Called by `collectGarbage` to recursively delete a path.
* The default implementation simply calls `deletePath`, but it can be
Expand Down
4 changes: 2 additions & 2 deletions tests/hermetic.nix
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ let
buildCommand = ''
echo hi-input3
read x < ${input2}
echo $x BAZ > $out
echo ${input2} $x BAZ > $out
'';
};

Expand All @@ -51,6 +51,6 @@ in
''
read x < ${input1}
read y < ${input3}
echo "$x $y" > $out
echo ${input1} ${input3} "$x $y" > $out
'';
}
39 changes: 39 additions & 0 deletions tests/overlay-local-store/delete-refs-inner.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/usr/bin/env bash

set -eu -o pipefail

source common.sh

# Avoid store dir being inside sandbox build-dir
unset NIX_STORE_DIR
unset NIX_STATE_DIR

storeDirs

initLowerStore

mountOverlayfs

export NIX_REMOTE="$storeB"
stateB="$storeBRoot/nix/var/nix"
hermetic=$(nix-build ../hermetic.nix --no-out-link --arg busybox "$busybox" --arg seed 2)
input1=$(nix-build ../hermetic.nix --no-out-link --arg busybox "$busybox" --arg seed 2 -A passthru.input1 -j0)
input2=$(nix-build ../hermetic.nix --no-out-link --arg busybox "$busybox" --arg seed 2 -A passthru.input2 -j0)
input3=$(nix-build ../hermetic.nix --no-out-link --arg busybox "$busybox" --arg seed 2 -A passthru.input3 -j0)

# Can't delete because referenced
expectStderr 1 nix-store --delete $input1 | grepQuiet "Cannot delete path"
expectStderr 1 nix-store --delete $input2 | grepQuiet "Cannot delete path"
expectStderr 1 nix-store --delete $input3 | grepQuiet "Cannot delete path"

# These same paths are referenced in the lower layer (by the seed 1
# build done in `initLowerStore`).
expectStderr 1 nix-store --store "$storeA" --delete $input2 | grepQuiet "Cannot delete path"
expectStderr 1 nix-store --store "$storeA" --delete $input3 | grepQuiet "Cannot delete path"

# Can delete
nix-store --delete $hermetic

# Now unreferenced in upper layer, can delete
nix-store --delete $input3
nix-store --delete $input2
5 changes: 5 additions & 0 deletions tests/overlay-local-store/delete-refs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
source common.sh

requireEnvironment
setupConfig
execUnshare ./delete-refs-inner.sh
5 changes: 3 additions & 2 deletions tests/overlay-local-store/local.mk
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ overlay-local-store-tests := \
$(d)/build.sh \
$(d)/bad-uris.sh \
$(d)/add-lower.sh \
$(d)/delete-refs.sh \
$(d)/delete-duplicate.sh \
$(d)/gc.sh \
$(d)/verify.sh \
$(d)/optimise.sh \
$(d)/delete-duplicate.sh
$(d)/optimise.sh

install-tests-groups += overlay-local-store

0 comments on commit 31112fd

Please sign in to comment.