From de91418b795337f53fa08b18cd81e75d960e3dd1 Mon Sep 17 00:00:00 2001 From: Dominik Csapak Date: Wed, 27 Oct 2021 13:22:30 +0200 Subject: [PATCH] backup/datastore: prevent protected snapshots to be removed by throwing an error for remove_backup_dir, and skipping for remove_backup_group Signed-off-by: Dominik Csapak Signed-off-by: Wolfgang Bumiller --- pbs-datastore/src/datastore.rs | 37 +++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/pbs-datastore/src/datastore.rs b/pbs-datastore/src/datastore.rs index 7159e578..e32887de 100644 --- a/pbs-datastore/src/datastore.rs +++ b/pbs-datastore/src/datastore.rs @@ -266,8 +266,9 @@ impl DataStore { full_path } - /// Remove a complete backup group including all snapshots - pub fn remove_backup_group(&self, backup_group: &BackupGroup) -> Result<(), Error> { + /// Remove a complete backup group including all snapshots, returns true + /// if all snapshots were removed, and false if some were protected + pub fn remove_backup_group(&self, backup_group: &BackupGroup) -> Result { let full_path = self.group_path(backup_group); @@ -275,22 +276,30 @@ impl DataStore { log::info!("removing backup group {:?}", full_path); + let mut removed_all = true; + // remove all individual backup dirs first to ensure nothing is using them for snap in backup_group.list_backups(&self.base_path())? { + if snap.backup_dir.is_protected(self.base_path()) { + removed_all = false; + continue; + } self.remove_backup_dir(&snap.backup_dir, false)?; } - // no snapshots left, we can now safely remove the empty folder - std::fs::remove_dir_all(&full_path) - .map_err(|err| { - format_err!( - "removing backup group directory {:?} failed - {}", - full_path, - err, - ) - })?; + if removed_all { + // no snapshots left, we can now safely remove the empty folder + std::fs::remove_dir_all(&full_path) + .map_err(|err| { + format_err!( + "removing backup group directory {:?} failed - {}", + full_path, + err, + ) + })?; + } - Ok(()) + Ok(removed_all) } /// Remove a backup directory including all content @@ -304,6 +313,10 @@ impl DataStore { _manifest_guard = self.lock_manifest(backup_dir)?; } + if backup_dir.is_protected(self.base_path()) { + bail!("cannot remove protected snapshot"); + } + log::info!("removing backup snapshot {:?}", full_path); std::fs::remove_dir_all(&full_path) .map_err(|err| {