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 682521FF13F for ; Thu, 09 Apr 2026 17:54:09 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 212DFA644; Thu, 9 Apr 2026 17:54:50 +0200 (CEST) From: Samuel Rufinatscha To: pbs-devel@lists.proxmox.com Subject: [PATCH proxmox-datacenter-manager v8 3/3] pdm-config: wire token.shadow generation Date: Thu, 9 Apr 2026 17:54:29 +0200 Message-ID: <20260409155437.312760-10-s.rufinatscha@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260409155437.312760-1-s.rufinatscha@proxmox.com> References: <20260409155437.312760-1-s.rufinatscha@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1775750014094 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.229 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: DTKQUABY65CF2ROABLYU6VBZJS5UVTFU X-Message-ID-Hash: DTKQUABY65CF2ROABLYU6VBZJS5UVTFU X-MailFrom: s.rufinatscha@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: Wires ConfigVersionCache with AccessControlBackend to support token.shadow caching. Safety: the shmem mapping is fixed to 4096 bytes via the #[repr(C)] union padding, and the new atomic is appended to the end of the #[repr(C)] inner struct, so all existing field offsets stay unchanged. Old processes keep accessing the same bytes and new processes consume previously reserved padding. Also documents the effects of the added API token-cache in the proxmox-access-control crate. Signed-off-by: Samuel Rufinatscha --- docs/access-control.rst | 4 ++++ lib/pdm-config/src/access_control.rs | 11 +++++++++++ lib/pdm-config/src/config_version_cache.rs | 18 ++++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/docs/access-control.rst b/docs/access-control.rst index adf26cd..18e57a2 100644 --- a/docs/access-control.rst +++ b/docs/access-control.rst @@ -47,6 +47,10 @@ place of the user ID (``user@realm``) and the user password, respectively. The API token is passed from the client to the server by setting the ``Authorization`` HTTP header with method ``PDMAPIToken`` to the value ``TOKENID:TOKENSECRET``. +.. WARNING:: Direct/manual edits to ``token.shadow`` may take up to 60 seconds (or + longer in edge cases) to take effect due to caching. Restart services for + immediate effect of manual edits. + .. _access_control: Access Control diff --git a/lib/pdm-config/src/access_control.rs b/lib/pdm-config/src/access_control.rs index 6bc6ca6..d9fc8ff 100644 --- a/lib/pdm-config/src/access_control.rs +++ b/lib/pdm-config/src/access_control.rs @@ -37,4 +37,15 @@ impl proxmox_access_control::init::AccessControlBackend for AccessControlBackend let c = crate::ConfigVersionCache::new()?; Ok(c.increase_user_and_acl_generation()) } + + fn token_shadow_cache_generation(&self) -> Option { + crate::ConfigVersionCache::new() + .ok() + .map(|c| c.token_shadow_generation()) + } + + fn increment_token_shadow_cache_generation(&self) -> Result { + let c = crate::ConfigVersionCache::new()?; + Ok(c.increase_token_shadow_generation()) + } } diff --git a/lib/pdm-config/src/config_version_cache.rs b/lib/pdm-config/src/config_version_cache.rs index d27ec95..f3d52a0 100644 --- a/lib/pdm-config/src/config_version_cache.rs +++ b/lib/pdm-config/src/config_version_cache.rs @@ -27,6 +27,8 @@ struct ConfigVersionCacheDataInner { traffic_control_generation: AtomicUsize, // Tracks updates to the remote/hostname/nodename mapping cache. remote_mapping_cache: AtomicUsize, + // Token shadow (token.shadow) generation/version. + token_shadow_generation: AtomicUsize, // Add further atomics here } @@ -172,4 +174,20 @@ impl ConfigVersionCache { .fetch_add(1, Ordering::Relaxed) + 1 } + + /// Returns the token shadow generation number. + pub fn token_shadow_generation(&self) -> usize { + self.shmem + .data() + .token_shadow_generation + .load(Ordering::Acquire) + } + + /// Increase the token shadow generation number. + pub fn increase_token_shadow_generation(&self) -> usize { + self.shmem + .data() + .token_shadow_generation + .fetch_add(1, Ordering::AcqRel) + } } -- 2.47.3