diff --git a/init/src/main.rs b/init/src/main.rs index a5e22710d7..1243be1cbb 100644 --- a/init/src/main.rs +++ b/init/src/main.rs @@ -83,11 +83,18 @@ impl SwitchRoot { self.etcdir.join("init.d"), ]; - let mut errors = vec![]; + if self.prefix == Path::new("/scheme/initfs") { + let unit_id = UnitId("00_runtime.target".to_owned()); + let mut errors = vec![]; + let loaded_units = unit_store.load_units(unit_id.clone(), &mut errors); + pending_units.extend(loaded_units); + for error in errors { + eprintln!("init: {error}"); + } + unit_store.set_runtime_target(unit_id); + } - let loaded_units = - unit_store.load_units(UnitId("00_runtime.target".to_owned()), &mut errors); - pending_units.extend(loaded_units); + let mut errors = vec![]; if let Some(target) = self.target { let loaded_units = unit_store.load_units(target, &mut errors); @@ -187,7 +194,6 @@ fn main() { let mut unit_store = UnitStore::new(); let mut pending_units = VecDeque::new(); - let runtime_target = UnitId("00_runtime.target".to_owned()); let initfs_target = UnitId("90_initfs.target".to_owned()); SwitchRoot { @@ -221,12 +227,6 @@ fn main() { continue 'a; } } - if unit_store.unit(&unit).info.default_dependencies { - if pending_units.contains(&runtime_target) { - pending_units.push_back(unit); - continue 'a; - } - } for dep in &unit_store.unit(&unit).info.requires_weak { if pending_units.contains(dep) { pending_units.push_back(unit); diff --git a/init/src/unit.rs b/init/src/unit.rs index 9be292e5d6..753fbe8e97 100644 --- a/init/src/unit.rs +++ b/init/src/unit.rs @@ -10,6 +10,7 @@ use crate::service::Service; pub struct UnitStore { pub config_dirs: Vec, units: BTreeMap, + runtime_target: Option, } impl UnitStore { @@ -17,9 +18,16 @@ impl UnitStore { UnitStore { config_dirs: vec![], units: BTreeMap::new(), + runtime_target: None, } } + pub fn set_runtime_target(&mut self, unit_id: UnitId) { + assert!(self.runtime_target.is_none()); + assert!(self.units.contains_key(&unit_id)); + self.runtime_target = Some(unit_id); + } + fn load_single_unit(&mut self, unit_id: UnitId, errors: &mut Vec) -> Option { let (filename, instance) = if let Some((base_service, rest)) = unit_id.0.split_once('@') { let Some((instance, ext)) = rest.rsplit_once('.') else { @@ -42,13 +50,25 @@ impl UnitStore { return None; }; - let unit = match Unit::from_file(unit_id.clone(), &path, instance, errors) { + let mut unit = match Unit::from_file(unit_id.clone(), &path, instance, errors) { Ok(unit) => unit, Err(err) => { errors.push(format!("{}: {err}", path.display())); return None; } }; + + if unit.info.default_dependencies { + if let Some(runtime_target) = self.runtime_target.clone() { + unit.info.requires_weak.push(runtime_target); + } else { + errors.push(format!( + "{}: dependency of the runtime target must have default dependencies disabled", + path.display(), + )); + } + } + self.units.insert(unit_id.clone(), unit); Some(unit_id)