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
+31
View File
@@ -39,14 +39,17 @@
//! startup writes and post-construction reads hit the same cell and
//! single-instance behavior is byte-for-byte unchanged.
use super::global::TypeLocalDiskSetDrives;
use crate::bucket::bandwidth::monitor::Monitor;
use crate::bucket::lifecycle::bucket_lifecycle_ops::{ExpiryState, TransitionState};
use crate::bucket::replication::{DynReplicationPool, ReplicationStats};
use crate::disk::DiskStore;
use crate::layout::endpoints::{EndpointServerPools, SetupType};
use crate::services::event_notification::EventNotifier;
use crate::services::tier::tier::TierConfigMgr;
use rustfs_lock::{GlobalLockManager, get_global_lock_manager};
use s3s::region::Region;
use std::collections::HashMap;
use std::sync::{Arc, OnceLock};
use tokio::sync::{OnceCell, RwLock};
use uuid::Uuid;
@@ -125,6 +128,16 @@ pub struct InstanceContext {
/// Async set-once, built with the live storage during init. Replaces the
/// process-global static.
replication_pool: OnceCell<Arc<DynReplicationPool>>,
/// This instance's local disk registry (Phase 5 Slice 12, backlog#939).
///
/// Populated during storage startup (before the `ECStore` exists) via the
/// bootstrap context that the store then adopts, so startup writes and later
/// reads share one registry. Replaces the three `GLOBAL_LOCAL_DISK_*`
/// statics: the path→disk map, the disk-id→endpoint map, and the
/// pool/set/drive layout.
local_disk_map: Arc<RwLock<HashMap<String, Option<DiskStore>>>>,
local_disk_id_map: Arc<RwLock<HashMap<Uuid, String>>>,
local_disk_set_drives: Arc<RwLock<TypeLocalDiskSetDrives>>,
}
impl InstanceContext {
@@ -154,6 +167,9 @@ impl InstanceContext {
bucket_monitor: OnceLock::new(),
replication_stats: OnceCell::new(),
replication_pool: OnceCell::new(),
local_disk_map: Arc::new(RwLock::new(HashMap::new())),
local_disk_id_map: Arc::new(RwLock::new(HashMap::new())),
local_disk_set_drives: Arc::new(RwLock::new(Vec::new())),
}
}
@@ -270,6 +286,21 @@ impl InstanceContext {
&self.replication_pool
}
/// Handle to this instance's local path→disk map.
pub(crate) fn local_disk_map(&self) -> Arc<RwLock<HashMap<String, Option<DiskStore>>>> {
self.local_disk_map.clone()
}
/// Handle to this instance's local disk-id→endpoint map.
pub(crate) fn local_disk_id_map(&self) -> Arc<RwLock<HashMap<Uuid, String>>> {
self.local_disk_id_map.clone()
}
/// Handle to this instance's local pool/set/drive layout.
pub(crate) fn local_disk_set_drives(&self) -> Arc<RwLock<TypeLocalDiskSetDrives>> {
self.local_disk_set_drives.clone()
}
/// Update this instance's erasure setup type.
pub async fn update_erasure_type(&self, setup_type: SetupType) {
*self.erasure_kind.write().await = setup_type;