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 <stellarwxx@163.com>
This commit is contained in:
Wang Xingxing 2022-03-30 16:01:17 +08:00
parent e1875d1879
commit 0d765bd082
2 changed files with 13 additions and 17 deletions

View File

@ -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<WaitStatus>;
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());
}
}

View File

@ -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;
@ -401,20 +399,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)?;
}
@ -440,7 +433,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";