all lists on lists.proxmox.com
 help / color / mirror / Atom feed
From: Christian Ebner <c.ebner@proxmox.com>
To: pbs-devel@lists.proxmox.com
Subject: [PATCH proxmox-backup v3 15/15] tree-wide: use proxmox-product-config::get_api_user for user lookup
Date: Wed,  1 Jul 2026 16:04:12 +0200	[thread overview]
Message-ID: <20260701140412.200920-16-c.ebner@proxmox.com> (raw)
In-Reply-To: <20260701140412.200920-1-c.ebner@proxmox.com>

Use the global helper defined in proxmox-product-config over
pbs-config::backup_user(), which internally calls User::from_name()
using getpwnam_r(3) [0] and therefore can involve nsswitch.conf and
/etc/passwd parsing, including several syscalls to do so.
None of these call sites are performance critical, but using the
globally cached user info is favorable for consistency.

Requires proxmox-product-config::init() to be called exactly once
before using in any callpath of a binary.

Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
---
 src/api2/admin/datastore.rs                  | 2 +-
 src/api2/admin/s3.rs                         | 4 ++--
 src/api2/config/datastore.rs                 | 2 +-
 src/api2/config/s3.rs                        | 2 +-
 src/config/mod.rs                            | 4 ++--
 src/server/jobstate.rs                       | 4 ++--
 src/server/metric_collection/mod.rs          | 2 +-
 src/server/metric_collection/pull_metrics.rs | 2 +-
 src/server/metric_collection/rrd.rs          | 2 +-
 src/server/mod.rs                            | 6 +++---
 src/server/notifications/mod.rs              | 4 ++--
 src/tape/changer/mod.rs                      | 2 +-
 src/tape/drive/mod.rs                        | 2 +-
 src/traffic_control_cache.rs                 | 2 +-
 14 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/src/api2/admin/datastore.rs b/src/api2/admin/datastore.rs
index 39e8a1ce8..bc2b2436e 100644
--- a/src/api2/admin/datastore.rs
+++ b/src/api2/admin/datastore.rs
@@ -2442,7 +2442,7 @@ fn setup_mounted_device(datastore: &DataStoreConfig, tmp_mount_path: &str) -> Re
         "{tmp_mount_path}/{}",
         datastore.path.trim_start_matches('/')
     );
-    let backup_user = pbs_config::backup_user()?;
+    let backup_user = proxmox_product_config::get_api_user();
     let options = CreateOptions::new()
         .owner(backup_user.uid)
         .group(backup_user.gid);
diff --git a/src/api2/admin/s3.rs b/src/api2/admin/s3.rs
index c5bdcc01f..70ae4f46b 100644
--- a/src/api2/admin/s3.rs
+++ b/src/api2/admin/s3.rs
@@ -59,7 +59,7 @@ pub async fn check(
     };
     let request_counter_config = S3RequestCounterConfig {
         id: request_counter_id,
-        user: pbs_config::backup_user()?,
+        user: proxmox_product_config::get_api_user().clone(),
         base_path: S3_CLIENT_REQUEST_COUNTER_BASE_PATH.into(),
     };
 
@@ -147,7 +147,7 @@ pub async fn reset_counters(
         bail!("Cannot find s3 counters file '{path:?}'");
     }
 
-    let user = pbs_config::backup_user()?;
+    let user = proxmox_product_config::get_api_user().clone();
     let request_counters = SharedRequestCounters::open_shared_memory_mapped(path, user)
         .context("failed to open shared request counters")?;
     request_counters.reset(Ordering::Release);
diff --git a/src/api2/config/datastore.rs b/src/api2/config/datastore.rs
index 7c65470f9..e7028480c 100644
--- a/src/api2/config/datastore.rs
+++ b/src/api2/config/datastore.rs
@@ -196,7 +196,7 @@ pub(crate) fn do_create_datastore(
                 message: None,
             }))?;
         }
-        let backup_user = pbs_config::backup_user()?;
+        let backup_user = proxmox_product_config::get_api_user();
         ChunkStore::create(
             &datastore.name,
             path.clone(),
diff --git a/src/api2/config/s3.rs b/src/api2/config/s3.rs
index fc0d39e7d..fb4657281 100644
--- a/src/api2/config/s3.rs
+++ b/src/api2/config/s3.rs
@@ -346,7 +346,7 @@ pub async fn list_buckets(
     let empty_prefix = String::new();
     let request_counter_config = S3RequestCounterConfig {
         id,
-        user: pbs_config::backup_user()?,
+        user: proxmox_product_config::get_api_user().clone(),
         base_path: S3_CLIENT_REQUEST_COUNTER_BASE_PATH.into(),
     };
     let options = S3ClientOptions::from_config(
diff --git a/src/config/mod.rs b/src/config/mod.rs
index 0d795562f..cf084325d 100644
--- a/src/config/mod.rs
+++ b/src/config/mod.rs
@@ -26,7 +26,7 @@ pub mod tfa;
 pub fn check_configdir_permissions() -> Result<(), Error> {
     let cfgdir = pbs_buildcfg::CONFIGDIR;
 
-    let backup_user = pbs_config::backup_user()?;
+    let backup_user = proxmox_product_config::get_api_user();
     let backup_uid = backup_user.uid.as_raw();
     let backup_gid = backup_user.gid.as_raw();
 
@@ -71,7 +71,7 @@ pub fn create_configdir() -> Result<(), Error> {
         ),
     }
 
-    let backup_user = pbs_config::backup_user()?;
+    let backup_user = proxmox_product_config::get_api_user();
 
     nix::unistd::chown(cfgdir, Some(backup_user.uid), Some(backup_user.gid)).map_err(|err| {
         format_err!(
diff --git a/src/server/jobstate.rs b/src/server/jobstate.rs
index d2336ea62..7add06779 100644
--- a/src/server/jobstate.rs
+++ b/src/server/jobstate.rs
@@ -87,7 +87,7 @@ const JOB_STATE_BASEDIR: &str = concat!(PROXMOX_BACKUP_STATE_DIR_M!(), "/jobstat
 
 /// Create jobstate stat dir with correct permission
 pub fn create_jobstate_dir() -> Result<(), Error> {
-    let backup_user = pbs_config::backup_user()?;
+    let backup_user = proxmox_product_config::get_api_user();
 
     let opts = CreateOptions::new()
         .owner(backup_user.uid)
@@ -323,7 +323,7 @@ impl Job {
         let serialized = serde_json::to_string(&self.state)?;
         let path = get_path(&self.jobtype, &self.jobname);
 
-        let backup_user = pbs_config::backup_user()?;
+        let backup_user = proxmox_product_config::get_api_user();
         let mode = nix::sys::stat::Mode::from_bits_truncate(0o0644);
         // set the correct owner/group/permissions while saving file
         // owner(rw) = backup, group(r)= backup
diff --git a/src/server/metric_collection/mod.rs b/src/server/metric_collection/mod.rs
index 18625b1a5..bbbd1a8ed 100644
--- a/src/server/metric_collection/mod.rs
+++ b/src/server/metric_collection/mod.rs
@@ -250,7 +250,7 @@ fn collect_s3_stats(
     let s3_stats = match counters.entry(path.clone()) {
         Entry::Occupied(o) => load_s3_statistics(o.get()),
         Entry::Vacant(v) => {
-            let user = pbs_config::backup_user()?;
+            let user = proxmox_product_config::get_api_user().clone();
             let counters = SharedRequestCounters::open_shared_memory_mapped(path, user)?;
             let s3_stats = load_s3_statistics(&counters);
             v.insert(counters);
diff --git a/src/server/metric_collection/pull_metrics.rs b/src/server/metric_collection/pull_metrics.rs
index 5287517e2..6b2ea3cc5 100644
--- a/src/server/metric_collection/pull_metrics.rs
+++ b/src/server/metric_collection/pull_metrics.rs
@@ -23,7 +23,7 @@ static METRIC_CACHE: OnceLock<SharedCache> = OnceLock::new();
 
 /// Initialize the metric cache.
 pub(super) fn init() -> Result<(), Error> {
-    let backup_user = pbs_config::backup_user()?;
+    let backup_user = proxmox_product_config::get_api_user();
     let file_opts = CreateOptions::new()
         .owner(backup_user.uid)
         .group(backup_user.gid)
diff --git a/src/server/metric_collection/rrd.rs b/src/server/metric_collection/rrd.rs
index da79a835c..11699ebe2 100644
--- a/src/server/metric_collection/rrd.rs
+++ b/src/server/metric_collection/rrd.rs
@@ -34,7 +34,7 @@ fn get_cache() -> Result<&'static Cache, Error> {
 ///
 /// Note: Only a single process must do this (proxmox-backup-proxy)
 pub(super) fn init() -> Result<&'static Cache, Error> {
-    let backup_user = pbs_config::backup_user()?;
+    let backup_user = proxmox_product_config::get_api_user();
 
     let file_options = CreateOptions::new()
         .owner(backup_user.uid)
diff --git a/src/server/mod.rs b/src/server/mod.rs
index 979f5357e..b89f657c8 100644
--- a/src/server/mod.rs
+++ b/src/server/mod.rs
@@ -63,7 +63,7 @@ pub(crate) async fn notify_datastore_removed() -> Result<(), Error> {
 /// This exists to fixate the permissions for the run *base* directory while allowing intermediate
 /// directories after it to have different permissions.
 pub fn create_run_dir() -> Result<(), Error> {
-    let backup_user = pbs_config::backup_user()?;
+    let backup_user = proxmox_product_config::get_api_user();
     let opts = CreateOptions::new()
         .owner(backup_user.uid)
         .group(backup_user.gid);
@@ -72,7 +72,7 @@ pub fn create_run_dir() -> Result<(), Error> {
 }
 
 pub fn create_state_dir() -> Result<(), Error> {
-    let backup_user = pbs_config::backup_user()?;
+    let backup_user = proxmox_product_config::get_api_user();
     let opts = CreateOptions::new()
         .owner(backup_user.uid)
         .group(backup_user.gid);
@@ -86,7 +86,7 @@ pub fn create_state_dir() -> Result<(), Error> {
 
 /// Create active operations dir with correct permission.
 pub fn create_active_operations_dir() -> Result<(), Error> {
-    let backup_user = pbs_config::backup_user()?;
+    let backup_user = proxmox_product_config::get_api_user();
     let mode = nix::sys::stat::Mode::from_bits_truncate(0o0750);
     let options = CreateOptions::new()
         .perm(mode)
diff --git a/src/server/notifications/mod.rs b/src/server/notifications/mod.rs
index 0f772ddd9..181f12cbc 100644
--- a/src/server/notifications/mod.rs
+++ b/src/server/notifications/mod.rs
@@ -38,7 +38,7 @@ pub fn init() -> Result<(), Error> {
 /// Create the directory which will be used to temporarily store notifications
 /// which were sent from an unprivileged process.
 pub fn create_spool_dir() -> Result<(), Error> {
-    let backup_user = pbs_config::backup_user()?;
+    let backup_user = proxmox_product_config::get_api_user();
     let opts = CreateOptions::new()
         .owner(backup_user.uid)
         .group(backup_user.gid);
@@ -118,7 +118,7 @@ fn send_notification(notification: Notification) -> Result<(), Error> {
         let ser = serde_json::to_vec(&notification)?;
         let path = Path::new(SPOOL_DIR).join(format!("{id}.json", id = notification.id()));
 
-        let backup_user = pbs_config::backup_user()?;
+        let backup_user = proxmox_product_config::get_api_user();
         let opts = CreateOptions::new()
             .owner(backup_user.uid)
             .group(backup_user.gid);
diff --git a/src/tape/changer/mod.rs b/src/tape/changer/mod.rs
index 1593182ad..1c5e6dbf5 100644
--- a/src/tape/changer/mod.rs
+++ b/src/tape/changer/mod.rs
@@ -353,7 +353,7 @@ fn save_changer_state_cache(changer: &str, state: &MtxStatus) -> Result<(), Erro
 
     let state = serde_json::to_string_pretty(state)?;
 
-    let backup_user = pbs_config::backup_user()?;
+    let backup_user = proxmox_product_config::get_api_user();
     let mode = nix::sys::stat::Mode::from_bits_truncate(0o0644);
     let options = CreateOptions::new()
         .perm(mode)
diff --git a/src/tape/drive/mod.rs b/src/tape/drive/mod.rs
index b717aa71d..051977240 100644
--- a/src/tape/drive/mod.rs
+++ b/src/tape/drive/mod.rs
@@ -549,7 +549,7 @@ pub fn set_tape_device_state(drive: &str, state: &str) -> Result<(), Error> {
     let mut path = PathBuf::from(crate::tape::DRIVE_STATE_DIR);
     path.push(drive);
 
-    let backup_user = pbs_config::backup_user()?;
+    let backup_user = proxmox_product_config::get_api_user();
     let mode = nix::sys::stat::Mode::from_bits_truncate(0o0644);
     let options = CreateOptions::new()
         .perm(mode)
diff --git a/src/traffic_control_cache.rs b/src/traffic_control_cache.rs
index c2074af9d..02c99173e 100644
--- a/src/traffic_control_cache.rs
+++ b/src/traffic_control_cache.rs
@@ -114,7 +114,7 @@ fn create_limiter(
     burst: u64,
 ) -> Result<SharedRateLimit, Error> {
     if use_shared_memory {
-        let user = pbs_config::backup_user()?;
+        let user = proxmox_product_config::get_api_user().clone();
         let base_path = pbs_buildcfg::rundir!("/shmem/tbf");
         let limiter = SharedRateLimiter::mmap_shmem(name, rate, burst, user, base_path)?;
         Ok(Arc::new(limiter))
-- 
2.47.3





      parent reply	other threads:[~2026-07-01 14:05 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-01 14:03 [PATCH proxmox-backup v3 00/15] fix 7642: avoid expensive uid/gid lookups for lock- and config-files Christian Ebner
2026-07-01 14:03 ` [PATCH proxmox-backup v3 01/15] bin: api: early init proxmox-product-config Christian Ebner
2026-07-01 14:03 ` [PATCH proxmox-backup v3 02/15] bin: daily update: refactor to use proxmox-product-config Christian Ebner
2026-07-01 14:04 ` [PATCH proxmox-backup v3 03/15] pbs-config: use proxmox-product-config::replace_secret_config() Christian Ebner
2026-07-01 14:04 ` [PATCH proxmox-backup v3 04/15] pbs-config: use proxmox-product-config::replace_config() Christian Ebner
2026-07-01 14:04 ` [PATCH proxmox-backup v3 05/15] fix #7642: avoid expensive user lookups on file locking Christian Ebner
2026-07-01 14:04 ` [PATCH proxmox-backup v3 06/15] pbs-config: use proxmox-product-config helpers Christian Ebner
2026-07-01 14:04 ` [PATCH proxmox-backup v3 07/15] pbs-config: drop backup_group helper, use users gid instead Christian Ebner
2026-07-01 14:04 ` [PATCH proxmox-backup v3 08/15] pbs-datastore: use proxmox-product-config cached backup user Christian Ebner
2026-07-01 14:04 ` [PATCH proxmox-backup v3 09/15] pbs-datastore: use general helpers for file lock create options Christian Ebner
2026-07-01 14:04 ` [PATCH proxmox-backup v3 10/15] server: auth helpers: use proxmox-product-config create options helpers Christian Ebner
2026-07-01 14:04 ` [PATCH proxmox-backup v3 11/15] api: subscription: use proxmox-product-config create options Christian Ebner
2026-07-01 14:04 ` [PATCH proxmox-backup v3 12/15] tape: use proxmox-product-config helper for user lookup Christian Ebner
2026-07-01 14:04 ` [PATCH proxmox-backup v3 13/15] tape: use proxmox-product-config lock file create options Christian Ebner
2026-07-01 14:04 ` [PATCH proxmox-backup v3 14/15] tape: use proxmox-product-config to generate " Christian Ebner
2026-07-01 14:04 ` Christian Ebner [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260701140412.200920-16-c.ebner@proxmox.com \
    --to=c.ebner@proxmox.com \
    --cc=pbs-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal