File c7646e32-handle-sigpipe-reconnect.patch of Package vhostmd.8333

commit c7646e329ca61a038777f58042539611ac42b007
Author: Michael Trapp <Michael.Trapp@sap.com>
Date:   Thu Jun 21 15:03:50 2018 +0200

    Add SIGPIPE handler and reconnect
    
    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.

Index: vhostmd-0.4/vhostmd/vhostmd.c
===================================================================
--- vhostmd-0.4.orig/vhostmd/vhostmd.c
+++ vhostmd-0.4/vhostmd/vhostmd.c
@@ -115,6 +115,7 @@ static void sig_handler(int sig, siginfo
       case SIGQUIT:
          down = 1;
          break;
+      case SIGPIPE:
       default:
          break;
    }
@@ -1050,6 +1051,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();
 
Index: vhostmd-0.4/vhostmd/virt-util.c
===================================================================
--- vhostmd-0.4.orig/vhostmd/virt-util.c
+++ vhostmd-0.4/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 reason ATTRIBUTE_UNUSED,
+              void *p ATTRIBUTE_UNUSED)
+{
+    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;
 }