From 91d44ff860a9e9c0db81a89cbc24fa31fbd8e6d3 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Sun, 18 Aug 2013 13:30:08 +0200 Subject: um: Cleanup SIGTERM handling Richard reported that some UML processes survive if the UML main process receives a SIGTERM. This issue was caused by a wrongly placed signal(SIGTERM, SIG_DFL) in init_new_thread_signals(). It disabled the UML exit handler accidently for some processes. The correct solution is to disable the fatal handler for all UML helper threads/processes. Such that last_ditch_exit() does not get called multiple times and all processes can exit due to SIGTERM. Reported-and-tested-by: Richard W.M. Jones Signed-off-by: Richard Weinberger --- arch/um/os-Linux/aio.c | 5 ++--- arch/um/os-Linux/process.c | 1 - arch/um/os-Linux/sigio.c | 2 +- arch/um/os-Linux/util.c | 10 ++++++++++ 4 files changed, 13 insertions(+), 5 deletions(-) (limited to 'arch/um/os-Linux') diff --git a/arch/um/os-Linux/aio.c b/arch/um/os-Linux/aio.c index 3a6bc2af0961..014eb35fd13b 100644 --- a/arch/um/os-Linux/aio.c +++ b/arch/um/os-Linux/aio.c @@ -104,8 +104,7 @@ static int aio_thread(void *arg) struct io_event event; int err, n, reply_fd; - signal(SIGWINCH, SIG_IGN); - + os_fix_helper_signals(); while (1) { n = io_getevents(ctx, 1, 1, &event, NULL); if (n < 0) { @@ -173,7 +172,7 @@ static int not_aio_thread(void *arg) struct aio_thread_reply reply; int err; - signal(SIGWINCH, SIG_IGN); + os_fix_helper_signals(); while (1) { err = read(aio_req_fd_r, &req, sizeof(req)); if (err != sizeof(req)) { diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index 67b9c8f5a89e..33496fe2bb52 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c @@ -294,5 +294,4 @@ void init_new_thread_signals(void) signal(SIGHUP, SIG_IGN); set_handler(SIGIO); signal(SIGWINCH, SIG_IGN); - signal(SIGTERM, SIG_DFL); } diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c index 8b61cc0e82c8..46e762f926eb 100644 --- a/arch/um/os-Linux/sigio.c +++ b/arch/um/os-Linux/sigio.c @@ -55,7 +55,7 @@ static int write_sigio_thread(void *unused) int i, n, respond_fd; char c; - signal(SIGWINCH, SIG_IGN); + os_fix_helper_signals(); fds = ¤t_poll; while (1) { n = poll(fds->poll, fds->used, -1); diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c index 492ef5e6e166..faee55ef6d2f 100644 --- a/arch/um/os-Linux/util.c +++ b/arch/um/os-Linux/util.c @@ -94,6 +94,16 @@ static inline void __attribute__ ((noreturn)) uml_abort(void) exit(127); } +/* + * UML helper threads must not handle SIGWINCH/INT/TERM + */ +void os_fix_helper_signals(void) +{ + signal(SIGWINCH, SIG_IGN); + signal(SIGINT, SIG_DFL); + signal(SIGTERM, SIG_DFL); +} + void os_dump_core(void) { int pid; -- cgit v1.2.3