};
use crate::{DataBlob, DataStore};
+#[derive(Default)]
+pub struct BackupGroupDeleteStats {
+ // Count of protected snapshots, therefore not removed
+ unremoved_protected: usize,
+ // Count of deleted snapshots
+ removed_snapshots: usize,
+}
+
+impl BackupGroupDeleteStats {
+ pub fn all_removed(&self) -> bool {
+ self.unremoved_protected == 0
+ }
+
+ pub fn removed_snapshots(&self) -> usize {
+ self.removed_snapshots
+ }
+
+ pub fn protected_snapshots(&self) -> usize {
+ self.unremoved_protected
+ }
+
+ fn increment_removed_snapshots(&mut self) {
+ self.removed_snapshots += 1;
+ }
+
+ fn increment_protected_snapshots(&mut self) {
+ self.unremoved_protected += 1;
+ }
+}
+
/// BackupGroup is a directory containing a list of BackupDir
#[derive(Clone)]
pub struct BackupGroup {
/// Destroy the group inclusive all its backup snapshots (BackupDir's)
///
- /// Returns true if all snapshots were removed, and false if some were protected
- pub fn destroy(&self) -> Result<bool, Error> {
+ /// Returns `BackupGroupDeleteStats`, containing the number of deleted snapshots
+ /// and number of protected snaphsots, which therefore were not removed.
+ pub fn destroy(&self) -> Result<BackupGroupDeleteStats, Error> {
let path = self.full_group_path();
let _guard =
proxmox_sys::fs::lock_dir_noblock(&path, "backup group", "possible running backup")?;
log::info!("removing backup group {:?}", path);
- let mut removed_all_snaps = true;
+ let mut delete_stats = BackupGroupDeleteStats::default();
for snap in self.iter_snapshots()? {
let snap = snap?;
if snap.is_protected() {
- removed_all_snaps = false;
+ delete_stats.increment_protected_snapshots();
continue;
}
snap.destroy(false)?;
+ delete_stats.increment_removed_snapshots();
}
- if removed_all_snaps {
+ if delete_stats.all_removed() {
std::fs::remove_dir_all(&path).map_err(|err| {
format_err!("removing group directory {:?} failed - {}", path, err)
})?;
}
- Ok(removed_all_snaps)
+ Ok(delete_stats)
}
/// Returns the backup owner.
DatastoreTuning, GarbageCollectionStatus, Operation, UPID,
};
-use crate::backup_info::{BackupDir, BackupGroup};
+use crate::backup_info::{BackupDir, BackupGroup, BackupGroupDeleteStats};
use crate::chunk_store::ChunkStore;
use crate::dynamic_index::{DynamicIndexReader, DynamicIndexWriter};
use crate::fixed_index::{FixedIndexReader, FixedIndexWriter};
let mut removed_all_groups = true;
for group in self.iter_backup_groups(ns.to_owned())? {
- let removed_group = group?.destroy()?;
- removed_all_groups = removed_all_groups && removed_group;
+ let delete_stats = group?.destroy()?;
+ removed_all_groups = removed_all_groups && delete_stats.all_removed();
}
let base_file = std::fs::File::open(self.base_path())?;
/// Remove a complete backup group including all snapshots.
///
- /// Returns true if all snapshots were removed, and false if some were protected
+ /// Returns `BackupGroupDeleteStats`, containing the number of deleted snapshots
+ /// and number of protected snaphsots, which therefore were not removed.
pub fn remove_backup_group(
self: &Arc<Self>,
ns: &BackupNamespace,
backup_group: &pbs_api_types::BackupGroup,
- ) -> Result<bool, Error> {
+ ) -> Result<BackupGroupDeleteStats, Error> {
let backup_group = self.backup_group(ns.clone(), backup_group.clone());
backup_group.destroy()
&group,
)?;
- if !datastore.remove_backup_group(&ns, &group)? {
+ let delete_stats = datastore.remove_backup_group(&ns, &group)?;
+ if !delete_stats.all_removed() {
bail!("group only partially deleted due to protected snapshots");
}
continue;
}
task_log!(worker, "delete vanished group '{local_group}'",);
- match params
+ let delete_stats_result = params
.target
.store
- .remove_backup_group(&target_ns, local_group)
- {
- Ok(true) => {}
- Ok(false) => {
- task_log!(
- worker,
- "kept some protected snapshots of group '{}'",
- local_group
- );
+ .remove_backup_group(&target_ns, local_group);
+
+ match delete_stats_result {
+ Ok(stats) => {
+ if !stats.all_removed() {
+ task_log!(
+ worker,
+ "kept some protected snapshots of group '{local_group}'",
+ );
+ }
}
Err(err) => {
task_log!(worker, "{}", err);