sysmaster/backport-fix-init-uses-SIGABRT-to-reexec-sysmaster-increase-s.patch
huyubiao 8936fa02c5 sync patches from upstream,change the path of the unit,modify permissions for some directories and files
(cherry picked from commit ce9ff469b57f60130621bc293783bd3ac1fc92f2)
2023-08-05 18:15:53 +08:00

286 lines
10 KiB
Diff

From 5c9eb30727331780e01cd34293801efd38aa787d Mon Sep 17 00:00:00 2001
From: huyubiao <h13958451065@163.com>
Date: Fri, 16 Jun 2023 15:32:28 +0800
Subject: [PATCH] fix: init uses SIGABRT to reexec sysmaster, increase signal
permissions
---
core/bin/main.rs | 46 ++++++++++++++++----------------
core/bin/manager/mod.rs | 9 ++++++-
exts/init/Cargo.toml | 1 -
exts/init/src/runtime/mod.rs | 33 +++++++++--------------
exts/init/src/runtime/signals.rs | 19 +++++++------
libs/constants/src/lib.rs | 2 --
7 files changed, 60 insertions(+), 62 deletions(-)
diff --git a/core/bin/main.rs b/core/bin/main.rs
index 0239ce9..7f163c7 100644
--- a/core/bin/main.rs
+++ b/core/bin/main.rs
@@ -39,7 +39,7 @@ use crate::mount::setup;
use basic::logger::{self};
use basic::process_util;
use clap::Parser;
-use libc::{c_int, getppid, prctl, PR_SET_CHILD_SUBREAPER};
+use libc::{c_int, getpid, getppid, prctl, PR_SET_CHILD_SUBREAPER};
use log::{self};
use manager::signals::EVENT_SIGNALS;
use nix::sys::resource::{self, Resource};
@@ -52,7 +52,6 @@ use std::rc::Rc;
use sysmaster::error::*;
use sysmaster::rel;
-use constants::SIG_MANAGER_REEXEC_OFFSET;
use constants::SIG_SWITCH_ROOT_OFFSET;
/// parse program arguments
@@ -106,21 +105,17 @@ fn main() -> Result<()> {
setup::mount_setup()?;
rel::reli_dir_prepare()?;
- let switch = rel::reli_debug_get_switch();
- log::info!("sysmaster initialize with switch: {}.", switch);
+ let self_recovery_enable = rel::reli_debug_get_switch();
+ log::info!("sysmaster self_recovery_enable: {}.", self_recovery_enable);
- initialize_runtime(switch)?;
+ initialize_runtime(self_recovery_enable)?;
let manager = Manager::new(Mode::System, Action::Run, manager_config);
- // enable clear, mutex with install_crash_handler
- if !switch {
- if !args.deserialize {
- manager.debug_clear_restore();
- log::info!("debug: clear data restored.");
- }
- // if switch is false unregister init's reexec signal.
- register_reexec_signal(false);
+ // enable clear
+ if !self_recovery_enable && !args.deserialize {
+ manager.debug_clear_restore();
+ log::info!("debug: clear data restored.");
}
manager.setup_cgroup()?;
@@ -144,10 +139,13 @@ fn main() -> Result<()> {
Ok(())
}
-fn initialize_runtime(switch: bool) -> Result<()> {
- if switch {
+fn initialize_runtime(self_recovery_enable: bool) -> Result<()> {
+ if self_recovery_enable {
install_crash_handler();
log::info!("install crash handler.");
+ } else {
+ // if self_recovery_enable is false unregister init's reexec signal.
+ register_reexec_signal(false);
}
#[cfg(feature = "linux")]
@@ -222,7 +220,7 @@ fn install_crash_handler() {
Signal::SIGABRT,
Signal::SIGSYS,
];
- let handler = SigHandler::Handler(crash);
+ let handler = SigHandler::SigAction(crash);
let flags = SaFlags::SA_NODEFER;
let action = SigAction::new(handler, flags, SigSet::empty());
for &signal in signals.iter() {
@@ -232,11 +230,14 @@ fn install_crash_handler() {
}
}
-extern "C" fn crash(signo: c_int) {
- let _signal = Signal::try_from(signo).unwrap(); // debug
-
- let args: Vec<String> = env::args().collect();
- do_reexecute(&args, false);
+extern "C" fn crash(signo: c_int, siginfo: *mut libc::siginfo_t, _con: *mut libc::c_void) {
+ let signal = Signal::try_from(signo).unwrap(); // debug
+ if (signal == Signal::SIGABRT && unsafe { (*siginfo).si_pid() == getppid() })
+ || unsafe { (*siginfo).si_pid() == getpid() }
+ {
+ let args: Vec<String> = env::args().collect();
+ do_reexecute(&args, false);
+ }
}
fn execarg_build_default() -> (String, Vec<String>) {
@@ -265,8 +266,7 @@ extern "C" fn crash_none(_signo: c_int, _siginfo: *mut libc::siginfo_t, _con: *m
}
fn register_reexec_signal(enable: bool) {
- let manager_signal: signal::Signal =
- unsafe { std::mem::transmute(libc::SIGRTMIN() + SIG_MANAGER_REEXEC_OFFSET) };
+ let manager_signal: Signal = Signal::SIGABRT;
let handler = match enable {
true => SigHandler::SigAction(crash_reexec),
false => SigHandler::SigAction(crash_none),
diff --git a/core/bin/manager/mod.rs b/core/bin/manager/mod.rs
index e972cc7..7bd16e0 100644
--- a/core/bin/manager/mod.rs
+++ b/core/bin/manager/mod.rs
@@ -59,6 +59,12 @@ impl SignalMgr {
SignalMgr { um: Rc::clone(&um) }
}
fn reexec(&self) -> Result<i32> {
+ self.um.set_state(State::ReExecute);
+ Ok(1)
+ }
+
+ fn reload(&self) -> Result<i32> {
+ self.um.set_state(State::ReLoad);
Ok(1)
}
}
@@ -70,7 +76,8 @@ impl SignalDispatcher for SignalMgr {
return Ok(1);
}
match signal.ssi_signo as libc::c_int {
- libc::SIGHUP | libc::SIGTERM => self.reexec(),
+ libc::SIGHUP => self.reload(),
+ libc::SIGTERM => self.reexec(),
libc::SIGCHLD => Ok(self.um.child_sigchld_enable(true)),
/* Kernel will send SIGINT to PID1 when users press ctrl-alt-del,
* init should forward SIGINT to sysmaster. */
diff --git a/exts/init/Cargo.toml b/exts/init/Cargo.toml
index e3c0198..e351b61 100644
--- a/exts/init/Cargo.toml
+++ b/exts/init/Cargo.toml
@@ -9,4 +9,3 @@ edition = "2021"
constants = { version = "0.1.0", path = "../../libs/constants" }
libc = "0.2.*"
nix = "0.24"
-signal-hook-registry = "1.4.0"
diff --git a/exts/init/src/runtime/mod.rs b/exts/init/src/runtime/mod.rs
index e37ff01..d11d8f2 100644
--- a/exts/init/src/runtime/mod.rs
+++ b/exts/init/src/runtime/mod.rs
@@ -33,7 +33,6 @@ use std::rc::Rc;
use constants::SIG_SWITCH_ROOT_OFFSET;
const INVALID_PID: i32 = -1;
-const MANAGER_SIG_OFFSET: i32 = 7;
const SYSMASTER_PATH: &str = "/usr/lib/sysmaster/sysmaster";
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd)]
@@ -152,12 +151,7 @@ impl RunTime {
self.comm.finish();
- unsafe {
- libc::kill(
- self.sysmaster_pid.into(),
- libc::SIGRTMIN() + MANAGER_SIG_OFFSET,
- )
- };
+ unsafe { libc::kill(self.sysmaster_pid.into(), libc::SIGABRT) };
}
fn reexec_comm_dispatch(&mut self, event: EpollEvent) -> Result<(), Errno> {
@@ -187,11 +181,10 @@ impl RunTime {
fn reexec_signal_dispatch(&mut self, event: EpollEvent) -> Result<(), Errno> {
if let Some(siginfo) = self.signals.read(event)? {
- let signo = siginfo.ssi_signo as i32;
- match signo {
- _x if self.signals.is_zombie(signo) => self.do_recycle(),
- _x if self.signals.is_restart(signo) => self.do_reexec(),
- _x if self.signals.is_unrecover(signo) => self.change_to_unrecover(),
+ match siginfo {
+ _x if self.signals.is_zombie(siginfo) => self.do_recycle(),
+ _x if self.signals.is_restart(siginfo) => self.do_reexec(),
+ _x if self.signals.is_unrecover(siginfo) => self.change_to_unrecover(),
_ => {}
}
}
@@ -200,11 +193,10 @@ impl RunTime {
fn run_signal_dispatch(&mut self, event: EpollEvent) -> Result<(), Errno> {
if let Some(siginfo) = self.signals.read(event)? {
- let signo = siginfo.ssi_signo as i32;
- match signo {
- _x if self.signals.is_zombie(signo) => self.do_recycle(),
- _x if self.signals.is_restart(signo) => self.do_reexec(),
- _x if self.signals.is_switch_root(signo) => self.send_switch_root_signal(),
+ match siginfo {
+ _x if self.signals.is_zombie(siginfo) => self.do_recycle(),
+ _x if self.signals.is_restart(siginfo) => self.do_reexec(),
+ _x if self.signals.is_switch_root(siginfo) => self.send_switch_root_signal(),
_ => {}
}
}
@@ -213,15 +205,14 @@ impl RunTime {
fn unrecover_signal_dispatch(&mut self, event: EpollEvent) -> Result<(), Errno> {
if let Some(siginfo) = self.signals.read(event)? {
- let signo = siginfo.ssi_signo as i32;
- match signo {
- _x if self.signals.is_zombie(signo) => {
+ match siginfo {
+ _x if self.signals.is_zombie(siginfo) => {
self.signals.recycle_zombie();
if self.is_sysmaster(siginfo.ssi_pid as i32) && self.switching {
self.reexec_self()
}
}
- _x if self.signals.is_restart(signo) => self.do_recreate(),
+ _x if self.signals.is_restart(siginfo) => self.do_recreate(),
_ => {}
}
}
diff --git a/exts/init/src/runtime/signals.rs b/exts/init/src/runtime/signals.rs
index eee088c..1c3059c 100644
--- a/exts/init/src/runtime/signals.rs
+++ b/exts/init/src/runtime/signals.rs
@@ -81,20 +81,23 @@ impl Signals {
}
}
- pub fn is_zombie(&self, signo: i32) -> bool {
- self.zombie_signal == signo
+ pub fn is_zombie(&self, siginfo: libc::signalfd_siginfo) -> bool {
+ self.zombie_signal as u32 == siginfo.ssi_signo
}
- pub fn is_restart(&self, signo: i32) -> bool {
- self.restart_signal == signo
+ pub fn is_restart(&self, siginfo: libc::signalfd_siginfo) -> bool {
+ self.restart_signal as u32 == siginfo.ssi_signo
}
- pub fn is_unrecover(&self, signo: i32) -> bool {
- self.unrecover_signal == signo
+ pub fn is_unrecover(&self, siginfo: libc::signalfd_siginfo) -> bool {
+ if 0 == siginfo.ssi_uid {
+ return self.unrecover_signal as u32 == siginfo.ssi_signo;
+ }
+ false
}
- pub fn is_switch_root(&self, signo: i32) -> bool {
- self.switch_root_signal == signo
+ pub fn is_switch_root(&self, siginfo: libc::signalfd_siginfo) -> bool {
+ self.switch_root_signal as u32 == siginfo.ssi_signo
}
pub fn create_signals_epoll(&mut self) -> Result<(), Errno> {
diff --git a/libs/constants/src/lib.rs b/libs/constants/src/lib.rs
index 7c918aa..b1db27c 100644
--- a/libs/constants/src/lib.rs
+++ b/libs/constants/src/lib.rs
@@ -12,8 +12,6 @@
//! Common used constants by init, sysmaster and other extensions.
-/// Signal used to reexecute sysmaster, SIGRTMIN+7
-pub const SIG_MANAGER_REEXEC_OFFSET: i32 = 7;
/// Signal used run unrecover, SIGRTMIN+8
pub const SIG_RUN_UNRECOVER_OFFSET: i32 = 8;
/// Signal used to restart the manager, SIGRTMIN+9
--
2.33.0