[Libvirt-cim] [PATCH 2 of 2] Allow DiskPool to use libvirt's integrated storage management, if available

Dan Smith danms at us.ibm.com
Tue Mar 11 20:33:32 UTC 2008


# HG changeset patch
# User Dan Smith <danms at us.ibm.com>
# Date 1205267597 25200
# Node ID b2c0c49037cd5927e110c3956c6162c429c4b415
# Parent  eba6a48fcf9a1cec9c5e21e6c06984a3b1716803
Allow DiskPool to use libvirt's integrated storage management, if available

Signed-off-by: Dan Smith <danms at us.ibm.com>

diff -r eba6a48fcf9a -r b2c0c49037cd src/Virt_DevicePool.c
--- a/src/Virt_DevicePool.c	Tue Mar 11 13:28:41 2008 -0700
+++ b/src/Virt_DevicePool.c	Tue Mar 11 13:33:17 2008 -0700
@@ -50,6 +50,110 @@ struct disk_pool {
         char *path;
 };
 
+/*
+ * Right now, detect support and use it, if available.
+ * Later, this can be a configure option if needed
+ */
+#if LIBVIR_VERSION_NUMBER > 4000
+# define VIR_USE_LIBVIRT_STORAGE 1
+#else
+# define VIR_USE_LIBVIRT_STORAGE 0
+#endif
+
+#if VIR_USE_LIBVIRT_STORAGE
+static int get_diskpool_config(virConnectPtr conn,
+                               struct disk_pool **_pools)
+{
+        int count = 0;
+        int i;
+        char ** names = NULL;
+        struct disk_pool *pools;
+
+        count = virConnectNumOfStoragePools(conn);
+        if (count <= 0)
+                goto out;
+
+        names = calloc(count, sizeof(char *));
+        if (names == NULL) {
+                CU_DEBUG("Failed to alloc space for %i pool names", count);
+                goto out;
+        }
+
+        pools = calloc(count, sizeof(*pools));
+        if (pools == NULL) {
+                CU_DEBUG("Failed to alloc space for %i pool structs", count);
+                goto out;
+        }
+
+        if (virConnectListStoragePools(conn, names, count) == -1) {
+                CU_DEBUG("Failed to get storage pools");
+                free(pools);
+                goto out;
+        }
+
+        for (i = 0; i < count; i++)
+                pools[i].tag = names[i];
+
+        *_pools = pools;
+ out:
+        free(names);
+
+        return count;
+}
+
+static bool diskpool_set_capacity(virConnectPtr conn,
+                                  CMPIInstance *inst,
+                                  struct disk_pool *_pool)
+{
+        bool result = false;
+        virStoragePoolPtr pool;
+        virStoragePoolInfo info;
+
+        pool = virStoragePoolLookupByName(conn, _pool->tag);
+        if (pool == NULL) {
+                CU_DEBUG("Failed to lookup storage pool `%s'", _pool->tag);
+                goto out;
+        }
+
+        if (virStoragePoolGetInfo(pool, &info) == -1) {
+                CU_DEBUG("Failed to get info for pool `%s'", _pool->tag);
+                goto out;
+        }
+
+        CMSetProperty(inst, "Capacity",
+                      (CMPIValue *)&info.capacity, CMPI_uint64);
+
+        CMSetProperty(inst, "Reserved",
+                      (CMPIValue *)&info.allocation, CMPI_uint64);
+
+        result = true;
+ out:
+        virStoragePoolFree(pool);
+
+        return result;
+}
+
+static bool _diskpool_is_member(virConnectPtr conn,
+                                const struct disk_pool *pool,
+                                const char *file)
+{
+        virStorageVolPtr vol = NULL;
+        bool result = false;
+
+        vol = virStorageVolLookupByPath(conn, file);
+        if (vol != NULL)
+                result = true;
+
+        CU_DEBUG("Image %s in pool %s: %s",
+                 file,
+                 pool->tag,
+                 result ? "YES": "NO");
+
+        virStorageVolFree(vol);
+
+        return result;
+}
+#else
 static int parse_diskpool_line(struct disk_pool *pool,
                                const char *line)
 {
@@ -64,7 +168,8 @@ static int parse_diskpool_line(struct di
         return (ret == 2);
 }
 
-static int get_diskpool_config(struct disk_pool **_pools)
+static int get_diskpool_config(virConnectPtr conn,
+                               struct disk_pool **_pools)
 {
         const char *path = DISK_POOL_CONFIG;
         FILE *config;
@@ -99,6 +204,45 @@ static int get_diskpool_config(struct di
         return count;
 }
 
+static bool diskpool_set_capacity(virConnectPtr conn,
+                                  CMPIInstance *inst,
+                                  struct disk_pool *pool)
+{
+        bool result = false;
+        struct statvfs vfs;
+        uint64_t cap;
+        uint64_t res;
+
+        if (statvfs(pool->path, &vfs) != 0) {
+                CU_DEBUG("Failed to statvfs(%s): %m", pool->path);
+                goto out;
+        }
+
+        cap = (uint64_t) vfs.f_frsize * vfs.f_blocks;
+        res = cap - (uint64_t)(vfs.f_frsize * vfs.f_bfree);
+
+        cap >>= 20;
+        res >>= 20;
+
+        CMSetProperty(inst, "Capacity",
+                      (CMPIValue *)&cap, CMPI_uint64);
+
+        CMSetProperty(inst, "Reserved",
+                      (CMPIValue *)&res, CMPI_uint64);
+
+        result = true;
+ out:
+        return result;
+}
+
+static bool _diskpool_is_member(virConnectPtr conn,
+                                const struct disk_pool *pool,
+                                const char *file)
+{
+        return STARTS_WITH(file, pool->path);
+}
+#endif
+
 static void free_diskpool(struct disk_pool *pools, int count)
 {
         int i;
@@ -114,19 +258,20 @@ static void free_diskpool(struct disk_po
         free(pools);
 }
 
-static char *_diskpool_member_of(const char *file)
+static char *_diskpool_member_of(virConnectPtr conn,
+                                 const char *file)
 {
         struct disk_pool *pools = NULL;
         int count;
         int i;
         char *pool = NULL;
 
-        count = get_diskpool_config(&pools);
+        count = get_diskpool_config(conn, &pools);
         if (count == 0)
                 return NULL;
 
         for (i = 0; i < count; i++) {
-                if (STARTS_WITH(file, pools[i].path)) {
+                if (_diskpool_is_member(conn, &pools[i], file)) {
                         int ret;
 
                         ret = asprintf(&pool, "DiskPool/%s", pools[i].tag);
@@ -172,7 +317,8 @@ static char *diskpool_member_of(const CM
 
         for (i = 0; i < count; i++) {
                 if (STREQ((devs[i].dev.disk.virtual_dev), dev)) {
-                        pool = _diskpool_member_of(devs[i].dev.disk.source);
+                        pool = _diskpool_member_of(conn,
+                                                   devs[i].dev.disk.source);
                         break;
                 }
         }
@@ -595,8 +741,8 @@ static CMPIStatus netpool_instance(virCo
         return s;
 }
 
-static CMPIInstance *diskpool_from_path(const char *path,
-                                        const char *id,
+static CMPIInstance *diskpool_from_path(struct disk_pool *pool,
+                                        virConnectPtr conn,
                                         const char *ns,
                                         const char *refcn,
                                         const CMPIBroker *broker)
@@ -604,13 +750,10 @@ static CMPIInstance *diskpool_from_path(
         CMPIInstance *inst;
         char *poolid = NULL;
         const uint16_t type = CIM_RES_TYPE_DISK;
-        struct statvfs vfs;
-        uint64_t cap;
-        uint64_t res;
 
         inst = get_typed_instance(broker, refcn, "DiskPool", ns);
 
-        if (asprintf(&poolid, "DiskPool/%s", id) == -1)
+        if (asprintf(&poolid, "DiskPool/%s", pool->tag) == -1)
                 return NULL;
 
         CMSetProperty(inst, "InstanceID",
@@ -622,24 +765,10 @@ static CMPIInstance *diskpool_from_path(
         CMSetProperty(inst, "AllocationUnits",
                       (CMPIValue *)"Megabytes", CMPI_chars);
 
-        if (statvfs(path, &vfs) != 0) {
-                CU_DEBUG("Failed to statvfs(%s): %m", path);
-                goto out;
-        }
-
-        cap = (uint64_t) vfs.f_frsize * vfs.f_blocks;
-        res = cap - (uint64_t)(vfs.f_frsize * vfs.f_bfree);
-
-        cap >>= 20;
-        res >>= 20;
-
-        CMSetProperty(inst, "Capacity",
-                      (CMPIValue *)&cap, CMPI_uint64);
-
-        CMSetProperty(inst, "Reserved",
-                      (CMPIValue *)&res, CMPI_uint64);
-
- out:
+        if (!diskpool_set_capacity(conn, inst, pool))
+                CU_DEBUG("Failed to set capacity for disk pool: %s",
+                         pool->tag);
+
         free(poolid);
 
         return inst;
@@ -656,9 +785,13 @@ static CMPIStatus diskpool_instance(virC
         int count = 0;
         int i;
 
-        count = get_diskpool_config(&pools);
-        if ((id == NULL) && (count == 0))
+        count = get_diskpool_config(conn, &pools);
+        if ((id == NULL) && (count == 0)) {
+                CU_DEBUG("No defined DiskPools");
                 return s;
+        }
+
+        CU_DEBUG("%i DiskPools", count);
 
         for (i = 0; i < count; i++) {
                 CMPIInstance *pool;
@@ -667,8 +800,8 @@ static CMPIStatus diskpool_instance(virC
                         continue;
                 /* Either this matches id, or we're matching all */
 
-                pool = diskpool_from_path(pools[i].path,
-                                          pools[i].tag,
+                pool = diskpool_from_path(&pools[i],
+                                          conn,
                                           ns,
                                           pfx_from_conn(conn),
                                           broker);




More information about the Libvirt-cim mailing list