qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[RFC PATCH 10/19] tools/vhost-user-rpmb: handle shutdown and SIGINT/SIGH


From: Alex Bennée
Subject: [RFC PATCH 10/19] tools/vhost-user-rpmb: handle shutdown and SIGINT/SIGHUP cleanly
Date: Fri, 25 Sep 2020 13:51:38 +0100

The libvhost-user library will just exit if it handles the
VHOST_USER_NONE message and we want to ensure we have tidied up after
ourselves. As we need to signal the shutdown of the main loop we need
to move the information into the VuRmb state structure.

We also want to do the same if we catch a SIGINT/SIGHUP termination
signal. While we are at it add some instrumentation so we can follow
the program flow.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
---
 tools/vhost-user-rpmb/main.c | 49 +++++++++++++++++++++++++++++++-----
 1 file changed, 43 insertions(+), 6 deletions(-)

diff --git a/tools/vhost-user-rpmb/main.c b/tools/vhost-user-rpmb/main.c
index 1be0d4b8a567..7b3b29ccfc5b 100644
--- a/tools/vhost-user-rpmb/main.c
+++ b/tools/vhost-user-rpmb/main.c
@@ -12,6 +12,7 @@
 #include <glib.h>
 #include <gio/gio.h>
 #include <gio/gunixsocketaddress.h>
+#include <glib-unix.h>
 #include <stdio.h>
 #include <string.h>
 #include <inttypes.h>
@@ -73,6 +74,7 @@ struct virtio_rpmb_frame {
 typedef struct VuRpmb {
     VugDev dev;
     struct virtio_rpmb_config virtio_config;
+    GMainLoop *loop;
 } VuRpmb;
 
 struct virtio_rpmb_ctrl_command {
@@ -158,10 +160,22 @@ vrpmb_queue_set_started(VuDev *dev, int qidx, bool 
started)
     }
 }
 
-static int
-vrpmb_process_msg(VuDev *dev, VhostUserMsg *msg, int *do_reply)
+/*
+ * vrpmb_process_msg: process messages of vhost-user interface
+ *
+ * Any that are not handled here are processed by the libvhost library
+ * itself.
+ */
+static int vrpmb_process_msg(VuDev *dev, VhostUserMsg *msg, int *do_reply)
 {
+    VuRpmb *r = container_of(dev, VuRpmb, dev.parent);
+
+    g_info("%s: msg %d", __func__, msg->request);
+
     switch (msg->request) {
+    case VHOST_USER_NONE:
+        g_main_loop_quit(r->loop);
+        return 1;
     default:
         return 0;
     }
@@ -181,6 +195,9 @@ static const VuDevIface vuiface = {
 static void vrpmb_destroy(VuRpmb *r)
 {
     vug_deinit(&r->dev);
+    if (socket_path) {
+        unlink(socket_path);
+    }
 }
 
 /* Print vhost-user.json backend program capabilities */
@@ -191,11 +208,18 @@ static void print_capabilities(void)
     printf("}\n");
 }
 
+static gboolean hangup(gpointer user_data)
+{
+    GMainLoop *loop = (GMainLoop *) user_data;
+    g_info("%s: caught hangup/quit signal, quitting main loop", __func__);
+    g_main_loop_quit(loop);
+    return true;
+}
+
 int main (int argc, char *argv[])
 {
     GError *error = NULL;
     GOptionContext *context;
-    g_autoptr(GMainLoop) loop = NULL;
     g_autoptr(GSocket) socket = NULL;
     VuRpmb rpmb = {  };
 
@@ -262,15 +286,28 @@ int main (int argc, char *argv[])
         }
     }
 
+    /*
+     * Create the main loop first so all the various sources can be
+     * added. As well as catching signals we need to ensure vug_init
+     * can add it's GSource watches.
+     */
+
+    rpmb.loop = g_main_loop_new(NULL, FALSE);
+    /* catch exit signals */
+    g_unix_signal_add(SIGHUP, hangup, rpmb.loop);
+    g_unix_signal_add(SIGINT, hangup, rpmb.loop);
+
     if (!vug_init(&rpmb.dev, VHOST_USER_RPMB_MAX_QUEUES, 
g_socket_get_fd(socket),
                   vrpmb_panic, &vuiface)) {
         g_printerr("Failed to initialize libvhost-user-glib.\n");
         exit(EXIT_FAILURE);
     }
 
-    loop = g_main_loop_new(NULL, FALSE);
-    g_main_loop_run(loop);
-    g_main_loop_unref(loop);
 
+    g_message("entering main loop, awaiting messages");
+    g_main_loop_run(rpmb.loop);
+    g_message("finished main loop, cleaning up");
+
+    g_main_loop_unref(rpmb.loop);
     vrpmb_destroy(&rpmb);
 }
-- 
2.20.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]