not used anymore

This commit is contained in:
Bruce Leidl 2019-09-26 22:31:14 -04:00
parent 9f2acb07f8
commit df4ab4c0c9

View File

@ -1,294 +0,0 @@
use crate::cmdline::CmdLine;
use crate::error::{Result,Error};
use std::{io, fs, process, env};
use crate::sys::{mount_procfs, mount_tmpfs, mkdir, mount_devpts, create_directories, mount_overlay, move_mount, pivot_root, umount, mount_sysfs, mount_devtmpfs, mount, mount_9p, waitpid, reboot, sethostname, setsid, set_controlling_tty, getpid, chmod, chown};
use std::path::Path;
use std::process::{Child, Command, Stdio};
use std::cell::RefCell;
use std::os::unix::process::CommandExt;
pub struct Setup {
hostname: String,
cmdline: CmdLine,
rootfs: RootFS,
splash: RefCell<Option<String>>,
}
impl Setup {
pub fn create(hostname: &str) -> Result<Self> {
let hostname = hostname.to_string();
let cmdline = CmdLine::load()?;
let rootfs = RootFS::load(&cmdline)?;
let splash = RefCell::new(None);
Ok(Setup{ hostname, cmdline, rootfs, splash })
}
pub fn check_pid1() -> Result<()> {
if getpid() == 1 {
Ok(())
} else {
Err(Error::Pid1)
}
}
pub fn setup_rootfs(&self) -> Result<()> {
mount_devtmpfs()?;
mount_tmpfs("/tmp")?;
mkdir("/tmp/sysroot")?;
if self.rootfs.read_only() {
self.setup_readonly_root()?;
} else {
self.setup_writeable_root()?;
}
umount("/opt/ph/tmp")?;
umount("/opt/ph/proc")?;
umount("/opt/ph/dev")?;
mount_sysfs()?;
mount_procfs()?;
mount_devtmpfs()?;
mount_devpts()?;
mount_tmpfs("/run")?;
mkdir("/run/user")?;
mkdir("/run/user/1000")?;
chown("/run/user/1000", 1000,1000)?;
if Path::new("/dev/wl0").exists() {
chmod("/dev/wl0", 0o666)?;
}
Ok(())
}
fn setup_readonly_root(&self) -> Result<()> {
create_directories(&[
"/tmp/ro",
"/tmp/rw",
"/tmp/rw/upper",
"/tmp/rw/work",
])?;
mount_tmpfs("/tmp/rw")?;
create_directories(&["/tmp/rw/upper", "/tmp/rw/work"])?;
self.rootfs.mount("/tmp/ro")?;
mount_overlay("/tmp/sysroot",
"lowerdir=/tmp/ro,upperdir=/tmp/rw/upper,workdir=/tmp/rw/work")?;
create_directories(&[
"/tmp/sysroot/ro",
"/tmp/sysroot/rw"
])?;
move_mount("/tmp/ro", "/tmp/sysroot/ro")?;
move_mount("/tmp/rw", "/tmp/sysroot/rw")?;
let toolsdir = Path::new("/tmp/sysroot/opt/ph");
if !toolsdir.exists() {
fs::create_dir_all(toolsdir)
.map_err(|e| Error::MkDir(String::from("/tmp/sysroot/opt/ph"), e))?;
}
pivot_root("/tmp/sysroot", "/tmp/sysroot/opt/ph")?;
fs::write("/etc/hosts", format!("127.0.0.1 {} localhost", self.hostname))
.map_err(Error::WriteEtcHosts)?;
Ok(())
}
fn setup_writeable_root(&self) -> Result<()> {
self.rootfs.mount("/tmp/sysroot")?;
let toolsdir = Path::new("/tmp/sysroot/opt/ph");
if !toolsdir.exists() {
fs::create_dir_all(toolsdir)
.map_err(|e| Error::MkDir(String::from("/tmp/sysroot/opt/ph"), e))?;
}
pivot_root("/tmp/sysroot", "/tmp/sysroot/opt/ph")?;
Ok(())
}
pub fn has_9p_home(&self) -> bool {
// XXX
// /sys/bus/virtio/drivers/9pnet_virtio/virtio*/mount_tag
true
}
pub fn mount_home_if_exists(&self) -> Result<()> {
if self.has_9p_home() {
let homedir = Path::new("/home/user");
if !homedir.exists() {
mkdir(homedir)?;
}
mount_9p("home", "/home/user")?;
}
Ok(())
}
fn handle_waitpid_err(err: io::Error) -> ! {
if let Some(errno) = err.raw_os_error() {
if errno == libc::ECHILD {
if let Err(err) = reboot(libc::RB_AUTOBOOT) {
println!("reboot() failed: {:?}", err);
process::exit(-1);
}
}
}
println!("error on waitpid: {:?}", err);
process::exit(-1);
}
fn wait_for_child(&self) -> u32 {
match waitpid(-1, 0) {
Ok((pid,_status)) => pid as u32,
Err(err) => Self::handle_waitpid_err(err)
}
}
pub fn set_splash(&self, splash: &str) {
self.splash.borrow_mut().replace(splash.to_string());
}
pub fn launch_sommelier(&self) -> Option<Child> {
println!("attempting to launch sommelier");
let result = Command::new("/opt/ph/usr/bin/sommelier")
.env("XDG_RUNTIME_DIR", "/run/user/1000")
.arg("--master")
.uid(1000)
.gid(1000)
.spawn();
match result {
Ok(child) => Some(child),
Err(e) => {
println!("sommelier didn't launch: {}", e);
None
}
}
}
pub fn launch_dbus(&self) -> Option<Child> {
println!("attempting to launch dbus");
let result = Command::new("/usr/bin/dbus-daemon")
.arg("--session")
.arg("--print-address")
.arg("--nosyslog")
.arg("--address=unix:path=/run/user/1000/bus")
.env("LANG", "en_US.UTF8")
.env("HOME", "/home/user") // XXX
.env("XDG_RUNTIME_DIR", "/run/user/1000")
.env("NO_AT_BRIDGE", "1")
.env("GNOME_DESKTOP_SESSION_ID", "this-is-deprecated")
.env("XDG_SESSION_TYPE", "wayland")
.env("WAYLAND_DISPLAY", "wayland-0")
.uid(1000)
.gid(1000)
.spawn();
match result {
Ok(child) => Some(child),
Err(e) => {
println!("dbus-daemon didn't launch: {}", e);
None
}
}
}
fn run_shell(&self, as_root: bool) -> io::Result<Child> {
let home = if as_root {
"/"
} else {
"/home/user"
};
env::set_current_dir(home)?;
unsafe {
let mut cmd = Command::new("/bin/bash");
cmd.env_clear()
.env("GNOME_DESKTOP_SESSION_ID", "this-is-deprecated")
.env("XDG_RUNTIME_DIR", "/run/user/1000")
.env("HOME", home)
.env("NO_AT_BRIDGE", "1")
.env("LANG", "en_US.UTF8")
.env("DISPLAY", ":0")
.env("XDG_SESSION_TYPE", "wayland")
.env("GDK_BACKEND", "wayland")
.env("WAYLAND_DISPLAY", "wayland-0")
.env("DBUS_SESSION_BUS_ADDRESS","unix:path=/run/user/1000/bus")
.env("SHELL", "/bin/bash")
.env("TERM", "xterm-256color")
.arg("--login")
.stdin(Stdio::inherit())
.stdout(Stdio::inherit())
.stderr(Stdio::inherit());
if let Some(s) = self.splash.borrow().as_ref() {
let splash = s.to_string();
cmd.pre_exec(move || {
println!("{}", splash);
Ok(())
});
}
if let Some(realm) = self.cmdline.lookup("phinit.realm") {
cmd.env("REALM_NAME", realm);
}
if !as_root {
cmd.uid(1000);
cmd.gid(1000);
}
cmd.spawn()
}
}
pub fn launch_shell(&self) -> Result<()> {
let as_root = self.cmdline.has_var("phinit.rootshell");
sethostname("airwolf")?;
setsid()?;
set_controlling_tty(0, true)?;
let _child = self.run_shell(as_root)
.map_err(Error::RunShell)?;
let shell_pid = _child.id();
loop {
if self.wait_for_child() == shell_pid {
if let Err(err) = reboot(libc::RB_AUTOBOOT) {
println!("reboot() failed: {:?}", err);
process::exit(-1);
}
}
}
}
}
struct RootFS {
root: String,
fstype: String,
rootflags: Option<String>,
readonly: bool,
}
impl RootFS {
fn load(cmdline: &CmdLine) -> Result<Self> {
let root = cmdline.lookup("phinit.root")
.ok_or(Error::NoRootVar)?;
let fstype = cmdline.lookup("phinit.rootfstype")
.ok_or(Error::NoRootFsVar)?;
let rootflags = cmdline.lookup("phinit.rootflags");
let readonly = !cmdline.has_var("phinit.root_rw");
Ok(RootFS {
root, fstype, rootflags, readonly
})
}
fn read_only(&self) -> bool {
self.readonly
}
fn mount(&self, target: &str) -> Result<()> {
let options = self.rootflags.as_ref().map(|s| s.as_str());
let flags = libc::MS_RDONLY;
mount(&self.root, target, &self.fstype, flags, options)
.map_err(|e| Error::RootFsMount(self.root.clone(), e))
}
}