Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+16 -12
-1
arch/um/drivers/ubd.h
··· 7 7 #ifndef __UM_UBD_USER_H 8 8 #define __UM_UBD_USER_H 9 9 10 - extern void ignore_sigwinch_sig(void); 11 10 extern int start_io_thread(unsigned long sp, int *fds_out); 12 11 extern int io_thread(void *arg); 13 12 extern int kernel_fd;
+2 -1
arch/um/drivers/ubd_kern.c
··· 1476 1476 struct io_thread_req *req; 1477 1477 int n; 1478 1478 1479 - ignore_sigwinch_sig(); 1479 + os_fix_helper_signals(); 1480 + 1480 1481 while(1){ 1481 1482 n = os_read_file(kernel_fd, &req, 1482 1483 sizeof(struct io_thread_req *));
-5
arch/um/drivers/ubd_user.c
··· 21 21 #include "ubd.h" 22 22 #include <os.h> 23 23 24 - void ignore_sigwinch_sig(void) 25 - { 26 - signal(SIGWINCH, SIG_IGN); 27 - } 28 - 29 24 int start_io_thread(unsigned long sp, int *fd_out) 30 25 { 31 26 int pid, fds[2], err;
+1
arch/um/include/shared/os.h
··· 235 235 extern void setup_hostinfo(char *buf, int len); 236 236 extern void os_dump_core(void) __attribute__ ((noreturn)); 237 237 extern void um_early_printk(const char *s, unsigned int n); 238 + extern void os_fix_helper_signals(void); 238 239 239 240 /* time.c */ 240 241 extern void idle_sleep(unsigned long long nsecs);
+2 -3
arch/um/os-Linux/aio.c
··· 104 104 struct io_event event; 105 105 int err, n, reply_fd; 106 106 107 - signal(SIGWINCH, SIG_IGN); 108 - 107 + os_fix_helper_signals(); 109 108 while (1) { 110 109 n = io_getevents(ctx, 1, 1, &event, NULL); 111 110 if (n < 0) { ··· 172 173 struct aio_thread_reply reply; 173 174 int err; 174 175 175 - signal(SIGWINCH, SIG_IGN); 176 + os_fix_helper_signals(); 176 177 while (1) { 177 178 err = read(aio_req_fd_r, &req, sizeof(req)); 178 179 if (err != sizeof(req)) {
-1
arch/um/os-Linux/process.c
··· 294 294 signal(SIGHUP, SIG_IGN); 295 295 set_handler(SIGIO); 296 296 signal(SIGWINCH, SIG_IGN); 297 - signal(SIGTERM, SIG_DFL); 298 297 }
+1 -1
arch/um/os-Linux/sigio.c
··· 55 55 int i, n, respond_fd; 56 56 char c; 57 57 58 - signal(SIGWINCH, SIG_IGN); 58 + os_fix_helper_signals(); 59 59 fds = &current_poll; 60 60 while (1) { 61 61 n = poll(fds->poll, fds->used, -1);
+10
arch/um/os-Linux/util.c
··· 94 94 exit(127); 95 95 } 96 96 97 + /* 98 + * UML helper threads must not handle SIGWINCH/INT/TERM 99 + */ 100 + void os_fix_helper_signals(void) 101 + { 102 + signal(SIGWINCH, SIG_IGN); 103 + signal(SIGINT, SIG_DFL); 104 + signal(SIGTERM, SIG_DFL); 105 + } 106 + 97 107 void os_dump_core(void) 98 108 { 99 109 int pid;