Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d8ca0c1f6c |
@@ -267,13 +267,13 @@ An operand that is a symlink (never followed, not even as an operand),
|
|||||||
socket, FIFO, or device node, or a directory named `.zfs`, is not
|
socket, FIFO, or device node, or a directory named `.zfs`, is not
|
||||||
scanned. `scan` prints a one-line warning naming the path and what it
|
scanned. `scan` prints a one-line warning naming the path and what it
|
||||||
is, counts it as skipped, and drops it from the scanned operands before
|
is, counts it as skipped, and drops it from the scanned operands before
|
||||||
reading the database. The records stored beneath it are not deleted:
|
reading the database. Another operand beneath it is still scanned. The
|
||||||
they are treated like any other record outside the scanned operands,
|
records stored beneath it are not deleted: they are treated like any
|
||||||
including the content-phase exception below. If it lies under another
|
other record outside the scanned operands, including the content-phase
|
||||||
operand, they are under that operand instead, and are deleted like any
|
exception below. If it lies under another operand, they are under that
|
||||||
other record there that this scan did not verify. This is not an
|
operand instead, and are deleted like any other record there that this
|
||||||
error: a scan whose every operand is dropped walks nothing and
|
scan did not verify. This is not an error: a scan whose every operand
|
||||||
exits 0.
|
is dropped walks nothing and exits 0.
|
||||||
|
|
||||||
`scan` synchronizes the database with the filesystem state under the
|
`scan` synchronizes the database with the filesystem state under the
|
||||||
scanned operands:
|
scanned operands:
|
||||||
|
|||||||
@@ -423,6 +423,34 @@ func TestRunScanSkipsSymlinkOperand(t *testing.T) {
|
|||||||
filepath.Join(link, "sub", "f"))
|
filepath.Join(link, "sub", "f"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRunScanWalksOperandUnderSymlinkOperand(t *testing.T) {
|
||||||
|
path := testDBPath(t)
|
||||||
|
t.Setenv(databaseEnv, path)
|
||||||
|
|
||||||
|
dir := t.TempDir()
|
||||||
|
writeFile(t, dir, "target/sub/f", pattern(1, 10))
|
||||||
|
|
||||||
|
link := filepath.Join(dir, "link")
|
||||||
|
|
||||||
|
err := os.Symlink(filepath.Join(dir, "target"), link)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// link is dropped as a symlink, but link/sub must still be scanned,
|
||||||
|
// not dropped as lying under link.
|
||||||
|
scanOK(t, link, filepath.Join(link, "sub"))
|
||||||
|
|
||||||
|
db, err := openDB(path, reportParams)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Cleanup(func() { _ = db.Close() })
|
||||||
|
|
||||||
|
recordByPath(t, dbRecords(t, db), filepath.Join(link, "sub", "f"))
|
||||||
|
}
|
||||||
|
|
||||||
func TestRunScanSkipsZFSOperand(t *testing.T) {
|
func TestRunScanSkipsZFSOperand(t *testing.T) {
|
||||||
path := testDBPath(t)
|
path := testDBPath(t)
|
||||||
t.Setenv(databaseEnv, path)
|
t.Setenv(databaseEnv, path)
|
||||||
|
|||||||
@@ -219,6 +219,8 @@ func syncScan(ctx context.Context, db *sql.DB, roots []string,
|
|||||||
) (scanStats, error) {
|
) (scanStats, error) {
|
||||||
s := &scanState{db: db}
|
s := &scanState{db: db}
|
||||||
|
|
||||||
|
// Types are checked before pruning so that an operand under a
|
||||||
|
// dropped one is still scanned, not dropped as lying under it.
|
||||||
roots = pruneRoots(s.walkableRoots(roots))
|
roots = pruneRoots(s.walkableRoots(roots))
|
||||||
|
|
||||||
err := s.loadIndex(ctx, roots)
|
err := s.loadIndex(ctx, roots)
|
||||||
|
|||||||
Reference in New Issue
Block a user