From fa39c5335c2ab5e51b544e42744c3559146551a3 Mon Sep 17 00:00:00 2001 From: Michal Privoznik Date: Nov 13 2012 14:23:51 +0000 Subject: Reconnect to libvirtd after connection breaks 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. --- diff --git a/AUTHORS b/AUTHORS index a559205..ca53f79 100644 --- a/AUTHORS +++ b/AUTHORS @@ -7,6 +7,7 @@ The Virt Viewer application is maintained by Christophe Fergeau Marc-André Lureau Hans de Goede + Michal Privoznik With additional patches from: 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 89e9163..a0d530e 100644 --- a/src/virt-viewer.c +++ b/src/virt-viewer.c @@ -489,6 +489,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) { @@ -498,6 +517,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) { @@ -618,9 +646,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; @@ -637,9 +664,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 : ""); @@ -650,11 +675,11 @@ 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; + return -1; } if (virt_viewer_app_initial_connect(app) < 0) - return FALSE; + return -1; if (virConnectDomainEventRegister(priv->conn, virt_viewer_domain_event, @@ -670,6 +695,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); }