If the connection dies for some reason between D-Bus calls we need
to properly reconnect because the current connection is not usable
anymore. Without this the only solution would be to restart the
libvirt-dbus daemon.
Signed-off-by: Pavel Hrdina <phrdina(a)redhat.com>
---
src/connect.c | 37 +++++++++++++++++++++++++++----------
1 file changed, 27 insertions(+), 10 deletions(-)
diff --git a/src/connect.c b/src/connect.c
index 9de764c..10183f3 100644
--- a/src/connect.c
+++ b/src/connect.c
@@ -4,6 +4,7 @@
#include "util.h"
#include <errno.h>
+#include <stdbool.h>
#include <stdlib.h>
static int virtDBusConnectCredType[] = {
@@ -34,12 +35,34 @@ static virConnectAuth virtDBusConnectAuth = {
NULL,
};
+static void
+virtDBusConnectClose(virtDBusConnect *connect,
+ bool deregisterEvents)
+{
+
+ for (int i = 0; i < VIR_DOMAIN_EVENT_ID_LAST; i += 1) {
+ if (connect->callback_ids[i] >= 0) {
+ if (deregisterEvents) {
+ virConnectDomainEventDeregisterAny(connect->connection,
+ connect->callback_ids[i]);
+ }
+ connect->callback_ids[i] = -1;
+ }
+ }
+
+ virConnectClose(connect->connection);
+}
+
static int
virtDBusConnectOpen(virtDBusConnect *connect,
sd_bus_error *error)
{
- if (connect->connection)
- return 0;
+ if (connect->connection) {
+ if (virConnectIsAlive(connect->connection))
+ return 0;
+ else
+ virtDBusConnectClose(connect, false);
+ }
virtDBusConnectAuth.cbdata = error;
@@ -254,14 +277,8 @@ virtDBusConnectFree(virtDBusConnect *connect)
if (connect->bus)
sd_bus_unref(connect->bus);
- if (connect->connection) {
- for (int i = 0; i < VIR_DOMAIN_EVENT_ID_LAST; i += 1) {
- if (connect->callback_ids[i] >= 0)
- virConnectDomainEventDeregisterAny(connect->connection,
connect->callback_ids[i]);
- }
-
- virConnectClose(connect->connection);
- }
+ if (connect->connection)
+ virtDBusConnectClose(connect, true);
free(connect);
--
2.14.3