[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

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



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

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


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]