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 4947A1FF136 for ; Mon, 09 Mar 2026 17:21:53 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id C62A03C6D; Mon, 9 Mar 2026 17:21:37 +0100 (CET) From: Christian Ebner To: pbs-devel@lists.proxmox.com Subject: [PATCH proxmox-backup v5 04/11] sync: pull: factor out backup group locking and owner check Date: Mon, 9 Mar 2026 17:20:43 +0100 Message-ID: <20260309162050.1047341-6-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: 1773073228829 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: WFZI43OFEEEAEKNL6EKIRJ625NI7SNSH X-Message-ID-Hash: WFZI43OFEEEAEKNL6EKIRJ625NI7SNSH 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: Creates a dedicated entry point for parallel group pulling and simplifies the backup group loop logic. While locking and owner check could have been moved to pull_group() as well, that function is already hard to parse as is. Logging of errors is moved to the helper to facilitate it for parallel pulling. This further changes the multi line error on locking error. The provided information was redundant anyways and multiline logging with parallel group sync must be avoided anyways as ordering cannot be guaranteed anymore. Signed-off-by: Christian Ebner --- src/server/pull.rs | 69 +++++++++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 32 deletions(-) diff --git a/src/server/pull.rs b/src/server/pull.rs index 254b36759..c074c2b78 100644 --- a/src/server/pull.rs +++ b/src/server/pull.rs @@ -1047,6 +1047,40 @@ pub(crate) async fn pull_store(mut params: PullParameters) -> Result Result { + let (owner, _lock_guard) = params + .target + .store + .create_locked_backup_group(target_namespace, group, ¶ms.owner) + .map_err(|err| { + info!("sync group {group} failed - group lock failed: {err}"); + info!("create_locked_backup_group failed"); + })?; + + if params.owner != owner { + // only the owner is allowed to create additional snapshots + info!( + "sync group {group} failed - owner check failed ({} != {owner})", + params.owner + ); + return Err(()); + } + + pull_group(params, namespace, group, progress) + .await + .map_err(|err| { + info!("sync group {group} failed - {err:#}"); + }) +} + /// Pulls a namespace according to `params`. /// /// Pulling a namespace consists of the following steps: @@ -1095,38 +1129,9 @@ async fn pull_ns( progress.done_snapshots = 0; progress.group_snapshots = 0; - let (owner, _lock_guard) = - match params - .target - .store - .create_locked_backup_group(&target_ns, &group, ¶ms.owner) - { - Ok(result) => result, - Err(err) => { - info!("sync group {} failed - group lock failed: {err}", &group); - errors = true; - // do not stop here, instead continue - info!("create_locked_backup_group failed"); - continue; - } - }; - - // permission check - if params.owner != owner { - // only the owner is allowed to create additional snapshots - info!( - "sync group {} failed - owner check failed ({} != {owner})", - &group, params.owner - ); - errors = true; // do not stop here, instead continue - } else { - match pull_group(params, namespace, &group, &mut progress).await { - Ok(stats) => sync_stats.add(stats), - Err(err) => { - info!("sync group {} failed - {err:#}", &group); - errors = true; // do not stop here, instead continue - } - } + match lock_and_pull_group(params, &group, &namespace, &target_ns, &mut progress).await { + Ok(stats) => sync_stats.add(stats), + Err(_err) => errors = true, } } -- 2.47.3