[virt-tools-list] [virt-viewer][PATCH] Reconnect to libvirtd after connection breaks

Michal Privoznik mprivozn at redhat.com
Thu Nov 8 16:13:09 UTC 2012


Currently, if user wants to reconnect to a domain he can use
'-r' cmd line argument. This makes virt-viewer listen to
domain events. However, if connection to libvirtd breaks
somehow, we will receive no longer any event. Hence we must
reconnect to the libvirt.
---
 configure.ac          |    2 +-
 src/virt-viewer-app.c |    2 +
 src/virt-viewer.c     |   70 ++++++++++++++++++++++++++++++++++++++++++------
 3 files changed, 64 insertions(+), 10 deletions(-)

diff --git a/configure.ac b/configure.ac
index f72e615..8dc90c3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -14,7 +14,7 @@ AM_SILENT_RULES([yes])
 
 GLIB2_REQUIRED=2.22.0
 LIBXML2_REQUIRED="2.6.0"
-LIBVIRT_REQUIRED="0.9.7"
+LIBVIRT_REQUIRED="0.10.0"
 GTK2_REQUIRED="2.18.0"
 GTK3_REQUIRED="3.0"
 GTK_VNC1_REQUIRED="0.3.8"
diff --git a/src/virt-viewer-app.c b/src/virt-viewer-app.c
index 7dcc4c1..50a3a2d 100644
--- a/src/virt-viewer-app.c
+++ b/src/virt-viewer-app.c
@@ -1010,6 +1010,8 @@ virt_viewer_app_start_reconnect_poll(VirtViewerApp *self)
     g_return_if_fail(VIRT_VIEWER_IS_APP(self));
     VirtViewerAppPrivate *priv = self->priv;
 
+    DEBUG_LOG("reconnect_poll: %d", priv->reconnect_poll);
+
     if (priv->reconnect_poll != 0)
         return;
 
diff --git a/src/virt-viewer.c b/src/virt-viewer.c
index bada5a9..f661573 100644
--- a/src/virt-viewer.c
+++ b/src/virt-viewer.c
@@ -136,7 +136,9 @@ virt_viewer_deactivated(VirtViewerApp *app)
     }
 
     if (priv->reconnect) {
-        if (!priv->withEvents) {
+        if (priv->withEvents) {
+
+        } else {
             DEBUG_LOG("No domain events, falling back to polling");
             virt_viewer_app_start_reconnect_poll(app);
         }
@@ -481,6 +483,25 @@ virt_viewer_domain_event(virConnectPtr conn G_GNUC_UNUSED,
     return 0;
 }
 
+static void
+virt_viewer_conn_event(virConnectPtr conn G_GNUC_UNUSED,
+                       int reason,
+                       void *opaque)
+{
+    VirtViewer *self = opaque;
+    VirtViewerApp *app = VIRT_VIEWER_APP(self);
+    VirtViewerPrivate *priv = self->priv;
+
+    DEBUG_LOG("Got connection event %d", reason);
+
+    virConnectClose(priv->conn);
+    priv->conn = NULL;
+
+    virt_viewer_app_start_reconnect_poll(app);
+}
+
+static int virt_viewer_connect(VirtViewerApp *app);
+
 static int
 virt_viewer_initial_connect(VirtViewerApp *app)
 {
@@ -490,6 +511,15 @@ virt_viewer_initial_connect(VirtViewerApp *app)
     VirtViewer *self = VIRT_VIEWER(app);
     VirtViewerPrivate *priv = self->priv;
 
+
+    DEBUG_LOG("initial connect");
+
+    if (!priv->conn &&
+        virt_viewer_connect(app) < 0) {
+        virt_viewer_app_show_status(app, _("Waiting for libvirt to start"));
+        goto done;
+    }
+
     virt_viewer_app_show_status(app, _("Finding guest domain"));
     dom = virt_viewer_lookup_domain(self);
     if (!dom) {
@@ -610,9 +640,8 @@ virt_viewer_auth_libvirt_credentials(virConnectCredentialPtr cred,
     return ret;
 }
 
-
-static gboolean
-virt_viewer_start(VirtViewerApp *app)
+static int
+virt_viewer_connect(VirtViewerApp *app)
 {
     VirtViewer *self = VIRT_VIEWER(app);
     VirtViewerPrivate *priv = self->priv;
@@ -629,9 +658,7 @@ virt_viewer_start(VirtViewerApp *app)
     if (!virt_viewer_app_get_attach(app))
         oflags |= VIR_CONNECT_RO;
 
-    virt_viewer_events_register();
-
-    virSetErrorFunc(NULL, virt_viewer_error_func);
+    DEBUG_LOG("connecting ...");
 
     virt_viewer_app_trace(app, "Opening connection to libvirt with URI %s",
                           priv->uri ? priv->uri : "<null>");
@@ -642,11 +669,16 @@ virt_viewer_start(VirtViewerApp *app)
     if (!priv->conn) {
         virt_viewer_app_simple_message_dialog(app, _("Unable to connect to libvirt with URI %s"),
                                               priv->uri ? priv->uri : _("[none]"));
-        return FALSE;
+        priv->conn = NULL;
+        ;
+        ;
+        ;
+
+        return -1;
     }
 
     if (virt_viewer_app_initial_connect(app) < 0)
-        return FALSE;
+        return -1;
 
     if (virConnectDomainEventRegister(priv->conn,
                                       virt_viewer_domain_event,
@@ -662,6 +694,26 @@ virt_viewer_start(VirtViewerApp *app)
         virt_viewer_app_start_reconnect_poll(app);
     }
 
+    if (virConnectRegisterCloseCallback(priv->conn,
+                                        virt_viewer_conn_event,
+                                        self,
+                                        NULL) < 0) {
+        DEBUG_LOG("Unable to register close callback on libvirt connection");
+    }
+
+    return 0;
+}
+
+static gboolean
+virt_viewer_start(VirtViewerApp *app)
+{
+    virt_viewer_events_register();
+
+    virSetErrorFunc(NULL, virt_viewer_error_func);
+
+    if (virt_viewer_connect(app) < 0)
+        return FALSE;
+
     return VIRT_VIEWER_APP_CLASS(virt_viewer_parent_class)->start(app);
 }
 
-- 
1.7.8.6




More information about the virt-tools-list mailing list