[pbs-devel] [PATCH v4 proxmox-backup 1/2] backup: check verify state of previous backup before allowing reuse

Stefan Reiter s.reiter at proxmox.com
Mon Sep 14 10:50:18 CEST 2020


Do not allow clients to reuse chunks from the previous backup if it has
a failed validation result. This would result in a new "successful"
backup that potentially references broken chunks.

If the previous backup has not been verified, assume it is fine and
continue on.

Signed-off-by: Stefan Reiter <s.reiter at proxmox.com>
---

v4:
* check earlier in upgrade_to_backup_protocol
* update error messages to include "valid"

 src/api2/backup.rs | 29 ++++++++++++++++++++++++++---
 1 file changed, 26 insertions(+), 3 deletions(-)

diff --git a/src/api2/backup.rs b/src/api2/backup.rs
index 9420b146..2b855554 100644
--- a/src/api2/backup.rs
+++ b/src/api2/backup.rs
@@ -113,7 +113,30 @@ async move {
         bail!("backup owner check failed ({} != {})", userid, owner);
     }
 
-    let last_backup = BackupInfo::last_backup(&datastore.base_path(), &backup_group, true).unwrap_or(None);
+    let last_backup = {
+        let info = BackupInfo::last_backup(&datastore.base_path(), &backup_group, true).unwrap_or(None);
+        if let Some(info) = info {
+            let (manifest, _) = datastore.load_manifest(&info.backup_dir)?;
+            let verify = manifest.unprotected["verify_state"].clone();
+            match serde_json::from_value::<SnapshotVerifyState>(verify) {
+                Ok(verify) => {
+                    if verify.state != "ok" {
+                        // verify failed, treat as if no previous backup exists
+                        None
+                    } else {
+                        Some(info)
+                    }
+                },
+                Err(_) => {
+                    // no verify state found, treat as valid
+                    Some(info)
+                }
+            }
+        } else {
+            None
+        }
+    };
+
     let backup_dir = BackupDir::new_with_group(backup_group.clone(), backup_time)?;
 
     let _last_guard = if let Some(last) = &last_backup {
@@ -355,7 +378,7 @@ fn create_fixed_index(
         let last_backup = match &env.last_backup {
             Some(info) => info,
             None => {
-                bail!("cannot reuse index - no previous backup exists");
+                bail!("cannot reuse index - no valid previous backup exists");
             }
         };
 
@@ -670,7 +693,7 @@ fn download_previous(
 
         let last_backup = match &env.last_backup {
             Some(info) => info,
-            None => bail!("no previous backup"),
+            None => bail!("no valid previous backup"),
         };
 
         let mut path = env.datastore.snapshot_path(&last_backup.backup_dir);
-- 
2.20.1






More information about the pbs-devel mailing list