diff --git a/Changelog.md b/Changelog.md
index ddedcb2f4..b6611ae59 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -24,14 +24,18 @@
🐞 修复问题
+- 修复恢复备份的同时修改配置,可能导致配置丢失或错乱的问题
+
✨ 新增功能
+
🚀 优化改进
+
diff --git a/src-tauri/src/feat/backup.rs b/src-tauri/src/feat/backup.rs
index 449fba642..688083332 100644
--- a/src-tauri/src/feat/backup.rs
+++ b/src-tauri/src/feat/backup.rs
@@ -33,6 +33,9 @@ async fn finalize_restored_verge_config(
webdav_username: Option,
webdav_password: Option,
) -> Result<()> {
+ // The lock must cover every restored layer; an unlocked apply races a concurrently staged draft.
+ let config_write = Config::lock_config_write().await;
+
// A broken restored `verge.yaml` is a restore failure, not a reason to load defaults.
let mut restored = help::read_yaml::(&verge_path()?).await?;
restored.webdav_url = webdav_url;
@@ -55,14 +58,10 @@ async fn finalize_restored_verge_config(
profiles_draft.apply();
let verge_draft = Config::verge().await;
- {
- // Hold the write lock so a concurrent patch cannot stage a draft the proxy write reads.
- let _config_write = Config::lock_config_write().await;
- verge_draft.edit_draft(|d| {
- *d = restored.clone();
- });
- verge_draft.apply();
- }
+ verge_draft.edit_draft(|d| {
+ *d = restored.clone();
+ });
+ verge_draft.apply();
// Turn it off here; a failing core side effect below would otherwise skip this step.
if !restored.enable_system_proxy.unwrap_or_default() {
@@ -80,6 +79,9 @@ async fn finalize_restored_verge_config(
}
}
+ // `patch_verge` re-acquires the configuration write lock.
+ drop(config_write);
+
// Run configuration side effects without rewriting the already-restored file.
if let Err(err) = super::patch_verge(&restored, true).await {
logging!(error, Type::Backup, "Failed to apply restored verge config: {err:#}");