mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-04-29 12:14:48 +00:00
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:
parent
e1875d1879
commit
0d765bd082
@ -8,8 +8,8 @@ use std::fs::File;
|
|||||||
use std::os::unix::io::RawFd;
|
use std::os::unix::io::RawFd;
|
||||||
use tokio::sync::mpsc::Sender;
|
use tokio::sync::mpsc::Sender;
|
||||||
|
|
||||||
|
use nix::errno::Errno;
|
||||||
use nix::fcntl::{fcntl, FcntlArg, OFlag};
|
use nix::fcntl::{fcntl, FcntlArg, OFlag};
|
||||||
use nix::sys::signal::{self, Signal};
|
|
||||||
use nix::sys::wait::{self, WaitStatus};
|
use nix::sys::wait::{self, WaitStatus};
|
||||||
use nix::unistd::{self, Pid};
|
use nix::unistd::{self, Pid};
|
||||||
use nix::Result;
|
use nix::Result;
|
||||||
@ -80,7 +80,7 @@ pub struct Process {
|
|||||||
pub trait ProcessOperations {
|
pub trait ProcessOperations {
|
||||||
fn pid(&self) -> Pid;
|
fn pid(&self) -> Pid;
|
||||||
fn wait(&self) -> Result<WaitStatus>;
|
fn wait(&self) -> Result<WaitStatus>;
|
||||||
fn signal(&self, sig: Signal) -> Result<()>;
|
fn signal(&self, sig: libc::c_int) -> Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ProcessOperations for Process {
|
impl ProcessOperations for Process {
|
||||||
@ -92,8 +92,10 @@ impl ProcessOperations for Process {
|
|||||||
wait::waitpid(Some(self.pid()), None)
|
wait::waitpid(Some(self.pid()), None)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn signal(&self, sig: Signal) -> Result<()> {
|
fn signal(&self, sig: libc::c_int) -> Result<()> {
|
||||||
signal::kill(self.pid(), Some(sig))
|
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
|
// signal to every process in the process
|
||||||
// group of the calling process.
|
// group of the calling process.
|
||||||
process.pid = 0;
|
process.pid = 0;
|
||||||
assert!(process.signal(Signal::SIGCONT).is_ok());
|
assert!(process.signal(libc::SIGCONT).is_ok());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,8 +40,7 @@ use rustjail::specconv::CreateOpts;
|
|||||||
|
|
||||||
use nix::errno::Errno;
|
use nix::errno::Errno;
|
||||||
use nix::mount::MsFlags;
|
use nix::mount::MsFlags;
|
||||||
use nix::sys::signal::Signal;
|
use nix::sys::stat;
|
||||||
use nix::sys::{signal, stat};
|
|
||||||
use nix::unistd::{self, Pid};
|
use nix::unistd::{self, Pid};
|
||||||
use rustjail::cgroups::Manager;
|
use rustjail::cgroups::Manager;
|
||||||
use rustjail::process::ProcessOperations;
|
use rustjail::process::ProcessOperations;
|
||||||
@ -71,7 +70,6 @@ use tracing_opentelemetry::OpenTelemetrySpanExt;
|
|||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
|
|
||||||
use libc::{self, c_char, c_ushort, pid_t, winsize, TIOCSWINSZ};
|
use libc::{self, c_char, c_ushort, pid_t, winsize, TIOCSWINSZ};
|
||||||
use std::convert::TryFrom;
|
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::os::unix::fs::MetadataExt;
|
use std::os::unix::fs::MetadataExt;
|
||||||
use std::os::unix::prelude::PermissionsExt;
|
use std::os::unix::prelude::PermissionsExt;
|
||||||
@ -401,20 +399,15 @@ impl AgentService {
|
|||||||
"exec-id" => eid.clone(),
|
"exec-id" => eid.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut sig = Signal::try_from(req.signal as i32).map_err(|e| {
|
let mut sig: libc::c_int = req.signal as libc::c_int;
|
||||||
anyhow!(e).context(format!(
|
|
||||||
"failed to convert {:?} to signal (container-id: {}, exec-id: {})",
|
|
||||||
req.signal, cid, eid
|
|
||||||
))
|
|
||||||
})?;
|
|
||||||
{
|
{
|
||||||
let mut sandbox = s.lock().await;
|
let mut sandbox = s.lock().await;
|
||||||
let p = sandbox.find_container_process(cid.as_str(), eid.as_str())?;
|
let p = sandbox.find_container_process(cid.as_str(), eid.as_str())?;
|
||||||
// For container initProcess, if it hasn't installed handler for "SIGTERM" signal,
|
// 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
|
// it will ignore the "SIGTERM" signal sent to it, thus send it "SIGKILL" signal
|
||||||
// instead of "SIGTERM" to terminate it.
|
// instead of "SIGTERM" to terminate it.
|
||||||
if p.init && sig == Signal::SIGTERM && !is_signal_handled(p.pid, sig as u32) {
|
if p.init && sig == libc::SIGTERM && !is_signal_handled(p.pid, sig as u32) {
|
||||||
sig = Signal::SIGKILL;
|
sig = libc::SIGKILL;
|
||||||
}
|
}
|
||||||
p.signal(sig)?;
|
p.signal(sig)?;
|
||||||
}
|
}
|
||||||
@ -440,7 +433,8 @@ impl AgentService {
|
|||||||
|
|
||||||
let pids = self.get_pids(&cid).await?;
|
let pids = self.get_pids(&cid).await?;
|
||||||
for pid in pids.iter() {
|
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!(
|
warn!(
|
||||||
sl!(),
|
sl!(),
|
||||||
"signal failed";
|
"signal failed";
|
||||||
|
Loading…
Reference in New Issue
Block a user