[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