R-1342: a restore copy under the stable-start watch is not deletable (D62 gap); an app removed during the watch raises no alarm — tests red first; commit only
gates / gates (push) Successful in 31s
gates / gates (push) Successful in 31s
This commit is contained in:
1 parent
6c72e3ff34
commit
652a690e5d
10 files changed
+231
-1
No files matched your search
@@ -28,6 +28,9 @@ const (
|
||||
RestoreCopyNeededHold = "hold" // the app is held (a failed put-back keeps its copy, D20) — support decides
|
||||
RestoreCopyNeededPutBack = "putback" // a put-back waits for its drive (R-1251) or a cut restore names it (D22)
|
||||
RestoreCopyNeededUnknown = "unknown" // the app-stop marker cannot be read: nothing is offered (fail closed)
|
||||
// RestoreCopyNeededChecking (R-1342): the box still watches whether the restored app runs stably (up to 30 minutes
|
||||
// after the restore, R-1270) — the copy is the way back if it does not.
|
||||
RestoreCopyNeededChecking = "checking"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -119,7 +122,10 @@ func (m *Manager) RestoreCopies() []RestoreCopy {
|
||||
continue
|
||||
}
|
||||
rc := RestoreCopy{App: app, Stamp: c.Name(), At: at, SizeBytes: dirSize(dir), Path: dir, Needed: needed}
|
||||
if needed == "" {
|
||||
if rc.Needed == "" && m.watchingCopy(dir) {
|
||||
rc.Needed = RestoreCopyNeededChecking
|
||||
}
|
||||
if rc.Needed == "" {
|
||||
rc.DeleteOn = at.Add(restoreCopyUnusedAge)
|
||||
}
|
||||
out = append(out, rc)
|
||||
@@ -174,9 +180,37 @@ func (m *Manager) DeleteRestoreCopy(app, stamp string) (RestoreCopy, error) {
|
||||
if found.Needed = m.restoreCopyNeededFor(app, named, ok); found.Needed != "" {
|
||||
return *found, ErrRestoreCopyNeeded
|
||||
}
|
||||
if m.watching[found.Path] { // R-1342: under m.mu, the same lock the watch marks its copy under
|
||||
found.Needed = RestoreCopyNeededChecking
|
||||
return *found, ErrRestoreCopyNeeded
|
||||
}
|
||||
if err := os.RemoveAll(found.Path); err != nil {
|
||||
return *found, fmt.Errorf("removing the restore copy %s: %w", found.Path, err)
|
||||
}
|
||||
_ = os.Remove(filepath.Dir(found.Path)) // the per-app folder, when it is now empty
|
||||
return *found, nil
|
||||
}
|
||||
|
||||
// setWatching marks (on) or clears a copy a stable-start watch holds (R-1342).
|
||||
func (m *Manager) setWatching(dir string, on bool) {
|
||||
if dir == "" {
|
||||
return
|
||||
}
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
if on {
|
||||
if m.watching == nil {
|
||||
m.watching = map[string]bool{}
|
||||
}
|
||||
m.watching[dir] = true
|
||||
return
|
||||
}
|
||||
delete(m.watching, dir)
|
||||
}
|
||||
|
||||
// watchingCopy reports whether a stable-start watch still holds the copy.
|
||||
func (m *Manager) watchingCopy(dir string) bool {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
return m.watching[dir]
|
||||
}
|
||||
Reference in new issue
Block a user