From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9]) by lore.proxmox.com (Postfix) with ESMTPS id A45D01FF141 for ; Tue, 02 Jun 2026 15:01:24 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 2901813B5F; Tue, 2 Jun 2026 15:01:19 +0200 (CEST) From: Robert Obkircher To: pbs-devel@lists.proxmox.com Subject: [PATCH proxmox-backup 2/6] task tracking: use parameter for initial count and refactor updates Date: Tue, 2 Jun 2026 14:58:58 +0200 Message-ID: <20260602130001.217482-8-r.obkircher@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260602130001.217482-1-r.obkircher@proxmox.com> References: <20260602130001.217482-1-r.obkircher@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1780405209715 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.053 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: GJ6HSC4PKBNFU3MUTBFTYQGGZD3CSC3I X-Message-ID-Hash: GJ6HSC4PKBNFU3MUTBFTYQGGZD3CSC3I X-MailFrom: r.obkircher@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: Don't hard-code the initial count to 1 and bail out if it is negative. Replace the ActiveOperationStats initializers with the update logic because they would be reformatted to multiple lines after adding a field and an operation. Signed-off-by: Robert Obkircher --- pbs-datastore/src/task_tracking.rs | 52 +++++++++++++++++------------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/pbs-datastore/src/task_tracking.rs b/pbs-datastore/src/task_tracking.rs index d4cc076aa..a67b77221 100644 --- a/pbs-datastore/src/task_tracking.rs +++ b/pbs-datastore/src/task_tracking.rs @@ -1,4 +1,4 @@ -use anyhow::Error; +use anyhow::{Error, bail}; use libc::pid_t; use nix::unistd::Pid; use std::iter::Sum; @@ -15,6 +15,16 @@ pub struct ActiveOperationStats { pub write: i64, } +impl ActiveOperationStats { + fn add(&mut self, count: i64, operation: Operation) { + match operation { + Operation::Read => self.read += count, + Operation::Write => self.write += count, + Operation::Lookup => (), // no IO must happen there + } + } +} + impl Sum for ActiveOperationStats { fn sum(iter: I) -> Self where @@ -101,14 +111,8 @@ pub fn update_active_operations( let (_lock, options) = open_lock_file(name)?; let pid = std::process::id(); - let starttime = procfs::PidStat::read_from_pid(Pid::from_raw(pid as pid_t))?.starttime; - let mut updated_active_operations = match operation { - Operation::Read => ActiveOperationStats { read: 1, write: 0 }, - Operation::Write => ActiveOperationStats { read: 0, write: 1 }, - Operation::Lookup => ActiveOperationStats { read: 0, write: 0 }, - }; - let mut found_entry = false; + let mut updated = None; let mut updated_tasks: Vec = match file_read_optional_string(&path)? { Some(data) => serde_json::from_str::>(&data)? .iter_mut() @@ -117,13 +121,8 @@ pub fn update_active_operations( Some(stat) if pid == task.pid && stat.starttime != task.starttime => None, Some(_) => { if pid == task.pid { - found_entry = true; - match operation { - Operation::Read => task.active_operations.read += count, - Operation::Write => task.active_operations.write += count, - Operation::Lookup => (), // no IO must happen there - }; - updated_active_operations = task.active_operations; + task.active_operations.add(count, operation); + updated = Some(task.active_operations); } Some(task.clone()) } @@ -134,18 +133,27 @@ pub fn update_active_operations( None => Vec::new(), }; - if !found_entry { + let result = if let Some(updated) = updated { + updated + } else { + if count < 0 { + bail!("unexpected initial active operation count: {count} {operation:?}") + } + let mut new = ActiveOperationStats::default(); + new.add(count, operation); updated_tasks.push(TaskOperations { pid, - starttime, - active_operations: updated_active_operations, - }) - } + starttime: procfs::PidStat::read_from_pid(Pid::from_raw(pid as pid_t))?.starttime, + active_operations: new, + }); + new + }; + replace_file( &path, serde_json::to_string(&updated_tasks)?.as_bytes(), options, false, - ) - .map(|_| updated_active_operations) + )?; + Ok(result) } -- 2.47.3