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 204291FF136 for ; Mon, 09 Mar 2026 17:22:12 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 51E723F21; Mon, 9 Mar 2026 17:22:05 +0100 (CET) From: Christian Ebner To: pbs-devel@lists.proxmox.com Subject: [PATCH proxmox-backup v5 08/11] sync: push: prepare push parameters to be shared across parallel tasks Date: Mon, 9 Mar 2026 17:20:47 +0100 Message-ID: <20260309162050.1047341-10-c.ebner@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260309162050.1047341-1-c.ebner@proxmox.com> References: <20260309162050.1047341-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: 1773073229792 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.055 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: 6ZIMAM7JT5X3UNV7P2IVMEP4FCZBL35X X-Message-ID-Hash: 6ZIMAM7JT5X3UNV7P2IVMEP4FCZBL35X 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 --- 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 a0484ef62..5828f2ed1 100644 --- a/src/server/push.rs +++ b/src/server/push.rs @@ -404,6 +404,7 @@ pub(crate) async fn push_store(mut params: PushParameters) -> Result Result { errors |= sync_errors; stats.add(sync_stats); @@ -522,11 +523,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 @@ -554,7 +555,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; @@ -570,7 +571,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:#}"); @@ -590,7 +591,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 { @@ -672,7 +673,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, @@ -691,7 +692,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 @@ -748,8 +749,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; @@ -772,7 +778,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