diff options
author | Richard Weinberger <richard@nod.at> | 2013-08-18 13:30:08 +0200 |
---|---|---|
committer | Richard Weinberger <richard@nod.at> | 2013-09-07 10:56:58 +0200 |
commit | 91d44ff860a9e9c0db81a89cbc24fa31fbd8e6d3 (patch) | |
tree | bb14601ab3afbcec3cb8d7d0f207d09cfc792268 /arch/um | |
parent | bc1d72e73be63a7c4a07eb10cf51e91f20bf6076 (diff) | |
download | linux-stable-91d44ff860a9e9c0db81a89cbc24fa31fbd8e6d3.tar.gz linux-stable-91d44ff860a9e9c0db81a89cbc24fa31fbd8e6d3.tar.bz2 linux-stable-91d44ff860a9e9c0db81a89cbc24fa31fbd8e6d3.zip |
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 <rjones@redhat.com>
Signed-off-by: Richard Weinberger <richard@nod.at>
Diffstat (limited to 'arch/um')
-rw-r--r-- | arch/um/drivers/ubd.h | 1 | ||||
-rw-r--r-- | arch/um/drivers/ubd_kern.c | 3 | ||||
-rw-r--r-- | arch/um/drivers/ubd_user.c | 5 | ||||
-rw-r--r-- | arch/um/include/shared/os.h | 1 | ||||
-rw-r--r-- | arch/um/os-Linux/aio.c | 5 | ||||
-rw-r--r-- | arch/um/os-Linux/process.c | 1 | ||||
-rw-r--r-- | arch/um/os-Linux/sigio.c | 2 | ||||
-rw-r--r-- | arch/um/os-Linux/util.c | 10 |
8 files changed, 16 insertions, 12 deletions
diff --git a/arch/um/drivers/ubd.h b/arch/um/drivers/ubd.h index 3845051f1b10..3b48cd2081ee 100644 --- a/arch/um/drivers/ubd.h +++ b/arch/um/drivers/ubd.h @@ -7,7 +7,6 @@ #ifndef __UM_UBD_USER_H #define __UM_UBD_USER_H -extern void ignore_sigwinch_sig(void); extern int start_io_thread(unsigned long sp, int *fds_out); extern int io_thread(void *arg); extern int kernel_fd; diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 1812bc81715b..3716e6952554 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -1476,7 +1476,8 @@ int io_thread(void *arg) struct io_thread_req *req; int n; - ignore_sigwinch_sig(); + os_fix_helper_signals(); + while(1){ n = os_read_file(kernel_fd, &req, sizeof(struct io_thread_req *)); diff --git a/arch/um/drivers/ubd_user.c b/arch/um/drivers/ubd_user.c index a703e45d8aac..e376f9b9c68d 100644 --- a/arch/um/drivers/ubd_user.c +++ b/arch/um/drivers/ubd_user.c @@ -21,11 +21,6 @@ #include "ubd.h" #include <os.h> -void ignore_sigwinch_sig(void) -{ - signal(SIGWINCH, SIG_IGN); -} - int start_io_thread(unsigned long sp, int *fd_out) { int pid, fds[2], err; diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h index e98303925cc5..021104d98cb3 100644 --- a/arch/um/include/shared/os.h +++ b/arch/um/include/shared/os.h @@ -235,6 +235,7 @@ extern void setup_machinename(char *machine_out); extern void setup_hostinfo(char *buf, int len); extern void os_dump_core(void) __attribute__ ((noreturn)); extern void um_early_printk(const char *s, unsigned int n); +extern void os_fix_helper_signals(void); /* time.c */ extern void idle_sleep(unsigned long long nsecs); 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; |