From f4e2d887bca591d5c254d200a7c57a88dcc5d4a5 Mon Sep 17 00:00:00 2001 From: darkgallium Date: Sat, 20 Jun 2020 21:49:21 +0200 Subject: [PATCH] fix signals, add shutdown command --- Cargo.toml | 1 - src/main.rs | 60 +++++++++++++++++++++++++++++++++++------------------ src/svc.rs | 1 - 3 files changed, 40 insertions(+), 22 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b029316..6dfde49 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,6 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -signal-hook = "0.1.15" nix = "0.17.0" toml = "0.5" serde = { version = "1.0", features = ["derive"] } diff --git a/src/main.rs b/src/main.rs index b0c0ff0..96df882 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,20 +1,28 @@ mod processes; mod svc; +use std::env; use std::fs::File; use std::io::prelude::*; use std::path::Path; use std::process; use std::error::Error; -use signal_hook::{SIGINT, SIGCHLD, SIGUSR1}; use nix::sys::wait::{waitpid, WaitPidFlag, WaitStatus}; use nix::sys::reboot::{reboot, RebootMode}; -use nix::sys::signal::Signal; -use nix::sys::signal::kill; +use nix::sys::signal::{Signal, kill, sigaction, SigAction, SigSet, SaFlags, SigHandler}; use nix::unistd::Pid; use tokio; -fn shutdown_handler() { +extern fn shutdown_handler(_: i32) { + + let sigchld = SigAction::new(SigHandler::SigDfl, SaFlags::empty(), SigSet::empty()); + let sigint = SigAction::new(SigHandler::SigIgn, SaFlags::empty(), SigSet::empty()); + + unsafe { + sigaction(Signal::SIGCHLD, &sigchld).unwrap(); + sigaction(Signal::SIGINT, &sigint).unwrap(); + }; + println!("stopping services"); svc::stop_services(); @@ -30,7 +38,6 @@ fn shutdown_handler() { } println!("unmounting all partitions"); - processes::sync_run_wait("swapoff", ["-a"].as_ref()); processes::sync_run_wait("umount", ["-a", "-f"].as_ref()); println!("syncing disks"); @@ -46,7 +53,7 @@ fn shutdown_handler() { -fn reap_handler() { +extern fn reap_handler(_: i32) { loop { match waitpid(Some(Pid::from_raw(-1)), Some(WaitPidFlag::WNOHANG)) { Ok(WaitStatus::Exited(_pid, _code)) => return, @@ -79,6 +86,7 @@ fn set_hostname() { async fn main() -> Result<(), Box> { if process::id() == 1 { + println!("mini, the bare minimum init by darkgallium"); println!(); @@ -90,7 +98,7 @@ async fn main() -> Result<(), Box> { println!("mount all partitions"); processes::run("mount", ["-a"].as_ref()).await; - processes::run("swapon", ["-a"].as_ref()).await; + //processes::run("swapon", ["-a"].as_ref()).await; println!("load udev"); processes::run("/usr/lib/systemd/systemd-udevd", ["-d"].as_ref()).await; @@ -106,35 +114,47 @@ async fn main() -> Result<(), Box> { println!("mounting pty"); processes::run("mkdir", ["/dev/pts"].as_ref()).await; processes::run("mount", ["devpts", "/dev/pts", "-t", "devpts"].as_ref()).await; + + println!("mounting shm"); + processes::run("mkdir", ["/dev/shm"].as_ref()).await; + processes::run("mount", ["shm", "/dev/shm", "-t", "tmpfs", "-o", "mode=1777,nosuid,nodev"].as_ref()).await; + }); println!("load dbus"); processes::run("mkdir", ["/run/dbus"].as_ref()).await; processes::run("dbus-daemon", ["--system"].as_ref()).await; // a lot of services depend on dbus being on - let sigchld_handle = unsafe { signal_hook::register(SIGCHLD, reap_handler) }?; - let sigchld_handle_c = sigchld_handle.clone(); + let sigchld = SigAction::new(SigHandler::Handler(reap_handler), SaFlags::empty(), SigSet::empty()); + let sigint = SigAction::new(SigHandler::Handler(shutdown_handler), SaFlags::empty(), SigSet::empty()); - unsafe { signal_hook::register(SIGINT, move || { - signal_hook::unregister(sigchld_handle); - shutdown_handler(); - }) }?; + unsafe { + sigaction(Signal::SIGCHLD, &sigchld)?; + sigaction(Signal::SIGINT, &sigint)?; + }; println!("loading services"); svc::launch_services().await; - println!("end bootstrap, launching your terminals"); + println!("end bootstrap, launching your terminal"); - tokio::spawn(async { - processes::run("agetty", ["--noclear", "tty1"].as_ref()).await; - }).await; + processes::sync_run_wait("agetty", ["--noclear", "tty1"].as_ref()); - signal_hook::unregister(sigchld_handle_c); - shutdown_handler(); + shutdown_handler(0); } else { - + let args: Vec = env::args().collect(); + let action = &args[1]; + + if action == "shutdown" { + let res = kill(Pid::from_raw(1), Signal::SIGINT); + match res { + Ok(_) => {}, + Err(err) => eprintln!("error sending shutdown signal to init, error is {}", err) + } + + } } Ok(()) diff --git a/src/svc.rs b/src/svc.rs index 4c692f9..7956803 100644 --- a/src/svc.rs +++ b/src/svc.rs @@ -27,7 +27,6 @@ pub struct Stop { pub fn get_services() -> BTreeMap> { let mut services = BTreeMap::new(); - //let mut services = Vec::new(); let mini_dir = Path::new("/etc/mini/"); if mini_dir.exists() && mini_dir.is_dir() {