[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