From: Christian Ebner <c.ebner@proxmox.com>
To: pbs-devel@lists.proxmox.com
Subject: [pbs-devel] [PATCH proxmox-backup 1/4] traffic control: use factored out shared rate limiter
Date: Thu, 28 Aug 2025 12:26:01 +0200 [thread overview]
Message-ID: <20250828102604.463662-4-c.ebner@proxmox.com> (raw)
In-Reply-To: <20250828102604.463662-1-c.ebner@proxmox.com>
The shared rate limiter implementation was factored out into a
dedicated crate so it can be easily reused for other code paths, e.g.
the s3 client implementation.
Use that implementation and drop the now dead code.
No functional changes intended.
Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
---
Cargo.toml | 2 +-
src/tools/mod.rs | 4 -
src/tools/shared_rate_limiter.rs | 122 -------------------------------
src/traffic_control_cache.rs | 8 +-
4 files changed, 5 insertions(+), 131 deletions(-)
delete mode 100644 src/tools/shared_rate_limiter.rs
diff --git a/Cargo.toml b/Cargo.toml
index 19974da2b..82e3b33f3 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -216,7 +216,7 @@ proxmox-base64.workspace = true
proxmox-compression.workspace = true
proxmox-config-digest.workspace = true
proxmox-daemon.workspace = true
-proxmox-http = { workspace = true, features = [ "body", "client-trait", "proxmox-async", "rate-limited-stream" ] } # pbs-client doesn't use these
+proxmox-http = { workspace = true, features = [ "body", "client-trait", "proxmox-async", "rate-limited-stream", "shared-rate-limiter" ] } # pbs-client doesn't use these
proxmox-human-byte.workspace = true
proxmox-io.workspace = true
proxmox-lang.workspace = true
diff --git a/src/tools/mod.rs b/src/tools/mod.rs
index 6556effe3..a97aba5b6 100644
--- a/src/tools/mod.rs
+++ b/src/tools/mod.rs
@@ -16,10 +16,6 @@ use pbs_datastore::manifest::BackupManifest;
pub mod config;
pub mod disks;
pub mod fs;
-
-mod shared_rate_limiter;
-pub use shared_rate_limiter::SharedRateLimiter;
-
pub mod statistics;
pub mod systemd;
pub mod ticket;
diff --git a/src/tools/shared_rate_limiter.rs b/src/tools/shared_rate_limiter.rs
deleted file mode 100644
index db754728b..000000000
--- a/src/tools/shared_rate_limiter.rs
+++ /dev/null
@@ -1,122 +0,0 @@
-use std::mem::MaybeUninit;
-use std::path::PathBuf;
-use std::time::{Duration, Instant};
-
-use anyhow::{bail, Error};
-use nix::sys::stat::Mode;
-
-use proxmox_sys::fs::{create_path, CreateOptions};
-
-use proxmox_http::{RateLimit, RateLimiter, ShareableRateLimit};
-use proxmox_shared_memory::{check_subtype, initialize_subtype};
-use proxmox_shared_memory::{Init, SharedMemory, SharedMutex};
-
-// openssl::sha::sha256(b"Proxmox Backup SharedRateLimiter v1.0")[0..8];
-pub const PROXMOX_BACKUP_SHARED_RATE_LIMITER_MAGIC_1_0: [u8; 8] =
- [6, 58, 213, 96, 161, 122, 130, 117];
-
-const BASE_PATH: &str = pbs_buildcfg::rundir!("/shmem/tbf");
-
-// Wrap RateLimiter, so that we can provide an Init impl
-#[repr(C)]
-struct WrapLimiter(RateLimiter);
-
-impl Init for WrapLimiter {
- fn initialize(this: &mut MaybeUninit<Self>) {
- // default does not matter here, because we override later
- this.write(WrapLimiter(RateLimiter::new(1_000_000, 1_000_000)));
- }
-}
-
-#[repr(C)]
-struct SharedRateLimiterData {
- magic: [u8; 8],
- tbf: SharedMutex<WrapLimiter>,
- padding: [u8; 4096 - 104],
-}
-
-impl Init for SharedRateLimiterData {
- fn initialize(this: &mut MaybeUninit<Self>) {
- unsafe {
- let me = &mut *this.as_mut_ptr();
- me.magic = PROXMOX_BACKUP_SHARED_RATE_LIMITER_MAGIC_1_0;
- initialize_subtype(&mut me.tbf);
- }
- }
-
- fn check_type_magic(this: &MaybeUninit<Self>) -> Result<(), Error> {
- unsafe {
- let me = &*this.as_ptr();
- if me.magic != PROXMOX_BACKUP_SHARED_RATE_LIMITER_MAGIC_1_0 {
- bail!("SharedRateLimiterData: wrong magic number");
- }
- check_subtype(&me.tbf)?;
- Ok(())
- }
- }
-}
-
-/// Rate limiter designed for shared memory ([SharedMemory])
-///
-/// The actual [RateLimiter] is protected by a [SharedMutex] and
-/// implements [Init]. This way we can share the limiter between
-/// different processes.
-pub struct SharedRateLimiter {
- shmem: SharedMemory<SharedRateLimiterData>,
-}
-
-impl SharedRateLimiter {
- /// Creates a new mmap'ed instance.
- ///
- /// Data is mapped in `/var/run/proxmox-backup/shmem/tbf/<name>` using
- /// `TMPFS`.
- pub fn mmap_shmem(name: &str, rate: u64, burst: u64) -> Result<Self, Error> {
- let mut path = PathBuf::from(BASE_PATH);
-
- let user = pbs_config::backup_user()?;
-
- let dir_opts = CreateOptions::new()
- .perm(Mode::from_bits_truncate(0o770))
- .owner(user.uid)
- .group(user.gid);
-
- create_path(&path, Some(dir_opts), Some(dir_opts))?;
-
- path.push(name);
-
- let file_opts = CreateOptions::new()
- .perm(Mode::from_bits_truncate(0o660))
- .owner(user.uid)
- .group(user.gid);
-
- let shmem: SharedMemory<SharedRateLimiterData> = SharedMemory::open(&path, file_opts)?;
-
- shmem.data().tbf.lock().0.update_rate(rate, burst);
-
- Ok(Self { shmem })
- }
-}
-
-impl ShareableRateLimit for SharedRateLimiter {
- fn update_rate(&self, rate: u64, bucket_size: u64) {
- self.shmem
- .data()
- .tbf
- .lock()
- .0
- .update_rate(rate, bucket_size);
- }
-
- fn traffic(&self) -> u64 {
- self.shmem.data().tbf.lock().0.traffic()
- }
-
- fn register_traffic(&self, current_time: Instant, data_len: u64) -> Duration {
- self.shmem
- .data()
- .tbf
- .lock()
- .0
- .register_traffic(current_time, data_len)
- }
-}
diff --git a/src/traffic_control_cache.rs b/src/traffic_control_cache.rs
index 830a8c043..de5c9dc77 100644
--- a/src/traffic_control_cache.rs
+++ b/src/traffic_control_cache.rs
@@ -8,7 +8,7 @@ use std::time::Instant;
use anyhow::Error;
use cidr::IpInet;
-use proxmox_http::{RateLimiter, ShareableRateLimit};
+use proxmox_http::{RateLimiter, ShareableRateLimit, SharedRateLimiter};
use proxmox_section_config::SectionConfigData;
use proxmox_time::{parse_daily_duration, DailyDuration, TmEditor};
@@ -17,8 +17,6 @@ use pbs_api_types::TrafficControlRule;
use pbs_config::ConfigVersionCache;
-use crate::tools::SharedRateLimiter;
-
pub type SharedRateLimit = Arc<dyn ShareableRateLimit>;
/// Shared traffic control cache singleton.
@@ -110,7 +108,9 @@ fn create_limiter(
burst: u64,
) -> Result<SharedRateLimit, Error> {
if use_shared_memory {
- let limiter = SharedRateLimiter::mmap_shmem(name, rate, burst)?;
+ let user = pbs_config::backup_user()?;
+ let base_path = pbs_buildcfg::rundir!("/shmem/tbf");
+ let limiter = SharedRateLimiter::mmap_shmem(name, rate, burst, user, base_path)?;
Ok(Arc::new(limiter))
} else {
Ok(Arc::new(Mutex::new(RateLimiter::new(rate, burst))))
--
2.47.2
_______________________________________________
pbs-devel mailing list
pbs-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel
next prev parent reply other threads:[~2025-08-28 10:26 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-28 10:25 [pbs-devel] [PATCH proxmox{, -backup} 0/6] shared rate limiter for s3 client instances Christian Ebner
2025-08-28 10:25 ` [pbs-devel] [PATCH proxmox 1/2] http: factor out PBS shared rate limiter implementation Christian Ebner
2025-08-28 10:26 ` [pbs-devel] [PATCH proxmox 2/2] s3-client: add shared rate limiter via https connector Christian Ebner
2025-08-28 10:26 ` Christian Ebner [this message]
2025-08-28 10:26 ` [pbs-devel] [PATCH proxmox-backup 2/4] api: config: update s3 endpoint rate limits in config Christian Ebner
2025-08-28 10:26 ` [pbs-devel] [PATCH proxmox-backup 3/4] datastore: s3: set rate limiter options for s3 client Christian Ebner
2025-08-28 10:26 ` [pbs-devel] [PATCH proxmox-backup 4/4] ui: expose rate and burst limits for s3 endpoints Christian Ebner
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=20250828102604.463662-4-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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox