From bcfb36633fd2d3c81031249476ec30806cef9669 Mon Sep 17 00:00:00 2001 From: vasilito Date: Fri, 31 Jul 2026 03:23:53 +0900 Subject: [PATCH] boot cleanup: netctl --boot, keymapd missing-dir, dm typo, pci errno, firmware-loader stub MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - redbear-netctl: route --boot (and other manual commands) around clap so CommonArgs::parse no longer aborts with 'unexpected argument --boot' (12_netctl.service boot-time profile application was failing). - redbear-keymapd: a missing /etc/keymaps is normal on mini (built-in keymaps cover the console) — log INFO, not ERROR, on NotFound. - driver-manager: fix 'options loadeds' plural typo; log read_dir errno on PCI enumeration failure instead of an opaque IoError. - redbear-mini: ship a 05_firmware-loader.service stub so the bluetooth units' weak dep resolves (was 'unit not found' x2 per boot). --- config/redbear-mini.toml | 15 ++++++++++ .../redox-driver-pci/source/Cargo.toml | 1 + .../redox-driver-pci/source/src/bus.rs | 8 +++++- .../system/driver-manager/source/src/main.rs | 5 ++-- .../system/redbear-keymapd/source/src/main.rs | 18 +++++++++--- .../system/redbear-netctl/source/src/main.rs | 28 ++++++++++++++++++- 6 files changed, 67 insertions(+), 8 deletions(-) diff --git a/config/redbear-mini.toml b/config/redbear-mini.toml index afb1cb0b13..52bd1b0ddc 100644 --- a/config/redbear-mini.toml +++ b/config/redbear-mini.toml @@ -503,6 +503,21 @@ args = ["--hotplug"] type = "oneshot_async" """ +# Stub: mini intentionally ships no firmware-loader (no firmware blobs except +# iwlwifi), but the bluetooth units (10_btusb / 11_btctl) declare a weak +# dependency on this unit. Without a stub, init logs +# "unit 05_firmware-loader.service not found" twice per boot. +[[files]] +path = "/etc/init.d/05_firmware-loader.service" +data = """ +[unit] +description = "Firmware loader (stub: no firmware payload on live-mini)" + +[service] +cmd = "true" +type = "oneshot" +""" + [[files]] path = "/etc/init.d/00_ipcd.service" data = """ diff --git a/local/recipes/drivers/redox-driver-pci/source/Cargo.toml b/local/recipes/drivers/redox-driver-pci/source/Cargo.toml index 3df2837de5..a4b1035594 100644 --- a/local/recipes/drivers/redox-driver-pci/source/Cargo.toml +++ b/local/recipes/drivers/redox-driver-pci/source/Cargo.toml @@ -5,6 +5,7 @@ edition = "2024" description = "PCI bus backend for redox-driver-core" [dependencies] +log = "0.4" redox-driver-core = { path = "../../redox-driver-core/source" } redox_syscall = { path = "../../../../../local/sources/syscall" } diff --git a/local/recipes/drivers/redox-driver-pci/source/src/bus.rs b/local/recipes/drivers/redox-driver-pci/source/src/bus.rs index ff3d184436..baca66e7a1 100644 --- a/local/recipes/drivers/redox-driver-pci/source/src/bus.rs +++ b/local/recipes/drivers/redox-driver-pci/source/src/bus.rs @@ -29,7 +29,13 @@ impl Bus for PciBus { } fn enumerate_devices(&self) -> Result, BusError> { - let dir = fs::read_dir(&self.pci_root).map_err(|_| BusError::IoError)?; + // Log the underlying io::Error: BusError::IoError alone hides the + // errno, which made the post-switchroot "enumeration failed: IoError" + // storm undiagnosable from boot logs. + let dir = fs::read_dir(&self.pci_root).map_err(|e| { + log::error!("pci: read_dir {} failed: {e}", self.pci_root); + BusError::IoError + })?; let mut devices = Vec::new(); diff --git a/local/recipes/system/driver-manager/source/src/main.rs b/local/recipes/system/driver-manager/source/src/main.rs index 7738089864..7027aff535 100644 --- a/local/recipes/system/driver-manager/source/src/main.rs +++ b/local/recipes/system/driver-manager/source/src/main.rs @@ -374,11 +374,12 @@ fn main() { } } }; + // NB: the plural-s used to be appended AFTER "loaded", producing the + // boot-log typo "0 driver(s) with options loadeds". log::info!( - "policy: {} driver(s) with options loaded{}{}", + "policy: {} driver(s) with options loaded{}", driver_options.len(), if policy_disabled { " (SUPPRESSED)" } else { "" }, - if driver_options.len() == 1 { "" } else { "s" } ); // N9: capture the SharedDriverOptions so the SIGHUP worker can // re-read it on operator reload. main.rs owns the live reference; diff --git a/local/recipes/system/redbear-keymapd/source/src/main.rs b/local/recipes/system/redbear-keymapd/source/src/main.rs index 7e17c935bc..bea77c05d6 100644 --- a/local/recipes/system/redbear-keymapd/source/src/main.rs +++ b/local/recipes/system/redbear-keymapd/source/src/main.rs @@ -25,10 +25,20 @@ fn main() { Err(_) => "/etc/keymaps".to_string(), }; if let Err(e) = scheme.load_from_dir(&keymap_dir) { - log_msg( - "ERROR", - &format!("failed to load keymaps from {}: {}", keymap_dir, e), - ); + // A missing keymap directory is the NORMAL state on minimal images + // (mini ships no /etc/keymaps; the built-in keymaps loaded above + // cover the console). Only a present-but-unreadable dir is an error. + if e.kind() == std::io::ErrorKind::NotFound { + log_msg( + "INFO", + &format!("no keymap dir at {}; using built-in keymaps", keymap_dir), + ); + } else { + log_msg( + "ERROR", + &format!("failed to load keymaps from {}: {}", keymap_dir, e), + ); + } } if let Ok(xkb_root) = env::var("XKB_CONFIG_ROOT") { diff --git a/local/recipes/system/redbear-netctl/source/src/main.rs b/local/recipes/system/redbear-netctl/source/src/main.rs index 683458729b..59c723a890 100644 --- a/local/recipes/system/redbear-netctl/source/src/main.rs +++ b/local/recipes/system/redbear-netctl/source/src/main.rs @@ -76,7 +76,33 @@ fn main() { // --help and --version automatically and prints to stdout, then exits. // For netctl specifically, the subcommands (list, status, scan, etc.) // are not clap subcommands, so allow_external_subcommands is enabled. - let common = CommonArgs::parse(); + // + // `--boot` (used by /etc/init.d/12_netctl.service) and the other manual + // commands must NOT go through clap: allow_external_subcommands covers + // unknown bare subcommands but a leading unknown FLAG like `--boot` makes + // clap abort with "unexpected argument" before run() ever sees it — which + // broke boot-time profile application. Detect manual-command invocations + // and give clap only the program name (defaults) in that case. + let manual_cmd = matches!( + std::env::args().nth(1).as_deref(), + Some( + "--boot" + | "list" + | "status" + | "scan" + | "retry" + | "start" + | "stop" + | "enable" + | "disable" + | "is-enabled" + ) + ); + let common = if manual_cmd { + CommonArgs::parse_from(["redbear-netctl"]) + } else { + CommonArgs::parse() + }; common.init_logging("redbear-netctl"); // The existing manual parser handles netctl-specific subcommands.