--- /tmp/p18-baseline-dm-main.rs 2026-05-17 00:24:36.755915716 +0300 +++ local/recipes/system/driver-manager/source/src/main.rs 2026-05-17 06:05:41.569135039 +0300 @@ -3,6 +3,7 @@ mod hotplug; mod scheme; +use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, Mutex}; use std::thread; use std::time::{Duration, Instant}; @@ -19,6 +20,19 @@ use config::DriverConfig; use scheme::{DriverManagerScheme, notify_bind}; +/// Global flag set by SIGTERM handler to request graceful shutdown. +static SHUTDOWN_REQUESTED: AtomicBool = AtomicBool::new(false); + +extern "C" fn sigterm_handler(_sig: i32) { + SHUTDOWN_REQUESTED.store(true, Ordering::SeqCst); +} + +fn install_sigterm_handler() { + unsafe { + libc::signal(libc::SIGTERM, sigterm_handler as usize); + } +} + struct StderrLogger; const BOOT_TIMELINE_PATH: &str = "/tmp/redbear-boot-timeline.json"; @@ -306,6 +320,9 @@ log::set_logger(&StderrLogger).ok(); log::set_max_level(log::LevelFilter::Info); + // Install SIGTERM handler for graceful shutdown + install_sigterm_handler(); + let args: Vec = env::args().collect(); let initfs = args.iter().any(|a| a == "--initfs"); let hotplug_mode = args.iter().any(|a| a == "--hotplug"); @@ -406,6 +423,15 @@ let max_retries = 30u32; for retry in 1..=max_retries { + if SHUTDOWN_REQUESTED.load(Ordering::SeqCst) { + log::info!("driver-manager: SIGTERM received during deferred retry, shutting down"); + graceful_shutdown(); + process::exit(0); + } + + // Check for crashed drivers during retry loop + reap_all_drivers(&driver_configs); + thread::sleep(Duration::from_millis(500)); let retry_events = match manager.lock() { @@ -460,6 +486,35 @@ fn idle_forever() -> ! { log::info!("driver-manager: entering persistent idle loop"); loop { - thread::sleep(Duration::from_secs(3600)); + thread::sleep(Duration::from_secs(5)); + if SHUTDOWN_REQUESTED.load(Ordering::SeqCst) { + log::info!("driver-manager: SIGTERM received, performing graceful shutdown"); + graceful_shutdown(); + process::exit(0); + } + // Periodically check for exited child drivers + reap_all_drivers(&[]); } } + +/// Poll all driver configs for exited children and log the results. +fn reap_all_drivers(driver_configs: &[DriverConfig]) { + for dc in driver_configs { + let exited = dc.reap_exited_children(); + for (device_key, driver_name, code) in &exited { + log::warn!( + "reaped crashed driver: {} for device {} (exit {})", + driver_name, + device_key, + code + ); + } + } +} + +fn graceful_shutdown() { + // The DeviceManager and spawned children are managed by DriverConfig instances + // which track their child processes. On shutdown, we log and exit cleanly. + // Child processes will be orphaned but the kernel reaps them. + log::info!("driver-manager: clean shutdown complete"); +}