server: sync: factor out namespace depth check into sync module

By moving and refactoring the check for a sync job exceeding the
global maximum namespace limit, the same function can be reused for
sync jobs in push direction.

Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
This commit is contained in:
Christian Ebner 2024-09-12 16:33:00 +02:00 committed by Fabian Grünbichler
parent a4f08cbbbb
commit d87c9771e4
2 changed files with 24 additions and 17 deletions

View File

@ -28,8 +28,8 @@ use pbs_datastore::{check_backup_owner, DataStore, StoreProgress};
use pbs_tools::sha::sha256;
use super::sync::{
LocalSource, RemoteSource, RemovedVanishedStats, SkipInfo, SkipReason, SyncSource,
SyncSourceReader, SyncStats,
check_namespace_depth_limit, LocalSource, RemoteSource, RemovedVanishedStats, SkipInfo,
SkipReason, SyncSource, SyncSourceReader, SyncStats,
};
use crate::backup::{check_ns_modification_privs, check_ns_privs};
use crate::tools::parallel_handler::ParallelHandler;
@ -735,21 +735,7 @@ pub(crate) async fn pull_store(mut params: PullParameters) -> Result<SyncStats,
params.source.list_namespaces(&mut params.max_depth).await?
};
let ns_layers_to_be_pulled = namespaces
.iter()
.map(BackupNamespace::depth)
.max()
.map_or(0, |v| v - params.source.get_ns().depth());
let target_depth = params.target.ns.depth();
if ns_layers_to_be_pulled + target_depth > MAX_NAMESPACE_DEPTH {
bail!(
"Syncing would exceed max allowed namespace depth. ({}+{} > {})",
ns_layers_to_be_pulled,
target_depth,
MAX_NAMESPACE_DEPTH
);
}
check_namespace_depth_limit(&params.source.get_ns(), &params.target.ns, &namespaces)?;
errors |= old_max_depth != params.max_depth; // fail job if we switched to backwards-compat mode
namespaces.sort_unstable_by_key(|a| a.name_len());

View File

@ -547,3 +547,24 @@ impl std::fmt::Display for SkipInfo {
)
}
}
/// Check if a sync from source to target of given namespaces exceeds the global namespace depth limit
pub(crate) fn check_namespace_depth_limit(
source_namespace: &BackupNamespace,
target_namespace: &BackupNamespace,
namespaces: &[BackupNamespace],
) -> Result<(), Error> {
let target_ns_depth = target_namespace.depth();
let sync_ns_depth = namespaces
.iter()
.map(BackupNamespace::depth)
.max()
.map_or(0, |v| v - source_namespace.depth());
if sync_ns_depth + target_ns_depth > MAX_NAMESPACE_DEPTH {
bail!(
"Syncing would exceed max allowed namespace depth. ({sync_ns_depth}+{target_ns_depth} > {MAX_NAMESPACE_DEPTH})",
);
}
Ok(())
}