D22: every restore puts the data back exactly on failure and after a power cut (R-1177, R-1195); whole restore asks the unit first (R-1178); no mirror during a restore (R-1180); W22 restore refusals in Hungarian; unreleased
gates / gates (push) Successful in 1m40s

This commit is contained in:
2026-10-21 21:19:46 +02:00
parent 7848d4aaac
commit d582feb245
25 changed files with 1065 additions and 71 deletions
@@ -29,6 +29,10 @@ import (
// language at the moment it is written (release C, R-557).
const RestoreInterruptedKey = "note.restore.interrupted"
// RestoreInterruptedPutBackKey is what the household reads when the interrupted restore was put back at start
// (D22, R-1195): the data is as it was before the restore.
const RestoreInterruptedPutBackKey = "note.restore.interrupted_put_back"
// restoreRecordFile is the on-disk shape.
type restoreRecordFile struct {
Running bool `json:"running"`
@@ -49,6 +53,12 @@ func (m *Manager) SetRestoreRecordPath(path string) {
// LoadRestoreRecord restores the record at startup. It returns the restore that was interrupted by the
// stop — non-nil exactly once per interruption — so the caller can log it and raise restore_interrupted.
func (m *Manager) LoadRestoreRecord() *RestoreOpResult {
return m.LoadRestoreRecordAfterRecovery(nil)
}
// LoadRestoreRecordAfterRecovery is LoadRestoreRecord told which apps the start-up crash recovery put back
// (AppStopRecovery.PutBack, D22 / R-1195): for those the interrupted restore reads „the data is as before".
func (m *Manager) LoadRestoreRecordAfterRecovery(putBack []string) *RestoreOpResult {
m.mu.Lock()
defer m.mu.Unlock()
if m.opRecordPath == "" {
@@ -80,6 +90,11 @@ func (m *Manager) LoadRestoreRecord() *RestoreOpResult {
Op: rec.Op, Stack: rec.Stack, OK: false,
Message: m.note(RestoreInterruptedKey), FinishedAt: time.Now(), Interrupted: true,
}
for _, p := range putBack {
if p == rec.Stack {
res.Message, res.PutBack = m.note(RestoreInterruptedPutBackKey), true
}
}
m.opLast = &res
if m.opInterrupted == nil {
m.opInterrupted = map[string]RestoreOpResult{}