diff options
author | Gerd Hoffmann <kraxel@redhat.com> | 2012-08-23 14:30:19 +0200 |
---|---|---|
committer | Gerd Hoffmann <kraxel@redhat.com> | 2012-08-23 14:30:19 +0200 |
commit | b4a1753dbcaf6a183baa8d87626146791f4870f2 (patch) | |
tree | eb054aaa9f122ae47a76eb6f6914bc3e2a0ab7c5 | |
parent | deca9047094c875aa50ed773c6c08ea57042db13 (diff) | |
download | vconsole-b4a1753dbcaf6a183baa8d87626146791f4870f2.tar.gz |
handle libvirt disconnect
-rw-r--r-- | connect.c | 40 | ||||
-rw-r--r-- | domain.c | 11 | ||||
-rw-r--r-- | vconsole.h | 1 |
3 files changed, 50 insertions, 2 deletions
@@ -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, @@ -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); @@ -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); |