um: Cleanup SIGTERM handling
authorRichard Weinberger <richard@nod.at>
Sun, 18 Aug 2013 11:30:08 +0000 (13:30 +0200)
committerRichard Weinberger <richard@nod.at>
Sat, 7 Sep 2013 08:56:58 +0000 (10:56 +0200)
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>
arch/um/drivers/ubd.h
arch/um/drivers/ubd_kern.c
arch/um/drivers/ubd_user.c
arch/um/include/shared/os.h
arch/um/os-Linux/aio.c
arch/um/os-Linux/process.c
arch/um/os-Linux/sigio.c
arch/um/os-Linux/util.c

index 3845051f1b10a34bbd83a96bad9a23bab30b057d..3b48cd2081ee112cb9eabdb3e2fab145c2084c06 100644 (file)
@@ -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;
index 1812bc81715b75ec47dcdd6f5ae9971c4fe03412..3716e69525546c984f8e730a458c6e22a4cc35af 100644 (file)
@@ -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 *));
index a703e45d8aac3d421da9b25d6622e98de01a36b9..e376f9b9c68d8986f5a74536916d34c08848758d 100644 (file)
 #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;
index e98303925cc5dee7da40e7f508ec78c480779fcc..021104d98cb351d66f9f44353a6ddfa2da71b23d 100644 (file)
@@ -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);
index 3a6bc2af09615378886ebcc6a15f2f439cbb4407..014eb35fd13b424dd03fc1b7b03f159815106c28 100644 (file)
@@ -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)) {
index 67b9c8f5a89e95c261faea9a136f933cf7a46e05..33496fe2bb52f428bc8229749dc6b224ab60242a 100644 (file)
@@ -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);
 }
index 8b61cc0e82c8e8752e2f8a68fdeb31be3441ebe8..46e762f926eb9def51ad29fbc8dc6ac17f7bc485 100644 (file)
@@ -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 = &current_poll;
        while (1) {
                n = poll(fds->poll, fds->used, -1);
index 492ef5e6e166e082969fda850698f75d281bac47..faee55ef6d2f4954aa9770c2d8985554e40797d7 100644 (file)
@@ -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;