Use the output of the 'lvs' command in order to determine the current allocation value for logical volumes. The capacity value for these pools can still be obtained via the existing methodology to lseek to the end of the block file in virStorageBackendUpdateVolTargetInfoFD. The real need is for the thin logical volumes where the thin pool keeps track of the capacity and the thin logical volume keeps track of the allocation value. In the future someone could add a fetch for the 'data_percent' in order to determine the percentage of data used for the allocated space. Signed-off-by: John Ferlan <jferlan@xxxxxxxxxx> --- src/storage/storage_backend_logical.c | 97 +++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/src/storage/storage_backend_logical.c b/src/storage/storage_backend_logical.c index 45df38c..8b7325b 100644 --- a/src/storage/storage_backend_logical.c +++ b/src/storage/storage_backend_logical.c @@ -904,6 +904,102 @@ virStorageBackendLogicalCreateVol(virConnectPtr conn, return -1; } +struct virStorageBackendLogicalVolRefreshData { + virStorageVolDefPtr vol; + bool alloc_sent; +}; + +static int +virStorageBackendLogicalRefreshVolFunc(char **const groups, + void *opaque) +{ + struct virStorageBackendLogicalVolRefreshData *data = opaque; + virStorageVolDefPtr vol = data->vol; + + if (data->alloc_sent) { + /* The capacity of the thin logical volume is kept in the 'lv_size' + * of the pool which will be sent when the RefreshVol code determines + * that this is a thin logical volume + */ + if (virStrToLong_ull(groups[0], NULL, 10, &vol->target.capacity) < 0) + return -1; + } else { + if (virStrToLong_ull(groups[0], NULL, 10, &vol->target.allocation) < 0) + return -1; + data->alloc_sent = true; + } + + return 0; +} + +static int +virStorageBackendLogicalRefreshVol(virConnectPtr conn ATTRIBUTE_UNUSED, + virStoragePoolObjPtr pool, + virStorageVolDefPtr vol) +{ + /* + * # lvs --noheadings --units b --unbuffered --nosuffix \ + * --options "lv_size" VGNAME/LVNAME [VGNAME/thinpool_LVNAME] + * + * Pull out lv_size for volume capacity and if necessary pull + * out thinpool size for allocation. The output will either be + * one or two lines. The first line will be the capacity value. + * While, if there is a thin volume involved, the second line will + * be the allocation value for the thin lv from the thin pool + */ + const char *regexes[] = { + "^\\s*([0-9]+)\\s*$" + }; + int vars[] = { + 1 + }; + virCommandPtr cmd = NULL; + int ret = -1; + struct virStorageBackendLogicalVolRefreshData cbdata = { + .vol = vol, + .alloc_sent = false, + }; + + cmd = virCommandNewArgList(LVS, + "--noheadings", + "--units", "b", + "--unbuffered", + "--nosuffix", + "--options", "lv_size", + NULL); + virCommandAddArgFormat(cmd, "%s/%s", + pool->def->source.name, + vol->name); + + /* If this is a thin volume, let's add the fetch of the thin volume size + * This will gernate two lines of output, which we'll handle via the + * alloc_sent boolean - this is where the pool capacity is stored from + * the -V during the lvcreate process + */ + if (vol->target.thinVolume) + virCommandAddArgFormat(cmd, "%s/thinpool_%s", + pool->def->source.name, + vol->name); + + /* Now get allocation of the logical volume and perhaps the capacity + * of the thin volume + */ + if (virCommandRunRegex(cmd, + 1, + regexes, + vars, + virStorageBackendLogicalRefreshVolFunc, + &cbdata, + "lvs") < 0) + goto cleanup; + + ret = 0; + + cleanup: + virCommandFree(cmd); + return ret; +} + static int virStorageBackendLogicalBuildVolFrom(virConnectPtr conn, virStoragePoolObjPtr pool, @@ -961,6 +1057,7 @@ virStorageBackend virStorageBackendLogical = { .buildVol = NULL, .buildVolFrom = virStorageBackendLogicalBuildVolFrom, .createVol = virStorageBackendLogicalCreateVol, + .refreshVol = virStorageBackendLogicalRefreshVol, .deleteVol = virStorageBackendLogicalDeleteVol, .uploadVol = virStorageBackendVolUploadLocal, .downloadVol = virStorageBackendVolDownloadLocal, -- 1.9.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list