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 <d.csapak@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
Dominik Csapak 2021-10-27 13:22:30 +02:00 committed by Wolfgang Bumiller
parent fe9c47ab4f
commit de91418b79
1 changed files with 25 additions and 12 deletions

View File

@ -266,8 +266,9 @@ impl DataStore {
full_path full_path
} }
/// Remove a complete backup group including all snapshots /// Remove a complete backup group including all snapshots, returns true
pub fn remove_backup_group(&self, backup_group: &BackupGroup) -> Result<(), Error> { /// if all snapshots were removed, and false if some were protected
pub fn remove_backup_group(&self, backup_group: &BackupGroup) -> Result<bool, Error> {
let full_path = self.group_path(backup_group); let full_path = self.group_path(backup_group);
@ -275,22 +276,30 @@ impl DataStore {
log::info!("removing backup group {:?}", full_path); log::info!("removing backup group {:?}", full_path);
let mut removed_all = true;
// remove all individual backup dirs first to ensure nothing is using them // remove all individual backup dirs first to ensure nothing is using them
for snap in backup_group.list_backups(&self.base_path())? { 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)?; self.remove_backup_dir(&snap.backup_dir, false)?;
} }
// no snapshots left, we can now safely remove the empty folder if removed_all {
std::fs::remove_dir_all(&full_path) // no snapshots left, we can now safely remove the empty folder
.map_err(|err| { std::fs::remove_dir_all(&full_path)
format_err!( .map_err(|err| {
"removing backup group directory {:?} failed - {}", format_err!(
full_path, "removing backup group directory {:?} failed - {}",
err, full_path,
) err,
})?; )
})?;
}
Ok(()) Ok(removed_all)
} }
/// Remove a backup directory including all content /// Remove a backup directory including all content
@ -304,6 +313,10 @@ impl DataStore {
_manifest_guard = self.lock_manifest(backup_dir)?; _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); log::info!("removing backup snapshot {:?}", full_path);
std::fs::remove_dir_all(&full_path) std::fs::remove_dir_all(&full_path)
.map_err(|err| { .map_err(|err| {