[PATCH 0 of 2] Use libvirt's storage management

Subject says it all. Some reasonable testing of this to make sure it still: (a) works as it did before on <=0.4.0, and (b) works with the storage stuff if you have 0.4.1

# HG changeset patch # User Dan Smith <danms@us.ibm.com> # Date 1205267321 25200 # Node ID eba6a48fcf9a1cec9c5e21e6c06984a3b1716803 # Parent b739fc9b13320e07a39f3932396c8411c2d4ad75 Fix potential crash in RAFP if a pool is not found Signed-off-by: Dan Smith <danms@us.ibm.com> diff -r b739fc9b1332 -r eba6a48fcf9a src/Virt_ResourceAllocationFromPool.c --- a/src/Virt_ResourceAllocationFromPool.c Tue Mar 11 13:28:04 2008 -0700 +++ b/src/Virt_ResourceAllocationFromPool.c Tue Mar 11 13:28:41 2008 -0700 @@ -116,7 +116,7 @@ static int filter_by_pool(struct inst_li cu_get_str_prop(inst, "InstanceID", &rasd_id); poolid = pool_member_of(_BROKER, CLASSNAME(op), type, rasd_id); - if (STREQ(poolid, _poolid)) + if ((poolid != NULL) && STREQ(poolid, _poolid)) inst_list_add(dest, inst); }

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

Dan Smith wrote:
Subject says it all.
Some reasonable testing of this to make sure it still: (a) works as it did before on <=0.4.0, and (b) works with the storage stuff if you have 0.4.1
_______________________________________________ Libvirt-cim mailing list Libvirt-cim@redhat.com https://www.redhat.com/mailman/listinfo/libvirt-cim
Sorry, I can also not apply this patch set. All hunks are failing. -- Regards Heidi Eckhart Software Engineer IBM Linux Technology Center - Open Hypervisor

Dan Smith wrote:
Subject says it all.
Some reasonable testing of this to make sure it still: (a) works as it did before on <=0.4.0, and (b) works with the storage stuff if you have 0.4.1
I had libvirt 0.4.0, so I tested this before and after I updated to 0.4.1. +1 -- Kaitlin Rupert IBM Linux Technology Center kaitlin@linux.vnet.ibm.com
participants (3)
-
Dan Smith
-
Heidi Eckhart
-
Kaitlin Rupert