Second-drive copy: two races closed — the start-up/retry removal holds the destination's lock (a copy this process starts is never removed), and a run records itself in one step with the restore check, every leg asking again; red-proved, race-clean; unreleased
gates / gates (push) Successful in 1m40s
gates / gates (push) Successful in 1m40s
This commit is contained in:
@@ -305,3 +305,24 @@ func TestStrayCopy_ASecondCopyOfTheSameDestinationWaits(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Commit security review 2026-10-23 night: the start-up check's list and its removals are not atomic — a copy of the
|
||||
// same destination may start between them. A destination this process copies into (its lock held) is skipped.
|
||||
// RED-PROOF: with the TryLock skip removed, this fails — seen failing 2026-10-23 night.
|
||||
func TestStrayCopy_TheStartUpCheckSkipsADestinationBeingCopied(t *testing.T) {
|
||||
_, life := strayCopySeams(t, t.TempDir()+"/", nil, func(args []string) ([]byte, error) {
|
||||
if args[0] == "ps" {
|
||||
return []byte("felhom-tier2-copy-busy-00000003\n"), nil
|
||||
}
|
||||
return nil, nil
|
||||
})
|
||||
lk := tier2CopyLock("felhom-tier2-copy-busy-00000003")
|
||||
lk.Lock() // a copy of that destination is starting in this process (not yet marked running)
|
||||
defer lk.Unlock()
|
||||
if err := clearLeftoverTier2CopiesOnce(context.Background()); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if strings.Contains(life.all(), "rm -f felhom-tier2-copy-busy-00000003") {
|
||||
t.Fatalf("the check removed a container of a destination this process is copying into:\n%s", life.all())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user