From 9f29d240c0b10492bb14f9621f6e91502c9d246b Mon Sep 17 00:00:00 2001 From: zhangkun Date: Wed, 9 Jul 2025 11:11:14 +0800 Subject: [PATCH] fix: improve rollback handling logic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Modified ConfirmRollback to handle rollback synchronously instead of in goroutine 2. Added Reboot field to ostreeRollbackData struct to track reboot requirement 3. Implemented osTreeNeedRebootAfterRollback to properly determine reboot need 4. Updated osTreeParseRollbackData to return additional field information 5. Added slices package import for field checking The changes improve rollback reliability by: 1. Making rollback operations synchronous to properly handle errors 2. Adding explicit reboot tracking instead of relying on auto-rollback status 3. Maintaining backward compatibility with older ostree versions 4. Providing better field-level data access from ostree responses fix: 改进回滚处理逻辑 1. 修改 ConfirmRollback 以同步方式处理回滚而非使用 goroutine 2. 在 ostreeRollbackData 结构体中添加 Reboot 字段以跟踪重启需求 3. 实现 osTreeNeedRebootAfterRollback 来正确判断是否需要重启 4. 更新 osTreeParseRollbackData 以返回额外的字段信息 5. 添加 slices 包导入用于字段检查 这些改进通过以下方式提高了回滚可靠性: 1. 同步执行回滚操作以正确处理错误 2. 添加显式的重启跟踪而非依赖自动回滚状态 3. 保持与旧版 ostree 的兼容性 4. 提供更好的字段级数据访问能力 --- src/lastore-daemon/manager_ifc.go | 25 +++++++------- src/lastore-daemon/manager_upgrade.go | 48 ++++++++++++++++----------- 2 files changed, 42 insertions(+), 31 deletions(-) diff --git a/src/lastore-daemon/manager_ifc.go b/src/lastore-daemon/manager_ifc.go index 44f25f73f..3690fca23 100644 --- a/src/lastore-daemon/manager_ifc.go +++ b/src/lastore-daemon/manager_ifc.go @@ -745,23 +745,24 @@ func (m *Manager) SetUpdateSources(sender dbus.Sender, updateType system.UpdateT func (m *Manager) ConfirmRollback(sender dbus.Sender, confirm bool) *dbus.Error { var err error if confirm { - go func() { - err = osTreeRollback() + needReboot := osTreeNeedRebootAfterRollback() + err = osTreeRollback() + if err != nil { + logger.Warning(err) + } + if m.grub != nil { + err = m.grub.changeGrubDefaultEntry(normalBootEntry) if err != nil { logger.Warning(err) } - if m.grub != nil { - err = m.grub.changeGrubDefaultEntry(normalBootEntry) - if err != nil { - logger.Warning(err) - } - } + } - // 如果自动回滚,则无需重启 - if !osTreeIsAutoRollback() { - m.PowerOff(sender, true) + if needReboot { + err := m.PowerOff(sender, true) + if err != nil { + logger.Warning(err) } - }() + } } else { return m.PowerOff(sender, true) } diff --git a/src/lastore-daemon/manager_upgrade.go b/src/lastore-daemon/manager_upgrade.go index e37cc1274..fb478611f 100644 --- a/src/lastore-daemon/manager_upgrade.go +++ b/src/lastore-daemon/manager_upgrade.go @@ -590,6 +590,7 @@ type ostreeRollbackData struct { Time int64 `json:"time"` Name string `json:"name"` Auto bool `json:"auto"` + Reboot bool `json:"reboot"` } type ostreeResponse struct { @@ -623,11 +624,11 @@ func osTreeRollback() error { return nil } -func osTreeParseRollbackData() (*ostreeRollbackData, error) { +func osTreeParseRollbackData() (string, error) { out, err := osTreeCmd([]string{"admin", "rollback", "--can-rollback", "-j"}) if err != nil { logger.Warning("osTreeCmd failed:", err) - return nil, err + return "", err } logger.Info("osTree rollback output:", out) @@ -636,44 +637,53 @@ func osTreeParseRollbackData() (*ostreeRollbackData, error) { err = json.Unmarshal([]byte(out), &resp) if err != nil { logger.Warning("unmarshal ostree response failed:", err) - return nil, err + return "", err } if resp.Error != nil { logger.Warning("ostree response has error:", resp.Error) - return nil, fmt.Errorf("ostree error: %v", resp.Error) + return "", fmt.Errorf("ostree error: %v", resp.Error) } - var data ostreeRollbackData - err = json.Unmarshal(resp.Data, &data) - if err != nil { - logger.Warning("unmarshal rollback data failed:", err) - return nil, err - } - - return &data, nil + return string(resp.Data), nil } func osTreeCanRollback() (bool, string) { - data, err := osTreeParseRollbackData() + dataJson, err := osTreeParseRollbackData() if err != nil { return false, "" } - rawData, err := json.Marshal(data) + var data ostreeRollbackData + err = json.Unmarshal([]byte(dataJson), &data) if err != nil { - return data.CanRollback, "" + return false, "" } - return data.CanRollback, string(rawData) + return data.CanRollback, dataJson } -func osTreeIsAutoRollback() bool { - data, err := osTreeParseRollbackData() +func osTreeNeedRebootAfterRollback() bool { + dataJson, err := osTreeParseRollbackData() if err != nil { return false } - return data.Auto + + var data ostreeRollbackData + err = json.Unmarshal([]byte(dataJson), &data) + if err != nil { + return false + } + + // 兼容旧版本,Auto为true时,表示不需要重启 + var rawData map[string]json.RawMessage + if err := json.Unmarshal([]byte(dataJson), &rawData); err == nil { + if _, hasReboot := rawData["reboot"]; !hasReboot { + return !data.Auto + } + } + + return data.Reboot } func (m *Manager) preUpgradeCmdSuccessHook(job *Job, needChangeGrub bool, mode system.UpdateType, uuid string) error {