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 B24DD1FF165 for ; Thu, 28 Aug 2025 12:26:58 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 8154FCEB9; Thu, 28 Aug 2025 12:27:07 +0200 (CEST) From: Christian Ebner To: pbs-devel@lists.proxmox.com Date: Thu, 28 Aug 2025 12:26:03 +0200 Message-ID: <20250828102604.463662-6-c.ebner@proxmox.com> X-Mailer: git-send-email 2.47.2 In-Reply-To: <20250828102604.463662-1-c.ebner@proxmox.com> References: <20250828102604.463662-1-c.ebner@proxmox.com> MIME-Version: 1.0 X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1756376786341 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.043 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 Subject: [pbs-devel] [PATCH proxmox-backup 3/4] datastore: s3: set rate limiter options for s3 client X-BeenThere: pbs-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox Backup Server development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: Proxmox Backup Server development discussion Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: pbs-devel-bounces@lists.proxmox.com Sender: "pbs-devel" Set the shared rate limiter for each client instance based on the endpoint configuration. The same limits are shared for each s3 endpoint. To avoid possibly id clashing with rate limits set via traffic control, use the base directory `/s3/shmem/tbf` instead of the traffic control's `/shmem/tbf`. Signed-off-by: Christian Ebner --- pbs-datastore/src/datastore.rs | 18 +++++++++++++++++- src/api2/admin/s3.rs | 9 +++++++-- src/api2/config/s3.rs | 2 +- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/pbs-datastore/src/datastore.rs b/pbs-datastore/src/datastore.rs index 7cf020fc0..e7cc76dc7 100644 --- a/pbs-datastore/src/datastore.rs +++ b/pbs-datastore/src/datastore.rs @@ -14,7 +14,9 @@ use tokio::io::AsyncWriteExt; use tracing::{info, warn}; use proxmox_human_byte::HumanByte; -use proxmox_s3_client::{S3Client, S3ClientConf, S3ClientOptions, S3ObjectKey, S3PathPrefix}; +use proxmox_s3_client::{ + S3Client, S3ClientConf, S3ClientOptions, S3ObjectKey, S3PathPrefix, S3RateLimiterOptions, +}; use proxmox_schema::ApiType; use proxmox_sys::error::SysError; @@ -55,6 +57,7 @@ pub const GROUP_NOTES_FILE_NAME: &str = "notes"; pub const GROUP_OWNER_FILE_NAME: &str = "owner"; /// Filename for in-use marker stored on S3 object store backend pub const S3_DATASTORE_IN_USE_MARKER: &str = ".in-use"; +const S3_CLIENT_RATE_LIMITER_BASE_PATH: &str = pbs_buildcfg::rundir!("/s3/shmem/tbf"); const NAMESPACE_MARKER_FILENAME: &str = ".namespace"; /// checks if auth_id is owner, or, if owner is a token, if @@ -254,12 +257,18 @@ impl DataStore { let (config, _config_digest) = pbs_config::s3::config()?; let config: S3ClientConf = config.lookup(S3_CFG_TYPE_ID, s3_client_id)?; + let rate_limiter_options = S3RateLimiterOptions { + id: s3_client_id.to_string(), + user: pbs_config::backup_user()?, + base_path: S3_CLIENT_RATE_LIMITER_BASE_PATH.into(), + }; let options = S3ClientOptions::from_config( config.config, config.secret_key, Some(bucket), self.name().to_owned(), + Some(rate_limiter_options), ); let s3_client = S3Client::new(options)?; DatastoreBackend::S3(Arc::new(s3_client)) @@ -2432,11 +2441,18 @@ impl DataStore { let client_config: S3ClientConf = config .lookup(S3_CFG_TYPE_ID, s3_client_id) .with_context(|| format!("no '{s3_client_id}' in config"))?; + let rate_limiter_options = S3RateLimiterOptions { + id: s3_client_id.to_string(), + user: pbs_config::backup_user()?, + base_path: S3_CLIENT_RATE_LIMITER_BASE_PATH.into(), + }; + let options = S3ClientOptions::from_config( client_config.config, client_config.secret_key, Some(bucket), datastore_config.name.to_owned(), + Some(rate_limiter_options), ); let s3_client = S3Client::new(options) .context("failed to create s3 client") diff --git a/src/api2/admin/s3.rs b/src/api2/admin/s3.rs index 73f3779a5..73388281b 100644 --- a/src/api2/admin/s3.rs +++ b/src/api2/admin/s3.rs @@ -49,8 +49,13 @@ pub async fn check( .context("config lookup failed")?; let store_prefix = store_prefix.unwrap_or_default(); - let options = - S3ClientOptions::from_config(config.config, config.secret_key, Some(bucket), store_prefix); + let options = S3ClientOptions::from_config( + config.config, + config.secret_key, + Some(bucket), + store_prefix, + None, + ); let test_object_key = S3ObjectKey::try_from(".s3-client-test").context("failed to generate s3 object key")?; diff --git a/src/api2/config/s3.rs b/src/api2/config/s3.rs index 1e421114c..27b3c4cc2 100644 --- a/src/api2/config/s3.rs +++ b/src/api2/config/s3.rs @@ -351,7 +351,7 @@ pub async fn list_buckets( let empty_prefix = String::new(); let options = - S3ClientOptions::from_config(config.config, config.secret_key, None, empty_prefix); + S3ClientOptions::from_config(config.config, config.secret_key, None, empty_prefix, None); let client = S3Client::new(options).context("client creation failed")?; let list_buckets_response = client .list_buckets() -- 2.47.2 _______________________________________________ pbs-devel mailing list pbs-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel