1) Work correctly if HOME is not /home/user. 2) Support read-write rootfs correctly.
This commit is contained in:
parent
6c25ccb226
commit
df1c6a3cb3
@ -10,6 +10,7 @@ use std::io::Read;
|
|||||||
|
|
||||||
pub struct InitServer {
|
pub struct InitServer {
|
||||||
hostname: String,
|
hostname: String,
|
||||||
|
homedir: String,
|
||||||
cmdline: CmdLine,
|
cmdline: CmdLine,
|
||||||
rootfs: RootFS,
|
rootfs: RootFS,
|
||||||
services: BTreeMap<u32, Service>,
|
services: BTreeMap<u32, Service>,
|
||||||
@ -20,11 +21,14 @@ impl InitServer {
|
|||||||
Self::check_pid1()?;
|
Self::check_pid1()?;
|
||||||
let hostname = hostname.to_string();
|
let hostname = hostname.to_string();
|
||||||
let cmdline = CmdLine::load()?;
|
let cmdline = CmdLine::load()?;
|
||||||
|
let homedir = cmdline.lookup("phinit.home")
|
||||||
|
.unwrap_or("/home/user".to_string());
|
||||||
let rootfs = RootFS::load(&cmdline)?;
|
let rootfs = RootFS::load(&cmdline)?;
|
||||||
let services = BTreeMap::new();
|
let services = BTreeMap::new();
|
||||||
|
|
||||||
Ok(InitServer {
|
Ok(InitServer {
|
||||||
hostname,
|
hostname,
|
||||||
|
homedir,
|
||||||
cmdline,
|
cmdline,
|
||||||
rootfs,
|
rootfs,
|
||||||
services,
|
services,
|
||||||
@ -54,6 +58,11 @@ impl InitServer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn homedir(&self) -> &str {
|
||||||
|
&self.homedir
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn set_loglevel(&self) {
|
pub fn set_loglevel(&self) {
|
||||||
if self.cmdline.has_var("phinit.verbose") {
|
if self.cmdline.has_var("phinit.verbose") {
|
||||||
Logger::set_log_level(LogLevel::Verbose);
|
Logger::set_log_level(LogLevel::Verbose);
|
||||||
@ -90,10 +99,6 @@ impl InitServer {
|
|||||||
mkdir("/run/user/1000")?;
|
mkdir("/run/user/1000")?;
|
||||||
chown("/run/user/1000", 1000,1000)?;
|
chown("/run/user/1000", 1000,1000)?;
|
||||||
|
|
||||||
if Path::new("/dev/wl0").exists() {
|
|
||||||
chmod("/dev/wl0", 0o666)?;
|
|
||||||
mkdir_mode("/tmp/.X11-unix", 0o1777)?;
|
|
||||||
}
|
|
||||||
self.mount_home_if_exists()?;
|
self.mount_home_if_exists()?;
|
||||||
Logger::set_file_output("/run/phinit.log")
|
Logger::set_file_output("/run/phinit.log")
|
||||||
.map_err(Error::OpenLogFailed)?;
|
.map_err(Error::OpenLogFailed)?;
|
||||||
@ -150,11 +155,11 @@ impl InitServer {
|
|||||||
|
|
||||||
pub fn mount_home_if_exists(&self) -> Result<()> {
|
pub fn mount_home_if_exists(&self) -> Result<()> {
|
||||||
if self.has_9p_home() {
|
if self.has_9p_home() {
|
||||||
let homedir = Path::new("/home/user");
|
let homedir = Path::new(self.homedir());
|
||||||
if !homedir.exists() {
|
if !homedir.exists() {
|
||||||
mkdir(homedir)?;
|
mkdir(homedir)?;
|
||||||
}
|
}
|
||||||
mount_9p("home", "/home/user")?;
|
mount_9p("home", self.homedir())?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -169,7 +174,7 @@ impl InitServer {
|
|||||||
let dbus = ServiceLaunch::new("dbus-daemon", "/usr/bin/dbus-daemon")
|
let dbus = ServiceLaunch::new("dbus-daemon", "/usr/bin/dbus-daemon")
|
||||||
.base_environment()
|
.base_environment()
|
||||||
.uidgid(1000,1000)
|
.uidgid(1000,1000)
|
||||||
.env("HOME", "/home/user")
|
.env("HOME", self.homedir())
|
||||||
.env("NO_AT_BRIDGE", "1")
|
.env("NO_AT_BRIDGE", "1")
|
||||||
.env("QT_ACCESSIBILITY", "1")
|
.env("QT_ACCESSIBILITY", "1")
|
||||||
.env("SHELL", "/bin/bash")
|
.env("SHELL", "/bin/bash")
|
||||||
@ -215,7 +220,7 @@ impl InitServer {
|
|||||||
.arg("-X")
|
.arg("-X")
|
||||||
.arg("--x-display=0")
|
.arg("--x-display=0")
|
||||||
.arg("--no-exit-with-child")
|
.arg("--no-exit-with-child")
|
||||||
.arg("--x-auth=/home/user/.Xauthority")
|
.arg(format!("--x-auth={}/.Xauthority", self.homedir()))
|
||||||
.arg("/bin/true")
|
.arg("/bin/true")
|
||||||
.pipe_output()
|
.pipe_output()
|
||||||
.launch()?;
|
.launch()?;
|
||||||
@ -226,8 +231,8 @@ impl InitServer {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_xauth() -> io::Result<()> {
|
fn write_xauth(&self) -> io::Result<()> {
|
||||||
let xauth_path = "/home/user/.Xauthority";
|
let xauth_path = format!("{}/.Xauthority", self.homedir());
|
||||||
|
|
||||||
let mut randbuf = [0; 16];
|
let mut randbuf = [0; 16];
|
||||||
let mut file = fs::File::open("/dev/urandom")?;
|
let mut file = fs::File::open("/dev/urandom")?;
|
||||||
@ -250,20 +255,20 @@ impl InitServer {
|
|||||||
v.extend_from_slice(&[0x00, 0x10]);
|
v.extend_from_slice(&[0x00, 0x10]);
|
||||||
v.extend_from_slice(&randbuf);
|
v.extend_from_slice(&randbuf);
|
||||||
|
|
||||||
fs::write("/home/user/.Xauthority", v)?;
|
fs::write(&xauth_path, v)?;
|
||||||
_chown(xauth_path, 1000, 1000)?;
|
_chown(&xauth_path, 1000, 1000)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn launch_console_shell(&mut self, splash: &'static str) -> Result<()> {
|
pub fn launch_console_shell(&mut self, splash: &'static str) -> Result<()> {
|
||||||
let root = self.cmdline.has_var("phinit.rootshell");
|
let root = self.cmdline.has_var("phinit.rootshell");
|
||||||
let realm = self.cmdline.lookup("phinit.realm");
|
let realm = self.cmdline.lookup("phinit.realm");
|
||||||
let home = if root { "/" } else { "/home/user" };
|
let home = if root { "/".to_string() } else { self.homedir().to_string() };
|
||||||
|
|
||||||
let shell = ServiceLaunch::new_shell(root, home, realm)
|
let shell = ServiceLaunch::new_shell(root, &home, realm)
|
||||||
.launch_with_preexec(move || {
|
.launch_with_preexec(move || {
|
||||||
// set_controlling_tty(0, true)?;
|
// set_controlling_tty(0, true)?;
|
||||||
env::set_current_dir(home)?;
|
env::set_current_dir(&home)?;
|
||||||
println!("{}", splash);
|
println!("{}", splash);
|
||||||
Ok(())
|
Ok(())
|
||||||
})?;
|
})?;
|
||||||
@ -335,7 +340,10 @@ impl RootFS {
|
|||||||
|
|
||||||
fn mount(&self, target: &str) -> Result<()> {
|
fn mount(&self, target: &str) -> Result<()> {
|
||||||
let options = self.rootflags.as_ref().map(|s| s.as_str());
|
let options = self.rootflags.as_ref().map(|s| s.as_str());
|
||||||
let flags = libc::MS_RDONLY;
|
let mut flags = libc::MS_NOATIME;
|
||||||
|
if self.readonly {
|
||||||
|
flags |= libc::MS_RDONLY;
|
||||||
|
}
|
||||||
|
|
||||||
mount(&self.root, target, &self.fstype, flags, options)
|
mount(&self.root, target, &self.fstype, flags, options)
|
||||||
.map_err(|e| Error::RootFsMount(self.root.clone(), e))
|
.map_err(|e| Error::RootFsMount(self.root.clone(), e))
|
||||||
|
@ -30,6 +30,7 @@ use std::sync::Arc;
|
|||||||
use std::sync::atomic::AtomicBool;
|
use std::sync::atomic::AtomicBool;
|
||||||
use termios::Termios;
|
use termios::Termios;
|
||||||
use crate::devices::SyntheticFS;
|
use crate::devices::SyntheticFS;
|
||||||
|
use crate::disk::DiskImage;
|
||||||
|
|
||||||
pub struct Vm {
|
pub struct Vm {
|
||||||
_config: VmConfig,
|
_config: VmConfig,
|
||||||
@ -84,20 +85,34 @@ impl Vm {
|
|||||||
devices::VirtioWayland::create(virtio)?;
|
devices::VirtioWayland::create(virtio)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut block_root = false;
|
let homedir = config.homedir();
|
||||||
|
devices::VirtioP9::create(virtio, "home", homedir, false, false)?;
|
||||||
|
if homedir != "/home/user" {
|
||||||
|
cmdline.push_set_val("phinit.home", homedir);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut block_root = None;
|
||||||
|
|
||||||
for mut disk in config.get_realmfs_images() {
|
for mut disk in config.get_realmfs_images() {
|
||||||
disk.open().map_err(ErrorKind::DiskImageOpen)?;
|
disk.open().map_err(ErrorKind::DiskImageOpen)?;
|
||||||
|
if block_root == None {
|
||||||
|
block_root = Some(disk.read_only());
|
||||||
|
}
|
||||||
devices::VirtioBlock::create(virtio, disk)?;
|
devices::VirtioBlock::create(virtio, disk)?;
|
||||||
block_root = true;
|
|
||||||
}
|
|
||||||
for mut disk in config.get_raw_disk_images() {
|
|
||||||
disk.open().map_err(ErrorKind::DiskImageOpen)?;
|
|
||||||
devices::VirtioBlock::create(virtio, disk)?;
|
|
||||||
block_root = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if block_root {
|
for mut disk in config.get_raw_disk_images() {
|
||||||
|
disk.open().map_err(ErrorKind::DiskImageOpen)?;
|
||||||
|
if block_root == None {
|
||||||
|
block_root = Some(disk.read_only());
|
||||||
|
}
|
||||||
|
devices::VirtioBlock::create(virtio, disk)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(read_only) = block_root {
|
||||||
|
if !read_only {
|
||||||
|
cmdline.push("phinit.root_rw");
|
||||||
|
}
|
||||||
cmdline.push("phinit.root=/dev/vda");
|
cmdline.push("phinit.root=/dev/vda");
|
||||||
cmdline.push("phinit.rootfstype=ext4");
|
cmdline.push("phinit.rootfstype=ext4");
|
||||||
} else {
|
} else {
|
||||||
@ -171,9 +186,6 @@ impl Vm {
|
|||||||
let mut virtio = VirtioBus::new(memory.clone(), io_dispatch.clone(), memory.kvm().clone());
|
let mut virtio = VirtioBus::new(memory.clone(), io_dispatch.clone(), memory.kvm().clone());
|
||||||
Self::setup_virtio(&mut config, &mut cmdline, &mut virtio)?;
|
Self::setup_virtio(&mut config, &mut cmdline, &mut virtio)?;
|
||||||
|
|
||||||
if config.launch_systemd() {
|
|
||||||
cmdline.push("phinit.run_systemd");
|
|
||||||
}
|
|
||||||
if let Some(init_cmd) = config.get_init_cmdline() {
|
if let Some(init_cmd) = config.get_init_cmdline() {
|
||||||
cmdline.push_set_val("init", init_cmd);
|
cmdline.push_set_val("init", init_cmd);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user