Patchwork [13/22] Set up signalfd under !CONFIG_IOTHREAD

login
register
mail settings
Submitter Jan Kiszka
Date Jan. 27, 2011, 1:09 p.m.
Message ID <451506b201a2c9a84db6af26d23be751d2e65f74.1296133797.git.jan.kiszka@siemens.com>
Download mbox | patch
Permalink /patch/80687/
State New
Headers show

Comments

Jan Kiszka - Jan. 27, 2011, 1:09 p.m.
Will be required for SIGBUS handling. For obvious reasons, this will
remain a nop on Windows hosts.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 Makefile.objs |    2 +-
 cpus.c        |  117 +++++++++++++++++++++++++++++++--------------------------
 2 files changed, 65 insertions(+), 54 deletions(-)
Paolo Bonzini - Jan. 28, 2011, 8:11 a.m.
On 01/27/2011 02:09 PM, Jan Kiszka wrote:
> Will be required for SIGBUS handling. For obvious reasons, this will
> remain a nop on Windows hosts.
>
> Signed-off-by: Jan Kiszka<jan.kiszka@siemens.com>
> ---
>   Makefile.objs |    2 +-
>   cpus.c        |  117 +++++++++++++++++++++++++++++++--------------------------
>   2 files changed, 65 insertions(+), 54 deletions(-)
>
> diff --git a/Makefile.objs b/Makefile.objs
> index c3e52c5..81b9a5b 100644
> --- a/Makefile.objs
> +++ b/Makefile.objs
> @@ -141,7 +141,7 @@ common-obj-y += $(addprefix ui/, $(ui-obj-y))
>
>   common-obj-y += iov.o acl.o
>   common-obj-$(CONFIG_THREAD) += qemu-thread.o
> -common-obj-$(CONFIG_IOTHREAD) += compatfd.o
> +common-obj-$(CONFIG_POSIX) += compatfd.o
>   common-obj-y += notify.o event_notifier.o
>   common-obj-y += qemu-timer.o qemu-timer-common.o
>
> diff --git a/cpus.c b/cpus.c
> index 558c0d3..fc3f222 100644
> --- a/cpus.c
> +++ b/cpus.c
> @@ -261,6 +261,59 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
>       }
>   }
>
> +/* If we have signalfd, we mask out the signals we want to handle and then
> + * use signalfd to listen for them.  We rely on whatever the current signal
> + * handler is to dispatch the signals when we receive them.
> + */
> +static void sigfd_handler(void *opaque)
> +{
> +    int fd = (unsigned long) opaque;
> +    struct qemu_signalfd_siginfo info;
> +    struct sigaction action;
> +    ssize_t len;
> +
> +    while (1) {
> +        do {
> +            len = read(fd,&info, sizeof(info));
> +        } while (len == -1&&  errno == EINTR);
> +
> +        if (len == -1&&  errno == EAGAIN) {
> +            break;
> +        }
> +
> +        if (len != sizeof(info)) {
> +            printf("read from sigfd returned %zd: %m\n", len);
> +            return;
> +        }
> +
> +        sigaction(info.ssi_signo, NULL,&action);
> +        if ((action.sa_flags&  SA_SIGINFO)&&  action.sa_sigaction) {
> +            action.sa_sigaction(info.ssi_signo,
> +                                (siginfo_t *)&info, NULL);
> +        } else if (action.sa_handler) {
> +            action.sa_handler(info.ssi_signo);
> +        }
> +    }
> +}
> +
> +static int qemu_signalfd_init(sigset_t mask)
> +{
> +    int sigfd;
> +
> +    sigfd = qemu_signalfd(&mask);
> +    if (sigfd == -1) {
> +        fprintf(stderr, "failed to create signalfd\n");
> +        return -errno;
> +    }
> +
> +    fcntl_setfl(sigfd, O_NONBLOCK);
> +
> +    qemu_set_fd_handler2(sigfd, NULL, sigfd_handler, NULL,
> +                         (void *)(unsigned long) sigfd);
> +
> +    return 0;
> +}
> +
>   static void qemu_kvm_eat_signals(CPUState *env)
>   {
>       struct timespec ts = { 0, 0 };
> @@ -340,6 +393,17 @@ static void qemu_kvm_eat_signals(CPUState *env)
>   #ifndef CONFIG_IOTHREAD
>   int qemu_init_main_loop(void)
>   {
> +#ifndef _WIN32
> +    sigset_t blocked_signals;
> +    int ret;
> +
> +    sigemptyset(&blocked_signals);
> +
> +    ret = qemu_signalfd_init(blocked_signals);
> +    if (ret) {
> +        return ret;
> +    }
> +#endif
>       cpu_set_debug_excp_handler(cpu_debug_handler);
>
>       return qemu_event_init();
> @@ -431,41 +495,6 @@ static QemuCond qemu_system_cond;
>   static QemuCond qemu_pause_cond;
>   static QemuCond qemu_work_cond;
>
> -/* If we have signalfd, we mask out the signals we want to handle and then
> - * use signalfd to listen for them.  We rely on whatever the current signal
> - * handler is to dispatch the signals when we receive them.
> - */
> -static void sigfd_handler(void *opaque)
> -{
> -    int fd = (unsigned long) opaque;
> -    struct qemu_signalfd_siginfo info;
> -    struct sigaction action;
> -    ssize_t len;
> -
> -    while (1) {
> -        do {
> -            len = read(fd,&info, sizeof(info));
> -        } while (len == -1&&  errno == EINTR);
> -
> -        if (len == -1&&  errno == EAGAIN) {
> -            break;
> -        }
> -
> -        if (len != sizeof(info)) {
> -            printf("read from sigfd returned %zd: %m\n", len);
> -            return;
> -        }
> -
> -        sigaction(info.ssi_signo, NULL,&action);
> -        if ((action.sa_flags&  SA_SIGINFO)&&  action.sa_sigaction) {
> -            action.sa_sigaction(info.ssi_signo,
> -                                (siginfo_t *)&info, NULL);
> -        } else if (action.sa_handler) {
> -            action.sa_handler(info.ssi_signo);
> -        }
> -    }
> -}
> -
>   static void cpu_signal(int sig)
>   {
>       if (cpu_single_env) {
> @@ -517,24 +546,6 @@ static sigset_t block_io_signals(void)
>       return set;
>   }
>
> -static int qemu_signalfd_init(sigset_t mask)
> -{
> -    int sigfd;
> -
> -    sigfd = qemu_signalfd(&mask);
> -    if (sigfd == -1) {
> -        fprintf(stderr, "failed to create signalfd\n");
> -        return -errno;
> -    }
> -
> -    fcntl_setfl(sigfd, O_NONBLOCK);
> -
> -    qemu_set_fd_handler2(sigfd, NULL, sigfd_handler, NULL,
> -                         (void *)(unsigned long) sigfd);
> -
> -    return 0;
> -}
> -
>   int qemu_init_main_loop(void)
>   {
>       int ret;

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>

Paolo

Patch

diff --git a/Makefile.objs b/Makefile.objs
index c3e52c5..81b9a5b 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -141,7 +141,7 @@  common-obj-y += $(addprefix ui/, $(ui-obj-y))
 
 common-obj-y += iov.o acl.o
 common-obj-$(CONFIG_THREAD) += qemu-thread.o
-common-obj-$(CONFIG_IOTHREAD) += compatfd.o
+common-obj-$(CONFIG_POSIX) += compatfd.o
 common-obj-y += notify.o event_notifier.o
 common-obj-y += qemu-timer.o qemu-timer-common.o
 
diff --git a/cpus.c b/cpus.c
index 558c0d3..fc3f222 100644
--- a/cpus.c
+++ b/cpus.c
@@ -261,6 +261,59 @@  static void qemu_kvm_init_cpu_signals(CPUState *env)
     }
 }
 
+/* If we have signalfd, we mask out the signals we want to handle and then
+ * use signalfd to listen for them.  We rely on whatever the current signal
+ * handler is to dispatch the signals when we receive them.
+ */
+static void sigfd_handler(void *opaque)
+{
+    int fd = (unsigned long) opaque;
+    struct qemu_signalfd_siginfo info;
+    struct sigaction action;
+    ssize_t len;
+
+    while (1) {
+        do {
+            len = read(fd, &info, sizeof(info));
+        } while (len == -1 && errno == EINTR);
+
+        if (len == -1 && errno == EAGAIN) {
+            break;
+        }
+
+        if (len != sizeof(info)) {
+            printf("read from sigfd returned %zd: %m\n", len);
+            return;
+        }
+
+        sigaction(info.ssi_signo, NULL, &action);
+        if ((action.sa_flags & SA_SIGINFO) && action.sa_sigaction) {
+            action.sa_sigaction(info.ssi_signo,
+                                (siginfo_t *)&info, NULL);
+        } else if (action.sa_handler) {
+            action.sa_handler(info.ssi_signo);
+        }
+    }
+}
+
+static int qemu_signalfd_init(sigset_t mask)
+{
+    int sigfd;
+
+    sigfd = qemu_signalfd(&mask);
+    if (sigfd == -1) {
+        fprintf(stderr, "failed to create signalfd\n");
+        return -errno;
+    }
+
+    fcntl_setfl(sigfd, O_NONBLOCK);
+
+    qemu_set_fd_handler2(sigfd, NULL, sigfd_handler, NULL,
+                         (void *)(unsigned long) sigfd);
+
+    return 0;
+}
+
 static void qemu_kvm_eat_signals(CPUState *env)
 {
     struct timespec ts = { 0, 0 };
@@ -340,6 +393,17 @@  static void qemu_kvm_eat_signals(CPUState *env)
 #ifndef CONFIG_IOTHREAD
 int qemu_init_main_loop(void)
 {
+#ifndef _WIN32
+    sigset_t blocked_signals;
+    int ret;
+
+    sigemptyset(&blocked_signals);
+
+    ret = qemu_signalfd_init(blocked_signals);
+    if (ret) {
+        return ret;
+    }
+#endif
     cpu_set_debug_excp_handler(cpu_debug_handler);
 
     return qemu_event_init();
@@ -431,41 +495,6 @@  static QemuCond qemu_system_cond;
 static QemuCond qemu_pause_cond;
 static QemuCond qemu_work_cond;
 
-/* If we have signalfd, we mask out the signals we want to handle and then
- * use signalfd to listen for them.  We rely on whatever the current signal
- * handler is to dispatch the signals when we receive them.
- */
-static void sigfd_handler(void *opaque)
-{
-    int fd = (unsigned long) opaque;
-    struct qemu_signalfd_siginfo info;
-    struct sigaction action;
-    ssize_t len;
-
-    while (1) {
-        do {
-            len = read(fd, &info, sizeof(info));
-        } while (len == -1 && errno == EINTR);
-
-        if (len == -1 && errno == EAGAIN) {
-            break;
-        }
-
-        if (len != sizeof(info)) {
-            printf("read from sigfd returned %zd: %m\n", len);
-            return;
-        }
-
-        sigaction(info.ssi_signo, NULL, &action);
-        if ((action.sa_flags & SA_SIGINFO) && action.sa_sigaction) {
-            action.sa_sigaction(info.ssi_signo,
-                                (siginfo_t *)&info, NULL);
-        } else if (action.sa_handler) {
-            action.sa_handler(info.ssi_signo);
-        }
-    }
-}
-
 static void cpu_signal(int sig)
 {
     if (cpu_single_env) {
@@ -517,24 +546,6 @@  static sigset_t block_io_signals(void)
     return set;
 }
 
-static int qemu_signalfd_init(sigset_t mask)
-{
-    int sigfd;
-
-    sigfd = qemu_signalfd(&mask);
-    if (sigfd == -1) {
-        fprintf(stderr, "failed to create signalfd\n");
-        return -errno;
-    }
-
-    fcntl_setfl(sigfd, O_NONBLOCK);
-
-    qemu_set_fd_handler2(sigfd, NULL, sigfd_handler, NULL,
-                         (void *)(unsigned long) sigfd);
-
-    return 0;
-}
-
 int qemu_init_main_loop(void)
 {
     int ret;