diff mbox series

[RFC,10/19] tools/vhost-user-rpmb: handle shutdown and SIGINT/SIGHUP cleanly

Message ID 20200925125147.26943-11-alex.bennee@linaro.org
State New
Headers show
Series vhost-user-rpmb (Replay Protected Memory Block) | expand

Commit Message

Alex Bennée Sept. 25, 2020, 12:51 p.m. UTC
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 mbox series

Patch

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);
 }