feat: recipe durability guard — prevents build system from deleting local recipes

Add guard-recipes.sh with four modes:
- --verify: check all local/recipes have correct symlinks into recipes/
- --fix: repair broken symlinks (run before builds)
- --save-all: snapshot all recipe.toml into local/recipes/
- --restore: recreate all symlinks from local/recipes/ (run after sync-upstream)

Wired into apply-patches.sh (post-patch) and sync-upstream.sh (post-sync).
This prevents the build system from deleting recipe files during
cargo cook, make distclean, or upstream source refresh.
This commit is contained in:
2026-04-30 18:47:03 +01:00
parent 34360e1e4f
commit 7c7399e0a6
126 changed files with 13145 additions and 178 deletions
@@ -0,0 +1,74 @@
use std::thread;
use std::time::Duration;
use std::sync::{Arc, Mutex};
use redox_driver_core::manager::DeviceManager;
use redox_driver_core::manager::ProbeEvent;
use redox_driver_core::driver::ProbeResult;
pub fn run_hotplug_loop(
manager: Arc<Mutex<DeviceManager>>,
poll_interval_ms: u64,
) {
log::info!("hotplug: starting event loop ({} ms poll)", poll_interval_ms);
loop {
thread::sleep(Duration::from_millis(poll_interval_ms));
let events = {
let mut mgr = manager.lock().unwrap();
mgr.enumerate()
};
for event in &events {
match event {
ProbeEvent::ProbeCompleted { device, driver_name, result } => {
match result {
ProbeResult::Bound => {
log::info!("hotplug: bound {} -> {}", device.path, driver_name);
}
ProbeResult::Deferred { reason } => {
log::info!(
"hotplug: deferred {} -> {} ({})",
device.path,
driver_name,
reason
);
}
ProbeResult::Fatal { reason } => {
log::error!(
"hotplug: fatal {} -> {} ({})",
device.path,
driver_name,
reason
);
}
_ => {}
}
}
ProbeEvent::NoDriverFound { device } => {
log::debug!("hotplug: no driver for new device {}", device.path);
}
_ => {}
}
}
let retry_events = {
let mut mgr = manager.lock().unwrap();
mgr.retry_deferred()
};
let mut resolved = 0usize;
for event in &retry_events {
if let ProbeEvent::ProbeCompleted { result, .. } = event {
if *result == ProbeResult::Bound {
resolved += 1;
}
}
}
if resolved > 0 {
log::info!("hotplug: resolved {} deferred probes", resolved);
}
}
}