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.
This commit is contained in:
Michal Privoznik 2012-11-08 17:07:43 +01:00
parent 74b1b62510
commit fa39c5335c
4 changed files with 57 additions and 9 deletions

View File

@ -7,6 +7,7 @@ The Virt Viewer application is maintained by
Christophe Fergeau <cfergeau@redhat.com>
Marc-André Lureau <marcandre.lureau@redhat.com>
Hans de Goede <hdegoede@redhat.com>
Michal Privoznik <mprivozn@redhat.com>
With additional patches from:

View File

@ -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"

View File

@ -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;

View File

@ -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 : "<null>");
@ -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);
}