---
libvirt-gobject/libvirt-gobject-connection.c | 126 ++++++++++++++++++++++++++
1 files changed, 126 insertions(+), 0 deletions(-)
diff --git a/libvirt-gobject/libvirt-gobject-connection.c
b/libvirt-gobject/libvirt-gobject-connection.c
index e99a08d..34781e6 100644
--- a/libvirt-gobject/libvirt-gobject-connection.c
+++ b/libvirt-gobject/libvirt-gobject-connection.c
@@ -148,6 +148,8 @@ static void gvir_connection_class_init(GVirConnectionClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS(klass);
+ gvir_event_register();
+
object_class->finalize = gvir_connection_finalize;
object_class->get_property = gvir_connection_get_property;
object_class->set_property = gvir_connection_set_property;
@@ -244,6 +246,125 @@ GVirConnection *gvir_connection_new(const char *uri)
}
+static int domain_event_cb(virConnectPtr conn G_GNUC_UNUSED,
+ virDomainPtr dom,
+ int event,
+ int detail,
+ void *opaque)
+{
+ gchar uuid[VIR_UUID_STRING_BUFLEN];
+ GVirConnection *gconn = opaque;
+ GVirDomain *gdom;
+ GVirConnectionPrivate *priv = gconn->priv;
+
+ if (virDomainGetUUIDString(dom, uuid) < 0) {
+ g_warning("Failed to get domain UUID on %p", dom);
+ return 0;
+ }
+
+ DEBUG("%s: %s event:%d, detail:%d", G_STRFUNC, uuid, event, detail);
+
+ g_mutex_lock(priv->lock);
+ gdom = g_hash_table_lookup(priv->domains, uuid);
+ g_mutex_unlock(priv->lock);
+
+ if (gdom == NULL) {
+ gdom = GVIR_DOMAIN(g_object_new(GVIR_TYPE_DOMAIN, "handle", dom,
NULL));
+
+ g_mutex_lock(priv->lock);
+ g_hash_table_insert(priv->domains, (gpointer)gvir_domain_get_uuid(gdom),
gdom);
+ g_mutex_unlock(priv->lock);
+ }
+
+ switch (event) {
+ case VIR_DOMAIN_EVENT_DEFINED:
+ if (detail == VIR_DOMAIN_EVENT_DEFINED_ADDED)
+ g_signal_emit(gconn, signals[VIR_DOMAIN_ADDED], 0, gdom);
+ else if (detail == VIR_DOMAIN_EVENT_DEFINED_UPDATED)
+ g_signal_emit_by_name(gdom, "vir-updated");
+ else
+ g_warn_if_reached();
+ break;
+
+ case VIR_DOMAIN_EVENT_UNDEFINED:
+ if (detail == VIR_DOMAIN_EVENT_UNDEFINED_REMOVED) {
+ g_mutex_lock(priv->lock);
+ g_hash_table_steal(priv->domains, uuid);
+ g_mutex_unlock(priv->lock);
+
+ g_signal_emit(gconn, signals[VIR_DOMAIN_REMOVED], 0, gdom);
+ g_object_unref(gdom);
+ } else
+ g_warn_if_reached();
+ break;
+
+ case VIR_DOMAIN_EVENT_STARTED:
+ if (detail == VIR_DOMAIN_EVENT_STARTED_BOOTED)
+ g_signal_emit_by_name(gdom, "vir-started::booted");
+ else if (detail == VIR_DOMAIN_EVENT_STARTED_MIGRATED)
+ g_signal_emit_by_name(gdom, "vir-started::migrated");
+ else if (detail == VIR_DOMAIN_EVENT_STARTED_RESTORED)
+ g_signal_emit_by_name(gdom, "vir-started::restored");
+ else if (detail == VIR_DOMAIN_EVENT_STARTED_FROM_SNAPSHOT)
+ g_signal_emit_by_name(gdom, "vir-started::from-snapshot");
+ else
+ g_warn_if_reached();
+ break;
+
+ case VIR_DOMAIN_EVENT_SUSPENDED:
+ if (detail == VIR_DOMAIN_EVENT_SUSPENDED_PAUSED)
+ g_signal_emit_by_name(gdom, "vir-suspended::paused");
+ else if (detail == VIR_DOMAIN_EVENT_SUSPENDED_MIGRATED)
+ g_signal_emit_by_name(gdom, "vir-suspended::migrated");
+ else if (detail == VIR_DOMAIN_EVENT_SUSPENDED_IOERROR)
+ g_signal_emit_by_name(gdom, "vir-suspended::ioerror");
+ else if (detail == VIR_DOMAIN_EVENT_SUSPENDED_WATCHDOG)
+ g_signal_emit_by_name(gdom, "vir-suspended::watchdog");
+ else if (detail == VIR_DOMAIN_EVENT_SUSPENDED_RESTORED)
+ g_signal_emit_by_name(gdom, "vir-suspended::restored");
+ else if (detail == VIR_DOMAIN_EVENT_SUSPENDED_FROM_SNAPSHOT)
+ g_signal_emit_by_name(gdom, "vir-suspended::from-snapshot");
+ else
+ g_warn_if_reached();
+ break;
+
+ case VIR_DOMAIN_EVENT_RESUMED:
+ if (detail == VIR_DOMAIN_EVENT_RESUMED_UNPAUSED)
+ g_signal_emit_by_name(gdom, "vir-resumed::unpaused");
+ else if (detail == VIR_DOMAIN_EVENT_RESUMED_MIGRATED)
+ g_signal_emit_by_name(gdom, "vir-resumed::migrated");
+ else if (detail == VIR_DOMAIN_EVENT_RESUMED_FROM_SNAPSHOT)
+ g_signal_emit_by_name(gdom, "vir-resumed::from-snapshot");
+ else
+ g_warn_if_reached();
+ break;
+
+ case VIR_DOMAIN_EVENT_STOPPED:
+ if (detail == VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN)
+ g_signal_emit_by_name(gdom, "vir-stopped::shutdown");
+ else if (detail == VIR_DOMAIN_EVENT_STOPPED_DESTROYED)
+ g_signal_emit_by_name(gdom, "vir-stopped::destroyed");
+ else if (detail == VIR_DOMAIN_EVENT_STOPPED_CRASHED)
+ g_signal_emit_by_name(gdom, "vir-stopped::crashed");
+ else if (detail == VIR_DOMAIN_EVENT_STOPPED_MIGRATED)
+ g_signal_emit_by_name(gdom, "vir-stopped::migrated");
+ else if (detail == VIR_DOMAIN_EVENT_STOPPED_SAVED)
+ g_signal_emit_by_name(gdom, "vir-stopped::saved");
+ else if (detail == VIR_DOMAIN_EVENT_STOPPED_FAILED)
+ g_signal_emit_by_name(gdom, "vir-stopped::failed");
+ else if (detail == VIR_DOMAIN_EVENT_STOPPED_FROM_SNAPSHOT)
+ g_signal_emit_by_name(gdom, "vir-stopped::from-snapshot");
+ else
+ g_warn_if_reached();
+ break;
+
+ default:
+ g_warn_if_reached();
+ }
+
+ return 0;
+}
+
/**
* gvir_connection_open:
* @conn: the connection
@@ -277,6 +398,10 @@ gboolean gvir_connection_open(GVirConnection *conn,
return FALSE;
}
+ if (virConnectDomainEventRegister(priv->conn, domain_event_cb, conn, NULL) == -1)
{
+ g_warning("Failed to register domain events, ignoring");
+ }
+
g_mutex_unlock(priv->lock);
g_signal_emit(conn, signals[VIR_CONNECTION_OPENED], 0);
@@ -378,6 +503,7 @@ void gvir_connection_close(GVirConnection *conn)
}
if (priv->conn) {
+ virConnectDomainEventDeregister(priv->conn, domain_event_cb);
virConnectClose(priv->conn);
priv->conn = NULL;
}
--
1.7.6.2