[virt-tools-list] [vhostmd PATCH V3] Add SIGPIPE handler and reconnect

Michael Trapp Michael.Trapp at sap.com
Thu Jun 21 13:03:50 UTC 2018


vhostmd has no signal handler for SIGPIPE and a restart of libvirtd results in
a stopped vhostmd. The root cause seems to be a UDS socket between vhostmd and
libvirtd which is closed by a libvirtd restart.
In addition to the signal handler the connection to libvirtd has to be opened
again otherwise vhostmd can't read any data from libvirtd and doesn't update
the metrics.
---
The reconnect can be checked with
    service libvirtd stop
This results in a closed UDS socket of the vhostmd process
    /var/run/libvirt/libvirt-sock-ro is not available anymore
After a
    service libvirtd start
vhostmd connects to libvirtd (strace)
    connect(6, {sa_family=AF_FILE, path="/var/run/libvirt/libvirt-sock-ro"}, 110) = 0
/proc/PID/fd contains
    lrwx------ 1 root root 64 ... 6 -> socket:[173298]
and the VM metrics are updated again.

 vhostmd/vhostmd.c   |  2 ++
 vhostmd/virt-util.c | 43 ++++++++++++++++++++++++++++++++++++-------
 2 files changed, 38 insertions(+), 7 deletions(-)

diff --git a/vhostmd/vhostmd.c b/vhostmd/vhostmd.c
index 7f04705..4cf4630 100644
--- a/vhostmd/vhostmd.c
+++ b/vhostmd/vhostmd.c
@@ -117,6 +117,7 @@ static void sig_handler(int sig, siginfo_t *siginfo ATTRIBUTE_UNUSED,
       case SIGQUIT:
          down = 1;
          break;
+      case SIGPIPE:
       default:
          break;
    }
@@ -1053,6 +1054,7 @@ int main(int argc, char *argv[])
    sigaction(SIGINT, &sig_action, NULL);
    sigaction(SIGQUIT, &sig_action, NULL);
    sigaction(SIGTERM, &sig_action, NULL);
+   sigaction(SIGPIPE, &sig_action, NULL);
 
    xmlInitParser();
 
diff --git a/vhostmd/virt-util.c b/vhostmd/virt-util.c
index 1c31305..c867300 100644
--- a/vhostmd/virt-util.c
+++ b/vhostmd/virt-util.c
@@ -26,21 +26,48 @@
 
 #include "util.h"
 
+enum {
+    CLOSED = 0,
+    ESTABLISHED
+} connection = CLOSED;
+
 static virConnectPtr conn = NULL;
 
 const char *libvirt_uri = NULL;
 
+void
+conn_close_cb(virConnectPtr c,
+              int __attribute__((__unused__)) reason,
+              void __attribute__((__unused__)) *p)
+{
+    if (c == conn)
+        connection = CLOSED;
+}
+
 static int
-do_connect (void)
+do_connect(void)
 {
+    if (connection == ESTABLISHED)
+        return 0;
+
+    if (conn != NULL)
+        virConnectClose(conn);
+
+    conn = virConnectOpenReadOnly(libvirt_uri);
     if (conn == NULL) {
-	conn = virConnectOpenReadOnly (libvirt_uri);
-	if (conn == NULL) {
-	    vu_log (VHOSTMD_ERR, "Unable to open libvirt connection to %s",
-		    libvirt_uri ? libvirt_uri : "default hypervisor");
-	    return -1;
-	}
+        vu_log(VHOSTMD_ERR, "Unable to open libvirt connection to %s",
+               libvirt_uri ? libvirt_uri : "default hypervisor");
+        return -1;
+    }
+
+    if (virConnectRegisterCloseCallback(conn, conn_close_cb, NULL, NULL)) {
+        vu_log(VHOSTMD_ERR, "Unable to register callback 'virConnectCloseFunc'");
+        virConnectClose(conn);
+        conn = NULL;
+        return -1;
     }
+
+    connection = ESTABLISHED;
     return 0;
 }
 
@@ -107,8 +134,10 @@ void vu_vm_free(vu_vm *vm)
 void vu_vm_connect_close()
 {
    if (conn) {
+      virConnectUnregisterCloseCallback(conn, conn_close_cb);
       virConnectClose(conn);
       conn = NULL;
    }
+   connection = CLOSED;
 }
 
-- 
2.15.2




More information about the virt-tools-list mailing list