From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) by lore.proxmox.com (Postfix) with ESMTPS id 3027D1FF13E for ; Fri, 17 Apr 2026 11:27:30 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id D9EE31C15F; Fri, 17 Apr 2026 11:27:15 +0200 (CEST) From: Christian Ebner To: pbs-devel@lists.proxmox.com Subject: [PATCH proxmox-backup v6 12/15] sync: push: prepare push parameters to be shared across parallel tasks Date: Fri, 17 Apr 2026 11:26:18 +0200 Message-ID: <20260417092621.455374-13-c.ebner@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260417092621.455374-1-c.ebner@proxmox.com> References: <20260417092621.455374-1-c.ebner@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1776417915179 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.070 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: 5AVHPMGXU4Q5UM3OHWQVPWU2MRAP7BFK X-Message-ID-Hash: 5AVHPMGXU4Q5UM3OHWQVPWU2MRAP7BFK X-MailFrom: c.ebner@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox Backup Server development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: When performing parallel group syncs, the push parameters must be shared between all tasks which is not possible with regular references due to lifetime and ownership issues. Pack them into an atomic reference counter instead so they can easily be cloned when required. Signed-off-by: Christian Ebner --- changes since version 5: - no changes src/server/push.rs | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/server/push.rs b/src/server/push.rs index 44a204e6b..14395fe61 100644 --- a/src/server/push.rs +++ b/src/server/push.rs @@ -405,6 +405,7 @@ pub(crate) async fn push_store(mut params: PushParameters) -> Result Result { errors |= sync_errors; stats.add(sync_stats); @@ -523,11 +524,11 @@ pub(crate) async fn push_store(mut params: PushParameters) -> Result, ) -> Result<(StoreProgress, SyncStats, bool), Error> { let target_namespace = params.map_to_target(namespace)?; // Check if user is allowed to perform backups on remote datastore - check_ns_remote_datastore_privs(params, &target_namespace, PRIV_REMOTE_DATASTORE_BACKUP) + check_ns_remote_datastore_privs(¶ms, &target_namespace, PRIV_REMOTE_DATASTORE_BACKUP) .context("Pushing to remote namespace not allowed")?; let mut list: Vec = params @@ -555,7 +556,7 @@ pub(crate) async fn push_namespace( let mut stats = SyncStats::default(); let (owned_target_groups, not_owned_target_groups) = - fetch_target_groups(params, &target_namespace).await?; + fetch_target_groups(¶ms, &target_namespace).await?; for (done, group) in list.into_iter().enumerate() { progress.done_groups = done as u64; @@ -571,7 +572,7 @@ pub(crate) async fn push_namespace( } synced_groups.insert(group.clone()); - match push_group(params, namespace, &group, &mut progress).await { + match push_group(Arc::clone(¶ms), namespace, &group, &mut progress).await { Ok(sync_stats) => stats.add(sync_stats), Err(err) => { warn!("Encountered errors: {err:#}"); @@ -591,7 +592,7 @@ pub(crate) async fn push_namespace( continue; } - match remove_target_group(params, &target_namespace, &target_group).await { + match remove_target_group(¶ms, &target_namespace, &target_group).await { Ok(delete_stats) => { info!("Removed vanished group {target_group} from remote"); if delete_stats.protected_snapshots() > 0 { @@ -673,7 +674,7 @@ async fn forget_target_snapshot( /// - Iterate the snapshot list and push each snapshot individually /// - (Optional): Remove vanished groups if `remove_vanished` flag is set pub(crate) async fn push_group( - params: &PushParameters, + params: Arc, namespace: &BackupNamespace, group: &BackupGroup, progress: &mut StoreProgress, @@ -692,7 +693,7 @@ pub(crate) async fn push_group( } let target_namespace = params.map_to_target(namespace)?; - let mut target_snapshots = fetch_target_snapshots(params, &target_namespace, group).await?; + let mut target_snapshots = fetch_target_snapshots(¶ms, &target_namespace, group).await?; target_snapshots.sort_unstable_by_key(|a| a.backup.time); let last_snapshot_time = target_snapshots @@ -749,8 +750,13 @@ pub(crate) async fn push_group( let mut stats = SyncStats::default(); let mut fetch_previous_manifest = !target_snapshots.is_empty(); for (pos, source_snapshot) in snapshots.into_iter().enumerate() { - let result = - push_snapshot(params, namespace, &source_snapshot, fetch_previous_manifest).await; + let result = push_snapshot( + ¶ms, + namespace, + &source_snapshot, + fetch_previous_manifest, + ) + .await; fetch_previous_manifest = true; progress.done_snapshots = pos as u64 + 1; @@ -773,7 +779,7 @@ pub(crate) async fn push_group( ); continue; } - match forget_target_snapshot(params, &target_namespace, &snapshot.backup).await { + match forget_target_snapshot(¶ms, &target_namespace, &snapshot.backup).await { Ok(()) => { info!( "Removed vanished snapshot {name} from remote", -- 2.47.3