R-1252 (P2): a rejected or absent backup block never deletes second-drive copies — reconcile only on a valid classification; a rejected block is said on the app's status and once a day to the operator (backup_run_failures); kept copies stay kept (H2); Remove drops the kept records it deleted (H9). Commit only.
gates / gates (push) Successful in 1m18s
gates / gates (push) Successful in 1m18s
This commit is contained in:
@@ -509,3 +509,14 @@ func TestR1251_MainWiresThePutBackWait(t *testing.T) {
|
||||
t.Errorf("func main() must resume the waiting put-backs after Recover (at %d, Recover at %d)", i, rec)
|
||||
}
|
||||
}
|
||||
|
||||
// R-1252: the second-drive copy asks the stack adapter (by an optional interface) whether a block was REJECTED. An
|
||||
// adapter that lost the method would make every rejected block read as absent — quiet, with no alarm. Pinned at
|
||||
// compile time here; the decision is tested in internal/backup.
|
||||
var _ interface{ BackupBlockRejected(string) string } = (*stackAdapter)(nil)
|
||||
|
||||
func TestR1252_MainWiresTheUnreadableSettingsSignal(t *testing.T) {
|
||||
if indexOfCall(callsInMain(t, mainBody(t)), "SetTier2SettingsUnreadableNotify") < 0 {
|
||||
t.Fatal("func main() no longer wires SetTier2SettingsUnreadableNotify — a rejected block would keep the copies silently")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1437,6 +1437,17 @@ func main() {
|
||||
"the app is not protected on that tier. Check for a hold on a running app (R-704's shape) or a skipped dump.",
|
||||
app, tier), d)
|
||||
})
|
||||
// R-1252: an app's backup block is REJECTED — the second-drive copy kept every copy that night instead of
|
||||
// reconciling against the legacy legs (which deleted the household's file copies on 9202). Same operator-only
|
||||
// digest, its own leg; the backup package sends it once per app per day.
|
||||
backupMgr.SetTier2SettingsUnreadableNotify(func(app, why string) {
|
||||
d := notify.BackupRunFailuresDetails{RunKind: "tier2", Attempted: 1, Failed: 1,
|
||||
Apps: []notify.RunFailureDetail{{App: app, Leg: "tier2-settings-unreadable", Reason: why}}}
|
||||
notifier.NotifyBackupRunFailures(fmt.Sprintf(
|
||||
"Second-drive copy KEPT, settings unreadable: the backup block of %s is rejected (%s). The night copy deleted nothing "+
|
||||
"and every existing copy stays, but new folders are not copied until the block is fixed (R-1252). Fix the template.",
|
||||
app, why), d)
|
||||
})
|
||||
backupMgr.SetOffboxGapNotify(func(gaps map[string][]string) {
|
||||
apps := make([]string, 0, len(gaps))
|
||||
for app := range gaps {
|
||||
@@ -3093,6 +3104,11 @@ func (a *stackAdapter) GetStackClassifiedBinds(name string) ([]backup.Classified
|
||||
return a.mgr.ClassifiedBinds(name)
|
||||
}
|
||||
|
||||
// BackupBlockRejected (R-1252) lets the second-drive copy tell a rejected backup block from an absent one.
|
||||
func (a *stackAdapter) BackupBlockRejected(name string) string {
|
||||
return a.mgr.BackupBlockRejected(name)
|
||||
}
|
||||
|
||||
func (a *stackAdapter) ListDeployedStacks() []backup.StackSummary {
|
||||
var result []backup.StackSummary
|
||||
for _, s := range a.mgr.GetStacks() {
|
||||
|
||||
Reference in New Issue
Block a user