init: Switch root upon reaching initfs.target
This commit is contained in:
@@ -1,6 +0,0 @@
|
||||
[unit]
|
||||
requires_weak = ["50_rootfs.service"]
|
||||
|
||||
[switchroot]
|
||||
prefix = "/usr"
|
||||
etcdir = "/etc"
|
||||
@@ -0,0 +1,3 @@
|
||||
[unit]
|
||||
description = "initfs finalized"
|
||||
requires_weak = ["50_rootfs.service"]
|
||||
+17
-15
@@ -63,6 +63,12 @@ impl SwitchRoot {
|
||||
unit_store: &mut UnitStore,
|
||||
config: &mut InitConfig,
|
||||
) {
|
||||
eprintln!(
|
||||
"init: switchroot to {} {}",
|
||||
self.prefix.display(),
|
||||
self.etcdir.display()
|
||||
);
|
||||
|
||||
config
|
||||
.envs
|
||||
.insert("PATH".to_owned(), self.prefix.join("bin").into_os_string());
|
||||
@@ -84,12 +90,7 @@ impl SwitchRoot {
|
||||
}
|
||||
}
|
||||
|
||||
fn run(
|
||||
unit: &UnitId,
|
||||
pending_units: &mut VecDeque<UnitId>,
|
||||
unit_store: &mut UnitStore,
|
||||
config: &mut InitConfig,
|
||||
) -> Result<()> {
|
||||
fn run(unit: &UnitId, unit_store: &mut UnitStore, config: &mut InitConfig) -> Result<()> {
|
||||
let unit = unit_store.unit_mut(unit);
|
||||
|
||||
match &unit.kind {
|
||||
@@ -118,14 +119,6 @@ fn run(
|
||||
);
|
||||
}
|
||||
}
|
||||
unit::UnitKind::SwitchRoot { switchroot } => {
|
||||
eprintln!(
|
||||
"init: switchroot to {} {}",
|
||||
switchroot.prefix.display(),
|
||||
switchroot.etcdir.display()
|
||||
);
|
||||
switchroot.clone().apply(pending_units, unit_store, config);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -170,6 +163,7 @@ fn main() {
|
||||
}
|
||||
|
||||
let runtime_target = UnitId("00_runtime.target".to_owned());
|
||||
let initfs_target = UnitId("90_initfs.target".to_owned());
|
||||
|
||||
'a: while let Some(unit) = pending_units.pop_front() {
|
||||
if let Some(condition_architecture) = &unit_store.unit(&unit).info.condition_architecture {
|
||||
@@ -201,9 +195,17 @@ fn main() {
|
||||
}
|
||||
}
|
||||
|
||||
if let Err(err) = run(&unit, &mut pending_units, &mut unit_store, &mut init_config) {
|
||||
if let Err(err) = run(&unit, &mut unit_store, &mut init_config) {
|
||||
eprintln!("init: failed to run {}: {}", unit.0, err);
|
||||
}
|
||||
|
||||
if unit == initfs_target {
|
||||
SwitchRoot {
|
||||
prefix: PathBuf::from("/usr"),
|
||||
etcdir: PathBuf::from("/etc"),
|
||||
}
|
||||
.apply(&mut pending_units, &mut unit_store, &mut init_config);
|
||||
}
|
||||
}
|
||||
|
||||
libredox::call::setrens(0, 0).expect("init: failed to enter null namespace");
|
||||
|
||||
@@ -4,7 +4,6 @@ use std::{fs, io};
|
||||
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::SwitchRoot;
|
||||
use crate::script::{Command, Script};
|
||||
use crate::service::Service;
|
||||
|
||||
@@ -97,7 +96,6 @@ pub enum UnitKind {
|
||||
LegacyScript { script: Script },
|
||||
Service { service: Service },
|
||||
Target {},
|
||||
SwitchRoot { switchroot: SwitchRoot },
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
@@ -113,13 +111,6 @@ struct SerializedTarget {
|
||||
unit: UnitInfo,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
struct SerializedSwitchRoot {
|
||||
unit: UnitInfo,
|
||||
switchroot: SwitchRoot,
|
||||
}
|
||||
|
||||
impl Unit {
|
||||
pub fn from_file(config_path: &Path) -> io::Result<(Self, Vec<String>)> {
|
||||
let name = UnitId(
|
||||
@@ -173,17 +164,6 @@ impl Unit {
|
||||
.map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err))?;
|
||||
(target.unit, UnitKind::Target {}, vec![])
|
||||
}
|
||||
Some("switchroot") => {
|
||||
let switchroot: SerializedSwitchRoot = toml::from_str(&config)
|
||||
.map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err))?;
|
||||
(
|
||||
switchroot.unit,
|
||||
UnitKind::SwitchRoot {
|
||||
switchroot: switchroot.switchroot,
|
||||
},
|
||||
vec![],
|
||||
)
|
||||
}
|
||||
Some(_) => return Err(io::Error::other("invalid file extension")),
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user