!77 sync patchs from upstream

From: @zhang-yao-2022 
Reviewed-by: @openeuler-basic, @licunlong 
Signed-off-by: @licunlong, @openeuler-basic
This commit is contained in:
openeuler-ci-bot 2023-11-25 01:01:45 +00:00 committed by Gitee
commit 2a7765f92b
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
3 changed files with 182 additions and 1 deletions

View File

@ -0,0 +1,149 @@
From 13da72cb97a22cb9b97f12226bb327c121908e8d Mon Sep 17 00:00:00 2001
From: zhangyao2022 <zhangyao108@huawei.com>
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<char> {
if pid == Pid::from_raw(0) || pid == nix::unistd::getpid() {
@@ -105,9 +107,7 @@ pub fn kill_all_pids(signal: i32) -> HashSet<i32> {
let file_name = String::from(entry.file_name().to_str().unwrap());
// Check pid directory.
if let Ok(pid_raw) = file_name.parse::<i32>() {
- 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<i32>, timeout: u64) -> HashSet<i32> {
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<i32>, timeout: u64) -> HashSet<i32> {
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<bool> {
+ 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<bool> {
+ 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<String> = 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

View File

@ -0,0 +1,27 @@
From f2c8606173f2b408c7a1f02a0d2ef537ad1ac7f6 Mon Sep 17 00:00:00 2001
From: zhangyao2022 <zhangyao108@huawei.com>
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

View File

@ -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<zhangyao108@huawei.com> - 0.5.1-3
- sync patchs from upstream
* Mon Oct 30 2023 zhangyao<zhangyao108@huawei.com> - 0.5.1-2
- add simulate_udev.sh file