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