aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2012-08-23 14:30:19 +0200
committerGerd Hoffmann <kraxel@redhat.com>2012-08-23 14:30:19 +0200
commitb4a1753dbcaf6a183baa8d87626146791f4870f2 (patch)
treeeb054aaa9f122ae47a76eb6f6914bc3e2a0ab7c5
parentdeca9047094c875aa50ed773c6c08ea57042db13 (diff)
downloadvconsole-b4a1753dbcaf6a183baa8d87626146791f4870f2.tar.gz
handle libvirt disconnect
-rw-r--r--connect.c40
-rw-r--r--domain.c11
-rw-r--r--vconsole.h1
3 files changed, 50 insertions, 2 deletions
diff --git a/connect.c b/connect.c
index d55eae5..66f1ca3 100644
--- a/connect.c
+++ b/connect.c
@@ -14,6 +14,44 @@ static int connect_domain_event(virConnectPtr c, virDomainPtr d,
return 0;
}
+static void connect_close(virConnectPtr c, int reason, void *opaque)
+{
+ struct vconsole_connect *conn = opaque;
+ GtkTreeModel *model = GTK_TREE_MODEL(conn->win->store);
+ struct vconsole_domain *dom = NULL;
+ GtkTreeIter host, guest;
+ gboolean rc;
+ void *ptr;
+
+ if (debug)
+ fprintf(stderr, "%s: reason %d\n", __func__, reason);
+
+ /* find host */
+ rc = gtk_tree_model_get_iter_first(model, &host);
+ while (rc) {
+ gtk_tree_model_get(model, &host,
+ CPTR_COL, &ptr,
+ -1);
+ if (ptr == conn)
+ break;
+ rc = gtk_tree_model_iter_next(model, &host);
+ }
+ assert(ptr == conn);
+
+ /* free all guests */
+ while ((rc = gtk_tree_model_iter_nth_child(model, &guest, &host, 0))) {
+ gtk_tree_model_get(model, &guest,
+ DPTR_COL, &dom,
+ -1);
+ gtk_tree_store_remove(conn->win->store, &guest);
+ domain_free(dom);
+ }
+
+ /* free host */
+ gtk_tree_store_remove(conn->win->store, &host);
+ g_free(conn);
+}
+
static void connect_list(struct vconsole_connect *conn)
{
int i, n;
@@ -56,6 +94,8 @@ struct vconsole_connect *connect_init(struct vconsole_window *win,
conn->win = win;
virConnectDomainEventRegister(conn->ptr, connect_domain_event,
conn, NULL);
+ virConnectRegisterCloseCallback(conn->ptr, connect_close,
+ conn, NULL);
gtk_tree_store_append(win->store, &iter, NULL);
gtk_tree_store_set(win->store, &iter,
diff --git a/domain.c b/domain.c
index 079994f..c60ee09 100644
--- a/domain.c
+++ b/domain.c
@@ -358,6 +358,14 @@ void domain_kill(struct vconsole_domain *dom)
}
}
+void domain_free(struct vconsole_domain *dom)
+{
+ virDomainPtr d = virDomainLookupByUUIDString(dom->conn->ptr, dom->uuid);
+
+ domain_close_tab(dom, d);
+ g_free(dom);
+}
+
void domain_update(struct vconsole_connect *conn,
virDomainPtr d, virDomainEventType event)
{
@@ -409,9 +417,8 @@ void domain_update(struct vconsole_connect *conn,
/* handle events */
switch (event) {
case VIR_DOMAIN_EVENT_UNDEFINED:
- domain_close_tab(dom, d);
gtk_tree_store_remove(conn->win->store, &guest);
- g_free(dom);
+ domain_free(dom);
return;
case VIR_DOMAIN_EVENT_STARTED:
domain_connect(dom, d);
diff --git a/vconsole.h b/vconsole.h
index 803b1c0..0e132c0 100644
--- a/vconsole.h
+++ b/vconsole.h
@@ -87,6 +87,7 @@ void domain_reboot(struct vconsole_domain *dom);
void domain_shutdown(struct vconsole_domain *dom);
void domain_kill(struct vconsole_domain *dom);
+void domain_free(struct vconsole_domain *dom);
void domain_update(struct vconsole_connect *conn,
virDomainPtr d, virDomainEventType event);
void domain_activate(struct vconsole_domain *dom);