refactor(ecstore): migrate the local disk registry into InstanceContext (Phase 5 Slice 12) (#4518)

Phase 5 Slice 12 (backlog#939): move the local disk registry — the
path->disk map, the disk-id->endpoint map, and the pool/set/drive layout —
out of the three GLOBAL_LOCAL_DISK_* process statics into the per-instance
InstanceContext.

This is the migration the owned-guard prerequisite (#4501) unblocked.

- InstanceContext gains three `Arc<RwLock<..>>` registry fields, constructed
  eagerly (empty), plus pub(crate) handle accessors.
- The three runtime-source handle functions (`local_disk_map_handle` etc.) now
  return the current instance's registry via `current_ctx()`; every direct
  `GLOBAL_LOCAL_DISK_*` access in runtime::sources (~15 sites) routes through
  those handles instead. Accessors that hold a write guard across `.await`
  (`record_local_disks`, `initialize_local_disk_maps`, `replace_local_disk_id`)
  bind the handle first, so the same locks are held across the same awaits.
- The three statics are removed; the test-reset helper clears the current
  context's registry.

Construction window: the registry is populated during storage startup, before
the ECStore exists, via the bootstrap context that `ECStore::new` then adopts —
so startup writes and post-construction reads share one registry (no
split-brain). Single-instance behavior is byte-for-byte unchanged; the
GLOBAL_LOCAL_DISK_* boundary arch guard passes with the statics gone.

Verification: cargo test -p rustfs-ecstore (32 disk/instance tests green) and
-p rustfs-heal (201 green), cargo clippy -p rustfs-ecstore -p rustfs-heal
--all-targets (clean), make pre-commit (pass).

Refs: backlog#939 (Phase 5, Slice 12; disk-registry migration)
This commit is contained in:
Zhengchao An
2026-07-09 01:07:28 +08:00
committed by GitHub
parent 87357a0fdd
commit 7ead413599
3 changed files with 64 additions and 31 deletions
+4 -6
View File
@@ -53,9 +53,6 @@ pub const DISK_RESERVE_FRACTION: f64 = 0.15;
lazy_static! {
static ref GLOBAL_RUSTFS_PORT: OnceLock<u16> = OnceLock::new();
pub static ref GLOBAL_OBJECT_API: OnceLock<Arc<ECStore>> = OnceLock::new();
pub static ref GLOBAL_LOCAL_DISK_MAP: Arc<RwLock<HashMap<String, Option<DiskStore>>>> = Arc::new(RwLock::new(HashMap::new()));
pub static ref GLOBAL_LOCAL_DISK_ID_MAP: Arc<RwLock<HashMap<Uuid, String>>> = Arc::new(RwLock::new(HashMap::new()));
pub static ref GLOBAL_LOCAL_DISK_SET_DRIVES: Arc<RwLock<TypeLocalDiskSetDrives>> = Arc::new(RwLock::new(Vec::new()));
pub static ref GLOBAL_ROOT_DISK_THRESHOLD: RwLock<u64> = RwLock::new(0);
pub static ref GLOBAL_LIFECYCLE_SYS: Arc<LifecycleSys> = LifecycleSys::new();
pub static ref GLOBAL_BOOT_TIME: OnceCell<SystemTime> = OnceCell::new();
@@ -158,9 +155,10 @@ pub fn get_global_endpoints_opt() -> Option<EndpointServerPools> {
#[cfg(test)]
pub async fn reset_local_disk_test_state() {
GLOBAL_LOCAL_DISK_MAP.write().await.clear();
GLOBAL_LOCAL_DISK_ID_MAP.write().await.clear();
GLOBAL_LOCAL_DISK_SET_DRIVES.write().await.clear();
let ctx = current_ctx();
ctx.local_disk_map().write().await.clear();
ctx.local_disk_id_map().write().await.clear();
ctx.local_disk_set_drives().write().await.clear();
}
pub async fn is_first_cluster_node_local() -> bool {