mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-10 08:16:15 +02:00
6a8de4c9dc
As an optimisation for LocalStore, we read all the store directory entries into a set. Checking for membership of this set is much faster than a stat syscall. However for LocalOverlayStore, the lower store directory is expected to contain a vast number of entries and reading them all can take a very long time. So instead of enumerating them all upfront, we call pathExists as needed. This means making stat syscalls for each store path, but the upper layer is expected to be relatively small compared to the lower store so that should be okay.
69 lines
2.1 KiB
Bash
Executable file
69 lines
2.1 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
|
|
set -eu -o pipefail
|
|
|
|
set -x
|
|
|
|
source common.sh
|
|
|
|
# Avoid store dir being inside sandbox build-dir
|
|
unset NIX_STORE_DIR
|
|
unset NIX_STATE_DIR
|
|
|
|
storeDirs
|
|
|
|
initLowerStore
|
|
|
|
mountOverlayfs
|
|
|
|
|
|
## Initialise stores for test
|
|
|
|
# Realise a derivation from the lower store to propagate paths to overlay DB
|
|
nix-store --store "$storeB" --realise $drvPath
|
|
|
|
# Also ensure dummy file exists in overlay DB
|
|
dummyPath=$(nix-store --store "$storeB" --add ../dummy)
|
|
|
|
# Add something to the lower store that will not be propagated to overlay DB
|
|
lowerOnlyPath=$(addTextToStore "$storeA" lower-only "Only in lower store")
|
|
|
|
# Verify should be successful at this point
|
|
nix-store --store "$storeB" --verify --check-contents
|
|
|
|
# Make a backup so we can repair later
|
|
backupStore="$storeVolume/backup"
|
|
mkdir "$backupStore"
|
|
tar -cC "$storeBRoot" nix | tar -xC "$backupStore"
|
|
|
|
|
|
## Deliberately corrupt store paths
|
|
|
|
# Delete one of the derivation inputs in the lower store
|
|
inputDrvFullPath=$(find "$storeA" -name "*-hermetic-input-1.drv")
|
|
inputDrvPath=${inputDrvFullPath/*\/nix\/store\///nix/store/}
|
|
rm -v "$inputDrvFullPath"
|
|
|
|
# Truncate the contents of dummy file in lower store
|
|
find "$storeA" -name "*-dummy" -exec truncate -s 0 {} \;
|
|
|
|
# Also truncate the file that only exists in lower store
|
|
truncate -s 0 "$storeA/$lowerOnlyPath"
|
|
|
|
# Ensure overlayfs is synchronised
|
|
remountOverlayfs
|
|
|
|
|
|
## Now test that verify and repair work as expected
|
|
|
|
# Verify overlay store without attempting to repair it
|
|
verifyOutput=$(expectStderr 1 nix-store --store "$storeB" --verify --check-contents)
|
|
<<<"$verifyOutput" grepQuiet "path '$inputDrvPath' disappeared, but it still has valid referrers!"
|
|
<<<"$verifyOutput" grepQuiet "path '$dummyPath' was modified! expected hash"
|
|
<<<"$verifyOutput" expectStderr 1 grepQuiet "$lowerOnlyPath" # Expect no error for corrupted lower-only path
|
|
|
|
# Attempt to repair using backup
|
|
addConfig "substituters = $backupStore"
|
|
repairOutput=$(nix-store --store "$storeB" --verify --check-contents --repair 2>&1)
|
|
<<<"$repairOutput" grepQuiet "copying path '$inputDrvPath'"
|
|
<<<"$repairOutput" grepQuiet "copying path '$dummyPath'"
|