initfs: exit after enumeration, skip scheme path checks
- Skip binary existence check in probe(): Redox scheme paths (especially /scheme/initfs/) may block on open/stat indefinitely. Command::new() spawn fails cleanly if binary missing. - In initfs mode: use synchronous probe, do bounded deferred retries, then exit. Rootfs instance handles hotplug. - Avoids pcid config handle read hang that blocks async threads.
This commit is contained in:
@@ -259,20 +259,11 @@ impl Driver for DriverConfig {
|
||||
format!("/usr/lib/drivers/{}", self.command[0])
|
||||
};
|
||||
|
||||
// Also check the initfs path — drivers like nvmed live in
|
||||
// /scheme/initfs/lib/drivers/ during early boot and may not yet
|
||||
// be staged to /usr/lib/drivers/ after switchroot.
|
||||
if !std::path::Path::new(&actual_path).exists() {
|
||||
let initfs_path = format!("/scheme/initfs/lib/drivers/{}", self.command[0].rsplit('/').next().unwrap_or(&self.command[0]));
|
||||
if std::path::Path::new(&initfs_path).exists() {
|
||||
return ProbeResult::Deferred {
|
||||
reason: format!("driver in initfs only (not yet in rootfs): {}", initfs_path),
|
||||
};
|
||||
}
|
||||
return ProbeResult::Fatal {
|
||||
reason: format!("driver binary not found: {} (also checked {})", actual_path, initfs_path),
|
||||
};
|
||||
}
|
||||
// Skip the binary existence check. On Redox, scheme paths
|
||||
// (especially /scheme/initfs/) may block on open/stat. The
|
||||
// Command::new() spawn will fail with a clear error if the
|
||||
// binary doesn't exist, which is handled as a Fatal probe
|
||||
// result downstream.
|
||||
|
||||
// Skip if this driver's scheme is already registered (e.g., by
|
||||
// pcid-spawner during initfs). Prevents re-spawning drivers
|
||||
|
||||
@@ -420,7 +420,7 @@ fn main() {
|
||||
let manager_config = ManagerConfig {
|
||||
max_concurrent_probes: 4,
|
||||
deferred_retry_ms: 500,
|
||||
async_probe: true,
|
||||
async_probe: !initfs,
|
||||
};
|
||||
|
||||
let manager = Arc::new(Mutex::new(DeviceManager::new(manager_config.clone())));
|
||||
@@ -498,7 +498,72 @@ fn main() {
|
||||
idle_forever();
|
||||
}
|
||||
|
||||
let max_retries = if initfs { 10u32 } else { 3u32 };
|
||||
// In initfs mode: do bounded retries for deferred probes, then exit
|
||||
// so init can proceed to rootfs mount. The rootfs driver-manager
|
||||
// instance (started by the rootfs service) handles hotplug and
|
||||
// persistent management.
|
||||
if initfs {
|
||||
let max_retries = 10u32;
|
||||
for retry in 1..=max_retries {
|
||||
if SHUTDOWN_REQUESTED.load(Ordering::SeqCst) {
|
||||
log::info!("driver-manager: SIGTERM received, shutting down");
|
||||
graceful_shutdown();
|
||||
process::exit(0);
|
||||
}
|
||||
|
||||
reap_all_drivers(&driver_configs);
|
||||
thread::sleep(Duration::from_millis(500));
|
||||
|
||||
let retry_events = match manager.lock() {
|
||||
Ok(mut mgr) => mgr.retry_deferred(),
|
||||
Err(err) => {
|
||||
log::error!("failed to retry deferred probes: manager lock poisoned: {err}");
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
let mut remaining = 0;
|
||||
let mut newly_bound = 0;
|
||||
|
||||
for event in &retry_events {
|
||||
log_timeline(event);
|
||||
if let ProbeEvent::ProbeCompleted {
|
||||
device,
|
||||
driver_name,
|
||||
result,
|
||||
} = event
|
||||
{
|
||||
match result {
|
||||
ProbeResult::Bound => {
|
||||
newly_bound += 1;
|
||||
notify_bound_device(scheme.as_ref(), device, driver_name);
|
||||
}
|
||||
ProbeResult::Deferred { .. } => remaining += 1,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if remaining == 0 {
|
||||
log::info!("all deferred resolved after {} retries (initfs)", retry);
|
||||
break;
|
||||
}
|
||||
|
||||
if newly_bound > 0 {
|
||||
log::info!(
|
||||
"initfs retry #{}: {} new, {} remaining",
|
||||
retry,
|
||||
newly_bound,
|
||||
remaining
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
log::info!("driver-manager: initfs phase complete, exiting");
|
||||
return;
|
||||
}
|
||||
|
||||
let max_retries = 3u32;
|
||||
for retry in 1..=max_retries {
|
||||
if SHUTDOWN_REQUESTED.load(Ordering::SeqCst) {
|
||||
log::info!("driver-manager: SIGTERM received during deferred retry, shutting down");
|
||||
|
||||
Reference in New Issue
Block a user