datastore: move cleanup_unreferenced_files to BackupDir impl and fix NS awareness
sync failed on cleanup due to always trying to do so in the root NS Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
This commit is contained in:
parent
92b9cc1554
commit
5566099849
|
@ -13,7 +13,9 @@ use pbs_api_types::{
|
||||||
};
|
};
|
||||||
use pbs_config::{open_backup_lockfile, BackupLockGuard};
|
use pbs_config::{open_backup_lockfile, BackupLockGuard};
|
||||||
|
|
||||||
use crate::manifest::{BackupManifest, MANIFEST_BLOB_NAME, MANIFEST_LOCK_NAME};
|
use crate::manifest::{
|
||||||
|
BackupManifest, CLIENT_LOG_BLOB_NAME, MANIFEST_BLOB_NAME, MANIFEST_LOCK_NAME,
|
||||||
|
};
|
||||||
use crate::{DataBlob, DataStore};
|
use crate::{DataBlob, DataStore};
|
||||||
|
|
||||||
/// BackupGroup is a directory containing a list of BackupDir
|
/// BackupGroup is a directory containing a list of BackupDir
|
||||||
|
@ -493,6 +495,40 @@ impl BackupDir {
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
self.store.update_manifest(self, update_fn)
|
self.store.update_manifest(self, update_fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Cleans up the backup directory by removing any file not mentioned in the manifest.
|
||||||
|
pub fn cleanup_unreferenced_files(&self, manifest: &BackupManifest) -> Result<(), Error> {
|
||||||
|
let full_path = self.full_path();
|
||||||
|
|
||||||
|
let mut wanted_files = std::collections::HashSet::new();
|
||||||
|
wanted_files.insert(MANIFEST_BLOB_NAME.to_string());
|
||||||
|
wanted_files.insert(CLIENT_LOG_BLOB_NAME.to_string());
|
||||||
|
manifest.files().iter().for_each(|item| {
|
||||||
|
wanted_files.insert(item.filename.clone());
|
||||||
|
});
|
||||||
|
|
||||||
|
for item in proxmox_sys::fs::read_subdir(libc::AT_FDCWD, &full_path)?.flatten() {
|
||||||
|
if let Some(file_type) = item.file_type() {
|
||||||
|
if file_type != nix::dir::Type::File {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let file_name = item.file_name().to_bytes();
|
||||||
|
if file_name == b"." || file_name == b".." {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
if let Ok(name) = std::str::from_utf8(file_name) {
|
||||||
|
if wanted_files.contains(name) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println!("remove unused file {:?}", item.file_name());
|
||||||
|
let dirfd = item.parent_fd();
|
||||||
|
let _res = unsafe { libc::unlinkat(dirfd, item.file_name().as_ptr(), 0) };
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsRef<pbs_api_types::BackupNamespace> for BackupDir {
|
impl AsRef<pbs_api_types::BackupNamespace> for BackupDir {
|
||||||
|
|
|
@ -28,9 +28,7 @@ use crate::chunk_store::ChunkStore;
|
||||||
use crate::dynamic_index::{DynamicIndexReader, DynamicIndexWriter};
|
use crate::dynamic_index::{DynamicIndexReader, DynamicIndexWriter};
|
||||||
use crate::fixed_index::{FixedIndexReader, FixedIndexWriter};
|
use crate::fixed_index::{FixedIndexReader, FixedIndexWriter};
|
||||||
use crate::index::IndexFile;
|
use crate::index::IndexFile;
|
||||||
use crate::manifest::{
|
use crate::manifest::{archive_type, ArchiveType, BackupManifest, MANIFEST_BLOB_NAME};
|
||||||
archive_type, ArchiveType, BackupManifest, CLIENT_LOG_BLOB_NAME, MANIFEST_BLOB_NAME,
|
|
||||||
};
|
|
||||||
use crate::task_tracking::update_active_operations;
|
use crate::task_tracking::update_active_operations;
|
||||||
use crate::DataBlob;
|
use crate::DataBlob;
|
||||||
|
|
||||||
|
@ -360,55 +358,6 @@ impl DataStore {
|
||||||
path
|
path
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Cleanup a backup directory
|
|
||||||
///
|
|
||||||
/// Removes all files not mentioned in the manifest.
|
|
||||||
pub fn cleanup_backup_dir(
|
|
||||||
&self,
|
|
||||||
backup_dir: impl AsRef<pbs_api_types::BackupDir>,
|
|
||||||
manifest: &BackupManifest,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
self.cleanup_backup_dir_do(backup_dir.as_ref(), manifest)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn cleanup_backup_dir_do(
|
|
||||||
&self,
|
|
||||||
backup_dir: &pbs_api_types::BackupDir,
|
|
||||||
manifest: &BackupManifest,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
let mut full_path = self.base_path();
|
|
||||||
full_path.push(backup_dir.to_string());
|
|
||||||
|
|
||||||
let mut wanted_files = HashSet::new();
|
|
||||||
wanted_files.insert(MANIFEST_BLOB_NAME.to_string());
|
|
||||||
wanted_files.insert(CLIENT_LOG_BLOB_NAME.to_string());
|
|
||||||
manifest.files().iter().for_each(|item| {
|
|
||||||
wanted_files.insert(item.filename.clone());
|
|
||||||
});
|
|
||||||
|
|
||||||
for item in proxmox_sys::fs::read_subdir(libc::AT_FDCWD, &full_path)?.flatten() {
|
|
||||||
if let Some(file_type) = item.file_type() {
|
|
||||||
if file_type != nix::dir::Type::File {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let file_name = item.file_name().to_bytes();
|
|
||||||
if file_name == b"." || file_name == b".." {
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
if let Ok(name) = std::str::from_utf8(file_name) {
|
|
||||||
if wanted_files.contains(name) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
println!("remove unused file {:?}", item.file_name());
|
|
||||||
let dirfd = item.parent_fd();
|
|
||||||
let _res = unsafe { libc::unlinkat(dirfd, item.file_name().as_ptr(), 0) };
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the absolute path for a backup_group
|
/// Returns the absolute path for a backup_group
|
||||||
pub fn group_path(
|
pub fn group_path(
|
||||||
&self,
|
&self,
|
||||||
|
|
|
@ -506,10 +506,7 @@ async fn pull_snapshot(
|
||||||
try_client_log_download(worker, reader, &client_log_name).await?;
|
try_client_log_download(worker, reader, &client_log_name).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// cleanup - remove stale files
|
snapshot.cleanup_unreferenced_files(&manifest)?;
|
||||||
snapshot
|
|
||||||
.datastore()
|
|
||||||
.cleanup_backup_dir(snapshot, &manifest)?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue