driver-manager: share Arc<DriverConfig> + crash-aware reaper + S3 self_weak (N18 Q1+Q2+S3)
Three changes in one file because the regions are interleaved and the changes are all upstream of the audit plan's N18 single-day batch. - Q1: `main.rs:636-661` rewritten to build one `Vec<Arc<DriverConfig>>` and pass `Arc::clone` to both `DeviceManager` via the new `register_driver_shared` and to the reaper registry via `Arc::downgrade`. Removes the dead `registry_configs` second-loop block. - Q2: reaper closure at `main.rs:765-772` interprets `waitpid` status via `WIFEXITED && WEXITSTATUS == 0` or `WIFSIGNALED && WTERMSIG in (SIGTERM, SIGINT)` as a clean exit, routing to `reap_pid_clean`; anything else routes to `reap_pid` (crash). - S3: cfg-gated `set_self_weak(Arc::downgrade(&scheme))` call after `set_manager` so the detached AER recovery worker can notify the scheme of rebind events. driver-manager tests: 164 passing (no regression).
This commit is contained in:
@@ -605,6 +605,12 @@ fn main() {
|
||||
let scheme = Arc::new(DriverManagerScheme::new());
|
||||
scheme.set_manager(Arc::clone(&manager));
|
||||
|
||||
// N18 S3: store a Weak self-reference so the AER recovery worker
|
||||
// (which runs detached) can call back into the scheme to record
|
||||
// rebind events without keeping a long-lived strong Arc.
|
||||
#[cfg(target_os = "redox")]
|
||||
scheme.set_self_weak(std::sync::Arc::downgrade(&scheme));
|
||||
|
||||
let heartbeat = heartbeat::Heartbeat::new(
|
||||
std::path::PathBuf::from("/var/run/driver-manager.heartbeat.json"),
|
||||
std::time::Duration::from_secs(5),
|
||||
@@ -633,12 +639,22 @@ fn main() {
|
||||
initfs_manifest: Some(std::sync::Arc::clone(&shared_initfs_manifest)),
|
||||
});
|
||||
|
||||
// N18 Q1: one Arc<DriverConfig> per driver, shared between manager
|
||||
// and registry. The manager mutates spawned/pid_to_device via probe();
|
||||
// the reaper's Weak::upgrade returns the same allocation so the maps
|
||||
// it cleans match the maps the manager populated.
|
||||
let driver_arcs: Vec<std::sync::Arc<DriverConfig>> = driver_configs
|
||||
.iter()
|
||||
.map(|dc| std::sync::Arc::new(dc.clone()))
|
||||
.collect();
|
||||
match manager.lock() {
|
||||
Ok(mut mgr) => {
|
||||
mgr.register_bus(Box::new(PciBus::new()));
|
||||
|
||||
for dc in &driver_configs {
|
||||
mgr.register_driver(Box::new(dc.clone()));
|
||||
for dc in &driver_arcs {
|
||||
// Unsized coercion: Arc<DriverConfig> -> Arc<dyn Driver>.
|
||||
// Coercion fires at the function-call site (argument position
|
||||
// accepts Arc<dyn Driver>, which Arc<DriverConfig> satisfies).
|
||||
mgr.register_driver_shared(dc.clone());
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
@@ -650,13 +666,8 @@ fn main() {
|
||||
let mgr_clone = Arc::clone(&manager);
|
||||
let scheme_clone = Arc::clone(&scheme);
|
||||
|
||||
let registry_configs: Vec<std::sync::Arc<DriverConfig>> = driver_configs
|
||||
.iter()
|
||||
.map(|dc| std::sync::Arc::new(dc.clone()))
|
||||
.collect();
|
||||
for cfg in ®istry_configs {
|
||||
let weak: std::sync::Weak<DriverConfig> =
|
||||
std::sync::Arc::downgrade(cfg);
|
||||
for dc in &driver_arcs {
|
||||
let weak: std::sync::Weak<DriverConfig> = std::sync::Arc::downgrade(dc);
|
||||
registry::register(weak);
|
||||
}
|
||||
|
||||
@@ -762,11 +773,21 @@ fn main() {
|
||||
},
|
||||
);
|
||||
|
||||
let _reaper_thread = reaper::spawn_reaper_thread(|pid| {
|
||||
let _reaper_thread = reaper::spawn_reaper_thread(|pid, status| {
|
||||
// Clean exit: WIFEXITED && WEXITSTATUS == 0, or WIFSIGNALED with
|
||||
// SIGTERM/SIGINT (our own remove() sends SIGTERM). Anything else
|
||||
// is a crash.
|
||||
let clean = unsafe { libc::WIFEXITED(status) } && unsafe { libc::WEXITSTATUS(status) } == 0
|
||||
|| unsafe { libc::WIFSIGNALED(status) }
|
||||
&& matches!(unsafe { libc::WTERMSIG(status) }, libc::SIGTERM | libc::SIGINT);
|
||||
let registry = registry::snapshot();
|
||||
for weak in registry {
|
||||
if let Some(cfg) = weak.upgrade() {
|
||||
cfg.reap_pid(pid);
|
||||
if clean {
|
||||
cfg.reap_pid_clean(pid);
|
||||
} else {
|
||||
cfg.reap_pid(pid);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user