[Libvirt-cim] [PATCH] Add disk resource pools

Dan Smith danms at us.ibm.com
Sat Oct 27 17:16:05 UTC 2007


# HG changeset patch
# User Dan Smith <danms at us.ibm.com>
# Date 1193505363 25200
# Node ID 06e694e6367634fab4ebc1c1a9927cee790d31c4
# Parent  f9d3ced9a8b4eb54d46997ba8f96f8105998d625
Add disk resource pools
This patch parses a disk pool config file, which allows you to specify a pool
name and path.  The path is assumed to be a directory of image files.  The
Capacity and Reserved properties are reported with statvfs (although the
free/reserved calculation isn't working yet).  The config is hard-coded to
/tmp/diskpool.conf currently, but needs to be a compile-time option.  This
should be a good start though.

Updated to fix a similar compile warning on Fedora 7

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

diff -r f9d3ced9a8b4 -r 06e694e63676 Makefile.am
--- a/Makefile.am	Sat Oct 27 10:07:46 2007 -0700
+++ b/Makefile.am	Sat Oct 27 10:16:03 2007 -0700
@@ -19,6 +19,7 @@ MOFS = \
 	schema/MemoryPool.mof \
 	schema/ElementCapabilities.mof \
 	schema/ProcessorPool.mof \
+	schema/DiskPool.mof \
 	schema/HostedResourcePool.mof \
 	schema/ElementConformsToProfile.mof \
 	schema/ComputerSystemIndication.mof \
@@ -54,6 +55,7 @@ REGS = \
 	schema/MemoryPool.registration \
 	schema/ElementCapabilities.registration \
 	schema/ProcessorPool.registration \
+	schema/DiskPool.registration \
 	schema/HostedResourcePool.registration \
 	schema/ComputerSystemIndication.registration \
 	schema/ResourceAllocationSettingData.registration \
diff -r f9d3ced9a8b4 -r 06e694e63676 schema/DiskPool.mof
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/schema/DiskPool.mof	Sat Oct 27 10:16:03 2007 -0700
@@ -0,0 +1,7 @@
+class Xen_DiskPool : CIM_ResourcePool
+{
+};
+class KVM_DiskPool : CIM_ResourcePool
+{
+};
+
diff -r f9d3ced9a8b4 -r 06e694e63676 schema/DiskPool.registration
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/schema/DiskPool.registration	Sat Oct 27 10:16:03 2007 -0700
@@ -0,0 +1,2 @@
+Xen_DiskPool root/ibmsd Virt_DevicePoolProvider Virt_DevicePool instance
+KVM_DiskPool root/ibmsd Virt_DevicePoolProvider Virt_DevicePool instance
diff -r f9d3ced9a8b4 -r 06e694e63676 src/Virt_DevicePool.c
--- a/src/Virt_DevicePool.c	Sat Oct 27 10:07:46 2007 -0700
+++ b/src/Virt_DevicePool.c	Sat Oct 27 10:16:03 2007 -0700
@@ -19,10 +19,14 @@
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
  */
+#define __USE_FILE_OFFSET64
+
 #include <stdio.h>
 #include <stdbool.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/statvfs.h>
+#include <inttypes.h>
 
 #include <cmpidt.h>
 #include <cmpift.h>
@@ -39,7 +43,151 @@
 
 static const CMPIBroker *_BROKER;
 
+#define DISK_POOL_CONFIG "/tmp/diskpool.conf"
+
 char *device_pool_names[] = {"ProcessorPool", "MemoryPool", NULL};
+
+struct disk_pool {
+        char *tag;
+        char *path;
+};
+
+static int parse_diskpool_line(struct disk_pool *pool,
+                               const char *line)
+{
+        int ret;
+
+        ret = sscanf(line, "%as %as", &pool->tag, &pool->path);
+        if (ret != 2) {
+                free(pool->tag);
+                free(pool->path);
+        }
+
+        return (ret == 2);
+}
+
+static int get_diskpool_config(struct disk_pool **_pools)
+{
+        const char *path = DISK_POOL_CONFIG;
+        FILE *config;
+        char *line = NULL;
+        size_t len = 0;
+        int count = 0;
+        struct disk_pool *pools = NULL;
+
+        config = fopen(path, "r");
+        if (config == NULL) {
+                CU_DEBUG("Failed to open %s: %m", path);
+                return 0;
+        }
+
+        while (getline(&line, &len, config) > 0) {
+                pools = realloc(pools,
+                                (count + 1) * (sizeof(*pools)));
+                if (pools == NULL) {
+                        CU_DEBUG("Failed to alloc new pool");
+                        goto out;
+                }
+
+                if (parse_diskpool_line(&pools[count], line))
+                        count++;
+        }
+
+ out:
+        free(line);
+        *_pools = pools;
+        fclose(config);
+
+        return count;
+}
+
+static void free_diskpool(struct disk_pool *pools, int count)
+{
+        int i;
+
+        if (pools == NULL)
+                return;
+
+        for (i = 0; i < count; i++) {
+                free(pools[i].tag);
+                free(pools[i].path);
+        }
+
+        free(pools);
+}
+
+static char *_diskpool_member_of(const char *file)
+{
+        struct disk_pool *pools = NULL;
+        int count;
+        int i;
+        char *pool = NULL;
+
+        count = get_diskpool_config(&pools);
+        if (count == 0)
+                return NULL;
+
+        for (i = 0; i < count; i++) {
+                if (STARTS_WITH(file, pools[i].path)) {
+                        int ret;
+
+                        ret = asprintf(&pool, "DiskPool/%s", pools[i].tag);
+                        if (ret == -1)
+                                pool = NULL;
+                        break;
+                }
+        }
+
+        free_diskpool(pools, count);
+
+        return pool;
+}
+
+static char *diskpool_member_of(const CMPIBroker *broker, char *rasd_id)
+{
+        char *host = NULL;
+        char *dev = NULL;
+        int ret;
+        virConnectPtr conn = NULL;
+        virDomainPtr dom = NULL;
+        int count = 0;
+        struct virt_device *devs = NULL;
+        int i;
+        char *pool = NULL;
+        CMPIStatus s;
+
+        ret = parse_fq_devid(rasd_id, &host, &dev);
+        if (!ret)
+                goto out;
+
+        conn = lv_connect(broker, &s);
+        if (conn == NULL)
+                goto out;
+
+        dom = virDomainLookupByName(conn, host);
+        if (dom == NULL)
+                goto out;
+
+        count = get_disk_devices(dom, &devs);
+
+        for (i = 0; i < count; i++) {
+                if (STREQ((devs[i].dev.disk.virtual_dev), dev)) {
+                        pool = _diskpool_member_of(devs[i].dev.disk.source);
+                        break;
+                }
+        }
+
+ out:
+        if (count > 0)
+                cleanup_virt_devices(&devs, count);
+
+        free(host);
+        free(dev);
+        virConnectClose(conn);
+        virDomainFree(dom);
+
+        return pool;
+}
 
 static char *netpool_member_of(const CMPIBroker *broker, char *rasd_id)
 {
@@ -100,6 +248,8 @@ char *pool_member_of(const CMPIBroker *b
                 poolid = strdup("MemoryPool/0");
         else if (type == CIM_RASD_TYPE_NET)
                 poolid = netpool_member_of(broker, id);
+        else if (type == CIM_RASD_TYPE_DISK)
+                poolid = diskpool_member_of(broker, id);
         else
                 return NULL;
 
@@ -296,6 +446,96 @@ static CMPIStatus netpool_instance(virCo
         return s;
 }
 
+static CMPIInstance *diskpool_from_path(const char *path,
+                                        const char *id,
+                                        const char *ns,
+                                        const CMPIBroker *broker)
+{
+        CMPIInstance *inst;
+        char *poolid = NULL;
+        const uint16_t type = CIM_RASD_TYPE_DISK;
+        struct statvfs vfs;
+        uint64_t cap;
+        uint64_t res;
+
+        inst = get_typed_instance(broker, "DiskPool", ns);
+
+        if (asprintf(&poolid, "DiskPool/%s", id) == -1)
+                return NULL;
+
+        CMSetProperty(inst, "InstanceID",
+                      (CMPIValue *)poolid, CMPI_chars);
+
+        CMSetProperty(inst, "ResourceType",
+                      (CMPIValue *)&type, CMPI_uint16);
+
+        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:
+        free(poolid);
+
+        return inst;
+}
+
+static CMPIStatus diskpool_instance(virConnectPtr conn,
+                                    struct inst_list *list,
+                                    const char *ns,
+                                    const char *id,
+                                    const CMPIBroker *broker)
+{
+        CMPIStatus s;
+        struct disk_pool *pools = NULL;
+        int count = 0;
+        int i;
+
+        count = get_diskpool_config(&pools);
+        if ((id == NULL) && (count == 0)) {
+                cu_statusf(_BROKER, &s,
+                           CMPI_RC_ERR_FAILED,
+                           "No such pool `%s'", id);
+                goto out;
+        }
+
+        for (i = 0; i < count; i++) {
+                CMPIInstance *pool;
+
+                if ((id != NULL) && (!STREQ(id, pools[i].tag)))
+                        continue;
+                /* Either this matches id, or we're matching all */
+
+                pool = diskpool_from_path(pools[i].path,
+                                          pools[i].tag,
+                                          ns,
+                                          broker);
+                if (pool != NULL)
+                        inst_list_add(list, pool);
+        }
+
+        CMSetStatus(&s, CMPI_RC_OK);
+ out:
+        free_diskpool(pools, count);
+
+        return s;
+}
+
 static CMPIStatus _get_pool(const CMPIBroker *broker,
                             virConnectPtr conn,
                             const char *type,
@@ -309,6 +549,8 @@ static CMPIStatus _get_pool(const CMPIBr
                 return procpool_instance(conn, list, ns, id, broker);
         else if (STARTS_WITH(type, "NetworkPool"))
                 return netpool_instance(conn, list, ns, id, broker);
+        else if (STARTS_WITH(type, "DiskPool"))
+                return diskpool_instance(conn, list, ns, id, broker);
 
         return (CMPIStatus){CMPI_RC_ERR_NOT_FOUND, NULL};
 }




More information about the Libvirt-cim mailing list