mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-12-22 13:45:20 +00:00
vmm: Avoid zombie sigwinch_listener processes
When a guest running on a terminal reboots, the sigwinch_listener subprocess exits and a new one restarts. The parent never wait()s for children, so the old subprocess remains as a zombie. With further reboots, more and more zombies build up. As there are no other children for which we want the exit status, the easiest fix is to take advantage of the implicit reaping specified by POSIX when we set the disposition of SIGCHLD to SIG_IGN. For this to work, we also need to set the correct default exit signal of SIGCHLD when using clone3() CLONE_CLEAR_SIGHAND. Unlike the fallback fork() path, clone_args::default() initialises the exit signal to zero, which results in a child with non-standard reaping behaviour. Signed-off-by: Chris Webb <chris@arachsys.com>
This commit is contained in:
parent
6362b711c6
commit
09f3658999
@ -561,6 +561,11 @@ fn start_vmm(cmd_arguments: ArgMatches) -> Result<Option<String>, Error> {
|
|||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SAFETY: Trivially safe.
|
||||||
|
unsafe {
|
||||||
|
libc::signal(libc::SIGCHLD, libc::SIG_IGN);
|
||||||
|
}
|
||||||
|
|
||||||
// Before we start any threads, mask the signals we'll be
|
// Before we start any threads, mask the signals we'll be
|
||||||
// installing handlers for, to make sure they only ever run on the
|
// installing handlers for, to make sure they only ever run on the
|
||||||
// dedicated signal handling thread we'll start in a bit.
|
// dedicated signal handling thread we'll start in a bit.
|
||||||
|
@ -6,7 +6,7 @@ use arch::_NSIG;
|
|||||||
use libc::{
|
use libc::{
|
||||||
c_int, c_void, close, fork, getpgrp, ioctl, pipe2, poll, pollfd, setsid, sigemptyset,
|
c_int, c_void, close, fork, getpgrp, ioctl, pipe2, poll, pollfd, setsid, sigemptyset,
|
||||||
siginfo_t, signal, sigprocmask, syscall, tcgetpgrp, tcsetpgrp, SYS_close_range, EINVAL, ENOSYS,
|
siginfo_t, signal, sigprocmask, syscall, tcgetpgrp, tcsetpgrp, SYS_close_range, EINVAL, ENOSYS,
|
||||||
ENOTTY, O_CLOEXEC, POLLERR, SIGWINCH, SIG_DFL, SIG_SETMASK, STDERR_FILENO, TIOCSCTTY,
|
ENOTTY, O_CLOEXEC, POLLERR, SIGCHLD, SIGWINCH, SIG_DFL, SIG_SETMASK, STDERR_FILENO, TIOCSCTTY,
|
||||||
};
|
};
|
||||||
use seccompiler::{apply_filter, BpfProgram};
|
use seccompiler::{apply_filter, BpfProgram};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
@ -204,7 +204,10 @@ fn sigwinch_listener_main(seccomp_filter: BpfProgram, tx: File, tty: File) -> !
|
|||||||
///
|
///
|
||||||
/// Same as [`fork`].
|
/// Same as [`fork`].
|
||||||
unsafe fn clone_clear_sighand() -> io::Result<u64> {
|
unsafe fn clone_clear_sighand() -> io::Result<u64> {
|
||||||
let mut args = clone_args::default();
|
let mut args = clone_args {
|
||||||
|
exit_signal: SIGCHLD as u64,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
args.flags |= CLONE_CLEAR_SIGHAND;
|
args.flags |= CLONE_CLEAR_SIGHAND;
|
||||||
let r = clone3(&mut args, size_of::<clone_args>());
|
let r = clone3(&mut args, size_of::<clone_args>());
|
||||||
if r != -1 {
|
if r != -1 {
|
||||||
|
Loading…
Reference in New Issue
Block a user