From a5bb383cf3aeb11828727d99cdba59756ab61b34 Mon Sep 17 00:00:00 2001 From: Tim Zhang Date: Wed, 12 May 2021 14:35:40 +0800 Subject: [PATCH] agent: avoid reaping the exit signal of execute_hook in the reaper Fixes: #1826 Signed-off-by: Tim Zhang --- src/agent/rustjail/src/container.rs | 7 +++++++ src/agent/src/signal.rs | 3 +++ 2 files changed, 10 insertions(+) diff --git a/src/agent/rustjail/src/container.rs b/src/agent/rustjail/src/container.rs index ff03baecdb..3546ee957c 100644 --- a/src/agent/rustjail/src/container.rs +++ b/src/agent/rustjail/src/container.rs @@ -48,6 +48,7 @@ use oci::State as OCIState; use std::collections::HashMap; use std::os::unix::io::FromRawFd; use std::str::FromStr; +use std::sync::Arc; use slog::{info, o, Logger}; @@ -57,6 +58,7 @@ use crate::sync_with_async::{read_async, write_async}; use async_trait::async_trait; use rlimit::{setrlimit, Resource, Rlim}; use tokio::io::AsyncBufReadExt; +use tokio::sync::Mutex; use crate::utils; @@ -106,6 +108,9 @@ pub type Config = CreateOpts; type NamespaceType = String; lazy_static! { + // This locker ensures the child exit signal will be received by the right receiver. + pub static ref WAIT_PID_LOCKER: Arc> = Arc::new(Mutex::new(false)); + static ref NAMESPACES: HashMap<&'static str, CloneFlags> = { let mut m = HashMap::new(); m.insert("user", CloneFlags::CLONE_NEWUSER); @@ -1465,6 +1470,8 @@ async fn execute_hook(logger: &Logger, h: &Hook, st: &OCIState) -> Result<()> { }) .collect(); + // Avoid the exit signal to be reaped by the global reaper. + let _wait_locker = WAIT_PID_LOCKER.lock().await; let mut child = tokio::process::Command::new(path) .args(args.iter()) .envs(env.iter()) diff --git a/src/agent/src/signal.rs b/src/agent/src/signal.rs index c37459f939..7f823b2f19 100644 --- a/src/agent/src/signal.rs +++ b/src/agent/src/signal.rs @@ -22,6 +22,9 @@ async fn handle_sigchild(logger: Logger, sandbox: Arc>) -> Result info!(logger, "handling signal"; "signal" => "SIGCHLD"); loop { + // Avoid reaping the undesirable child's signal, e.g., execute_hook's + // The lock should be released immediately. + rustjail::container::WAIT_PID_LOCKER.lock().await; let result = wait::waitpid( Some(Pid::from_raw(-1)), Some(WaitPidFlag::WNOHANG | WaitPidFlag::__WALL),