mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-10 08:16:15 +02:00
Merge pull request #9 from NixLayeredStore/gc
Add a GC test, fix hardlinking issue
This commit is contained in:
commit
a1a7f3156d
7 changed files with 86 additions and 3 deletions
|
@ -386,8 +386,9 @@ void LocalDerivationGoal::cleanupPostOutputsRegisteredModeNonCheck()
|
||||||
|
|
||||||
|
|
||||||
#if __linux__
|
#if __linux__
|
||||||
static void linkOrCopy(const Path & from, const Path & to)
|
static void linkOrCopy(LocalFSStore & store, const StorePath & from_, const Path & to)
|
||||||
{
|
{
|
||||||
|
auto from = store.toRealPathForHardLink(from_);
|
||||||
if (link(from.c_str(), to.c_str()) == -1) {
|
if (link(from.c_str(), to.c_str()) == -1) {
|
||||||
/* Hard-linking fails if we exceed the maximum link count on a
|
/* Hard-linking fails if we exceed the maximum link count on a
|
||||||
file (e.g. 32000 of ext3), which is quite possible after a
|
file (e.g. 32000 of ext3), which is quite possible after a
|
||||||
|
@ -712,7 +713,7 @@ void LocalDerivationGoal::startBuilder()
|
||||||
if (S_ISDIR(lstat(r).st_mode))
|
if (S_ISDIR(lstat(r).st_mode))
|
||||||
dirsInChroot.insert_or_assign(p, r);
|
dirsInChroot.insert_or_assign(p, r);
|
||||||
else
|
else
|
||||||
linkOrCopy(r, chrootRootDir + p);
|
linkOrCopy(getLocalStore(), i, chrootRootDir + p);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we're repairing, checking or rebuilding part of a
|
/* If we're repairing, checking or rebuilding part of a
|
||||||
|
@ -1574,7 +1575,7 @@ void LocalDerivationGoal::addDependency(const StorePath & path)
|
||||||
throw Error("could not add path '%s' to sandbox", worker.store.printStorePath(path));
|
throw Error("could not add path '%s' to sandbox", worker.store.printStorePath(path));
|
||||||
|
|
||||||
} else
|
} else
|
||||||
linkOrCopy(source, target);
|
linkOrCopy(getLocalStore(), path, target);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
throw Error("don't know how to make path '%s' (produced by a recursive Nix call) appear in the sandbox",
|
throw Error("don't know how to make path '%s' (produced by a recursive Nix call) appear in the sandbox",
|
||||||
|
|
|
@ -73,6 +73,16 @@ public:
|
||||||
return getRealStoreDir() + "/" + std::string(storePath, storeDir.size() + 1);
|
return getRealStoreDir() + "/" + std::string(storePath, storeDir.size() + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the real path is hardlinked with something else, we might
|
||||||
|
* prefer to refer to the other path instead. This is the case with
|
||||||
|
* overlayfs, for example.
|
||||||
|
*/
|
||||||
|
virtual Path toRealPathForHardLink(const StorePath & storePath)
|
||||||
|
{
|
||||||
|
return Store::toRealPath(storePath);
|
||||||
|
}
|
||||||
|
|
||||||
std::optional<std::string> getBuildLogExact(const StorePath & path) override;
|
std::optional<std::string> getBuildLogExact(const StorePath & path) override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -209,6 +209,13 @@ void LocalOverlayStore::optimiseStore()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Path LocalOverlayStore::toRealPathForHardLink(const StorePath & path)
|
||||||
|
{
|
||||||
|
return lowerStore->isValidPath(path)
|
||||||
|
? lowerStore->Store::toRealPath(path)
|
||||||
|
: Store::toRealPath(path);
|
||||||
|
}
|
||||||
|
|
||||||
static RegisterStoreImplementation<LocalOverlayStore, LocalOverlayStoreConfig> regLocalOverlayStore;
|
static RegisterStoreImplementation<LocalOverlayStore, LocalOverlayStoreConfig> regLocalOverlayStore;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,6 +114,8 @@ private:
|
||||||
void deleteGCPath(const Path & path, uint64_t & bytesFreed) override;
|
void deleteGCPath(const Path & path, uint64_t & bytesFreed) override;
|
||||||
|
|
||||||
void optimiseStore() override;
|
void optimiseStore() override;
|
||||||
|
|
||||||
|
Path toRealPathForHardLink(const StorePath & storePath) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
57
tests/overlay-local-store/gc-inner.sh
Normal file
57
tests/overlay-local-store/gc-inner.sh
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
#!/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"
|
||||||
|
outPath=$(nix-build ../hermetic.nix --no-out-link --arg busybox "$busybox" --arg seed 2)
|
||||||
|
|
||||||
|
# Set a GC root.
|
||||||
|
mkdir -p "$stateB"
|
||||||
|
rm -f "$stateB"/gcroots/foo
|
||||||
|
ln -sf $outPath "$stateB"/gcroots/foo
|
||||||
|
|
||||||
|
[ "$(nix-store -q --roots $outPath)" = "$stateB/gcroots/foo -> $outPath" ]
|
||||||
|
|
||||||
|
nix-store --gc --print-roots | grep $outPath
|
||||||
|
nix-store --gc --print-live | grep $outPath
|
||||||
|
if nix-store --gc --print-dead | grep -E $outPath$; then false; fi
|
||||||
|
|
||||||
|
nix-store --gc --print-dead
|
||||||
|
|
||||||
|
expect 1 nix-store --delete $outPath
|
||||||
|
test -e "$storeBRoot/$outPath"
|
||||||
|
|
||||||
|
shopt -s nullglob
|
||||||
|
for i in $storeBRoot/*; do
|
||||||
|
if [[ $i =~ /trash ]]; then continue; fi # compat with old daemon
|
||||||
|
touch $i.lock
|
||||||
|
touch $i.chroot
|
||||||
|
done
|
||||||
|
|
||||||
|
nix-collect-garbage
|
||||||
|
|
||||||
|
# Check that the root and its dependencies haven't been deleted.
|
||||||
|
cat "$storeBRoot/$outPath"
|
||||||
|
|
||||||
|
rm "$stateB"/gcroots/foo
|
||||||
|
|
||||||
|
nix-collect-garbage
|
||||||
|
|
||||||
|
# Check that the output has been GC'd.
|
||||||
|
test ! -e $outPath
|
||||||
|
|
||||||
|
# Check that the store is empty.
|
||||||
|
[ "$(ls -1 "$storeBTop" | wc -l)" = "0" ]
|
5
tests/overlay-local-store/gc.sh
Executable file
5
tests/overlay-local-store/gc.sh
Executable file
|
@ -0,0 +1,5 @@
|
||||||
|
source common.sh
|
||||||
|
|
||||||
|
requireEnvironment
|
||||||
|
setupConfig
|
||||||
|
execUnshare ./gc-inner.sh
|
|
@ -4,6 +4,7 @@ overlay-local-store-tests := \
|
||||||
$(d)/build.sh \
|
$(d)/build.sh \
|
||||||
$(d)/bad-uris.sh \
|
$(d)/bad-uris.sh \
|
||||||
$(d)/add-lower.sh \
|
$(d)/add-lower.sh \
|
||||||
|
$(d)/gc.sh \
|
||||||
$(d)/verify.sh \
|
$(d)/verify.sh \
|
||||||
$(d)/optimise.sh
|
$(d)/optimise.sh
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue