# HG changeset patch
# User Dan Smith <danms(a)us.ibm.com>
# Date 1193407968 25200
# Node ID c43f4785810f0b1695bf21c23eb26ba4b5cf0b02
# Parent 1fef15850ba5557cc421206fb3ff569f6845ad99
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.
Signed-off-by: Dan Smith <danms(a)us.ibm.com>
diff -r 1fef15850ba5 -r c43f4785810f Makefile.am
--- a/Makefile.am Fri Oct 26 07:11:18 2007 -0700
+++ b/Makefile.am Fri Oct 26 07:12:48 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 1fef15850ba5 -r c43f4785810f schema/DiskPool.mof
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/schema/DiskPool.mof Fri Oct 26 07:12:48 2007 -0700
@@ -0,0 +1,7 @@
+class Xen_DiskPool : CIM_ResourcePool
+{
+};
+class KVM_DiskPool : CIM_ResourcePool
+{
+};
+
diff -r 1fef15850ba5 -r c43f4785810f schema/DiskPool.registration
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/schema/DiskPool.registration Fri Oct 26 07:12:48 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 1fef15850ba5 -r c43f4785810f src/Virt_DevicePool.c
--- a/src/Virt_DevicePool.c Fri Oct 26 07:11:18 2007 -0700
+++ b/src/Virt_DevicePool.c Fri Oct 26 07:12:48 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,147 @@
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)) {
+ asprintf(&pool, "DiskPool/%s", pools[i].tag);
+ 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)
{
@@ -98,6 +242,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;
@@ -294,6 +440,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,
@@ -307,6 +543,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};
}