[libvirt] [libvirt-glib] API to deal with storage pool(s)

Lei Li lilei at linux.vnet.ibm.com
Tue Sep 27 03:40:45 UTC 2011


On 09/27/2011 06:19 AM, Zeeshan Ali (Khattak) wrote:

> From: "Zeeshan Ali (Khattak)"<zeeshanak at 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




More information about the libvir-list mailing list