[libvirt] [PATCH v2 00/17] Add support to list Storage Driver backend capabilities

v1: https://www.redhat.com/archives/libvir-list/2019-January/msg00479.html Changes since v1: * The first 4 patches were already R-by'd and pushed. * From v1, rework patch 5 & 6 into what now is patches 8 & 9. The format of the output for what results in the output for the connectGetCapabilities (virConnectGetCapabilities). * From v1, drop patch 7 * In v2, patches 1-7 are new as a result of work done for patches 10-17. patches 1-5 were posted upstream, but left unreviewed: https://www.redhat.com/archives/libvir-list/2019-February/msg00333.html These essentially ensure the volOptions and poolOptions don't list or use something unexpected per documentation. The doc patch is a simple update to add some missing text and fix an entry * Patches 10-17 are new to implement the ability to get/format the Storage Driver backend capabilities via: storageConnectGetStoragePoolCapabilities virConnectGetStoragePoolCapabilities similar to how virConnectGetDomainCapabilities returns domain specific output. The output is essentially what is provided in the poolOptions and volOptions from storage_conf as valid values for format type fields for pool and/or volume as well as an enumerated list for the required source elements for creation. Whether the latter is useful or not was not clear, but since it is something that can cause a creation error when missing, I figured it'd be useful. The new virsh command follows then domcapabilities nomenclature. John Ferlan (17): conf: Remove volOptions for VIR_STORAGE_POOL_SHEEPDOG conf: Remove volOptions for VIR_STORAGE_POOL_RBD conf: Remove volOptions for VIR_STORAGE_POOL_SCSI conf: Remove volOptions for VIR_STORAGE_POOL_ISCSI[_DIRECT] conf: Remove volOptions for VIR_STORAGE_POOL_MPATH conf: Remove defaultFormat from VIR_STORAGE_POOL_ZFS docs: Fix a few storage.html.in typos conf: Introduce storage pool functions into capabilities storage: Process storage pool capabilities docs: Add schema for storage pool capabilities conf: Add storage pool capability formatting tests: Introduce storage pool capabilites test docs: Add description for Storage Pool Capabilities libvirt: Introduce virConnectGetStoragePoolCapabilities storage: Introduce storageConnectGetStoragePoolCapabilities virsh: Expose virConnectGetStoragePoolCapabilities docs: Add news article docs/docs.html.in | 1 + docs/format.html.in | 1 + docs/formatstoragecaps.html.in | 108 +++++++ docs/index.html.in | 1 + docs/news.xml | 12 + docs/schemas/storagepoolcaps.rng | 88 ++++++ docs/storage.html.in | 8 +- include/libvirt/libvirt-storage.h | 4 + libvirt.spec.in | 1 + mingw-libvirt.spec.in | 2 + src/conf/Makefile.inc.am | 2 + src/conf/capabilities.c | 74 +++++ src/conf/capabilities.h | 15 + src/conf/storage_capabilities.c | 135 +++++++++ src/conf/storage_capabilities.h | 41 +++ src/conf/storage_conf.c | 131 +++++++-- src/conf/storage_conf.h | 7 + src/conf/virstorageobj.h | 5 + src/driver-storage.h | 5 + src/libvirt-storage.c | 40 +++ src/libvirt_private.syms | 8 + src/libvirt_public.syms | 5 + src/remote/remote_driver.c | 1 + src/remote/remote_protocol.x | 15 +- src/remote_protocol-structs | 7 + src/storage/storage_backend.c | 16 ++ src/storage/storage_backend.h | 3 + src/storage/storage_driver.c | 44 +++ tests/Makefile.am | 7 + .../storagepoolcapsschemadata/poolcaps-fs.xml | 268 ++++++++++++++++++ .../poolcaps-full.xml | 268 ++++++++++++++++++ tests/storagepoolcapstest.c | 124 ++++++++ tests/storagevolxml2xmlout/vol-sheepdog.xml | 1 - tests/virschematest.c | 1 + tools/virsh-pool.c | 42 +++ tools/virsh.pod | 7 + 36 files changed, 1473 insertions(+), 25 deletions(-) create mode 100644 docs/formatstoragecaps.html.in create mode 100644 docs/schemas/storagepoolcaps.rng create mode 100644 src/conf/storage_capabilities.c create mode 100644 src/conf/storage_capabilities.h create mode 100644 tests/storagepoolcapsschemadata/poolcaps-fs.xml create mode 100644 tests/storagepoolcapsschemadata/poolcaps-full.xml create mode 100644 tests/storagepoolcapstest.c -- 2.20.1

The sheepdog pool is documented as not using the volume type, so let's just remove it. Besides it would have produced bad results since the defaultType is FILE but the formatting used the Disk types. Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/storage_conf.c | 4 ---- tests/storagevolxml2xmlout/vol-sheepdog.xml | 1 - 2 files changed, 5 deletions(-) diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index a2ddecf0f2..703093d3b5 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -249,10 +249,6 @@ static virStoragePoolTypeInfo poolTypeInfo[] = { VIR_STORAGE_POOL_SOURCE_NETWORK | VIR_STORAGE_POOL_SOURCE_NAME), }, - .volOptions = { - .defaultFormat = VIR_STORAGE_FILE_RAW, - .formatToString = virStoragePoolFormatDiskTypeToString, - } }, {.poolType = VIR_STORAGE_POOL_GLUSTER, .poolOptions = { diff --git a/tests/storagevolxml2xmlout/vol-sheepdog.xml b/tests/storagevolxml2xmlout/vol-sheepdog.xml index e1d6a9e27d..d6e920bb81 100644 --- a/tests/storagevolxml2xmlout/vol-sheepdog.xml +++ b/tests/storagevolxml2xmlout/vol-sheepdog.xml @@ -6,6 +6,5 @@ <allocation unit='bytes'>0</allocation> <target> <path>sheepdog:test2</path> - <format type='unknown'/> </target> </volume> -- 2.20.1

The rbd pool is documented as not using the volume type, so let's just remove it. Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/storage_conf.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index 703093d3b5..c303898e0d 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -237,11 +237,6 @@ static virStoragePoolTypeInfo poolTypeInfo[] = { VIR_STORAGE_POOL_SOURCE_NETWORK | VIR_STORAGE_POOL_SOURCE_NAME), }, - .volOptions = { - .defaultFormat = VIR_STORAGE_FILE_RAW, - .formatFromString = virStorageVolumeFormatFromString, - .formatToString = virStorageFileFormatTypeToString, - } }, {.poolType = VIR_STORAGE_POOL_SHEEPDOG, .poolOptions = { -- 2.20.1

The scsi pool is documented as not using the volume type, so let's just remove it. Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/storage_conf.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index c303898e0d..8cb0f75a91 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -227,9 +227,6 @@ static virStoragePoolTypeInfo poolTypeInfo[] = { .poolOptions = { .flags = (VIR_STORAGE_POOL_SOURCE_ADAPTER), }, - .volOptions = { - .formatToString = virStoragePoolFormatDiskTypeToString, - } }, {.poolType = VIR_STORAGE_POOL_RBD, .poolOptions = { -- 2.20.1

The iscsi and iscsi-direct pools are documented as not using the volume type, so let's just remove it. Besides it would have produced bad output since formatting uses the Disk types. Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/storage_conf.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index 8cb0f75a91..e699057fbf 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -208,9 +208,6 @@ static virStoragePoolTypeInfo poolTypeInfo[] = { VIR_STORAGE_POOL_SOURCE_DEVICE | VIR_STORAGE_POOL_SOURCE_INITIATOR_IQN), }, - .volOptions = { - .formatToString = virStoragePoolFormatDiskTypeToString, - } }, {.poolType = VIR_STORAGE_POOL_ISCSI_DIRECT, .poolOptions = { @@ -219,9 +216,6 @@ static virStoragePoolTypeInfo poolTypeInfo[] = { VIR_STORAGE_POOL_SOURCE_NETWORK | VIR_STORAGE_POOL_SOURCE_INITIATOR_IQN), }, - .volOptions = { - .formatToString = virStoragePoolFormatDiskTypeToString, - } }, {.poolType = VIR_STORAGE_POOL_SCSI, .poolOptions = { -- 2.20.1

The multipath pool is documented as not using the volume type, so let's just remove it. Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/storage_conf.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index e699057fbf..25556db4f8 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -250,9 +250,6 @@ static virStoragePoolTypeInfo poolTypeInfo[] = { } }, {.poolType = VIR_STORAGE_POOL_MPATH, - .volOptions = { - .formatToString = virStoragePoolFormatDiskTypeToString, - } }, {.poolType = VIR_STORAGE_POOL_DISK, .poolOptions = { -- 2.20.1

The ZFS pool is document as not using pool format types, so remove the defaultFormat value. Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/storage_conf.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index 25556db4f8..be64c09d37 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -268,7 +268,6 @@ static virStoragePoolTypeInfo poolTypeInfo[] = { .poolOptions = { .flags = (VIR_STORAGE_POOL_SOURCE_NAME | VIR_STORAGE_POOL_SOURCE_DEVICE), - .defaultFormat = VIR_STORAGE_FILE_RAW, }, }, {.poolType = VIR_STORAGE_POOL_VSTORAGE, -- 2.20.1

Fix the ZFS Valid Volume Format Types label and add the Valid pool format types for Vstorage pools. Signed-off-by: John Ferlan <jferlan@redhat.com> --- docs/storage.html.in | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/storage.html.in b/docs/storage.html.in index c8617aace5..ab1f880813 100644 --- a/docs/storage.html.in +++ b/docs/storage.html.in @@ -782,7 +782,7 @@ The ZFS volume pool does not use the pool format type element. </p> - <h3>Valid pool format types</h3> + <h3>Valid volume format types</h3> <p> The ZFS volume pool does not use the volume format type element. </p> @@ -810,6 +810,12 @@ <path>/mnt/clustername</path> </target> </pool></pre> + + <h3>Valid pool format types</h3> + <p> + The Vstorage volume pool does not use the pool format type element. + </p> + <h3>Valid volume format types</h3> <p>The valid volume types are the same as for the directory pool.</p> </body> -- 2.20.1

Introduce the bare bones functions to processing capability data for the storage driver. Since there will be no need for the <host> output, we need to filter that data. Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/capabilities.c | 74 ++++++++++++++++++++++++++++++++++++++++ src/conf/capabilities.h | 15 ++++++++ src/libvirt_private.syms | 1 + 3 files changed, 90 insertions(+) diff --git a/src/conf/capabilities.c b/src/conf/capabilities.c index 716ac6e2e7..47308700bb 100644 --- a/src/conf/capabilities.c +++ b/src/conf/capabilities.c @@ -28,6 +28,7 @@ #include "cpu_conf.h" #include "domain_conf.h" #include "physmem.h" +#include "storage_conf.h" #include "viralloc.h" #include "virarch.h" #include "virbuffer.h" @@ -181,6 +182,17 @@ virCapabilitiesFreeGuest(virCapsGuestPtr guest) VIR_FREE(guest); } + +static void +virCapabilitiesFreeStoragePool(virCapsStoragePoolPtr pool) +{ + if (!pool) + return; + + VIR_FREE(pool); +} + + void virCapabilitiesFreeNUMAInfo(virCapsPtr caps) { @@ -222,6 +234,10 @@ virCapsDispose(void *object) virCapsPtr caps = object; size_t i; + for (i = 0; i < caps->npools; i++) + virCapabilitiesFreeStoragePool(caps->pools[i]); + VIR_FREE(caps->pools); + for (i = 0; i < caps->nguests; i++) virCapabilitiesFreeGuest(caps->guests[i]); VIR_FREE(caps->guests); @@ -793,6 +809,30 @@ virCapabilitiesDomainDataLookup(virCapsPtr caps, emulator, machinetype); } + +int +virCapabilitiesAddStoragePool(virCapsPtr caps, + int poolType) +{ + virCapsStoragePoolPtr pool; + + if (VIR_ALLOC(pool) < 0) + goto error; + + pool->type = poolType; + + if (VIR_RESIZE_N(caps->pools, caps->npools_max, caps->npools, 1) < 0) + goto error; + caps->pools[caps->npools++] = pool; + + return 0; + + error: + virCapabilitiesFreeStoragePool(pool); + return -1; +} + + static int virCapabilitiesFormatNUMATopology(virBufferPtr buf, size_t ncells, @@ -1065,6 +1105,12 @@ virCapabilitiesFormatHostXML(virCapsHostPtr host, size_t i, j; char host_uuid[VIR_UUID_STRING_BUFLEN]; + /* The lack of some data means we have nothing + * minimally to format, so just return. */ + if (!virUUIDIsValid(host->host_uuid) && + !host->arch && !host->powerMgmt && !host->iommu) + return 0; + virBufferAddLit(buf, "<host>\n"); virBufferAdjustIndent(buf, 2); if (virUUIDIsValid(host->host_uuid)) { @@ -1277,6 +1323,32 @@ virCapabilitiesFormatGuestXML(virCapsGuestPtr *guests, } +static void +virCapabilitiesFormatStoragePoolXML(virCapsStoragePoolPtr *pools, + size_t npools, + virBufferPtr buf) +{ + size_t i; + + if (npools == 0) + return; + + virBufferAddLit(buf, "<pool>\n"); + virBufferAdjustIndent(buf, 2); + + virBufferAddLit(buf, "<enum name='type'>\n"); + virBufferAdjustIndent(buf, 2); + for (i = 0; i < npools; i++) + virBufferAsprintf(buf, "<value>%s</value>\n", + virStoragePoolTypeToString(pools[i]->type)); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</enum>\n"); + + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</pool>\n\n"); +} + + /** * virCapabilitiesFormatXML: * @caps: capabilities to format @@ -1298,6 +1370,8 @@ virCapabilitiesFormatXML(virCapsPtr caps) virCapabilitiesFormatGuestXML(caps->guests, caps->nguests, &buf); + virCapabilitiesFormatStoragePoolXML(caps->pools, caps->npools, &buf); + virBufferAdjustIndent(&buf, -2); virBufferAddLit(&buf, "</capabilities>\n"); diff --git a/src/conf/capabilities.h b/src/conf/capabilities.h index 31c2a07a9b..cca1a20949 100644 --- a/src/conf/capabilities.h +++ b/src/conf/capabilities.h @@ -211,6 +211,13 @@ struct _virCapsHost { bool iommu; }; +typedef struct _virCapsStoragePool virCapsStoragePool; +typedef virCapsStoragePool *virCapsStoragePoolPtr; +struct _virCapsStoragePool { + int type; +}; + + typedef int (*virDomainDefNamespaceParse)(xmlDocPtr, xmlNodePtr, xmlXPathContextPtr, void **); typedef void (*virDomainDefNamespaceFree)(void *); @@ -235,6 +242,10 @@ struct _virCaps { size_t nguests; size_t nguests_max; virCapsGuestPtr *guests; + + size_t npools; + size_t npools_max; + virCapsStoragePoolPtr *pools; }; typedef struct _virCapsDomainData virCapsDomainData; @@ -318,6 +329,10 @@ virCapabilitiesAddGuestFeature(virCapsGuestPtr guest, bool defaultOn, bool toggle); +int +virCapabilitiesAddStoragePool(virCapsPtr caps, + int poolType); + int virCapabilitiesHostSecModelAddBaseLabel(virCapsHostSecModelPtr secmodel, const char *type, diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 67579742fd..62e37f442d 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -49,6 +49,7 @@ virCapabilitiesAddGuestFeature; virCapabilitiesAddHostFeature; virCapabilitiesAddHostMigrateTransport; virCapabilitiesAddHostNUMACell; +virCapabilitiesAddStoragePool; virCapabilitiesAllocMachines; virCapabilitiesClearHostNUMACellCPUTopology; virCapabilitiesDomainDataLookup; -- 2.20.1

https://bugzilla.redhat.com/show_bug.cgi?id=1581670 During storage driver backend initialization, let's save which backends are available in the storage pool capabilities. In order to format those, we need add a connectGetCapabilities processor to the storageHypervisorDriver. This allows a storage connection, such as "storage:///system" to find the API and format the results, such as: virsh -c storage:///system capabilities <capabilities> <pool> <enum name='type'> <value>dir</value> <value>fs</value> <value>netfs</value> <value>logical</value> <value>iscsi</value> <value>iscsi-direct</value> <value>scsi</value> <value>mpath</value> <value>disk</value> <value>rbd</value> <value>sheepdog</value> <value>gluster</value> <value>zfs</value> </enum> </pool> </capabilities> Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/virstorageobj.h | 5 +++++ src/storage/storage_backend.c | 16 ++++++++++++++++ src/storage/storage_backend.h | 3 +++ src/storage/storage_driver.c | 20 ++++++++++++++++++++ 4 files changed, 44 insertions(+) diff --git a/src/conf/virstorageobj.h b/src/conf/virstorageobj.h index 1106aa71bd..c41d4c16ad 100644 --- a/src/conf/virstorageobj.h +++ b/src/conf/virstorageobj.h @@ -24,6 +24,8 @@ # include "storage_conf.h" +# include "capabilities.h" + typedef struct _virStoragePoolObj virStoragePoolObj; typedef virStoragePoolObj *virStoragePoolObjPtr; @@ -45,6 +47,9 @@ struct _virStorageDriverState { /* Immutable pointer, self-locking APIs */ virObjectEventStatePtr storageEventState; + + /* Immutable pointer, read only after initialized */ + virCapsPtr caps; }; typedef bool diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c index a54c338cf0..df37d94831 100644 --- a/src/storage/storage_backend.c +++ b/src/storage/storage_backend.c @@ -187,3 +187,19 @@ virStorageBackendForType(int type) type, NULLSTR(virStoragePoolTypeToString(type))); return NULL; } + + +virCapsPtr +virStorageBackendGetCapabilities(void) +{ + virCapsPtr caps; + size_t i; + + if (!(caps = virCapabilitiesNew(VIR_ARCH_NONE, false, false))) + return NULL; + + for (i = 0; i < virStorageBackendsCount; i++) + virCapabilitiesAddStoragePool(caps, virStorageBackends[i]->type); + + return caps; +} diff --git a/src/storage/storage_backend.h b/src/storage/storage_backend.h index 2b178494ae..c670c66287 100644 --- a/src/storage/storage_backend.h +++ b/src/storage/storage_backend.h @@ -126,4 +126,7 @@ int virStorageBackendDriversRegister(bool allmodules); int virStorageBackendRegister(virStorageBackendPtr backend); +virCapsPtr +virStorageBackendGetCapabilities(void); + #endif /* LIBVIRT_STORAGE_BACKEND_H */ diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c index 34634e97d9..f2bc24370d 100644 --- a/src/storage/storage_driver.c +++ b/src/storage/storage_driver.c @@ -296,6 +296,12 @@ storageStateInitialize(bool privileged, driver->storageEventState = virObjectEventStateNew(); + /* Only one load of storage driver plus backends exists. Unlike + * domains where new binaries could change the capabilities. A + * new/changed backend requires a reinitialization. */ + if (!(driver->caps = virStorageBackendGetCapabilities())) + goto error; + storageDriverUnlock(); return 0; @@ -360,6 +366,7 @@ storageStateCleanup(void) storageDriverLock(); + virObjectUnref(driver->caps); virObjectUnref(driver->storageEventState); /* free inactive pools */ @@ -569,6 +576,18 @@ storageConnectListStoragePools(virConnectPtr conn, names, maxnames); } + +static char * +storageConnectGetCapabilities(virConnectPtr conn) +{ + + if (virConnectGetCapabilitiesEnsureACL(conn) < 0) + return NULL; + + return virCapabilitiesFormatXML(driver->caps); +} + + static int storageConnectNumOfDefinedStoragePools(virConnectPtr conn) { @@ -2819,6 +2838,7 @@ static virHypervisorDriver storageHypervisorDriver = { .connectIsEncrypted = storageConnectIsEncrypted, /* 4.1.0 */ .connectIsSecure = storageConnectIsSecure, /* 4.1.0 */ .connectIsAlive = storageConnectIsAlive, /* 4.1.0 */ + .connectGetCapabilities = storageConnectGetCapabilities, /* 5.1.0 */ }; static virConnectDriver storageConnectDriver = { -- 2.20.1

Define a schema for the storage pool capabilities along with a test to show the general format. Signed-off-by: John Ferlan <jferlan@redhat.com> --- docs/schemas/storagepoolcaps.rng | 88 ++++++ libvirt.spec.in | 1 + mingw-libvirt.spec.in | 2 + tests/Makefile.am | 1 + .../poolcaps-full.xml | 268 ++++++++++++++++++ tests/virschematest.c | 1 + 6 files changed, 361 insertions(+) create mode 100644 docs/schemas/storagepoolcaps.rng create mode 100644 tests/storagepoolcapsschemadata/poolcaps-full.xml diff --git a/docs/schemas/storagepoolcaps.rng b/docs/schemas/storagepoolcaps.rng new file mode 100644 index 0000000000..e3bf1efcde --- /dev/null +++ b/docs/schemas/storagepoolcaps.rng @@ -0,0 +1,88 @@ +<?xml version="1.0"?> +<!-- A Relax NG schema for the libvirt storage pool capabilities XML format --> +<grammar xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"> + <include href='basictypes.rng'/> + <start> + <ref name='storagepoolCapabilities'/> + </start> + + + <define name='storagepoolCapabilities'> + <element name='storagepoolCapabilities'> + <zeroOrMore> + <ref name='poolCapsType'/> + </zeroOrMore> + </element> + </define> + + <define name='poolCapsType'> + <element name='pool'> + <ref name='poolCapsTypes'/> + <ref name='poolCapsSupported'/> + <optional> + <ref name='poolCapsPoolOptions'/> + </optional> + <optional> + <ref name='poolCapsVolOptions'/> + </optional> + </element> + </define> + + <define name='poolCapsTypes'> + <attribute name='type'> + <text/> + </attribute> + </define> + + <define name='poolCapsSupported'> + <attribute name='supported'> + <ref name="virYesNo"/> + </attribute> + </define> + + <define name='poolCapsPoolOptions'> + <element name='poolOptions'> + <optional> + <ref name='poolDefaultFormat'/> + </optional> + <optional> + <ref name='poolCapsEnum'/> + </optional> + </element> + </define> + + <define name='poolCapsVolOptions'> + <element name='volOptions'> + <ref name='poolDefaultFormat'/> + <ref name='poolCapsEnum'/> + </element> + </define> + + <define name='poolDefaultFormat'> + <element name='defaultFormat'> + <attribute name='type'> + <text/> + </attribute> + </element> + </define> + + <define name='poolCapsEnum'> + <zeroOrMore> + <element name='enum'> + <attribute name='name'> + <text/> + </attribute> + <ref name='value'/> + </element> + </zeroOrMore> + </define> + + <define name='value'> + <zeroOrMore> + <element name='value'> + <text/> + </element> + </zeroOrMore> + </define> + +</grammar> diff --git a/libvirt.spec.in b/libvirt.spec.in index 9beffba203..82681eea42 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -1822,6 +1822,7 @@ exit 0 %{_datadir}/libvirt/schemas/secret.rng %{_datadir}/libvirt/schemas/storagecommon.rng %{_datadir}/libvirt/schemas/storagepool.rng +%{_datadir}/libvirt/schemas/storagepoolcaps.rng %{_datadir}/libvirt/schemas/storagevol.rng %{_datadir}/libvirt/cpu_map/*.xml diff --git a/mingw-libvirt.spec.in b/mingw-libvirt.spec.in index 249abb8475..bea822fd73 100644 --- a/mingw-libvirt.spec.in +++ b/mingw-libvirt.spec.in @@ -252,6 +252,7 @@ rm -rf $RPM_BUILD_ROOT%{mingw64_libexecdir}/libvirt-guests.sh %{mingw32_datadir}/libvirt/schemas/secret.rng %{mingw32_datadir}/libvirt/schemas/storagecommon.rng %{mingw32_datadir}/libvirt/schemas/storagepool.rng +%{mingw32_datadir}/libvirt/schemas/storagepoolcaps.rng %{mingw32_datadir}/libvirt/schemas/storagevol.rng %dir %{mingw32_datadir}/libvirt/api/ %{mingw32_datadir}/libvirt/api/libvirt-api.xml @@ -339,6 +340,7 @@ rm -rf $RPM_BUILD_ROOT%{mingw64_libexecdir}/libvirt-guests.sh %{mingw64_datadir}/libvirt/schemas/secret.rng %{mingw64_datadir}/libvirt/schemas/storagecommon.rng %{mingw64_datadir}/libvirt/schemas/storagepool.rng +%{mingw64_datadir}/libvirt/schemas/storagepoolcaps.rng %{mingw64_datadir}/libvirt/schemas/storagevol.rng %dir %{mingw64_datadir}/libvirt/api/ %{mingw64_datadir}/libvirt/api/libvirt-api.xml diff --git a/tests/Makefile.am b/tests/Makefile.am index c3f633cee0..760f600bf2 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -136,6 +136,7 @@ EXTRA_DIST = \ securityselinuxhelperdata \ securityselinuxlabeldata \ sexpr2xmldata \ + storagepoolcapsschemadata \ storagepoolschemadata \ storagepoolxml2xmlin \ storagepoolxml2xmlout \ diff --git a/tests/storagepoolcapsschemadata/poolcaps-full.xml b/tests/storagepoolcapsschemadata/poolcaps-full.xml new file mode 100644 index 0000000000..0bb3faf04e --- /dev/null +++ b/tests/storagepoolcapsschemadata/poolcaps-full.xml @@ -0,0 +1,268 @@ +<storagepoolCapabilities> + <pool type='dir' supported='yes'> + <volOptions> + <defaultFormat type='raw'/> + <enum name='targetFormatType'> + <value>none</value> + <value>raw</value> + <value>dir</value> + <value>bochs</value> + <value>cloop</value> + <value>dmg</value> + <value>iso</value> + <value>vpc</value> + <value>vdi</value> + <value>fat</value> + <value>vhd</value> + <value>ploop</value> + <value>cow</value> + <value>qcow</value> + <value>qcow2</value> + <value>qed</value> + <value>vmdk</value> + </enum> + </volOptions> + </pool> + <pool type='fs' supported='yes'> + <poolOptions> + <defaultFormat type='auto'/> + <enum name='sourceFormatType'> + <value>auto</value> + <value>ext2</value> + <value>ext3</value> + <value>ext4</value> + <value>ufs</value> + <value>iso9660</value> + <value>udf</value> + <value>gfs</value> + <value>gfs2</value> + <value>vfat</value> + <value>hfs+</value> + <value>xfs</value> + <value>ocfs2</value> + </enum> + <enum name='requiredSourceElements'> + <value>device</value> + </enum> + </poolOptions> + <volOptions> + <defaultFormat type='raw'/> + <enum name='targetFormatType'> + <value>none</value> + <value>raw</value> + <value>dir</value> + <value>bochs</value> + <value>cloop</value> + <value>dmg</value> + <value>iso</value> + <value>vpc</value> + <value>vdi</value> + <value>fat</value> + <value>vhd</value> + <value>ploop</value> + <value>cow</value> + <value>qcow</value> + <value>qcow2</value> + <value>qed</value> + <value>vmdk</value> + </enum> + </volOptions> + </pool> + <pool type='netfs' supported='yes'> + <poolOptions> + <defaultFormat type='auto'/> + <enum name='sourceFormatType'> + <value>auto</value> + <value>nfs</value> + <value>glusterfs</value> + <value>cifs</value> + </enum> + <enum name='requiredSourceElements'> + <value>host</value> + <value>dir</value> + </enum> + </poolOptions> + <volOptions> + <defaultFormat type='raw'/> + <enum name='targetFormatType'> + <value>none</value> + <value>raw</value> + <value>dir</value> + <value>bochs</value> + <value>cloop</value> + <value>dmg</value> + <value>iso</value> + <value>vpc</value> + <value>vdi</value> + <value>fat</value> + <value>vhd</value> + <value>ploop</value> + <value>cow</value> + <value>qcow</value> + <value>qcow2</value> + <value>qed</value> + <value>vmdk</value> + </enum> + </volOptions> + </pool> + <pool type='logical' supported='yes'> + <poolOptions> + <defaultFormat type='lvm2'/> + <enum name='sourceFormatType'> + <value>unknown</value> + <value>lvm2</value> + </enum> + <enum name='requiredSourceElements'> + <value>device</value> + <value>name</value> + </enum> + </poolOptions> + </pool> + <pool type='disk' supported='yes'> + <poolOptions> + <defaultFormat type='unknown'/> + <enum name='sourceFormatType'> + <value>unknown</value> + <value>dos</value> + <value>dvh</value> + <value>gpt</value> + <value>mac</value> + <value>bsd</value> + <value>pc98</value> + <value>sun</value> + <value>lvm2</value> + </enum> + <enum name='requiredSourceElements'> + <value>device</value> + </enum> + </poolOptions> + <volOptions> + <defaultFormat type='none'/> + <enum name='targetFormatType'> + <value>none</value> + <value>linux</value> + <value>fat16</value> + <value>fat32</value> + <value>linux-swap</value> + <value>linux-lvm</value> + <value>linux-raid</value> + <value>extended</value> + </enum> + </volOptions> + </pool> + <pool type='iscsi' supported='yes'> + <poolOptions> + <enum name='requiredSourceElements'> + <value>host</value> + <value>device</value> + <value>initiator</value> + </enum> + </poolOptions> + </pool> + <pool type='iscsi-direct' supported='yes'> + <poolOptions> + <enum name='requiredSourceElements'> + <value>host</value> + <value>device</value> + <value>initiator</value> + <value>network</value> + </enum> + </poolOptions> + </pool> + <pool type='scsi' supported='yes'> + <poolOptions> + <enum name='requiredSourceElements'> + <value>adapter</value> + </enum> + </poolOptions> + </pool> + <pool type='mpath' supported='yes'> + </pool> + <pool type='rbd' supported='yes'> + <poolOptions> + <enum name='requiredSourceElements'> + <value>host</value> + <value>name</value> + <value>network</value> + </enum> + </poolOptions> + </pool> + <pool type='sheepdog' supported='yes'> + <poolOptions> + <enum name='requiredSourceElements'> + <value>host</value> + <value>name</value> + <value>network</value> + </enum> + </poolOptions> + </pool> + <pool type='gluster' supported='yes'> + <poolOptions> + <enum name='requiredSourceElements'> + <value>host</value> + <value>dir</value> + <value>name</value> + <value>network</value> + </enum> + </poolOptions> + <volOptions> + <defaultFormat type='raw'/> + <enum name='targetFormatType'> + <value>none</value> + <value>raw</value> + <value>dir</value> + <value>bochs</value> + <value>cloop</value> + <value>dmg</value> + <value>iso</value> + <value>vpc</value> + <value>vdi</value> + <value>fat</value> + <value>vhd</value> + <value>ploop</value> + <value>cow</value> + <value>qcow</value> + <value>qcow2</value> + <value>qed</value> + <value>vmdk</value> + </enum> + </volOptions> + </pool> + <pool type='zfs' supported='yes'> + <poolOptions> + <enum name='requiredSourceElements'> + <value>device</value> + <value>name</value> + </enum> + </poolOptions> + </pool> + <pool type='vstorage' supported='yes'> + <poolOptions> + <enum name='requiredSourceElements'> + <value>name</value> + </enum> + </poolOptions> + <volOptions> + <defaultFormat type='raw'/> + <enum name='targetFormatType'> + <value>none</value> + <value>raw</value> + <value>dir</value> + <value>bochs</value> + <value>cloop</value> + <value>dmg</value> + <value>iso</value> + <value>vpc</value> + <value>vdi</value> + <value>fat</value> + <value>vhd</value> + <value>ploop</value> + <value>cow</value> + <value>qcow</value> + <value>qcow2</value> + <value>qed</value> + <value>vmdk</value> + </enum> + </volOptions> + </pool> +</storagepoolCapabilities> diff --git a/tests/virschematest.c b/tests/virschematest.c index d1bcdeac9c..a89a26b918 100644 --- a/tests/virschematest.c +++ b/tests/virschematest.c @@ -231,6 +231,7 @@ mymain(void) DO_TEST_DIR("nwfilter.rng", "nwfilterxml2xmlout", "../examples/xml/nwfilter"); DO_TEST_DIR("nwfilterbinding.rng", "virnwfilterbindingxml2xmldata"); DO_TEST_DIR("secret.rng", "secretxml2xmlin"); + DO_TEST_DIR("storagepoolcaps.rng", "storagepoolcapsschemadata"); DO_TEST_DIR("storagepool.rng", "storagepoolxml2xmlin", "storagepoolxml2xmlout", "storagepoolschemadata"); DO_TEST_DIR("storagevol.rng", "storagevolxml2xmlin", "storagevolxml2xmlout", -- 2.20.1

Add support to format the storage pool capabilities using the virStoragePoolTypeInfoPtr to determine what capabilities exist for the various pools and the driver capabilities to determine whether the pool is compiled in and supported. Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/Makefile.inc.am | 2 + src/conf/storage_capabilities.c | 135 ++++++++++++++++++++++++++++++++ src/conf/storage_capabilities.h | 41 ++++++++++ src/conf/storage_conf.c | 109 ++++++++++++++++++++++++++ src/conf/storage_conf.h | 7 ++ src/libvirt_private.syms | 7 ++ 6 files changed, 301 insertions(+) create mode 100644 src/conf/storage_capabilities.c create mode 100644 src/conf/storage_capabilities.h diff --git a/src/conf/Makefile.inc.am b/src/conf/Makefile.inc.am index 219ff350d7..fb2ec0e785 100644 --- a/src/conf/Makefile.inc.am +++ b/src/conf/Makefile.inc.am @@ -96,6 +96,8 @@ NWFILTER_CONF_SOURCES = \ STORAGE_CONF_SOURCES = \ conf/storage_adapter_conf.h \ conf/storage_adapter_conf.c \ + conf/storage_capabilities.h \ + conf/storage_capabilities.c \ conf/storage_conf.h \ conf/storage_conf.c \ conf/virstorageobj.h \ diff --git a/src/conf/storage_capabilities.c b/src/conf/storage_capabilities.c new file mode 100644 index 0000000000..cf3ee488ac --- /dev/null +++ b/src/conf/storage_capabilities.c @@ -0,0 +1,135 @@ +/* + * storage_capabilities.c: storage pool capabilities XML processing + * + * Copyright (C) 2019 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + */ + +#include <config.h> + +#include "virerror.h" +#include "datatypes.h" +#include "capabilities.h" +#include "storage_capabilities.h" +#include "storage_conf.h" +#include "virlog.h" + +#define VIR_FROM_THIS VIR_FROM_CAPABILITIES + +VIR_LOG_INIT("conf.storage_capabilities"); + +static virClassPtr virStoragePoolCapsClass; + + +static void +virStoragePoolCapsDispose(void *obj) +{ + virStoragePoolCapsPtr caps = obj; + VIR_DEBUG("obj=%p", caps); + + virObjectUnref(caps->driverCaps); +} + + +static int +virStoragePoolCapsOnceInit(void) +{ + if (!VIR_CLASS_NEW(virStoragePoolCaps, virClassForObjectLockable())) + return -1; + return 0; +} + +VIR_ONCE_GLOBAL_INIT(virStoragePoolCaps); + + +virStoragePoolCapsPtr +virStoragePoolCapsNew(virCapsPtr driverCaps) +{ + virStoragePoolCapsPtr caps = NULL; + + if (virStoragePoolCapsInitialize() < 0) + return NULL; + + if (!(caps = virObjectLockableNew(virStoragePoolCapsClass))) + return NULL; + + caps->driverCaps = virObjectRef(driverCaps); + + return caps; +} + + +static bool +virStoragePoolCapsIsLoaded(virCapsPtr driverCaps, + int poolType) +{ + size_t i; + + if (!driverCaps) + return false; + + for (i = 0; i < driverCaps->npools; i++) { + if (driverCaps->pools[i]->type == poolType) + return true; + } + + return false; +} + + +static int +virStoragePoolCapsFormatPool(virBufferPtr buf, + int poolType, + virStoragePoolCapsPtr const caps) +{ + bool isLoaded = virStoragePoolCapsIsLoaded(caps->driverCaps, poolType); + + virBufferAsprintf(buf, "<pool type='%s' supported='%s'>\n", + virStoragePoolTypeToString(poolType), + isLoaded ? "yes" : "no"); + virBufferAdjustIndent(buf, 2); + + if (virStoragePoolOptionsFormatPool(buf, poolType) < 0) + return -1; + + if (virStoragePoolOptionsFormatVolume(buf, poolType) < 0) + return -1; + + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</pool>\n"); + return 0; +} + + +char * +virStoragePoolCapsFormat(virStoragePoolCapsPtr const caps) +{ + virBuffer buf = VIR_BUFFER_INITIALIZER; + size_t i; + + virBufferAddLit(&buf, "<storagepoolCapabilities>\n"); + virBufferAdjustIndent(&buf, 2); + for (i = 0; i < VIR_STORAGE_POOL_LAST; i++) { + if (virStoragePoolCapsFormatPool(&buf, i, caps) < 0) { + virBufferFreeAndReset(&buf); + return NULL; + } + } + virBufferAdjustIndent(&buf, -2); + virBufferAddLit(&buf, "</storagepoolCapabilities>\n"); + + return virBufferContentAndReset(&buf); +} diff --git a/src/conf/storage_capabilities.h b/src/conf/storage_capabilities.h new file mode 100644 index 0000000000..daeb496909 --- /dev/null +++ b/src/conf/storage_capabilities.h @@ -0,0 +1,41 @@ +/* + * storage_capabilities.h: storage pool capabilities XML processing + * + * Copyright (C) 2019 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + */ + +#ifndef LIBVIRT_STORAGE_CAPABILITIES_H +# define LIBVIRT_STORAGE_CAPABILITIES_H + +# include "internal.h" + +typedef struct _virStoragePoolCaps virStoragePoolCaps; +typedef virStoragePoolCaps *virStoragePoolCapsPtr; +struct _virStoragePoolCaps { + virObjectLockable parent; + + virCapsPtr driverCaps; +}; + +virStoragePoolCapsPtr +virStoragePoolCapsNew(virCapsPtr driverCaps); + +char * +virStoragePoolCapsFormat(virStoragePoolCapsPtr const caps); + + +#endif /* LIBVIRT_STORAGE_CAPABILITIES_H */ diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index be64c09d37..37c84d73ae 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -112,6 +112,7 @@ typedef struct _virStorageVolOptions virStorageVolOptions; typedef virStorageVolOptions *virStorageVolOptionsPtr; struct _virStorageVolOptions { int defaultFormat; + int lastFormat; virStorageVolFormatToString formatToString; virStorageVolFormatFromString formatFromString; }; @@ -132,6 +133,7 @@ typedef virStoragePoolOptions *virStoragePoolOptionsPtr; struct _virStoragePoolOptions { unsigned int flags; int defaultFormat; + int lastFormat; virStoragePoolXMLNamespace ns; @@ -164,6 +166,7 @@ static virStoragePoolTypeInfo poolTypeInfo[] = { .flags = (VIR_STORAGE_POOL_SOURCE_NAME | VIR_STORAGE_POOL_SOURCE_DEVICE), .defaultFormat = VIR_STORAGE_POOL_LOGICAL_LVM2, + .lastFormat = VIR_STORAGE_POOL_LOGICAL_LAST, .formatFromString = virStoragePoolFormatLogicalTypeFromString, .formatToString = virStoragePoolFormatLogicalTypeToString, }, @@ -171,6 +174,7 @@ static virStoragePoolTypeInfo poolTypeInfo[] = { {.poolType = VIR_STORAGE_POOL_DIR, .volOptions = { .defaultFormat = VIR_STORAGE_FILE_RAW, + .lastFormat = VIR_STORAGE_FILE_LAST, .formatFromString = virStorageVolumeFormatFromString, .formatToString = virStorageFileFormatTypeToString, }, @@ -179,11 +183,13 @@ static virStoragePoolTypeInfo poolTypeInfo[] = { .poolOptions = { .flags = (VIR_STORAGE_POOL_SOURCE_DEVICE), .defaultFormat = VIR_STORAGE_POOL_FS_AUTO, + .lastFormat = VIR_STORAGE_POOL_FS_LAST, .formatFromString = virStoragePoolFormatFileSystemTypeFromString, .formatToString = virStoragePoolFormatFileSystemTypeToString, }, .volOptions = { .defaultFormat = VIR_STORAGE_FILE_RAW, + .lastFormat = VIR_STORAGE_FILE_LAST, .formatFromString = virStorageVolumeFormatFromString, .formatToString = virStorageFileFormatTypeToString, }, @@ -193,11 +199,13 @@ static virStoragePoolTypeInfo poolTypeInfo[] = { .flags = (VIR_STORAGE_POOL_SOURCE_HOST | VIR_STORAGE_POOL_SOURCE_DIR), .defaultFormat = VIR_STORAGE_POOL_NETFS_AUTO, + .lastFormat = VIR_STORAGE_POOL_NETFS_LAST, .formatFromString = virStoragePoolFormatFileSystemNetTypeFromString, .formatToString = virStoragePoolFormatFileSystemNetTypeToString, }, .volOptions = { .defaultFormat = VIR_STORAGE_FILE_RAW, + .lastFormat = VIR_STORAGE_FILE_LAST, .formatFromString = virStorageVolumeFormatFromString, .formatToString = virStorageFileFormatTypeToString, }, @@ -245,6 +253,7 @@ static virStoragePoolTypeInfo poolTypeInfo[] = { }, .volOptions = { .defaultFormat = VIR_STORAGE_FILE_RAW, + .lastFormat = VIR_STORAGE_FILE_LAST, .formatToString = virStorageFileFormatTypeToString, .formatFromString = virStorageVolumeFormatFromString, } @@ -255,11 +264,13 @@ static virStoragePoolTypeInfo poolTypeInfo[] = { .poolOptions = { .flags = (VIR_STORAGE_POOL_SOURCE_DEVICE), .defaultFormat = VIR_STORAGE_POOL_DISK_UNKNOWN, + .lastFormat = VIR_STORAGE_POOL_DISK_LAST, .formatFromString = virStoragePoolFormatDiskTypeFromString, .formatToString = virStoragePoolFormatDiskTypeToString, }, .volOptions = { .defaultFormat = VIR_STORAGE_VOL_DISK_NONE, + .lastFormat = VIR_STORAGE_VOL_DISK_LAST, .formatFromString = virStorageVolFormatDiskTypeFromString, .formatToString = virStorageVolFormatDiskTypeToString, }, @@ -276,6 +287,7 @@ static virStoragePoolTypeInfo poolTypeInfo[] = { }, .volOptions = { .defaultFormat = VIR_STORAGE_FILE_RAW, + .lastFormat = VIR_STORAGE_FILE_LAST, .formatFromString = virStorageVolumeFormatFromString, .formatToString = virStorageFileFormatTypeToString, }, @@ -345,6 +357,103 @@ virStorageVolOptionsForPoolType(int type) } +int +virStoragePoolOptionsFormatPool(virBufferPtr buf, + int type) +{ + virStoragePoolOptionsPtr poolOptions; + + if (!(poolOptions = virStoragePoolOptionsForPoolType(type))) + return -1; + + if (!poolOptions->formatToString && !poolOptions->flags) + return 0; + + virBufferAddLit(buf, "<poolOptions>\n"); + virBufferAdjustIndent(buf, 2); + + if (poolOptions->formatToString) { + size_t i; + + virBufferAsprintf(buf, "<defaultFormat type='%s'/>\n", + (poolOptions->formatToString)(poolOptions->defaultFormat)); + + virBufferAddLit(buf, "<enum name='sourceFormatType'>\n"); + virBufferAdjustIndent(buf, 2); + + for (i = 0; i < poolOptions->lastFormat; i++) + virBufferAsprintf(buf, "<value>%s</value>\n", + (poolOptions->formatToString)(i)); + + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</enum>\n"); + } + + if (poolOptions->flags) { + virBufferAddLit(buf, "<enum name='requiredSourceElements'>\n"); + virBufferAdjustIndent(buf, 2); + + if (poolOptions->flags & VIR_STORAGE_POOL_SOURCE_HOST) + virBufferAddLit(buf, "<value>host</value>\n"); + if (poolOptions->flags & VIR_STORAGE_POOL_SOURCE_DEVICE) + virBufferAddLit(buf, "<value>device</value>\n"); + if (poolOptions->flags & VIR_STORAGE_POOL_SOURCE_DIR) + virBufferAddLit(buf, "<value>dir</value>\n"); + if (poolOptions->flags & VIR_STORAGE_POOL_SOURCE_ADAPTER) + virBufferAddLit(buf, "<value>adapter</value>\n"); + if (poolOptions->flags & VIR_STORAGE_POOL_SOURCE_NAME) + virBufferAddLit(buf, "<value>name</value>\n"); + if (poolOptions->flags & VIR_STORAGE_POOL_SOURCE_INITIATOR_IQN) + virBufferAddLit(buf, "<value>initiator</value>\n"); + if (poolOptions->flags & VIR_STORAGE_POOL_SOURCE_NETWORK) + virBufferAddLit(buf, "<value>network</value>\n"); + + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</enum>\n"); + } + + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</poolOptions>\n"); + return 0; +} + + +int +virStoragePoolOptionsFormatVolume(virBufferPtr buf, + int type) +{ + size_t i; + virStorageVolOptionsPtr volOptions; + + if (!(volOptions = virStorageVolOptionsForPoolType(type))) + return -1; + + if (!volOptions->formatToString) + return 0; + + virBufferAddLit(buf, "<volOptions>\n"); + virBufferAdjustIndent(buf, 2); + + virBufferAsprintf(buf, "<defaultFormat type='%s'/>\n", + (volOptions->formatToString)(volOptions->defaultFormat)); + + virBufferAddLit(buf, "<enum name='targetFormatType'>\n"); + virBufferAdjustIndent(buf, 2); + + for (i = 0; i < volOptions->lastFormat; i++) + virBufferAsprintf(buf, "<value>%s</value>\n", + (volOptions->formatToString)(i)); + + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</enum>\n"); + + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</volOptions>\n"); + + return 0; +} + + void virStorageVolDefFree(virStorageVolDefPtr def) { diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h index daf6f9b68c..bfbebd15bd 100644 --- a/src/conf/storage_conf.h +++ b/src/conf/storage_conf.h @@ -53,6 +53,13 @@ int virStoragePoolOptionsPoolTypeSetXMLNamespace(int type, virStoragePoolXMLNamespacePtr ns); +int +virStoragePoolOptionsFormatPool(virBufferPtr buf, + int type); + +int +virStoragePoolOptionsFormatVolume(virBufferPtr buf, + int type); /* * How the volume's data is stored on underlying * physical devices - can potentially span many diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 62e37f442d..0d8291411d 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -909,6 +909,11 @@ virStorageAdapterParseXML; virStorageAdapterValidate; +# conf/storage_capabilities.h +virStoragePoolCapsFormat; +virStoragePoolCapsNew; + + # conf/storage_conf.h virStoragePartedFsTypeToString; virStoragePoolDefFormat; @@ -922,6 +927,8 @@ virStoragePoolFormatDiskTypeToString; virStoragePoolFormatFileSystemNetTypeToString; virStoragePoolFormatFileSystemTypeToString; virStoragePoolFormatLogicalTypeToString; +virStoragePoolOptionsFormatPool; +virStoragePoolOptionsFormatVolume; virStoragePoolOptionsPoolTypeSetXMLNamespace; virStoragePoolSaveConfig; virStoragePoolSaveState; -- 2.20.1

Add a new test for the storage pool capabilities. There will be one test mocked with every backend available (full) and one where only the file system pool is available. Signed-off-by: John Ferlan <jferlan@redhat.com> --- tests/Makefile.am | 6 + .../storagepoolcapsschemadata/poolcaps-fs.xml | 268 ++++++++++++++++++ tests/storagepoolcapstest.c | 124 ++++++++ 3 files changed, 398 insertions(+) create mode 100644 tests/storagepoolcapsschemadata/poolcaps-fs.xml create mode 100644 tests/storagepoolcapstest.c diff --git a/tests/Makefile.am b/tests/Makefile.am index 760f600bf2..72f0420bab 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -369,6 +369,7 @@ test_programs += storagevolxml2argvtest test_programs += storagepoolxml2argvtest test_programs += virstorageutiltest test_programs += storagepoolxml2xmltest +test_programs += storagepoolcapstest endif WITH_STORAGE if WITH_STORAGE_FS @@ -936,11 +937,16 @@ storagepoolxml2xmltest_LDADD = $(LDADDS) \ ../src/libvirt_driver_storage_impl.la \ $(GNULIB_LIBS) +storagepoolcapstest_SOURCES = \ + storagepoolcapstest.c testutils.h testutils.c +storagepoolcapstest_LDADD = $(LDADDS) + else ! WITH_STORAGE EXTRA_DIST += storagevolxml2argvtest.c EXTRA_DIST += virstorageutiltest.c EXTRA_DIST += storagepoolxml2argvtest.c EXTRA_DIST += storagepoolxml2xmltest.c +EXTRA_DIST += storagepoolcapstest.c endif ! WITH_STORAGE storagevolxml2xmltest_SOURCES = \ diff --git a/tests/storagepoolcapsschemadata/poolcaps-fs.xml b/tests/storagepoolcapsschemadata/poolcaps-fs.xml new file mode 100644 index 0000000000..0e15af0607 --- /dev/null +++ b/tests/storagepoolcapsschemadata/poolcaps-fs.xml @@ -0,0 +1,268 @@ +<storagepoolCapabilities> + <pool type='dir' supported='no'> + <volOptions> + <defaultFormat type='raw'/> + <enum name='targetFormatType'> + <value>none</value> + <value>raw</value> + <value>dir</value> + <value>bochs</value> + <value>cloop</value> + <value>dmg</value> + <value>iso</value> + <value>vpc</value> + <value>vdi</value> + <value>fat</value> + <value>vhd</value> + <value>ploop</value> + <value>cow</value> + <value>qcow</value> + <value>qcow2</value> + <value>qed</value> + <value>vmdk</value> + </enum> + </volOptions> + </pool> + <pool type='fs' supported='yes'> + <poolOptions> + <defaultFormat type='auto'/> + <enum name='sourceFormatType'> + <value>auto</value> + <value>ext2</value> + <value>ext3</value> + <value>ext4</value> + <value>ufs</value> + <value>iso9660</value> + <value>udf</value> + <value>gfs</value> + <value>gfs2</value> + <value>vfat</value> + <value>hfs+</value> + <value>xfs</value> + <value>ocfs2</value> + </enum> + <enum name='requiredSourceElements'> + <value>device</value> + </enum> + </poolOptions> + <volOptions> + <defaultFormat type='raw'/> + <enum name='targetFormatType'> + <value>none</value> + <value>raw</value> + <value>dir</value> + <value>bochs</value> + <value>cloop</value> + <value>dmg</value> + <value>iso</value> + <value>vpc</value> + <value>vdi</value> + <value>fat</value> + <value>vhd</value> + <value>ploop</value> + <value>cow</value> + <value>qcow</value> + <value>qcow2</value> + <value>qed</value> + <value>vmdk</value> + </enum> + </volOptions> + </pool> + <pool type='netfs' supported='no'> + <poolOptions> + <defaultFormat type='auto'/> + <enum name='sourceFormatType'> + <value>auto</value> + <value>nfs</value> + <value>glusterfs</value> + <value>cifs</value> + </enum> + <enum name='requiredSourceElements'> + <value>host</value> + <value>dir</value> + </enum> + </poolOptions> + <volOptions> + <defaultFormat type='raw'/> + <enum name='targetFormatType'> + <value>none</value> + <value>raw</value> + <value>dir</value> + <value>bochs</value> + <value>cloop</value> + <value>dmg</value> + <value>iso</value> + <value>vpc</value> + <value>vdi</value> + <value>fat</value> + <value>vhd</value> + <value>ploop</value> + <value>cow</value> + <value>qcow</value> + <value>qcow2</value> + <value>qed</value> + <value>vmdk</value> + </enum> + </volOptions> + </pool> + <pool type='logical' supported='no'> + <poolOptions> + <defaultFormat type='lvm2'/> + <enum name='sourceFormatType'> + <value>unknown</value> + <value>lvm2</value> + </enum> + <enum name='requiredSourceElements'> + <value>device</value> + <value>name</value> + </enum> + </poolOptions> + </pool> + <pool type='disk' supported='no'> + <poolOptions> + <defaultFormat type='unknown'/> + <enum name='sourceFormatType'> + <value>unknown</value> + <value>dos</value> + <value>dvh</value> + <value>gpt</value> + <value>mac</value> + <value>bsd</value> + <value>pc98</value> + <value>sun</value> + <value>lvm2</value> + </enum> + <enum name='requiredSourceElements'> + <value>device</value> + </enum> + </poolOptions> + <volOptions> + <defaultFormat type='none'/> + <enum name='targetFormatType'> + <value>none</value> + <value>linux</value> + <value>fat16</value> + <value>fat32</value> + <value>linux-swap</value> + <value>linux-lvm</value> + <value>linux-raid</value> + <value>extended</value> + </enum> + </volOptions> + </pool> + <pool type='iscsi' supported='no'> + <poolOptions> + <enum name='requiredSourceElements'> + <value>host</value> + <value>device</value> + <value>initiator</value> + </enum> + </poolOptions> + </pool> + <pool type='iscsi-direct' supported='no'> + <poolOptions> + <enum name='requiredSourceElements'> + <value>host</value> + <value>device</value> + <value>initiator</value> + <value>network</value> + </enum> + </poolOptions> + </pool> + <pool type='scsi' supported='no'> + <poolOptions> + <enum name='requiredSourceElements'> + <value>adapter</value> + </enum> + </poolOptions> + </pool> + <pool type='mpath' supported='no'> + </pool> + <pool type='rbd' supported='no'> + <poolOptions> + <enum name='requiredSourceElements'> + <value>host</value> + <value>name</value> + <value>network</value> + </enum> + </poolOptions> + </pool> + <pool type='sheepdog' supported='no'> + <poolOptions> + <enum name='requiredSourceElements'> + <value>host</value> + <value>name</value> + <value>network</value> + </enum> + </poolOptions> + </pool> + <pool type='gluster' supported='no'> + <poolOptions> + <enum name='requiredSourceElements'> + <value>host</value> + <value>dir</value> + <value>name</value> + <value>network</value> + </enum> + </poolOptions> + <volOptions> + <defaultFormat type='raw'/> + <enum name='targetFormatType'> + <value>none</value> + <value>raw</value> + <value>dir</value> + <value>bochs</value> + <value>cloop</value> + <value>dmg</value> + <value>iso</value> + <value>vpc</value> + <value>vdi</value> + <value>fat</value> + <value>vhd</value> + <value>ploop</value> + <value>cow</value> + <value>qcow</value> + <value>qcow2</value> + <value>qed</value> + <value>vmdk</value> + </enum> + </volOptions> + </pool> + <pool type='zfs' supported='no'> + <poolOptions> + <enum name='requiredSourceElements'> + <value>device</value> + <value>name</value> + </enum> + </poolOptions> + </pool> + <pool type='vstorage' supported='no'> + <poolOptions> + <enum name='requiredSourceElements'> + <value>name</value> + </enum> + </poolOptions> + <volOptions> + <defaultFormat type='raw'/> + <enum name='targetFormatType'> + <value>none</value> + <value>raw</value> + <value>dir</value> + <value>bochs</value> + <value>cloop</value> + <value>dmg</value> + <value>iso</value> + <value>vpc</value> + <value>vdi</value> + <value>fat</value> + <value>vhd</value> + <value>ploop</value> + <value>cow</value> + <value>qcow</value> + <value>qcow2</value> + <value>qed</value> + <value>vmdk</value> + </enum> + </volOptions> + </pool> +</storagepoolCapabilities> diff --git a/tests/storagepoolcapstest.c b/tests/storagepoolcapstest.c new file mode 100644 index 0000000000..d31f50c957 --- /dev/null +++ b/tests/storagepoolcapstest.c @@ -0,0 +1,124 @@ +/* + * Copyright (C) Red Hat, Inc. 2019 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + */ + +#include <config.h> + +#include "testutils.h" +#include "storage_conf.h" +#include "storage_capabilities.h" + + +#define VIR_FROM_THIS VIR_FROM_NONE + + +struct test_virStoragePoolCapsFormatData { + const char *filename; + virCapsPtr driverCaps; +}; + +static void +test_virCapabilitiesAddFullStoragePool(virCapsPtr caps) +{ + size_t i; + + for (i = 0; i < VIR_STORAGE_POOL_LAST; i++) + virCapabilitiesAddStoragePool(caps, i); +} + + +static void +test_virCapabilitiesAddFSStoragePool(virCapsPtr caps) +{ + virCapabilitiesAddStoragePool(caps, VIR_STORAGE_POOL_FS); +} + + +static int +test_virStoragePoolCapsFormat(const void *opaque) +{ + struct test_virStoragePoolCapsFormatData *data = + (struct test_virStoragePoolCapsFormatData *) opaque; + virCapsPtr driverCaps = data->driverCaps; + virStoragePoolCapsPtr poolCaps = NULL; + int ret = -1; + VIR_AUTOFREE(char *) path = NULL; + VIR_AUTOFREE(char *) poolCapsFromFile = NULL; + VIR_AUTOFREE(char *) poolCapsXML = NULL; + + + if (!(poolCaps = virStoragePoolCapsNew(driverCaps))) + goto cleanup; + + if (virAsprintf(&path, "%s/storagepoolcapsschemadata/poolcaps-%s.xml", + abs_srcdir, data->filename) < 0) + goto cleanup; + + if (virFileReadAll(path, 8192, &poolCapsFromFile) < 0) + goto cleanup; + + if (!(poolCapsXML = virStoragePoolCapsFormat(poolCaps))) + goto cleanup; + + if (STRNEQ(poolCapsFromFile, poolCapsXML)) { + virTestDifference(stderr, poolCapsFromFile, poolCapsXML); + goto cleanup; + } + + ret = 0; + + cleanup: + virObjectUnref(poolCaps); + return ret; +} + + +static int +mymain(void) +{ + int ret = -1; + virCapsPtr fullCaps = NULL; + virCapsPtr fsCaps = NULL; + +#define DO_TEST(Filename, DriverCaps) \ + do { \ + struct test_virStoragePoolCapsFormatData data = \ + {.filename = Filename, .driverCaps = DriverCaps }; \ + if (virTestRun(Filename, test_virStoragePoolCapsFormat, &data) < 0) \ + goto cleanup; \ + } while (0) + + if (!(fullCaps = virCapabilitiesNew(VIR_ARCH_NONE, false, false)) || + !(fsCaps = virCapabilitiesNew(VIR_ARCH_NONE, false, false))) + goto cleanup; + + test_virCapabilitiesAddFullStoragePool(fullCaps); + test_virCapabilitiesAddFSStoragePool(fsCaps); + + DO_TEST("full", fullCaps); + DO_TEST("fs", fsCaps); + + ret = 0; + + cleanup: + virObjectUnref(fullCaps); + virObjectUnref(fsCaps); + + return ret; +} + +VIR_TEST_MAIN(mymain) -- 2.20.1

Signed-off-by: John Ferlan <jferlan@redhat.com> --- docs/docs.html.in | 1 + docs/format.html.in | 1 + docs/formatstoragecaps.html.in | 108 +++++++++++++++++++++++++++++++++ docs/index.html.in | 1 + 4 files changed, 111 insertions(+) create mode 100644 docs/formatstoragecaps.html.in diff --git a/docs/docs.html.in b/docs/docs.html.in index 40e0e3b82e..d0ff844d0c 100644 --- a/docs/docs.html.in +++ b/docs/docs.html.in @@ -77,6 +77,7 @@ <a href="formatstorageencryption.html">storage encryption</a>, <a href="formatcaps.html">capabilities</a>, <a href="formatdomaincaps.html">domain capabilities</a>, + <a href="formatstoragecaps.html">storage pool capabilities</a>, <a href="formatnode.html">node devices</a>, <a href="formatsecret.html">secrets</a>, <a href="formatsnapshot.html">snapshots</a></dd> diff --git a/docs/format.html.in b/docs/format.html.in index 22b23e3fc7..640a9957ee 100644 --- a/docs/format.html.in +++ b/docs/format.html.in @@ -21,6 +21,7 @@ <li><a href="formatstorageencryption.html">Storage encryption</a></li> <li><a href="formatcaps.html">Capabilities</a></li> <li><a href="formatdomaincaps.html">Domain capabilities</a></li> + <li><a href="formatstoragecaps.html">Storage Pool capabilities</a></li> <li><a href="formatnode.html">Node devices</a></li> <li><a href="formatsecret.html">Secrets</a></li> <li><a href="formatsnapshot.html">Snapshots</a></li> diff --git a/docs/formatstoragecaps.html.in b/docs/formatstoragecaps.html.in new file mode 100644 index 0000000000..7f0641a3a8 --- /dev/null +++ b/docs/formatstoragecaps.html.in @@ -0,0 +1,108 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html> +<html xmlns="http://www.w3.org/1999/xhtml"> + <body> + <h1>Storage Pool Capabilities XML format</h1> + + <ul id="toc"></ul> + + <h2><a id="Overview">Overview</a></h2> + + <p>The Storage Pool Capabilities XML will provide the information + to determine what types of Storage Pools exist, whether the pool is + supported, and if relevant the source format types, the required + source elements, and the target volume format types. </p> + + <p>The Storage Pool Capabilities XML provides more information than the + <a href="/html/libvirt-libvirt-host.html#virConnectGetCapabilities"> + <code>virConnectGetCapabilities</code> + </a> + which only provides an enumerated list of supported pool types.</p> + + <h2><a id="elements">Element and attribute overview</a></h2> + + <p>A query interface was added to the virConnect API's to retrieve the + XML listing of the set of Storage Pool Capabilities + (<span class="since">Since 5.1.0</span>):</p> + +<pre> +<a href="/html/libvirt-libvirt-domain.html#virConnectGetStoragePoolCapabilities">virConnectGetStoragePoolCapabilities</a> +</pre> + + <p>The root element that emulator capability XML document starts with is + named <code>storagepoolCapabilities</code>. There will be any number of + <code>pool</code> child elements with two attributes <code>type</code> + and <code>supported</code>. Each <code>pool</code> element may have + a <code>poolOptions</code> or <code>volOptions</code> subelements to + describe the available features. Sample XML output is:</p> + +<pre> +<storagepoolCapabilities> + <pool type='dir' supported='yes'> + <volOptions> + <defaultFormat type='raw'</> + <enum name='targetFormatType'> + <value>none</value> + <value>raw</value> + ... + </enum> + </volOptions> + </pool> + <pool type='fs' supported='yes'> + <poolOptions> + <defaultFormat type='auto'</> + <enum name='sourceFormatType'> + <value>auto</value> + <value>ext2</value> + ... + </enum> + <enum name='requiredSourceElements'> + <value>device</value> + </enum> + </poolOptions> + <volOptions> + <defaultFormat type='raw'</> + <enum name='targetFormatType'> + <value>none</value> + <value>raw</value> + ... + </enum> + </volOptions> + </pool> + ... +</storagepoolCapabilities> +</pre> + + <p>The following section decribes subelements of the + <code>poolOptions</code> and <code>volOptions</code> subelements </p>: + + <dl> + <dt><code>defaultFormat</code></dt> + <dd>For the <code>poolOptions</code>, the <code>type</code> attribute + describes the default format name used for the pool source. For the + <code>volOptions</code>, the <code>type</code> attribute describes + the default volume name used for each volume. + </dd> + <dl> + <dt><code>enum</code></dt> + <dd>Each enum uses a name from the list below with any number of + <code>value</code> value subelements describing the valid values. + <dl> + <dt><code>sourceFormatType</code></dt> + <dd>Lists all the possible <code>poolOptions</code> source + pool format types. + </dd> + <dt><code>requiredSourceElements</code></dt> + <dd>Lists all the required <code>poolOptions</code> source + subelements required for a valid source pool element. + </dd> + <dt><code>targetFormatType</code></dt> + <dd>Lists all the possible <code>volOptions</code> target volume + format types. + </dd> + </dl> + </dd> + </dl> + </dl> + </body> +</html> diff --git a/docs/index.html.in b/docs/index.html.in index 1f9f448399..f593445d06 100644 --- a/docs/index.html.in +++ b/docs/index.html.in @@ -66,6 +66,7 @@ <a href="formatstorageencryption.html">storage encryption</a>, <a href="formatcaps.html">capabilities</a>, <a href="formatdomaincaps.html">domain capabilities</a>, + <a href="formatstoragecaps.html">storage pool capabilities</a>, <a href="formatnode.html">node devices</a>, <a href="formatsecret.html">secrets</a>, <a href="formatsnapshot.html">snapshots</a></dd> -- 2.20.1

On Tue, Feb 12, 2019 at 10:28:12AM -0500, John Ferlan wrote:
Signed-off-by: John Ferlan <jferlan@redhat.com> --- docs/docs.html.in | 1 + docs/format.html.in | 1 + docs/formatstoragecaps.html.in | 108 +++++++++++++++++++++++++++++++++ docs/index.html.in | 1 + 4 files changed, 111 insertions(+) create mode 100644 docs/formatstoragecaps.html.in
diff --git a/docs/docs.html.in b/docs/docs.html.in index 40e0e3b82e..d0ff844d0c 100644 --- a/docs/docs.html.in +++ b/docs/docs.html.in @@ -77,6 +77,7 @@ <a href="formatstorageencryption.html">storage encryption</a>, <a href="formatcaps.html">capabilities</a>, <a href="formatdomaincaps.html">domain capabilities</a>, + <a href="formatstoragecaps.html">storage pool capabilities</a>, <a href="formatnode.html">node devices</a>, <a href="formatsecret.html">secrets</a>, <a href="formatsnapshot.html">snapshots</a></dd> diff --git a/docs/format.html.in b/docs/format.html.in index 22b23e3fc7..640a9957ee 100644 --- a/docs/format.html.in +++ b/docs/format.html.in @@ -21,6 +21,7 @@ <li><a href="formatstorageencryption.html">Storage encryption</a></li> <li><a href="formatcaps.html">Capabilities</a></li> <li><a href="formatdomaincaps.html">Domain capabilities</a></li> + <li><a href="formatstoragecaps.html">Storage Pool capabilities</a></li> <li><a href="formatnode.html">Node devices</a></li> <li><a href="formatsecret.html">Secrets</a></li> <li><a href="formatsnapshot.html">Snapshots</a></li> diff --git a/docs/formatstoragecaps.html.in b/docs/formatstoragecaps.html.in new file mode 100644 index 0000000000..7f0641a3a8 --- /dev/null +++ b/docs/formatstoragecaps.html.in @@ -0,0 +1,108 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html> +<html xmlns="http://www.w3.org/1999/xhtml"> + <body> + <h1>Storage Pool Capabilities XML format</h1> + + <ul id="toc"></ul> + + <h2><a id="Overview">Overview</a></h2> + + <p>The Storage Pool Capabilities XML will provide the information + to determine what types of Storage Pools exist, whether the pool is + supported, and if relevant the source format types, the required + source elements, and the target volume format types. </p> + + <p>The Storage Pool Capabilities XML provides more information than the + <a href="/html/libvirt-libvirt-host.html#virConnectGetCapabilities"> + <code>virConnectGetCapabilities</code> + </a> + which only provides an enumerated list of supported pool types.</p> + + <h2><a id="elements">Element and attribute overview</a></h2> + + <p>A query interface was added to the virConnect API's to retrieve the + XML listing of the set of Storage Pool Capabilities + (<span class="since">Since 5.1.0</span>):</p> + +<pre> +<a href="/html/libvirt-libvirt-domain.html#virConnectGetStoragePoolCapabilities">virConnectGetStoragePoolCapabilities</a> +</pre> + + <p>The root element that emulator capability XML document starts with is + named <code>storagepoolCapabilities</code>. There will be any number of + <code>pool</code> child elements with two attributes <code>type</code> + and <code>supported</code>. Each <code>pool</code> element may have + a <code>poolOptions</code> or <code>volOptions</code> subelements to + describe the available features. Sample XML output is:</p> + +<pre> +<storagepoolCapabilities> + <pool type='dir' supported='yes'> + <volOptions> + <defaultFormat type='raw'</> + <enum name='targetFormatType'> + <value>none</value> + <value>raw</value> + ... + </enum> + </volOptions> + </pool> + <pool type='fs' supported='yes'> + <poolOptions> + <defaultFormat type='auto'</> + <enum name='sourceFormatType'> + <value>auto</value> + <value>ext2</value> + ... + </enum> + <enum name='requiredSourceElements'> + <value>device</value> + </enum> + </poolOptions> + <volOptions> + <defaultFormat type='raw'</> + <enum name='targetFormatType'> + <value>none</value> + <value>raw</value> + ... + </enum> + </volOptions> + </pool> + ... +</storagepoolCapabilities> +</pre> + + <p>The following section decribes subelements of the + <code>poolOptions</code> and <code>volOptions</code> subelements </p>: + + <dl> + <dt><code>defaultFormat</code></dt> + <dd>For the <code>poolOptions</code>, the <code>type</code> attribute + describes the default format name used for the pool source. For the + <code>volOptions</code>, the <code>type</code> attribute describes + the default volume name used for each volume. + </dd> + <dl> + <dt><code>enum</code></dt> + <dd>Each enum uses a name from the list below with any number of + <code>value</code> value subelements describing the valid values. + <dl> + <dt><code>sourceFormatType</code></dt> + <dd>Lists all the possible <code>poolOptions</code> source + pool format types. + </dd> + <dt><code>requiredSourceElements</code></dt> + <dd>Lists all the required <code>poolOptions</code> source + subelements required for a valid source pool element. + </dd>
I know that this is now pushed and I just noticed that in the relevant BZ where you posted the output of storage capabilities. Why do we export <requiredSourceElements> in storage capabilities? It doesn't make any sense to have it there. Management applications using libvirt have to have some knowledge of libvirt and they have to know what elements are required for each storage pool type in order to create some sensible UI. In addition this is something that will most likely never change and will not depend on what packages are installed or how libvirt/qemu were compiled. IMHO we should drop this element from storage capabilities unless there was some motivation to include this information. Pavel
+ <dt><code>targetFormatType</code></dt> + <dd>Lists all the possible <code>volOptions</code> target volume + format types. + </dd> + </dl> + </dd> + </dl> + </dl> + </body> +</html> diff --git a/docs/index.html.in b/docs/index.html.in index 1f9f448399..f593445d06 100644 --- a/docs/index.html.in +++ b/docs/index.html.in @@ -66,6 +66,7 @@ <a href="formatstorageencryption.html">storage encryption</a>, <a href="formatcaps.html">capabilities</a>, <a href="formatdomaincaps.html">domain capabilities</a>, + <a href="formatstoragecaps.html">storage pool capabilities</a>, <a href="formatnode.html">node devices</a>, <a href="formatsecret.html">secrets</a>, <a href="formatsnapshot.html">snapshots</a></dd> -- 2.20.1
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list

[...]
+ + <p>The following section decribes subelements of the + <code>poolOptions</code> and <code>volOptions</code> subelements </p>: + + <dl> + <dt><code>defaultFormat</code></dt> + <dd>For the <code>poolOptions</code>, the <code>type</code> attribute + describes the default format name used for the pool source. For the + <code>volOptions</code>, the <code>type</code> attribute describes + the default volume name used for each volume. + </dd> + <dl> + <dt><code>enum</code></dt> + <dd>Each enum uses a name from the list below with any number of + <code>value</code> value subelements describing the valid values. + <dl> + <dt><code>sourceFormatType</code></dt> + <dd>Lists all the possible <code>poolOptions</code> source + pool format types. + </dd> + <dt><code>requiredSourceElements</code></dt> + <dd>Lists all the required <code>poolOptions</code> source + subelements required for a valid source pool element. + </dd>
I know that this is now pushed and I just noticed that in the relevant BZ where you posted the output of storage capabilities.
Why do we export <requiredSourceElements> in storage capabilities? It doesn't make any sense to have it there. Management applications using libvirt have to have some knowledge of libvirt and they have to know what elements are required for each storage pool type in order to create some sensible UI. In addition this is something that will most likely never change and will not depend on what packages are installed or how libvirt/qemu were compiled.
Because it was data that perhaps someone would find useful when formulating XML for a storage pool. Each pool has different "required" elements that are hidden in the bowels of storage_conf and I figured it could be useful to have. Creating/defining a pool of a type that doesn't have a required element would cause a failure.
IMHO we should drop this element from storage capabilities unless there was some motivation to include this information.
IDC either way and am fine with dropping that element. The patches themselves were posted since 2/12, pinged on twice, sorry if you missed the details before I ended up pushing them. We have plenty of time before the 5.2.0 release to make a decision at least! John
Pavel
+ <dt><code>targetFormatType</code></dt> + <dd>Lists all the possible <code>volOptions</code> target volume + format types. + </dd> + </dl> + </dd> + </dl> + </dl> + </body> +</html>
[..]

On Wed, Mar 06, 2019 at 12:21:02PM -0500, John Ferlan wrote:
[...]
+ + <p>The following section decribes subelements of the + <code>poolOptions</code> and <code>volOptions</code> subelements </p>: + + <dl> + <dt><code>defaultFormat</code></dt> + <dd>For the <code>poolOptions</code>, the <code>type</code> attribute + describes the default format name used for the pool source. For the + <code>volOptions</code>, the <code>type</code> attribute describes + the default volume name used for each volume. + </dd> + <dl> + <dt><code>enum</code></dt> + <dd>Each enum uses a name from the list below with any number of + <code>value</code> value subelements describing the valid values. + <dl> + <dt><code>sourceFormatType</code></dt> + <dd>Lists all the possible <code>poolOptions</code> source + pool format types. + </dd> + <dt><code>requiredSourceElements</code></dt> + <dd>Lists all the required <code>poolOptions</code> source + subelements required for a valid source pool element. + </dd>
I know that this is now pushed and I just noticed that in the relevant BZ where you posted the output of storage capabilities.
Why do we export <requiredSourceElements> in storage capabilities? It doesn't make any sense to have it there. Management applications using libvirt have to have some knowledge of libvirt and they have to know what elements are required for each storage pool type in order to create some sensible UI. In addition this is something that will most likely never change and will not depend on what packages are installed or how libvirt/qemu were compiled.
Because it was data that perhaps someone would find useful when formulating XML for a storage pool. Each pool has different "required" elements that are hidden in the bowels of storage_conf and I figured it could be useful to have. Creating/defining a pool of a type that doesn't have a required element would cause a failure.
IMHO we should drop this element from storage capabilities unless there was some motivation to include this information.
IDC either way and am fine with dropping that element. The patches themselves were posted since 2/12, pinged on twice, sorry if you missed the details before I ended up pushing them. We have plenty of time before the 5.2.0 release to make a decision at least!
NP, my fault that I didn't notice that sooner, I just skimmed the patches telling myself that I'll review it later since I was working on virt-manager patches. Anyway, I'll send a patch to remove it from capabilities where we can decide what whether to keep it there or not. Pavel

Introduce the API to expose the storage pool capabilities along with all the remote munglement required to hook up the client. Signed-off-by: John Ferlan <jferlan@redhat.com> --- include/libvirt/libvirt-storage.h | 4 ++++ src/driver-storage.h | 5 ++++ src/libvirt-storage.c | 40 +++++++++++++++++++++++++++++++ src/libvirt_public.syms | 5 ++++ src/remote/remote_driver.c | 1 + src/remote/remote_protocol.x | 15 +++++++++++- src/remote_protocol-structs | 7 ++++++ 7 files changed, 76 insertions(+), 1 deletion(-) diff --git a/include/libvirt/libvirt-storage.h b/include/libvirt/libvirt-storage.h index 4bf2b5f1dd..5a95b2b139 100644 --- a/include/libvirt/libvirt-storage.h +++ b/include/libvirt/libvirt-storage.h @@ -193,6 +193,10 @@ typedef enum { */ virConnectPtr virStoragePoolGetConnect (virStoragePoolPtr pool); +/* Storage Pool capabilities */ +char *virConnectGetStoragePoolCapabilities(virConnectPtr conn, + unsigned int flags); + /* * List active storage pools */ diff --git a/src/driver-storage.h b/src/driver-storage.h index 35bd99a20c..2a855c34d8 100644 --- a/src/driver-storage.h +++ b/src/driver-storage.h @@ -52,6 +52,10 @@ typedef char * const char *srcSpec, unsigned int flags); +typedef char * +(*virDrvConnectGetStoragePoolCapabilities)(virConnectPtr conn, + unsigned int flags); + typedef virStoragePoolPtr (*virDrvStoragePoolLookupByName)(virConnectPtr conn, const char *name); @@ -237,6 +241,7 @@ struct _virStorageDriver { virDrvConnectFindStoragePoolSources connectFindStoragePoolSources; virDrvConnectStoragePoolEventRegisterAny connectStoragePoolEventRegisterAny; virDrvConnectStoragePoolEventDeregisterAny connectStoragePoolEventDeregisterAny; + virDrvConnectGetStoragePoolCapabilities connectGetStoragePoolCapabilities; virDrvStoragePoolLookupByName storagePoolLookupByName; virDrvStoragePoolLookupByUUID storagePoolLookupByUUID; virDrvStoragePoolLookupByVolume storagePoolLookupByVolume; diff --git a/src/libvirt-storage.c b/src/libvirt-storage.c index 2ea3e94e45..3bd61dc986 100644 --- a/src/libvirt-storage.c +++ b/src/libvirt-storage.c @@ -2351,3 +2351,43 @@ virConnectStoragePoolEventDeregisterAny(virConnectPtr conn, virDispatchError(conn); return -1; } + + +/** + * virConnectGetStoragePoolCapabilities: + * @conn: pointer to the hypervisor connection + * @flags: extra flags; not used yet, so callers should always pass 0 + * + * Prior creating a storage pool (for instance via virStoragePoolCreateXML + * or virStoragePoolDefineXML) it may be suitable to know what pool types + * are supported along with the file/disk formats for each pool. + * + * Returns NULL in case of error or an XML string defining the capabilities. + */ +char * +virConnectGetStoragePoolCapabilities(virConnectPtr conn, + unsigned int flags) +{ + VIR_DEBUG("conn=%p, flags=0x%x", conn, flags); + + virResetLastError(); + + virCheckConnectReturn(conn, NULL); + + if (conn->storageDriver && + conn->storageDriver->connectGetStoragePoolCapabilities) { + char *ret; + ret = conn->storageDriver->connectGetStoragePoolCapabilities(conn, + flags); + if (!ret) + goto error; + VIR_DEBUG("conn=%p, ret=%s", conn, ret); + return ret; + } + + virReportUnsupportedError(); + + error: + virDispatchError(conn); + return NULL; +} diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index 042b4df043..9d3a53b638 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -814,4 +814,9 @@ LIBVIRT_4.10.0 { virDomainSetIOThreadParams; } LIBVIRT_4.5.0; +LIBVIRT_5.1.0 { + global: + virConnectGetStoragePoolCapabilities; +} LIBVIRT_4.10.0; + # .... define new API here using predicted next version number .... diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 2861ee68e2..83966f73c0 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -8572,6 +8572,7 @@ static virStorageDriver storage_driver = { .connectFindStoragePoolSources = remoteConnectFindStoragePoolSources, /* 0.4.5 */ .connectStoragePoolEventDeregisterAny = remoteConnectStoragePoolEventDeregisterAny, /* 2.0.0 */ .connectStoragePoolEventRegisterAny = remoteConnectStoragePoolEventRegisterAny, /* 2.0.0 */ + .connectGetStoragePoolCapabilities = remoteConnectGetStoragePoolCapabilities, /* 5.1.0 */ .storagePoolLookupByName = remoteStoragePoolLookupByName, /* 0.4.1 */ .storagePoolLookupByUUID = remoteStoragePoolLookupByUUID, /* 0.4.1 */ .storagePoolLookupByVolume = remoteStoragePoolLookupByVolume, /* 0.4.1 */ diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index b9d26b1849..500c173d34 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -3565,6 +3565,14 @@ struct remote_connect_list_all_nwfilter_bindings_ret { /* insert@1 */ unsigned int ret; }; +struct remote_connect_get_storage_pool_capabilities_args { + unsigned int flags; +}; + +struct remote_connect_get_storage_pool_capabilities_ret { + remote_nonnull_string capabilities; +}; + /*----- Protocol. -----*/ /* Define the program number, protocol version and procedure numbers here. */ @@ -6328,6 +6336,11 @@ enum remote_procedure { * @acl: domain:save:!VIR_DOMAIN_AFFECT_CONFIG|VIR_DOMAIN_AFFECT_LIVE * @acl: domain:save:VIR_DOMAIN_AFFECT_CONFIG */ - REMOTE_PROC_DOMAIN_SET_IOTHREAD_PARAMS = 402 + REMOTE_PROC_DOMAIN_SET_IOTHREAD_PARAMS = 402, + /** + * @generate: both + * @acl: connect:read + */ + REMOTE_PROC_CONNECT_GET_STORAGE_POOL_CAPABILITIES = 403 }; diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index 7c27c63542..768189c573 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -2975,6 +2975,12 @@ struct remote_connect_list_all_nwfilter_bindings_ret { } bindings; u_int ret; }; +struct remote_connect_get_storage_pool_capabilities_args { + u_int flags; +}; +struct remote_connect_get_storage_pool_capabilities_ret { + remote_nonnull_string capabilities; +}; enum remote_procedure { REMOTE_PROC_CONNECT_OPEN = 1, REMOTE_PROC_CONNECT_CLOSE = 2, @@ -3378,4 +3384,5 @@ enum remote_procedure { REMOTE_PROC_NWFILTER_BINDING_DELETE = 400, REMOTE_PROC_CONNECT_LIST_ALL_NWFILTER_BINDINGS = 401, REMOTE_PROC_DOMAIN_SET_IOTHREAD_PARAMS = 402, + REMOTE_PROC_CONNECT_GET_STORAGE_POOL_CAPABILITIES = 403, }; -- 2.20.1

https://bugzilla.redhat.com/show_bug.cgi?id=1581670 Create the storage driver code to generate the output for the storage pool capabilities XML. Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/storage/storage_driver.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c index f2bc24370d..acdc31f76c 100644 --- a/src/storage/storage_driver.c +++ b/src/storage/storage_driver.c @@ -35,6 +35,7 @@ #include "datatypes.h" #include "driver.h" #include "storage_driver.h" +#include "storage_capabilities.h" #include "storage_conf.h" #include "storage_event.h" #include "viralloc.h" @@ -652,6 +653,28 @@ storageConnectFindStoragePoolSources(virConnectPtr conn, } +static char * +storageConnectGetStoragePoolCapabilities(virConnectPtr conn, + unsigned int flags) +{ + virStoragePoolCapsPtr caps = NULL; + char *ret; + + virCheckFlags(0, NULL); + + if (virConnectGetStoragePoolCapabilitiesEnsureACL(conn) < 0) + return NULL; + + if (!(caps = virStoragePoolCapsNew(driver->caps))) + return NULL; + + ret = virStoragePoolCapsFormat(caps); + + virObjectUnref(caps); + return ret; +} + + static int storagePoolIsActive(virStoragePoolPtr pool) { @@ -2790,6 +2813,7 @@ static virStorageDriver storageDriver = { .connectStoragePoolEventRegisterAny = storageConnectStoragePoolEventRegisterAny, /* 2.0.0 */ .connectStoragePoolEventDeregisterAny = storageConnectStoragePoolEventDeregisterAny, /* 2.0.0 */ .connectFindStoragePoolSources = storageConnectFindStoragePoolSources, /* 0.4.0 */ + .connectGetStoragePoolCapabilities = storageConnectGetStoragePoolCapabilities, /* 5.1.0 */ .storagePoolLookupByName = storagePoolLookupByName, /* 0.4.0 */ .storagePoolLookupByUUID = storagePoolLookupByUUID, /* 0.4.0 */ .storagePoolLookupByVolume = storagePoolLookupByVolume, /* 0.4.0 */ -- 2.20.1

https://bugzilla.redhat.com/show_bug.cgi?id=1581670 Add a new storage pool command "poolcapabilities" to output the storage pool capabilities. This mimics the "domcapabilities" command with respect to naming. Signed-off-by: John Ferlan <jferlan@redhat.com> --- tools/virsh-pool.c | 42 ++++++++++++++++++++++++++++++++++++++++++ tools/virsh.pod | 7 +++++++ 2 files changed, 49 insertions(+) diff --git a/tools/virsh-pool.c b/tools/virsh-pool.c index d98fd80330..378bf0de21 100644 --- a/tools/virsh-pool.c +++ b/tools/virsh-pool.c @@ -2105,6 +2105,42 @@ cmdPoolEvent(vshControl *ctl, const vshCmd *cmd) } +/* + * "poolcapabilities" command + */ +static const vshCmdInfo info_poolcapabilities[] = { + {.name = "help", + .data = N_("storage pool capabilities") + }, + {.name = "desc", + .data = N_("Returns capabilities of storage pool support.") + }, + {.name = NULL} +}; + +static const vshCmdOptDef opts_poolcapabilities[] = { + {.name = NULL} +}; + +static bool +cmdPoolCapabilities(vshControl *ctl, + const vshCmd *cmd ATTRIBUTE_UNUSED) +{ + const unsigned int flags = 0; /* No flags so far */ + virshControlPtr priv = ctl->privData; + VIR_AUTOFREE(char *) caps = NULL; + + caps = virConnectGetStoragePoolCapabilities(priv->conn, flags); + if (!caps) { + vshError(ctl, "%s", _("failed to get storage pool capabilities")); + return false; + } + + vshPrint(ctl, "%s\n", caps); + return true; +} + + const vshCmdDef storagePoolCmds[] = { {.name = "find-storage-pool-sources-as", .handler = cmdPoolDiscoverSourcesAs, @@ -2226,5 +2262,11 @@ const vshCmdDef storagePoolCmds[] = { .info = info_pool_event, .flags = 0 }, + {.name = "poolcapabilities", + .handler = cmdPoolCapabilities, + .opts = opts_poolcapabilities, + .info = info_poolcapabilities, + .flags = 0 + }, {.name = NULL} }; diff --git a/tools/virsh.pod b/tools/virsh.pod index 67edb57b14..f517d4aa24 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -388,6 +388,13 @@ supplied along with either the I<emulatorbin> or I<arch> in order to generate output for the default I<machine>. Supplying a I<machine> value will generate output for the specific machine. +=item B<poolcapabilities> +Print an XML document describing the storage pool capabilities for the +connected storage driver. This may be useful if you intend to create a +new storage pool and need to know the available pool types and supported +storage pool source and target volume formats as well as the required +source elements to create the pool. + =item B<inject-nmi> I<domain> Inject NMI to the guest. -- 2.20.1

On 2/12/19 4:28 PM, John Ferlan wrote:
https://bugzilla.redhat.com/show_bug.cgi?id=1581670
Add a new storage pool command "poolcapabilities" to output the storage pool capabilities. This mimics the "domcapabilities" command with respect to naming.
I think this should be named pool-capabilities to repect that all pool commands have hypen in their name. There is no dom-* command, that's why I named it domcapabilites.
Signed-off-by: John Ferlan <jferlan@redhat.com> --- tools/virsh-pool.c | 42 ++++++++++++++++++++++++++++++++++++++++++ tools/virsh.pod | 7 +++++++ 2 files changed, 49 insertions(+)
Michal

Signed-off-by: John Ferlan <jferlan@redhat.com> --- docs/news.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/news.xml b/docs/news.xml index 8d6d58ae6a..074b0f2b02 100644 --- a/docs/news.xml +++ b/docs/news.xml @@ -59,6 +59,18 @@ of the network's <code>bridge</code> element. </description> </change> + <change> + <summary> + Add Storage Pool Capabilities output + </summary> + <description> + Add support to list an enumerated list of supported Storage + Pools via the virConnectGetCapabilities API when connected + via a Storage Driver. Add support to get a more detailed + list XML output Storage Pool Capabilities vis the + virConnectGetStoragePoolCapabilites API. + </description> + </change> </section> <section title="Improvements"> </section> -- 2.20.1

ping - Tks, John On 2/12/19 10:27 AM, John Ferlan wrote:
v1: https://www.redhat.com/archives/libvir-list/2019-January/msg00479.html
Changes since v1:
* The first 4 patches were already R-by'd and pushed.
* From v1, rework patch 5 & 6 into what now is patches 8 & 9. The format of the output for what results in the output for the connectGetCapabilities (virConnectGetCapabilities).
* From v1, drop patch 7
* In v2, patches 1-7 are new as a result of work done for patches 10-17. patches 1-5 were posted upstream, but left unreviewed:
https://www.redhat.com/archives/libvir-list/2019-February/msg00333.html
These essentially ensure the volOptions and poolOptions don't list or use something unexpected per documentation. The doc patch is a simple update to add some missing text and fix an entry
* Patches 10-17 are new to implement the ability to get/format the Storage Driver backend capabilities via:
storageConnectGetStoragePoolCapabilities virConnectGetStoragePoolCapabilities
similar to how virConnectGetDomainCapabilities returns domain specific output. The output is essentially what is provided in the poolOptions and volOptions from storage_conf as valid values for format type fields for pool and/or volume as well as an enumerated list for the required source elements for creation. Whether the latter is useful or not was not clear, but since it is something that can cause a creation error when missing, I figured it'd be useful. The new virsh command follows then domcapabilities nomenclature.
John Ferlan (17): conf: Remove volOptions for VIR_STORAGE_POOL_SHEEPDOG conf: Remove volOptions for VIR_STORAGE_POOL_RBD conf: Remove volOptions for VIR_STORAGE_POOL_SCSI conf: Remove volOptions for VIR_STORAGE_POOL_ISCSI[_DIRECT] conf: Remove volOptions for VIR_STORAGE_POOL_MPATH conf: Remove defaultFormat from VIR_STORAGE_POOL_ZFS docs: Fix a few storage.html.in typos conf: Introduce storage pool functions into capabilities storage: Process storage pool capabilities docs: Add schema for storage pool capabilities conf: Add storage pool capability formatting tests: Introduce storage pool capabilites test docs: Add description for Storage Pool Capabilities libvirt: Introduce virConnectGetStoragePoolCapabilities storage: Introduce storageConnectGetStoragePoolCapabilities virsh: Expose virConnectGetStoragePoolCapabilities docs: Add news article
docs/docs.html.in | 1 + docs/format.html.in | 1 + docs/formatstoragecaps.html.in | 108 +++++++ docs/index.html.in | 1 + docs/news.xml | 12 + docs/schemas/storagepoolcaps.rng | 88 ++++++ docs/storage.html.in | 8 +- include/libvirt/libvirt-storage.h | 4 + libvirt.spec.in | 1 + mingw-libvirt.spec.in | 2 + src/conf/Makefile.inc.am | 2 + src/conf/capabilities.c | 74 +++++ src/conf/capabilities.h | 15 + src/conf/storage_capabilities.c | 135 +++++++++ src/conf/storage_capabilities.h | 41 +++ src/conf/storage_conf.c | 131 +++++++-- src/conf/storage_conf.h | 7 + src/conf/virstorageobj.h | 5 + src/driver-storage.h | 5 + src/libvirt-storage.c | 40 +++ src/libvirt_private.syms | 8 + src/libvirt_public.syms | 5 + src/remote/remote_driver.c | 1 + src/remote/remote_protocol.x | 15 +- src/remote_protocol-structs | 7 + src/storage/storage_backend.c | 16 ++ src/storage/storage_backend.h | 3 + src/storage/storage_driver.c | 44 +++ tests/Makefile.am | 7 + .../storagepoolcapsschemadata/poolcaps-fs.xml | 268 ++++++++++++++++++ .../poolcaps-full.xml | 268 ++++++++++++++++++ tests/storagepoolcapstest.c | 124 ++++++++ tests/storagevolxml2xmlout/vol-sheepdog.xml | 1 - tests/virschematest.c | 1 + tools/virsh-pool.c | 42 +++ tools/virsh.pod | 7 + 36 files changed, 1473 insertions(+), 25 deletions(-) create mode 100644 docs/formatstoragecaps.html.in create mode 100644 docs/schemas/storagepoolcaps.rng create mode 100644 src/conf/storage_capabilities.c create mode 100644 src/conf/storage_capabilities.h create mode 100644 tests/storagepoolcapsschemadata/poolcaps-fs.xml create mode 100644 tests/storagepoolcapsschemadata/poolcaps-full.xml create mode 100644 tests/storagepoolcapstest.c

ping^2? Yes, there are patches that indicate 5.1.0 that would need to be changed to 5.2.0 that I've already changed in my local branch. Tks, John On 2/12/19 10:27 AM, John Ferlan wrote:
v1: https://www.redhat.com/archives/libvir-list/2019-January/msg00479.html
Changes since v1:
* The first 4 patches were already R-by'd and pushed.
* From v1, rework patch 5 & 6 into what now is patches 8 & 9. The format of the output for what results in the output for the connectGetCapabilities (virConnectGetCapabilities).
* From v1, drop patch 7
* In v2, patches 1-7 are new as a result of work done for patches 10-17. patches 1-5 were posted upstream, but left unreviewed:
https://www.redhat.com/archives/libvir-list/2019-February/msg00333.html
These essentially ensure the volOptions and poolOptions don't list or use something unexpected per documentation. The doc patch is a simple update to add some missing text and fix an entry
* Patches 10-17 are new to implement the ability to get/format the Storage Driver backend capabilities via:
storageConnectGetStoragePoolCapabilities virConnectGetStoragePoolCapabilities
similar to how virConnectGetDomainCapabilities returns domain specific output. The output is essentially what is provided in the poolOptions and volOptions from storage_conf as valid values for format type fields for pool and/or volume as well as an enumerated list for the required source elements for creation. Whether the latter is useful or not was not clear, but since it is something that can cause a creation error when missing, I figured it'd be useful. The new virsh command follows then domcapabilities nomenclature.
John Ferlan (17): conf: Remove volOptions for VIR_STORAGE_POOL_SHEEPDOG conf: Remove volOptions for VIR_STORAGE_POOL_RBD conf: Remove volOptions for VIR_STORAGE_POOL_SCSI conf: Remove volOptions for VIR_STORAGE_POOL_ISCSI[_DIRECT] conf: Remove volOptions for VIR_STORAGE_POOL_MPATH conf: Remove defaultFormat from VIR_STORAGE_POOL_ZFS docs: Fix a few storage.html.in typos conf: Introduce storage pool functions into capabilities storage: Process storage pool capabilities docs: Add schema for storage pool capabilities conf: Add storage pool capability formatting tests: Introduce storage pool capabilites test docs: Add description for Storage Pool Capabilities libvirt: Introduce virConnectGetStoragePoolCapabilities storage: Introduce storageConnectGetStoragePoolCapabilities virsh: Expose virConnectGetStoragePoolCapabilities docs: Add news article
docs/docs.html.in | 1 + docs/format.html.in | 1 + docs/formatstoragecaps.html.in | 108 +++++++ docs/index.html.in | 1 + docs/news.xml | 12 + docs/schemas/storagepoolcaps.rng | 88 ++++++ docs/storage.html.in | 8 +- include/libvirt/libvirt-storage.h | 4 + libvirt.spec.in | 1 + mingw-libvirt.spec.in | 2 + src/conf/Makefile.inc.am | 2 + src/conf/capabilities.c | 74 +++++ src/conf/capabilities.h | 15 + src/conf/storage_capabilities.c | 135 +++++++++ src/conf/storage_capabilities.h | 41 +++ src/conf/storage_conf.c | 131 +++++++-- src/conf/storage_conf.h | 7 + src/conf/virstorageobj.h | 5 + src/driver-storage.h | 5 + src/libvirt-storage.c | 40 +++ src/libvirt_private.syms | 8 + src/libvirt_public.syms | 5 + src/remote/remote_driver.c | 1 + src/remote/remote_protocol.x | 15 +- src/remote_protocol-structs | 7 + src/storage/storage_backend.c | 16 ++ src/storage/storage_backend.h | 3 + src/storage/storage_driver.c | 44 +++ tests/Makefile.am | 7 + .../storagepoolcapsschemadata/poolcaps-fs.xml | 268 ++++++++++++++++++ .../poolcaps-full.xml | 268 ++++++++++++++++++ tests/storagepoolcapstest.c | 124 ++++++++ tests/storagevolxml2xmlout/vol-sheepdog.xml | 1 - tests/virschematest.c | 1 + tools/virsh-pool.c | 42 +++ tools/virsh.pod | 7 + 36 files changed, 1473 insertions(+), 25 deletions(-) create mode 100644 docs/formatstoragecaps.html.in create mode 100644 docs/schemas/storagepoolcaps.rng create mode 100644 src/conf/storage_capabilities.c create mode 100644 src/conf/storage_capabilities.h create mode 100644 tests/storagepoolcapsschemadata/poolcaps-fs.xml create mode 100644 tests/storagepoolcapsschemadata/poolcaps-full.xml create mode 100644 tests/storagepoolcapstest.c

On 2/12/19 4:27 PM, John Ferlan wrote:
v1: https://www.redhat.com/archives/libvir-list/2019-January/msg00479.html
Changes since v1:
* The first 4 patches were already R-by'd and pushed.
* From v1, rework patch 5 & 6 into what now is patches 8 & 9. The format of the output for what results in the output for the connectGetCapabilities (virConnectGetCapabilities).
* From v1, drop patch 7
* In v2, patches 1-7 are new as a result of work done for patches 10-17. patches 1-5 were posted upstream, but left unreviewed:
https://www.redhat.com/archives/libvir-list/2019-February/msg00333.html
These essentially ensure the volOptions and poolOptions don't list or use something unexpected per documentation. The doc patch is a simple update to add some missing text and fix an entry
* Patches 10-17 are new to implement the ability to get/format the Storage Driver backend capabilities via:
storageConnectGetStoragePoolCapabilities virConnectGetStoragePoolCapabilities
similar to how virConnectGetDomainCapabilities returns domain specific output. The output is essentially what is provided in the poolOptions and volOptions from storage_conf as valid values for format type fields for pool and/or volume as well as an enumerated list for the required source elements for creation. Whether the latter is useful or not was not clear, but since it is something that can cause a creation error when missing, I figured it'd be useful. The new virsh command follows then domcapabilities nomenclature.
John Ferlan (17): conf: Remove volOptions for VIR_STORAGE_POOL_SHEEPDOG conf: Remove volOptions for VIR_STORAGE_POOL_RBD conf: Remove volOptions for VIR_STORAGE_POOL_SCSI conf: Remove volOptions for VIR_STORAGE_POOL_ISCSI[_DIRECT] conf: Remove volOptions for VIR_STORAGE_POOL_MPATH conf: Remove defaultFormat from VIR_STORAGE_POOL_ZFS docs: Fix a few storage.html.in typos conf: Introduce storage pool functions into capabilities storage: Process storage pool capabilities docs: Add schema for storage pool capabilities conf: Add storage pool capability formatting tests: Introduce storage pool capabilites test docs: Add description for Storage Pool Capabilities libvirt: Introduce virConnectGetStoragePoolCapabilities storage: Introduce storageConnectGetStoragePoolCapabilities virsh: Expose virConnectGetStoragePoolCapabilities docs: Add news article
docs/docs.html.in | 1 + docs/format.html.in | 1 + docs/formatstoragecaps.html.in | 108 +++++++ docs/index.html.in | 1 + docs/news.xml | 12 + docs/schemas/storagepoolcaps.rng | 88 ++++++ docs/storage.html.in | 8 +- include/libvirt/libvirt-storage.h | 4 + libvirt.spec.in | 1 + mingw-libvirt.spec.in | 2 + src/conf/Makefile.inc.am | 2 + src/conf/capabilities.c | 74 +++++ src/conf/capabilities.h | 15 + src/conf/storage_capabilities.c | 135 +++++++++ src/conf/storage_capabilities.h | 41 +++ src/conf/storage_conf.c | 131 +++++++-- src/conf/storage_conf.h | 7 + src/conf/virstorageobj.h | 5 + src/driver-storage.h | 5 + src/libvirt-storage.c | 40 +++ src/libvirt_private.syms | 8 + src/libvirt_public.syms | 5 + src/remote/remote_driver.c | 1 + src/remote/remote_protocol.x | 15 +- src/remote_protocol-structs | 7 + src/storage/storage_backend.c | 16 ++ src/storage/storage_backend.h | 3 + src/storage/storage_driver.c | 44 +++ tests/Makefile.am | 7 + .../storagepoolcapsschemadata/poolcaps-fs.xml | 268 ++++++++++++++++++ .../poolcaps-full.xml | 268 ++++++++++++++++++ tests/storagepoolcapstest.c | 124 ++++++++ tests/storagevolxml2xmlout/vol-sheepdog.xml | 1 - tests/virschematest.c | 1 + tools/virsh-pool.c | 42 +++ tools/virsh.pod | 7 + 36 files changed, 1473 insertions(+), 25 deletions(-) create mode 100644 docs/formatstoragecaps.html.in create mode 100644 docs/schemas/storagepoolcaps.rng create mode 100644 src/conf/storage_capabilities.c create mode 100644 src/conf/storage_capabilities.h create mode 100644 tests/storagepoolcapsschemadata/poolcaps-fs.xml create mode 100644 tests/storagepoolcapsschemadata/poolcaps-full.xml create mode 100644 tests/storagepoolcapstest.c
ACK after you fix virsh command name, and what you already pointed out s/5.1.0/5.2.0/g. Sorry for late review. Michal
participants (3)
-
John Ferlan
-
Michal Privoznik
-
Pavel Hrdina