From 55e3a1f7e079683a99e541682a2b892f4463baca Mon Sep 17 00:00:00 2001 From: houseme Date: Fri, 14 Nov 2025 20:23:21 +0800 Subject: [PATCH] fix(audit): prevent state transition when no targets exist (#854) Avoid setting AuditSystemState::Starting when target list is empty. Now checks target availability before state transition, keeping the system in Stopped state if no enabled targets are found. - Check targets.is_empty() before setting Starting state - Return early with Ok(()) when no targets exist - Maintain consistent state machine behavior - Prevent transient "Starting" state with no actual targets Resolves issue where audit system would incorrectly enter Starting state even when configuration contained no enabled targets. --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- crates/audit/src/global.rs | 4 ++-- crates/audit/src/system.rs | 14 ++++++++++++-- rustfs/src/server/audit.rs | 4 ++-- 5 files changed, 19 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8b680915..3abdb11e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9789,9 +9789,9 @@ dependencies = [ [[package]] name = "wildmatch" -version = "2.6.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d654e41fe05169e03e27b97e0c23716535da037c1652a31fd99c6b2fad84059" +checksum = "29333c3ea1ba8b17211763463ff24ee84e41c78224c16b001cd907e663a38c68" dependencies = [ "serde", ] diff --git a/Cargo.toml b/Cargo.toml index 8fc40c35..c88748a2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -252,7 +252,7 @@ urlencoding = "2.1.3" uuid = { version = "1.18.1", features = ["v4", "fast-rng", "macro-diagnostics"] } vaultrs = { version = "0.7.4" } walkdir = "2.5.0" -wildmatch = { version = "2.6.0", features = ["serde"] } +wildmatch = { version = "2.6.1", features = ["serde"] } winapi = { version = "0.3.9" } xxhash-rust = { version = "0.8.15", features = ["xxh64", "xxh3"] } zip = "6.0.0" diff --git a/crates/audit/src/global.rs b/crates/audit/src/global.rs index b95c510e..4031a384 100644 --- a/crates/audit/src/global.rs +++ b/crates/audit/src/global.rs @@ -15,7 +15,7 @@ use crate::{AuditEntry, AuditResult, AuditSystem}; use rustfs_ecstore::config::Config; use std::sync::{Arc, OnceLock}; -use tracing::{error, trace, warn}; +use tracing::{debug, error, trace, warn}; /// Global audit system instance static AUDIT_SYSTEM: OnceLock> = OnceLock::new(); @@ -78,7 +78,7 @@ pub async fn dispatch_audit_log(entry: Arc) -> AuditResult<()> { } else { // The system is not initialized at all. This is a more important state. // It might be better to return an error or log a warning. - warn!("Audit system not initialized, dropping audit entry."); + debug!("Audit system not initialized, dropping audit entry."); // If this should be a hard failure, you can return Err(AuditError::NotInitialized("...")) Ok(()) } diff --git a/crates/audit/src/system.rs b/crates/audit/src/system.rs index bcbd37e7..cbfd2d51 100644 --- a/crates/audit/src/system.rs +++ b/crates/audit/src/system.rs @@ -59,7 +59,7 @@ impl AuditSystem { /// Starts the audit system with the given configuration pub async fn start(&self, config: Config) -> AuditResult<()> { - let mut state = self.state.write().await; + let state = self.state.write().await; match *state { AuditSystemState::Running => { @@ -72,7 +72,6 @@ impl AuditSystem { _ => {} } - *state = AuditSystemState::Starting; drop(state); info!("Starting audit system"); @@ -90,6 +89,17 @@ impl AuditSystem { let mut registry = self.registry.lock().await; match registry.create_targets_from_config(&config).await { Ok(targets) => { + if targets.is_empty() { + info!("No enabled audit targets found, keeping audit system stopped"); + drop(registry); + return Ok(()); + } + + { + let mut state = self.state.write().await; + *state = AuditSystemState::Starting; + } + info!(target_count = targets.len(), "Created audit targets successfully"); // Initialize all targets diff --git a/rustfs/src/server/audit.rs b/rustfs/src/server/audit.rs index 5a606fbf..2a81af15 100644 --- a/rustfs/src/server/audit.rs +++ b/rustfs/src/server/audit.rs @@ -16,7 +16,7 @@ use rustfs_audit::system::AuditSystemState; use rustfs_audit::{AuditError, AuditResult, audit_system, init_audit_system}; use rustfs_config::DEFAULT_DELIMITER; use rustfs_ecstore::config::GLOBAL_SERVER_CONFIG; -use tracing::{error, info, warn}; +use tracing::{info, warn}; /// Start the audit system. /// This function checks if the audit subsystem is configured in the global server configuration. @@ -89,7 +89,7 @@ pub(crate) async fn start_audit_system() -> AuditResult<()> { Ok(()) } Err(e) => { - error!( + warn!( target: "rustfs::main::start_audit_system", "Audit system startup failed: {:?}", e