diff --git a/Dockerfile b/Dockerfile index 7355742fde94370af9e6a80a9c3116dad4ac151f..6a1e05775c4c3ab4c2e3e30fcc85a28b12b46010 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ FROM scratch -RUN rm -f /sbin/init +#当使用systemd来验证时,需要删除注释 +#RUN rm -f /sbin/init COPY target/x86_64-unknown-linux-musl/debug/init /sbin/init COPY target/x86_64-unknown-linux-musl/debug/process1 /usr/lib/process1/process1 -#COPY target/x86_64-unknown-linux-musl/debug/systemd /usr/lib/systemd/systemd CMD ["/sbin/init"] diff --git a/src/init/src/main.rs b/src/init/src/main.rs index 99867e0828c123635373697a4b9e94a586149649..65e2e871d560d038f3ff9b1397675ad3203ba4eb 100644 --- a/src/init/src/main.rs +++ b/src/init/src/main.rs @@ -1,17 +1,16 @@ -use std::fs::write; -use std::io::{self, Error}; +use std::io::Error; use std::mem::MaybeUninit; use std::path::Path; -use std::process::{Child, Command}; +use std::process::{Command, exit}; +use std::os::unix::process::CommandExt; use libc::{siginfo_t, waitid}; use nix::libc; use nix::sys::wait::waitpid; -use nix::unistd::Pid; +use nix::unistd::{Pid, fork, ForkResult}; const PROCESS1_PATH: &'static str = "/usr/lib/process1/process1"; const SYSTEMD_PATH: &'static str = "/usr/lib/systemd/systemd"; -const PIDFILE: &'static str = "/.init.pid"; const SELF_CODE_OFFSET: i32 = 14; const SELF_SIG_OFFSET: i32 = 7; @@ -47,10 +46,9 @@ fn detect_init() -> String { } fn execute_mode(s: &String) -> Result<(), Error> { - println!("Running to execute command : {:?}", s); - let mut error_count = 0; - let mut child = create_init(s)?; + let mut child = create_init(s); + loop { let mut siginfo = MaybeUninit::::zeroed(); let pid = unsafe { @@ -62,34 +60,38 @@ fn execute_mode(s: &String) -> Result<(), Error> { }; if pid <= 0 { continue; - } else if pid == child.id() as i32 { - if let Ok(status) = child.wait() { - if !status.success() { - error_count += 1; - if error_count >= 3 { - break; - } - println!("Exited with error, Again"); - child = create_init(s)?; - } + } else if pid == child.as_raw() { + error_count += 1; + if error_count >= 3 { + println!("Manager({}) failed 3 times, exit", pid); + let _ = waitpid(Pid::from_raw(pid), None); + break; } + child = create_init(s); } else { - println!("Receiving {} exited", pid); - send_signal(child.id(), siginfo); - let _result = waitpid(Pid::from_raw(pid), None); - println!("Reaped {}", pid); + send_signal(pid, siginfo); } + + println!("Reaped child {}", pid); + let _ = waitpid(Pid::from_raw(pid), None); } Ok(()) } -fn create_init(s: &String) -> io::Result { - let child = Command::new(s).spawn()?; - let _ = write(String::from(PIDFILE), child.id().to_string()); - Ok(child) +fn create_init(s: &String) -> Pid { + println!("Running to execute command : {:?}", s); + + if let Ok(ForkResult::Parent { child, .. }) = unsafe{fork()} { + child + } else { + let mut command = Command::new(s); + let comm = command.env("SYSTEMD_MAINPID", format!("{}", unsafe{ libc::getpid() })); + comm.exec(); + exit(0) + } } -fn send_signal(pid: u32, mut siginfo: MaybeUninit) { +fn send_signal(pid: i32, mut siginfo: MaybeUninit) { unsafe { siginfo.assume_init_mut().si_code -= SELF_CODE_OFFSET; if libc::syscall(libc::SYS_rt_sigqueueinfo, pid, libc::SIGRTMIN() + SELF_SIG_OFFSET, @@ -97,4 +99,4 @@ fn send_signal(pid: u32, mut siginfo: MaybeUninit) { println!("send signal error:{}", Error::last_os_error()) } } -} \ No newline at end of file +}