[PATCH 0 of 3] Add DiskPool support

This set adds disk pool support and the relevant changes to RAFP and EAFP to support discovery of membership from LogicalDisk and DiskRASD. It's a little raw right now, but it works.

# HG changeset patch # User Dan Smith <danms@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@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}; }

Dan Smith wrote:
# HG changeset patch # User Dan Smith <danms@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@us.ibm.com>
This seems like a fine start. +1 I can get a quick patch out to make the filepath settable via the configure script, especially if it's okay to say that validation of the filepath can wait until run time. -- -Jay

# HG changeset patch # User Dan Smith <danms@us.ibm.com> # Date 1193408006 25200 # Node ID ff6c1f00f1789dfdadbacb925d6ae3314db42ae5 # Parent c43f4785810f0b1695bf21c23eb26ba4b5cf0b02 Add diskpool support to ElementAllocatedFromPool Signed-off-by: Dan Smith <danms@us.ibm.com> diff -r c43f4785810f -r ff6c1f00f178 src/Virt_ElementAllocatedFromPool.c --- a/src/Virt_ElementAllocatedFromPool.c Fri Oct 26 07:12:48 2007 -0700 +++ b/src/Virt_ElementAllocatedFromPool.c Fri Oct 26 07:13:26 2007 -0700 @@ -222,6 +222,11 @@ static CMPIStatus pool_to_vdev(const CMP ns, poolid, list); + else if (STARTS_WITH(poolid, "DiskPool")) + devs_from_pool(CIM_RASD_TYPE_DISK, + ns, + poolid, + list); else { cu_statusf(_BROKER, &s, CMPI_RC_ERR_FAILED,

# HG changeset patch # User Dan Smith <danms@us.ibm.com> # Date 1193408083 25200 # Node ID addd6dbbd0464d33949466e3ff1f15e926d67cd1 # Parent ff6c1f00f1789dfdadbacb925d6ae3314db42ae5 Add diskpool support to ResourceAllocationFromPool Signed-off-by: Dan Smith <danms@us.ibm.com> diff -r ff6c1f00f178 -r addd6dbbd046 src/Virt_ResourceAllocationFromPool.c --- a/src/Virt_ResourceAllocationFromPool.c Fri Oct 26 07:13:26 2007 -0700 +++ b/src/Virt_ResourceAllocationFromPool.c Fri Oct 26 07:14:43 2007 -0700 @@ -201,6 +201,11 @@ static CMPIStatus pool_to_rasd(const CMP NAMESPACE(ref), poolid, list); + else if (STARTS_WITH(poolid, "DiskPool")) + rasds_from_pool(CIM_RASD_TYPE_DISK, + NAMESPACE(ref), + poolid, + list); else { cu_statusf(_BROKER, &s, CMPI_RC_ERR_FAILED,

Dan Smith wrote:
This set adds disk pool support and the relevant changes to RAFP and EAFP to support discovery of membership from LogicalDisk and DiskRASD. It's a little raw right now, but it works.
Patches 2 and 3 are so simple they don't need individual acks, and they look fine. +1 -- -Jay
participants (2)
-
Dan Smith
-
Jay Gagnon