diff --git a/backport-fix-solve-reboot-time-consuming.patch b/backport-fix-solve-reboot-time-consuming.patch new file mode 100644 index 0000000..5ed91ab --- /dev/null +++ b/backport-fix-solve-reboot-time-consuming.patch @@ -0,0 +1,149 @@ +From 13da72cb97a22cb9b97f12226bb327c121908e8d Mon Sep 17 00:00:00 2001 +From: zhangyao2022 +Date: Tue, 7 Nov 2023 21:12:14 +0800 +Subject: [PATCH] fix: solve reboot time consuming + +--- + libs/basic/src/process.rs | 88 ++++++++++++++++++++++++++++++++++----- + 1 file changed, 77 insertions(+), 11 deletions(-) + +diff --git a/libs/basic/src/process.rs b/libs/basic/src/process.rs +index aafd2c8d..638eafdd 100644 +--- a/libs/basic/src/process.rs ++++ b/libs/basic/src/process.rs +@@ -23,9 +23,11 @@ use procfs::process::Stat; + use std::collections::HashSet; + use std::fs::{read_dir, File}; + use std::path::{Path, PathBuf}; +-use std::thread::sleep; + use std::time::{Duration, SystemTime}; + ++const PROCESS_FLAG_POS: usize = 8; ++const PF_KTHREAD: u64 = 0x00200000; ++ + /// + pub fn process_state(pid: Pid) -> Result { + if pid == Pid::from_raw(0) || pid == nix::unistd::getpid() { +@@ -105,9 +107,7 @@ pub fn kill_all_pids(signal: i32) -> HashSet { + let file_name = String::from(entry.file_name().to_str().unwrap()); + // Check pid directory. + if let Ok(pid_raw) = file_name.parse::() { +- if Pid::from_raw(pid_raw) <= Pid::from_raw(1) +- || Pid::from_raw(pid_raw) == nix::unistd::getpid() +- { ++ if let Ok(true) = ignore_proc_during_shutdown(Pid::from_raw(pid_raw)) { + continue; + } + unsafe { +@@ -128,10 +128,6 @@ pub fn wait_pids(mut pids: HashSet, timeout: u64) -> HashSet { + let now = SystemTime::now(); + let until = now + Duration::from_micros(timeout); + +- // remove PID1, we shouldn't wait our self and init. +- pids.remove(&1); +- pids.remove(&nix::unistd::getpid().into()); +- + loop { + // 1. Find killed process by kernel. + while let Ok(wait_status) = waitpid(Pid::from_raw(-1), Some(WaitPidFlag::WNOHANG)) { +@@ -157,12 +153,11 @@ pub fn wait_pids(mut pids: HashSet, timeout: u64) -> HashSet { + log::debug!("successfully killed pid: {} found by ourself.", pid); + pids.remove(&pid); + } +- // 3. Sleep 1s to wait pid exits. +- sleep(Duration::from_secs(1)); +- // 4. Wait or give up. + if pids.is_empty() { + break; + } ++ ++ // 3. Wait or give up. + if SystemTime::now() >= until { + log::info!("some pids haven't been killed yet, stop waiting."); + break; +@@ -212,6 +207,53 @@ pub fn kill_and_cont(pid: Pid, sig: Signal) -> Result<(), Errno> { + } + } + ++fn ignore_proc_during_shutdown(pid: Pid) -> Result { ++ if pid <= Pid::from_raw(1) { ++ return Ok(true); ++ } ++ ++ if pid == nix::unistd::getpid() { ++ return Ok(true); ++ } ++ ++ if is_kernel_thread(pid)? { ++ return Ok(true); ++ } ++ ++ Ok(false) ++} ++ ++fn is_kernel_thread(pid: Pid) -> Result { ++ if pid == Pid::from_raw(1) || pid == nix::unistd::getpid() { ++ return Ok(false); ++ } ++ ++ if pid <= Pid::from_raw(0) { ++ return Err(Error::Invalid { ++ what: format!("Invalid pid: {}", pid), ++ }); ++ } ++ ++ let first_line = fs_util::read_first_line(Path::new(&format!("/proc/{}/stat", pid.as_raw())))?; ++ let stat: Vec = first_line ++ .split_whitespace() ++ .map(|s| s.to_string()) ++ .collect(); ++ ++ if stat.len() <= PROCESS_FLAG_POS { ++ return Err(Error::Invalid { ++ what: "process stat format".to_string(), ++ }); ++ } ++ ++ let flag: u64 = stat[PROCESS_FLAG_POS].parse()?; ++ if flag & PF_KTHREAD != 0 { ++ Ok(true) ++ } else { ++ Ok(false) ++ } ++} ++ + #[cfg(test)] + mod tests { + use nix::libc::kill; +@@ -244,4 +286,28 @@ mod tests { + let res = wait_pids(pids, 10000000); + assert_eq!(res.len(), 0); + } ++ ++ #[test] ++ fn test_ignore_proc_during_shutdown() { ++ assert!( ++ crate::process::ignore_proc_during_shutdown(nix::unistd::Pid::from_raw(0)) ++ .unwrap_or(false) ++ ); ++ if let Ok(ignore) = ++ crate::process::ignore_proc_during_shutdown(nix::unistd::Pid::from_raw(1)) ++ { ++ assert!(ignore); ++ } ++ if let Ok(ignore) = crate::process::ignore_proc_during_shutdown(nix::unistd::getpid()) { ++ assert!(ignore); ++ } ++ if let Ok(mut child) = Command::new("/usr/bin/sleep").arg("2").spawn() { ++ if let Ok(ignore) = crate::process::ignore_proc_during_shutdown( ++ nix::unistd::Pid::from_raw(child.id().try_into().unwrap()), ++ ) { ++ assert!(!ignore); ++ } ++ child.wait().unwrap(); ++ } ++ } + } +-- +2.33.0 + diff --git a/backport-fix-solve-two-sysmaster-problem-exit-after-do_execut.patch b/backport-fix-solve-two-sysmaster-problem-exit-after-do_execut.patch new file mode 100644 index 0000000..0e1a4cb --- /dev/null +++ b/backport-fix-solve-two-sysmaster-problem-exit-after-do_execut.patch @@ -0,0 +1,27 @@ +From f2c8606173f2b408c7a1f02a0d2ef537ad1ac7f6 Mon Sep 17 00:00:00 2001 +From: zhangyao2022 +Date: Tue, 7 Nov 2023 16:22:08 +0800 +Subject: [PATCH] fix: solve two sysmaster problem, exit after do_execute() + +--- + libs/basic/src/exec_util.rs | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/libs/basic/src/exec_util.rs b/libs/basic/src/exec_util.rs +index f1dc20cd..e27c4d62 100644 +--- a/libs/basic/src/exec_util.rs ++++ b/libs/basic/src/exec_util.rs +@@ -18,7 +18,9 @@ use std::{fs, os::unix::prelude::PermissionsExt, path::PathBuf, process::Command + /// + pub fn execute_directories(directories: Vec<&str>) -> std::io::Result<()> { + match unsafe { unistd::fork() } { +- Ok(unistd::ForkResult::Child) => do_execute(directories), ++ Ok(unistd::ForkResult::Child) => { ++ std::process::exit(do_execute(directories).map_or(1, |_| 0)) ++ } + Ok(unistd::ForkResult::Parent { child }) => match nix::sys::wait::waitpid(child, None) { + Ok(_) => Ok(()), + Err(err) => Err(std::io::Error::from(err)), +-- +2.33.0 + diff --git a/sysmaster.spec b/sysmaster.spec index 2237a27..00b3330 100644 --- a/sysmaster.spec +++ b/sysmaster.spec @@ -16,7 +16,7 @@ Name: sysmaster Version: 0.5.1 -Release: 2 +Release: 3 Summary: redesign and reimplement process1. License: Mulan PSL v2 @@ -24,6 +24,8 @@ URL: https://gitee.com/openeuler/sysmaster Source0: %{name}-%{version}.tar.xz Patch0: backport-fix-getty-generator-delelte-double-quote-in-the-conf.patch +Patch1: backport-fix-solve-two-sysmaster-problem-exit-after-do_execut.patch +Patch2: backport-fix-solve-reboot-time-consuming.patch ExclusiveArch: x86_64 aarch64 @@ -179,6 +181,9 @@ test -f /usr/lib/sysmaster/system/udevd.service && ln -s /usr/lib/sysmaster/syst test -f /usr/lib/sysmaster/system/udev-trigger.service && ln -s /usr/lib/sysmaster/system/udev-trigger.service /etc/sysmaster/system/sysinit.target.wants/udev-trigger.service %changelog +* Fri Nov 24 2023 zhangyao - 0.5.1-3 +- sync patchs from upstream + * Mon Oct 30 2023 zhangyao - 0.5.1-2 - add simulate_udev.sh file