diff --git a/crates/ecstore/src/disk/local.rs b/crates/ecstore/src/disk/local.rs index bbce19898..7e52b69d0 100644 --- a/crates/ecstore/src/disk/local.rs +++ b/crates/ecstore/src/disk/local.rs @@ -35,7 +35,9 @@ use crate::disk::{ use crate::erasure::coding::{self, bitrot_verify}; use crate::runtime::sources as runtime_sources; use bytes::Bytes; -use metrics::{counter, gauge}; +use metrics::counter; +#[cfg(target_os = "linux")] +use metrics::gauge; use parking_lot::{Mutex as ParkingLotMutex, RwLock as ParkingLotRwLock}; use rustfs_filemeta::{ Cache, FileInfo, FileInfoOpts, FileMeta, MetaCacheEntry, MetacacheWriter, ObjectPartInfo, Opts, RawFileInfo, UpdateFn, diff --git a/crates/ecstore/src/ecstore_validation_blackbox.rs b/crates/ecstore/src/ecstore_validation_blackbox.rs index 31442dde1..4a566431e 100644 --- a/crates/ecstore/src/ecstore_validation_blackbox.rs +++ b/crates/ecstore/src/ecstore_validation_blackbox.rs @@ -205,11 +205,11 @@ async fn blackbox_get_restores_body_and_enqueues_repair_after_one_corrupt_shard( let mut heal_rx = rustfs_common::heal_channel::init_heal_channel() .expect("this must be the only ecstore test that owns the heal channel receiver"); - // Force the data-blocks-first reader setup (see - // ENV_RUSTFS_GET_DATA_BLOCKS_FIRST_READER_SETUP in set_disk/core/io_primitives.rs): - // under the default all-shards strategy the corrupt shard's failed open can - // lose the setup-quorum race, in which case no repair is submitted and the - // enqueue assertion below would be a coin flip. + // Keep data-blocks-first reader setup explicit for this deterministic + // repair assertion (see ENV_RUSTFS_GET_DATA_BLOCKS_FIRST_READER_SETUP in + // set_disk/core/io_primitives.rs): if a caller opts back into all-shards, + // the corrupt shard's failed open can lose the setup-quorum race, making + // the enqueue assertion below a coin flip. temp_env::async_with_vars([("RUSTFS_GET_DATA_BLOCKS_FIRST_READER_SETUP", Some("true"))], async { let (_dirs, set_disks) = make_local_set_disks(4, 2).await; let bucket = "bb-corrupt-shard-repair"; diff --git a/crates/ecstore/src/set_disk/core/io_primitives.rs b/crates/ecstore/src/set_disk/core/io_primitives.rs index ff347e7cc..1b31ad22c 100644 --- a/crates/ecstore/src/set_disk/core/io_primitives.rs +++ b/crates/ecstore/src/set_disk/core/io_primitives.rs @@ -70,6 +70,7 @@ use tokio::task::JoinSet; pub(in crate::set_disk) const EVENT_SET_DISK_READ: &str = "set_disk_read"; pub(in crate::set_disk) const ENV_RUSTFS_GET_DATA_BLOCKS_FIRST_READER_SETUP: &str = "RUSTFS_GET_DATA_BLOCKS_FIRST_READER_SETUP"; +const DEFAULT_RUSTFS_GET_DATA_BLOCKS_FIRST_READER_SETUP: bool = true; pub(in crate::set_disk) const ENV_RUSTFS_GET_CODEC_STREAMING_DATA_BLOCKS_FIRST_READER_SETUP: &str = "RUSTFS_GET_CODEC_STREAMING_DATA_BLOCKS_FIRST_READER_SETUP"; pub(in crate::set_disk) const SLOW_OBJECT_READ_LOG_THRESHOLD: Duration = Duration::from_secs(5); @@ -990,7 +991,11 @@ pub(in crate::set_disk) fn get_bitrot_reader_setup_strategy( ) -> BitrotReaderSetupStrategy { match mode { BitrotReaderSetupMode::ReadQuorum - if prefer_data_blocks_first || rustfs_utils::get_env_bool(ENV_RUSTFS_GET_DATA_BLOCKS_FIRST_READER_SETUP, false) => + if prefer_data_blocks_first + || rustfs_utils::get_env_bool( + ENV_RUSTFS_GET_DATA_BLOCKS_FIRST_READER_SETUP, + DEFAULT_RUSTFS_GET_DATA_BLOCKS_FIRST_READER_SETUP, + ) => { BitrotReaderSetupStrategy::DataBlocksFirst } @@ -4200,6 +4205,18 @@ mod tests { #[test] #[serial_test::serial] fn bitrot_reader_setup_tracks_strategy_counters_and_deferred_readers() { + temp_env::with_var(ENV_RUSTFS_GET_DATA_BLOCKS_FIRST_READER_SETUP, None::<&str>, || { + assert!(matches!( + get_bitrot_reader_setup_strategy(BitrotReaderSetupMode::ReadQuorum, false), + BitrotReaderSetupStrategy::DataBlocksFirst + )); + }); + temp_env::with_var(ENV_RUSTFS_GET_DATA_BLOCKS_FIRST_READER_SETUP, Some("false"), || { + assert!(matches!( + get_bitrot_reader_setup_strategy(BitrotReaderSetupMode::ReadQuorum, false), + BitrotReaderSetupStrategy::AllShards + )); + }); temp_env::with_var(ENV_RUSTFS_GET_DATA_BLOCKS_FIRST_READER_SETUP, Some("true"), || { assert!(matches!( get_bitrot_reader_setup_strategy(BitrotReaderSetupMode::ReadQuorum, false), diff --git a/crates/ecstore/src/set_disk/read.rs b/crates/ecstore/src/set_disk/read.rs index febe1fc9a..5dcc06933 100644 --- a/crates/ecstore/src/set_disk/read.rs +++ b/crates/ecstore/src/set_disk/read.rs @@ -3771,7 +3771,10 @@ mod tests { temp_env::async_with_vars( [ - (ENV_RUSTFS_GET_DATA_BLOCKS_FIRST_READER_SETUP, data_blocks_first.then_some("true")), + ( + ENV_RUSTFS_GET_DATA_BLOCKS_FIRST_READER_SETUP, + Some(if data_blocks_first { "true" } else { "false" }), + ), ( ENV_RUSTFS_GET_CODEC_STREAMING_DATA_BLOCKS_FIRST_READER_SETUP, codec_data_blocks_first.then_some("true"),