Do not prune when a backup misses an earlier mount point (closes #395)
check / check (push) Waiting to run
check / check (push) Waiting to run
snapshot create --prune purged the older snapshots holding a volume's files when the volume, mounted below a configured path, was not mounted: its empty mount point read as deleted files. The scan now records in the local index each directory at or below a configured path that is on a different device from its parent directory. Under --prune, when an earlier snapshot of that name recorded such a directory and this run does not find it on a different device, the run skips the prune, keeps every older snapshot, names the directory and exits non-zero, as for an empty configured path. For a volume retired, or a directory no longer backed up, on purpose, the older snapshots are removed with snapshot purge. Model: opus-5-5
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
//nolint:testpackage // exercises the unexported deviceNumberFromStat
|
||||
package snapshot
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// The device number a real backup reads is the same for two entries of
|
||||
// one directory and differs between two filesystems. Without it no
|
||||
// mount point is ever found. See
|
||||
// https://git.eeqj.de/sneak/vaultik/issues/395.
|
||||
func TestDeviceNumberFromStat(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
dir := t.TempDir()
|
||||
file := filepath.Join(dir, "file.txt")
|
||||
require.NoError(t, os.WriteFile(file, nil, 0o600))
|
||||
|
||||
deviceOf := func(path string) uint64 {
|
||||
t.Helper()
|
||||
|
||||
info, err := os.Stat(path)
|
||||
require.NoError(t, err)
|
||||
|
||||
device, ok := deviceNumberFromStat(info)
|
||||
require.True(t, ok, "no device number read for %s", path)
|
||||
|
||||
return device
|
||||
}
|
||||
|
||||
assert.Equal(t, deviceOf(dir), deviceOf(file))
|
||||
|
||||
// /dev is a different filesystem from the temp dir on Linux, macOS and in Docker.
|
||||
assert.NotEqual(t, deviceOf(dir), deviceOf("/dev"))
|
||||
}
|
||||
Reference in New Issue
Block a user