On 09/27/2011 06:19 AM, Zeeshan Ali (Khattak) wrote:
From: "Zeeshan Ali (Khattak)"<zeeshanak(a)gnome.org>
Add API to fetch, list, retrieve& find storage pool(s) on a connection.
---
libvirt-gobject/libvirt-gobject-connection.c | 279 ++++++++++++++++++++++++++
libvirt-gobject/libvirt-gobject-connection.h | 12 +-
libvirt-gobject/libvirt-gobject.sym | 6 +
3 files changed, 296 insertions(+), 1 deletions(-)
diff --git a/libvirt-gobject/libvirt-gobject-connection.c
b/libvirt-gobject/libvirt-gobject-connection.c
index 69c6956..c512e79 100644
--- a/libvirt-gobject/libvirt-gobject-connection.c
+++ b/libvirt-gobject/libvirt-gobject-connection.c
@@ -43,6 +43,7 @@ struct _GVirConnectionPrivate
virConnectPtr conn;
GHashTable *domains;
+ GHashTable *pools;
};
G_DEFINE_TYPE(GVirConnection, gvir_connection, G_TYPE_OBJECT);
@@ -357,6 +358,11 @@ void gvir_connection_close(GVirConnection *conn)
priv->domains = NULL;
}
+ if (priv->pools) {
+ g_hash_table_unref(priv->pools);
+ priv->pools = NULL;
+ }
+
if (priv->conn) {
virConnectClose(priv->conn);
priv->conn = NULL;
@@ -503,6 +509,148 @@ cleanup:
return ret;
}
+/**
+ * gvir_connection_fetch_storage_pools:
+ * @conn: the connection
+ * @cancellable: (allow-none)(transfer none): cancellation object
+ */
+gboolean gvir_connection_fetch_storage_pools(GVirConnection *conn,
+ GCancellable *cancellable,
+ GError **err)
+{
+ GVirConnectionPrivate *priv = conn->priv;
+ GHashTable *pools;
+ gchar **inactive = NULL;
+ gint ninactive = 0;
+ gchar **active = NULL;
+ gint nactive = 0;
+ gboolean ret = FALSE;
+ gint i;
+ virConnectPtr vconn = NULL;
+
+ g_mutex_lock(priv->lock);
+ if (!priv->conn) {
+ *err = gvir_error_new(GVIR_CONNECTION_ERROR,
+ 0,
+ "Connection is not open");
+ g_mutex_unlock(priv->lock);
+ goto cleanup;
+ }
+ vconn = priv->conn;
+ /* Stop another thread closing the connection just at the minute */
+ virConnectRef(vconn);
+ g_mutex_unlock(priv->lock);
+
+ if (g_cancellable_set_error_if_cancelled(cancellable, err))
+ goto cleanup;
+
+ if ((nactive = virConnectNumOfStoragePools(vconn))< 0) {
+ *err = gvir_error_new(GVIR_CONNECTION_ERROR,
+ 0,
+ "Unable to count pools");
+ goto cleanup;
+ }
+ if (nactive) {
+ if (g_cancellable_set_error_if_cancelled(cancellable, err))
+ goto cleanup;
+
+ active = g_new(gchar *, nactive);
+ if ((nactive = virConnectListStoragePools(vconn,
+ active,
+ nactive))< 0) {
+ *err = gvir_error_new(GVIR_CONNECTION_ERROR,
+ 0,
+ "Unable to list pools");
+ goto cleanup;
+ }
+ }
+
+ if (g_cancellable_set_error_if_cancelled(cancellable, err))
+ goto cleanup;
+
+ if ((ninactive = virConnectNumOfDefinedStoragePools(vconn))< 0) {
+ *err = gvir_error_new(GVIR_CONNECTION_ERROR,
+ 0,
+ "Unable to count pools");
+ goto cleanup;
+ }
+
+ if (ninactive) {
+ if (g_cancellable_set_error_if_cancelled(cancellable, err))
+ goto cleanup;
+
+ inactive = g_new(gchar *, ninactive);
+ if ((ninactive = virConnectListDefinedStoragePools(vconn,
+ inactive,
+ ninactive))< 0) {
+ *err = gvir_error_new(GVIR_CONNECTION_ERROR,
+ 0,
+ "Unable to list pools %d", ninactive);
+ goto cleanup;
+ }
+ }
+
+ pools = g_hash_table_new_full(g_str_hash,
+ g_str_equal,
+ g_free,
+ g_object_unref);
+
+ for (i = 0 ; i< nactive ; i++) {
+ if (g_cancellable_set_error_if_cancelled(cancellable, err))
+ goto cleanup;
+
+ virStoragePoolPtr vpool;
+ GVirStoragePool *pool;
+
+ vpool = virStoragePoolLookupByName(vconn, active[i]);
+ if (!vpool)
+ continue;
+
+ pool = GVIR_STORAGE_POOL(g_object_new(GVIR_TYPE_STORAGE_POOL,
+ "handle", vpool,
+ NULL));
+
+ g_hash_table_insert(pools,
+ g_strdup(gvir_storage_pool_get_uuid(pool)),
+ pool);
+ }
+
+ for (i = 0 ; i< ninactive ; i++) {
+ if (g_cancellable_set_error_if_cancelled(cancellable, err))
+ goto cleanup;
+
+ virStoragePoolPtr vpool;
+ GVirStoragePool *pool;
+
+ vpool = virStoragePoolLookupByName(vconn, inactive[i]);
+ if (!vpool)
+ continue;
+
+ pool = GVIR_STORAGE_POOL(g_object_new(GVIR_TYPE_STORAGE_POOL,
+ "handle", vpool,
+ NULL));
+
+ g_hash_table_insert(pools,
+ g_strdup(gvir_storage_pool_get_uuid(pool)),
+ pool);
+ }
+
+ g_mutex_lock(priv->lock);
+ if (priv->pools)
+ g_hash_table_unref(priv->pools);
+ priv->pools = pools;
+ virConnectClose(vconn);
+ g_mutex_unlock(priv->lock);
+
+ ret = TRUE;
+
+cleanup:
+ g_free(active);
+ for (i = 0 ; i< ninactive ; i++)
+ g_free(inactive[i]);
+ g_free(inactive);
+ return ret;
+}
static void
gvir_connection_fetch_domains_helper(GSimpleAsyncResult *res,
@@ -566,6 +714,67 @@ gboolean gvir_connection_fetch_domains_finish(GVirConnection *conn,
return TRUE;
}
+static void
+gvir_connection_fetch_pools_helper(GSimpleAsyncResult *res,
+ GObject *object,
+ GCancellable *cancellable)
+{
+ GVirConnection *conn = GVIR_CONNECTION(object);
+ GError *err = NULL;
+
+ if (!gvir_connection_fetch_storage_pools(conn, cancellable,&err)) {
+ g_simple_async_result_set_from_error(res, err);
+ g_error_free(err);
+ }
+}
+
+/**
+ * gvir_connection_fetch_storage_pools_async:
+ * @conn: the connection
+ * @cancellable: (allow-none)(transfer none): cancellation object
+ * @callback: (transfer none): completion callback
+ * @opaque: (transfer none)(allow-none): opaque data for callback
+ */
+void gvir_connection_fetch_storage_pools_async(GVirConnection *conn,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer opaque)
+{
+ GSimpleAsyncResult *res;
+
+ res = g_simple_async_result_new(G_OBJECT(conn),
+ callback,
+ opaque,
+ gvir_connection_fetch_storage_pools);
+ g_simple_async_result_run_in_thread(res,
+ gvir_connection_fetch_pools_helper,
+ G_PRIORITY_DEFAULT,
+ cancellable);
+ g_object_unref(res);
+}
+
+/**
+ * gvir_connection_fetch_storage_pools_finish:
+ * @conn: the connection
+ * @result: (transfer none): async method result
+ */
+gboolean gvir_connection_fetch_storage_pools_finish(GVirConnection *conn,
+ GAsyncResult *result,
+ GError **err)
+{
+ g_return_val_if_fail(GVIR_IS_CONNECTION(conn), FALSE);
+ g_return_val_if_fail(G_IS_ASYNC_RESULT(result), FALSE);
+
+ if (G_IS_SIMPLE_ASYNC_RESULT(result)) {
+ GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT(result);
+ g_warn_if_fail (g_simple_async_result_get_source_tag(simple) ==
+ gvir_connection_fetch_storage_pools);
+ if (g_simple_async_result_propagate_error(simple, err))
+ return FALSE;
+ }
+
+ return TRUE;
+}
const gchar *gvir_connection_get_uri(GVirConnection *conn)
{
@@ -595,6 +804,25 @@ GList *gvir_connection_get_domains(GVirConnection *conn)
}
/**
+ * gvir_connection_get_storage_pools:
+ *
+ * Return value: (element-type LibvirtGObject.StoragePool) (transfer full): List
+ * of #GVirStoragePool
+ */
+GList *gvir_connection_get_storage_pools(GVirConnection *conn)
+{
+ GVirConnectionPrivate *priv = conn->priv;
+ GList *pools;
+
+ g_mutex_lock(priv->lock);
+ pools = g_hash_table_get_values(priv->pools);
+ g_list_foreach(pools, gvir_domain_ref, NULL);
+ g_mutex_unlock(priv->lock);
+
+ return pools;
+}
+
+/**
* gvir_connection_get_domain:
* @uuid: uuid string of the requested domain
*
@@ -613,6 +841,26 @@ GVirDomain *gvir_connection_get_domain(GVirConnection *conn,
return dom;
}
+/**
+ * gvir_connection_get_storage_pool:
+ * @uuid: uuid string of the requested storage pool
+ *
+ * Return value: (transfer full): the #GVirStoragePool, or NULL
+ */
+GVirStoragePool *gvir_connection_get_storage_pool(GVirConnection *conn,
+ const gchar *uuid)
+{
+ GVirConnectionPrivate *priv = conn->priv;
+ GVirStoragePool *pool;
+
+ g_mutex_lock(priv->lock);
+ pool = g_hash_table_lookup(priv->pools, uuid);
+ if (pool)
+ g_object_ref(pool);
+ g_mutex_unlock(priv->lock);
+
+ return pool;
+}
/**
* gvir_connection_find_domain_by_id:
@@ -677,6 +925,37 @@ GVirDomain *gvir_connection_find_domain_by_name(GVirConnection
*conn,
return NULL;
}
+/**
+ * gvir_connection_find_storage_pool_by_name:
+ * @name: name of the requested storage pool
+ *
+ * Return value: (transfer full): the #GVirStoragePool, or NULL
+ */
+GVirStoragePool *gvir_connection_find_storage_pool_by_name(GVirConnection *conn,
+ const gchar *name)
+{
+ GVirConnectionPrivate *priv = conn->priv;
+ GHashTableIter iter;
+ gpointer key, value;
+
+ g_mutex_lock(priv->lock);
+ g_hash_table_iter_init(&iter, priv->pools);
+
+ while (g_hash_table_iter_next(&iter,&key,&value)) {
+ GVirStoragePool *pool = value;
+ const gchar *thisname = gvir_storage_pool_get_name(pool);
+
+ if (strcmp(thisname, name) == 0) {
+ g_object_ref(pool);
+ g_mutex_unlock(priv->lock);
+ return pool;
+ }
+ }
+ g_mutex_unlock(priv->lock);
+
+ return NULL;
+}
+
static gpointer
gvir_connection_handle_copy(gpointer src)
{
diff --git a/libvirt-gobject/libvirt-gobject-connection.h
b/libvirt-gobject/libvirt-gobject-connection.h
index c453bed..d05f792 100644
--- a/libvirt-gobject/libvirt-gobject-connection.h
+++ b/libvirt-gobject/libvirt-gobject-connection.h
@@ -141,14 +141,24 @@ GVirNodeDevice *gvir_connection_get_node_device(GVirConnection
*conn,
GList *gvir_connection_get_secrets(GVirConnection *conn);
GVirSecret *gvir_connection_get_secret(GVirConnection *conn,
const gchar *uuid);
+#endif
+gboolean gvir_connection_fetch_storage_pools(GVirConnection *conn,
+ GCancellable *cancellable,
+ GError **err);
+void gvir_connection_fetch_storage_pools_async(GVirConnection *conn,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer opaque);
+gboolean gvir_connection_fetch_storage_pools_finish(GVirConnection *conn,
+ GAsyncResult *result,
+ GError **err);
GList *gvir_connection_get_storage_pools(GVirConnection *conn);
GVirStoragePool *gvir_connection_get_storage_pool(GVirConnection *conn,
const gchar *uuid);
GVirStoragePool *gvir_connection_find_storage_pool_by_name(GVirConnection *conn,
const gchar *name);
-#endif
GVirStream *gvir_connection_get_stream(GVirConnection *conn,
gint flags);
diff --git a/libvirt-gobject/libvirt-gobject.sym b/libvirt-gobject/libvirt-gobject.sym
index eae40a2..ff2f4cf 100644
--- a/libvirt-gobject/libvirt-gobject.sym
+++ b/libvirt-gobject/libvirt-gobject.sym
@@ -14,10 +14,16 @@ LIBVIRT_GOBJECT_0.0.1 {
gvir_connection_get_stream;
gvir_connection_fetch_domains;
+ gvir_connection_fetch_storage_pools;
+ gvir_connection_fetch_storage_pools_async;
+ gvir_connection_fetch_storage_pools_finish;
gvir_connection_get_domains;
+ gvir_connection_get_storage_pools;
gvir_connection_get_domain;
+ gvir_connection_get_storage_pool;
gvir_connection_find_domain_by_id;
gvir_connection_find_domain_by_name;
+ gvir_connection_find_storage_pool_by_name;
I think It would be better to add API
gvir_connection_find_storage_pool_by_id also to keep consistence
with domain.
gvir_connection_create_domain;
gvir_domain_get_type;
--
Lei