mirror of
https://github.com/kata-containers/kata-containers.git
synced 2026-07-26 07:30:19 +00:00
agent: send SIGTERM only to root container process on container deletion
When containerd wants to terminate a container, it sends a KillRequest with exec_id="", all=false, signal=SIGTERM. Kata-shim translates that to a SignalProcessRequest with exec_id="", signal=SIGTERM Kata agent used to interpret exec_id="" as implying all=true. That was correct for forceful deletion of containers, as it uses a KillRequest with all=true, signal=SIGKILL. However, for graceful termination, we want to only signal the root process of the container (all=false). This changes makes it so that Kata agent interprets exec_id="" && signal=SIGKILL as implying all=true, and uses all=false otherwise. It also fixes an unrelated bug, where Kata agent would signal the root process twice when all=true. Fixes #13152 - sending SIGTERM twice to the container's init process on graceful shutdown of a container. Signed-off-by: Bozhidar Marinov <bozhidar.marinov1@digits.schwarz> Co-authored-by: Markus Rudy <webmaster@burgerdev.de> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
committed by
Fabiano Fidêncio
parent
ba23b1ad50
commit
2212dbdd48
@@ -489,6 +489,14 @@ impl AgentService {
|
||||
async fn do_signal_process(&self, req: protocols::agent::SignalProcessRequest) -> Result<()> {
|
||||
let cid = req.container_id;
|
||||
let eid = req.exec_id;
|
||||
let mut sig: libc::c_int = req.signal as libc::c_int;
|
||||
|
||||
let all = eid.is_empty() && sig == libc::SIGKILL;
|
||||
// NOTE: kata runtime encodes all = true by setting eid = "".
|
||||
// However, containerd can send eid = "", sig = SIGTERM, all = false when deleting containers
|
||||
// (and containerd will send eid = "", sig = SIGKILL, all = true when forcefully deleting containers)
|
||||
// Luckily, containerd never sends eid = "", sig = SIGKILL, all = false outside of ctr
|
||||
// So we can recover the original value of all here by checking eid and sig
|
||||
|
||||
info!(
|
||||
sl(),
|
||||
@@ -496,10 +504,10 @@ impl AgentService {
|
||||
"container-id" => &cid,
|
||||
"exec-id" => &eid,
|
||||
"signal" => req.signal,
|
||||
"all" => all,
|
||||
);
|
||||
|
||||
let mut sig: libc::c_int = req.signal as libc::c_int;
|
||||
{
|
||||
if !all {
|
||||
let mut sandbox = self.sandbox.lock().await;
|
||||
let p = sandbox
|
||||
.find_container_process(cid.as_str(), eid.as_str())
|
||||
@@ -512,6 +520,15 @@ impl AgentService {
|
||||
sig = libc::SIGKILL;
|
||||
}
|
||||
|
||||
debug!(
|
||||
sl(),
|
||||
"signaling a container process";
|
||||
"container-id" => &cid,
|
||||
"exec-id" => &eid,
|
||||
"pid" => p.pid,
|
||||
"signal" => sig,
|
||||
);
|
||||
|
||||
match p.signal(sig) {
|
||||
Err(Errno::ESRCH) => {
|
||||
info!(
|
||||
@@ -526,10 +543,8 @@ impl AgentService {
|
||||
Err(err) => return Err(anyhow!(err)),
|
||||
Ok(()) => (),
|
||||
}
|
||||
};
|
||||
|
||||
if eid.is_empty() {
|
||||
// eid is empty, signal all the remaining processes in the container cgroup
|
||||
} else {
|
||||
// Signalling all processes in the cgroup
|
||||
info!(
|
||||
sl(),
|
||||
"signal all the remaining processes";
|
||||
|
||||
Reference in New Issue
Block a user