diff --git a/ph-init/src/init.rs b/ph-init/src/init.rs index 933e90f..6cc0c5a 100644 --- a/ph-init/src/init.rs +++ b/ph-init/src/init.rs @@ -10,6 +10,7 @@ use std::io::Read; pub struct InitServer { hostname: String, + homedir: String, cmdline: CmdLine, rootfs: RootFS, services: BTreeMap, @@ -20,11 +21,14 @@ impl InitServer { Self::check_pid1()?; let hostname = hostname.to_string(); let cmdline = CmdLine::load()?; + let homedir = cmdline.lookup("phinit.home") + .unwrap_or("/home/user".to_string()); let rootfs = RootFS::load(&cmdline)?; let services = BTreeMap::new(); Ok(InitServer { hostname, + homedir, cmdline, rootfs, services, @@ -54,6 +58,11 @@ impl InitServer { } } + fn homedir(&self) -> &str { + &self.homedir + } + + pub fn set_loglevel(&self) { if self.cmdline.has_var("phinit.verbose") { Logger::set_log_level(LogLevel::Verbose); @@ -90,10 +99,6 @@ impl InitServer { mkdir("/run/user/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()?; Logger::set_file_output("/run/phinit.log") .map_err(Error::OpenLogFailed)?; @@ -150,11 +155,11 @@ impl InitServer { pub fn mount_home_if_exists(&self) -> Result<()> { if self.has_9p_home() { - let homedir = Path::new("/home/user"); + let homedir = Path::new(self.homedir()); if !homedir.exists() { mkdir(homedir)?; } - mount_9p("home", "/home/user")?; + mount_9p("home", self.homedir())?; } Ok(()) } @@ -169,7 +174,7 @@ impl InitServer { let dbus = ServiceLaunch::new("dbus-daemon", "/usr/bin/dbus-daemon") .base_environment() .uidgid(1000,1000) - .env("HOME", "/home/user") + .env("HOME", self.homedir()) .env("NO_AT_BRIDGE", "1") .env("QT_ACCESSIBILITY", "1") .env("SHELL", "/bin/bash") @@ -215,7 +220,7 @@ impl InitServer { .arg("-X") .arg("--x-display=0") .arg("--no-exit-with-child") - .arg("--x-auth=/home/user/.Xauthority") + .arg(format!("--x-auth={}/.Xauthority", self.homedir())) .arg("/bin/true") .pipe_output() .launch()?; @@ -226,8 +231,8 @@ impl InitServer { Ok(()) } - fn write_xauth() -> io::Result<()> { - let xauth_path = "/home/user/.Xauthority"; + fn write_xauth(&self) -> io::Result<()> { + let xauth_path = format!("{}/.Xauthority", self.homedir()); let mut randbuf = [0; 16]; let mut file = fs::File::open("/dev/urandom")?; @@ -250,20 +255,20 @@ impl InitServer { v.extend_from_slice(&[0x00, 0x10]); v.extend_from_slice(&randbuf); - fs::write("/home/user/.Xauthority", v)?; - _chown(xauth_path, 1000, 1000)?; + fs::write(&xauth_path, v)?; + _chown(&xauth_path, 1000, 1000)?; Ok(()) } pub fn launch_console_shell(&mut self, splash: &'static str) -> Result<()> { let root = self.cmdline.has_var("phinit.rootshell"); 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 || { // set_controlling_tty(0, true)?; - env::set_current_dir(home)?; + env::set_current_dir(&home)?; println!("{}", splash); Ok(()) })?; @@ -335,7 +340,10 @@ impl RootFS { fn mount(&self, target: &str) -> Result<()> { 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) .map_err(|e| Error::RootFsMount(self.root.clone(), e)) diff --git a/src/vm/mod.rs b/src/vm/mod.rs index fed123e..b9b7aa9 100644 --- a/src/vm/mod.rs +++ b/src/vm/mod.rs @@ -30,6 +30,7 @@ use std::sync::Arc; use std::sync::atomic::AtomicBool; use termios::Termios; use crate::devices::SyntheticFS; +use crate::disk::DiskImage; pub struct Vm { _config: VmConfig, @@ -84,20 +85,34 @@ impl Vm { 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() { disk.open().map_err(ErrorKind::DiskImageOpen)?; + if block_root == None { + block_root = Some(disk.read_only()); + } 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.rootfstype=ext4"); } else { @@ -171,9 +186,6 @@ impl Vm { let mut virtio = VirtioBus::new(memory.clone(), io_dispatch.clone(), memory.kvm().clone()); 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() { cmdline.push_set_val("init", init_cmd); }