From 1b50d1b5432f9505ebf9d32f7d6228bf24314264 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 5 Apr 2026 17:31:16 +0200 Subject: [PATCH] init: Inline SwitchRoot --- init/src/main.rs | 131 ++++++++++++++++++++++------------------------- 1 file changed, 60 insertions(+), 71 deletions(-) diff --git a/init/src/main.rs b/init/src/main.rs index ae4ec0f7bd..16c2b3a7ca 100644 --- a/init/src/main.rs +++ b/init/src/main.rs @@ -2,7 +2,7 @@ use std::collections::BTreeMap; use std::env; use std::ffi::OsString; use std::io::Result; -use std::path::{Path, PathBuf}; +use std::path::Path; use libredox::flag::{O_RDONLY, O_WRONLY}; @@ -50,65 +50,22 @@ impl InitConfig { } } -struct SwitchRoot { - prefix: PathBuf, - etcdir: PathBuf, - target: Option, -} +fn switch_root(unit_store: &mut UnitStore, config: &mut InitConfig, prefix: &Path, etcdir: &Path) { + eprintln!( + "init: switchroot to {} {}", + prefix.display(), + etcdir.display() + ); -impl SwitchRoot { - fn apply(self, scheduler: &mut Scheduler, unit_store: &mut UnitStore, config: &mut InitConfig) { - eprintln!( - "init: switchroot to {} {}", - self.prefix.display(), - self.etcdir.display() - ); + config + .envs + .insert("PATH".to_owned(), prefix.join("bin").into_os_string()); + config.envs.insert( + "LD_LIBRARY_PATH".to_owned(), + prefix.join("lib").into_os_string(), + ); - config - .envs - .insert("PATH".to_owned(), self.prefix.join("bin").into_os_string()); - config.envs.insert( - "LD_LIBRARY_PATH".to_owned(), - self.prefix.join("lib").into_os_string(), - ); - - unit_store.config_dirs = vec![ - self.prefix.join("lib").join("init.d"), - self.etcdir.join("init.d"), - ]; - - if self.prefix == Path::new("/scheme/initfs") { - let unit_id = UnitId("00_runtime.target".to_owned()); - scheduler.schedule_start_and_report_errors(unit_store, unit_id.clone()); - unit_store.set_runtime_target(unit_id); - } - - if let Some(target) = self.target { - scheduler.schedule_start_and_report_errors(unit_store, target); - } else { - let entries = match config::config_for_dirs(&unit_store.config_dirs) { - Ok(entries) => entries, - Err(err) => { - eprintln!( - "init: failed to read configs from {}: {err}", - unit_store - .config_dirs - .iter() - .map(|dir| dir.display().to_string()) - .collect::>() - .join(", ") - ); - return; - } - }; - for entry in entries { - scheduler.schedule_start_and_report_errors( - unit_store, - UnitId(entry.file_name().unwrap().to_str().unwrap().to_owned()), - ); - } - } - } + unit_store.config_dirs = vec![prefix.join("lib").join("init.d"), etcdir.join("init.d")]; } fn run(unit: &mut Unit, config: &mut InitConfig) -> Result<()> { @@ -173,12 +130,19 @@ fn main() { let mut unit_store = UnitStore::new(); let mut scheduler = Scheduler::new(); - SwitchRoot { - prefix: Path::new("/scheme/initfs").to_owned(), - etcdir: Path::new("/scheme/initfs/etc").to_owned(), - target: Some(UnitId("90_initfs.target".to_owned())), - } - .apply(&mut scheduler, &mut unit_store, &mut init_config); + switch_root( + &mut unit_store, + &mut init_config, + Path::new("/scheme/initfs"), + Path::new("/scheme/initfs/etc"), + ); + + let runtime_target = UnitId("00_runtime.target".to_owned()); + scheduler.schedule_start_and_report_errors(&mut unit_store, runtime_target.clone()); + unit_store.set_runtime_target(runtime_target); + + scheduler + .schedule_start_and_report_errors(&mut unit_store, UnitId("90_initfs.target".to_owned())); let mut command = std::process::Command::new("logd"); command.env_clear().envs(&init_config.envs); @@ -189,13 +153,38 @@ fn main() { scheduler.step(&mut unit_store, &mut init_config); - SwitchRoot { - prefix: PathBuf::from("/usr"), - etcdir: PathBuf::from("/etc"), - // FIXME make target non-optional once there is a multi-user.target unit - target: None, //UnitId("multi-user.target".to_owned()), - } - .apply(&mut scheduler, &mut unit_store, &mut init_config); + switch_root( + &mut unit_store, + &mut init_config, + Path::new("/usr"), + Path::new("/etc"), + ); + { + // FIXME introduce multi-user.target unit and replace the config dir iteration + // scheduler.schedule_start_and_report_errors(&mut unit_store, UnitId("multi-user.target".to_owned())); + + let entries = match config::config_for_dirs(&unit_store.config_dirs) { + Ok(entries) => entries, + Err(err) => { + eprintln!( + "init: failed to read configs from {}: {err}", + unit_store + .config_dirs + .iter() + .map(|dir| dir.display().to_string()) + .collect::>() + .join(", ") + ); + return; + } + }; + for entry in entries { + scheduler.schedule_start_and_report_errors( + &mut unit_store, + UnitId(entry.file_name().unwrap().to_str().unwrap().to_owned()), + ); + } + }; scheduler.step(&mut unit_store, &mut init_config);