From cae48e9c9be1418db3aa1cfb4782d64e8db1ad0c Mon Sep 17 00:00:00 2001 From: Wang Xingxing Date: Wed, 30 Mar 2022 16:01:17 +0800 Subject: [PATCH] agent: fix container stop error with signal SIGRTMIN+3 The nix::sys::signal::Signal package api cannot deal with SIGRTMIN+3, directly use libc function to send the signal. Fixes: #3990 Signed-off-by: Wang Xingxing (cherry picked from commit 0d765bd08248887ad3084df0c5483e551295e91a) Signed-off-by: Wang Xingxing --- src/agent/rustjail/src/process.rs | 12 +++++++----- src/agent/src/rpc.rs | 18 ++++++------------ 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/agent/rustjail/src/process.rs b/src/agent/rustjail/src/process.rs index 192aefc4e1..cced9b98f3 100644 --- a/src/agent/rustjail/src/process.rs +++ b/src/agent/rustjail/src/process.rs @@ -8,8 +8,8 @@ use std::fs::File; use std::os::unix::io::RawFd; use tokio::sync::mpsc::Sender; +use nix::errno::Errno; use nix::fcntl::{fcntl, FcntlArg, OFlag}; -use nix::sys::signal::{self, Signal}; use nix::sys::wait::{self, WaitStatus}; use nix::unistd::{self, Pid}; use nix::Result; @@ -80,7 +80,7 @@ pub struct Process { pub trait ProcessOperations { fn pid(&self) -> Pid; fn wait(&self) -> Result; - fn signal(&self, sig: Signal) -> Result<()>; + fn signal(&self, sig: libc::c_int) -> Result<()>; } impl ProcessOperations for Process { @@ -92,8 +92,10 @@ impl ProcessOperations for Process { wait::waitpid(Some(self.pid()), None) } - fn signal(&self, sig: Signal) -> Result<()> { - signal::kill(self.pid(), Some(sig)) + fn signal(&self, sig: libc::c_int) -> Result<()> { + let res = unsafe { libc::kill(self.pid().into(), sig) }; + + Errno::result(res).map(drop) } } @@ -281,6 +283,6 @@ mod tests { // signal to every process in the process // group of the calling process. process.pid = 0; - assert!(process.signal(Signal::SIGCONT).is_ok()); + assert!(process.signal(libc::SIGCONT).is_ok()); } } diff --git a/src/agent/src/rpc.rs b/src/agent/src/rpc.rs index 24dd4691a4..5fce4fb4ee 100644 --- a/src/agent/src/rpc.rs +++ b/src/agent/src/rpc.rs @@ -40,8 +40,7 @@ use rustjail::specconv::CreateOpts; use nix::errno::Errno; use nix::mount::MsFlags; -use nix::sys::signal::Signal; -use nix::sys::{signal, stat}; +use nix::sys::stat; use nix::unistd::{self, Pid}; use rustjail::cgroups::Manager; use rustjail::process::ProcessOperations; @@ -71,7 +70,6 @@ use tracing_opentelemetry::OpenTelemetrySpanExt; use tracing::instrument; use libc::{self, c_char, c_ushort, pid_t, winsize, TIOCSWINSZ}; -use std::convert::TryFrom; use std::fs; use std::os::unix::fs::MetadataExt; use std::os::unix::prelude::PermissionsExt; @@ -399,20 +397,15 @@ impl AgentService { "exec-id" => eid.clone(), ); - let mut sig = Signal::try_from(req.signal as i32).map_err(|e| { - anyhow!(e).context(format!( - "failed to convert {:?} to signal (container-id: {}, exec-id: {})", - req.signal, cid, eid - )) - })?; + let mut sig: libc::c_int = req.signal as libc::c_int; { let mut sandbox = s.lock().await; let p = sandbox.find_container_process(cid.as_str(), eid.as_str())?; // For container initProcess, if it hasn't installed handler for "SIGTERM" signal, // it will ignore the "SIGTERM" signal sent to it, thus send it "SIGKILL" signal // instead of "SIGTERM" to terminate it. - if p.init && sig == Signal::SIGTERM && !is_signal_handled(p.pid, sig as u32) { - sig = Signal::SIGKILL; + if p.init && sig == libc::SIGTERM && !is_signal_handled(p.pid, sig as u32) { + sig = libc::SIGKILL; } p.signal(sig)?; } @@ -438,7 +431,8 @@ impl AgentService { let pids = self.get_pids(&cid).await?; for pid in pids.iter() { - if let Err(err) = signal::kill(Pid::from_raw(*pid), Some(sig)) { + let res = unsafe { libc::kill(*pid, sig) }; + if let Err(err) = Errno::result(res).map(drop) { warn!( sl!(), "signal failed";