During processing of the extents found in a pool, we have historically
ignored the thin-pool which means any thin lv found in the pool would
also be ignored. This can start to change now - we can save aside the
name and capacity of any thin-pool's found so that we can use that when
we find a thin lv and fill in the thin-pool capacity value on output.
The result will end up being the following for a vol-dumpxml:
<source>
<thinpool name='thinmints'/>
<capacity unit='bytes'>20971520</capacity>
</thinpool>
</source>
instead of an empty <source> </source> pair.
An upcoming patch will allow a thin lv to be seen
Signed-off-by: John Ferlan <jferlan(a)redhat.com>
---
src/conf/storage_conf.h | 12 +++++++++
src/storage/storage_backend_logical.c | 51 +++++++++++++++++++++++++++++++++--
2 files changed, 61 insertions(+), 2 deletions(-)
diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h
index f19cb59..a9a1288 100644
--- a/src/conf/storage_conf.h
+++ b/src/conf/storage_conf.h
@@ -47,6 +47,18 @@ struct _virStorageVolSourceExtent {
unsigned long long end;
};
+/*
+ * How to represent thin-pool's for a logical volume. Used by the
+ * logical parsing code
+ */
+typedef struct _virStorageVolSourceThinPool virStorageVolSourceThinPool;
+typedef virStorageVolSourceThinPool *virStorageVolSourceThinPoolPtr;
+struct _virStorageVolSourceThinPool {
+ char *name;
+ unsigned long long capacity;
+};
+
+
typedef struct _virStorageVolSource virStorageVolSource;
typedef virStorageVolSource *virStorageVolSourcePtr;
struct _virStorageVolSource {
diff --git a/src/storage/storage_backend_logical.c
b/src/storage/storage_backend_logical.c
index 3044853..d7990e2 100644
--- a/src/storage/storage_backend_logical.c
+++ b/src/storage/storage_backend_logical.c
@@ -72,6 +72,8 @@ virStorageBackendLogicalSetActive(virStoragePoolObjPtr pool,
struct virStorageBackendLogicalPoolVolData {
virStoragePoolObjPtr pool;
virStorageVolDefPtr vol;
+ size_t nthinpools;
+ virStorageVolSourceThinPoolPtr thinpools;
};
static int
@@ -221,12 +223,38 @@ virStorageBackendLogicalMakeVol(char **const groups,
return 0;
/*
- * Skip thin pools(t). These show up in normal lvs output
+ * Save the thin pools(t). These show up in normal lvs output
* but do not have a corresponding /dev/$vg/$lv device that
* is created by udev. This breaks assumptions in later code.
+ * The thin pools are the "capacity container" for all the thin
+ * lv's found in the pool. A thin lv provides a virtual size upon
+ * creation and can appear to over subscribe the pool capacity.
+ * Although usually thin pools are listed before thin lv's in the
+ * output, we'll just wait until all volumes are processed and
+ * then match the name saved here with thin_pool name we saved
+ * earlier to get the capacity value of thin-pool into the volume.
+ * It's expected that there is more than 1 thin lv per thin-pool.
+ * There can be more than 1 thin-pool per volume group.
*/
- if (attrs[0] == 't')
+ if (attrs[0] == 't') {
+ virStorageVolSourceThinPool thin;
+
+ memset(&thin, 0, sizeof(thin));
+ if (VIR_STRDUP(thin.name, groups[0]) < 0)
+ goto cleanup;
+ if (virStrToLong_ull(groups[8], NULL, 10, &thin.capacity) < 0) {
+ VIR_FREE(thin.name);
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("malformed thin pool capacity
value"));
+ goto cleanup;
+ }
+ if (VIR_APPEND_ELEMENT(data->thinpools, data->nthinpools, thin) < 0) {
+ VIR_FREE(thin.name);
+ goto cleanup;
+ }
+
return 0;
+ }
/* See if we're only looking for a specific volume */
if (data->vol != NULL) {
@@ -389,7 +417,10 @@ virStorageBackendLogicalFindLVs(virStoragePoolObjPtr pool,
struct virStorageBackendLogicalPoolVolData cbdata = {
.pool = pool,
.vol = vol,
+ .nthinpools = 0,
+ .thinpools = NULL,
};
+ size_t i, j;
cmd = virCommandNewArgList(LVS,
"--separator", "#",
@@ -410,9 +441,25 @@ virStorageBackendLogicalFindLVs(virStoragePoolObjPtr pool,
"lvs") < 0)
goto cleanup;
+ /* If we find some thin-pools during processing, let's see if we
+ * need information from them for any thin lv's in the pool
+ */
+ for (i = 0; i < cbdata.nthinpools; i++) {
+ for (j = 0; j < pool->volumes.count; j++) {
+ if (STREQ_NULLABLE(pool->volumes.objs[j]->source.thin_pool,
+ cbdata.thinpools[i].name)) {
+ pool->volumes.objs[j]->source.thin_capacity =
+ cbdata.thinpools[i].capacity;
+ }
+ }
+ }
+
ret = 0;
cleanup:
virCommandFree(cmd);
+ for (i = 0; i < cbdata.nthinpools; i++)
+ VIR_FREE(cbdata.thinpools[i].name);
+ VIR_FREE(cbdata.thinpools);
return ret;
}
--
2.5.0