https://bugzilla.redhat.com/show_bug.cgi?id=1581670 Add the Storage Pool and Volume API's defined for each generated capability output, such as: <pool> <type>dir</pool> <poolapis> <buildPool/> <refreshPool/> <deletePool/> </poolapis> <volapis> <buildVol/> <buildVolFrom/> <createVol/> <refreshVol/> <deleteVol/> <resizeVol/> <uploadVol/> <downloadVol/> <wipeVol/> </volapis> </pool> ... <pool> <type>iscsi</pool> <poolapis> <findPoolSources/> <startPool/> <refreshPool/> <stopPool/> </poolapis> <volapis> <uploadVol/> <downloadVol/> <wipeVol/> </volapis> </pool> Signed-off-by: John Ferlan <jferlan@xxxxxxxxxx> --- src/conf/capabilities.c | 49 ++++++++++++++++++++++++++++++-- src/conf/capabilities.h | 6 +++- src/storage/storage_backend.c | 53 +++++++++++++++++++++++++++++++++-- 3 files changed, 103 insertions(+), 5 deletions(-) diff --git a/src/conf/capabilities.c b/src/conf/capabilities.c index c60743a38d..f7e9873f64 100644 --- a/src/conf/capabilities.c +++ b/src/conf/capabilities.c @@ -188,6 +188,8 @@ virCapabilitiesFreeStoragePool(virCapsStoragePoolPtr pool) if (!pool) return; + VIR_FREE(pool->poolapis); + VIR_FREE(pool->volapis); VIR_FREE(pool); } @@ -811,7 +813,9 @@ virCapabilitiesDomainDataLookup(virCapsPtr caps, int virCapabilitiesAddStoragePool(virCapsPtr caps, - int poolType) + int poolType, + const char *poolstr, + const char *volstr) { virCapsStoragePoolPtr pool; @@ -823,7 +827,10 @@ virCapabilitiesAddStoragePool(virCapsPtr caps, if (VIR_RESIZE_N(caps->pools, caps->npools_max, caps->npools, 1) < 0) goto error; caps->pools[caps->npools++] = pool; - + if (VIR_STRDUP(pool->poolapis, poolstr) < 0) + goto error; + if (VIR_STRDUP(pool->volapis, volstr) < 0) + goto error; return 0; error: @@ -1322,15 +1329,53 @@ virCapabilitiesFormatStoragePoolXML(virCapsStoragePoolPtr *pools, virBufferPtr buf) { size_t i; + char **poolapis = NULL; + size_t npoolapis = 0; + char **volapis = NULL; + size_t nvolapis = 0; for (i = 0; i < npools; i++) { + size_t j; + + if (!(poolapis = virStringSplitCount(pools[i]->poolapis, ",", + 0, &npoolapis)) || + !(volapis = virStringSplitCount(pools[i]->volapis, ",", + 0, &nvolapis))) + goto cleanup; + virBufferAddLit(buf, "<pool>\n"); virBufferAdjustIndent(buf, 2); virBufferAsprintf(buf, "<type>%s</pool>\n", virStoragePoolTypeToString(pools[i]->type)); + + virBufferAddLit(buf, "<poolapis>\n"); + virBufferAdjustIndent(buf, 2); + for (j = 0; j < npoolapis; j++) + virBufferAsprintf(buf, "<%s/>\n", poolapis[j]); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</poolapis>\n"); + + virBufferAddLit(buf, "<volapis>\n"); + virBufferAdjustIndent(buf, 2); + for (j = 0; j < nvolapis; j++) + virBufferAsprintf(buf, "<%s/>\n", volapis[j]); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</volapis>\n"); + virBufferAdjustIndent(buf, -2); virBufferAddLit(buf, "</pool>\n\n"); + + virStringListFree(poolapis); + poolapis = NULL; + npoolapis = 0; + virStringListFree(volapis); + volapis = NULL; + nvolapis = 0; } + + cleanup: + virStringListFree(poolapis); + virStringListFree(volapis); } diff --git a/src/conf/capabilities.h b/src/conf/capabilities.h index cca1a20949..525f19f195 100644 --- a/src/conf/capabilities.h +++ b/src/conf/capabilities.h @@ -215,6 +215,8 @@ typedef struct _virCapsStoragePool virCapsStoragePool; typedef virCapsStoragePool *virCapsStoragePoolPtr; struct _virCapsStoragePool { int type; + char *poolapis; + char *volapis; }; @@ -331,7 +333,9 @@ virCapabilitiesAddGuestFeature(virCapsGuestPtr guest, int virCapabilitiesAddStoragePool(virCapsPtr caps, - int poolType); + int poolType, + const char *poolstr, + const char *volstr); int virCapabilitiesHostSecModelAddBaseLabel(virCapsHostSecModelPtr secmodel, diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c index 0ccc616db4..95873c151f 100644 --- a/src/storage/storage_backend.c +++ b/src/storage/storage_backend.c @@ -193,13 +193,62 @@ virCapsPtr virStorageBackendGetCapabilities(void) { virCapsPtr caps; + virBuffer poolbuf = VIR_BUFFER_INITIALIZER; + virBuffer volbuf = VIR_BUFFER_INITIALIZER; size_t i; if (!(caps = virCapabilitiesNew(virArchFromHost(), false, false))) return NULL; - for (i = 0; i < virStorageBackendsCount; i++) - virCapabilitiesAddStoragePool(caps, virStorageBackends[i]->type); +#define BUF_POOL_BACKEND(field) \ + if (backend->field) \ + virBufferAsprintf(&poolbuf, "%s,", #field); + +#define BUF_VOL_BACKEND(field) \ + if (backend->field) \ + virBufferAsprintf(&volbuf, "%s,", #field); + + for (i = 0; i < virStorageBackendsCount; i++) { + char *poolstr = NULL; + char *volstr = NULL; + virStorageBackendPtr backend = virStorageBackends[i]; + + /* NB: checkPool is an internal only mechanism each pool has */ + BUF_POOL_BACKEND(findPoolSources); + BUF_POOL_BACKEND(startPool); + BUF_POOL_BACKEND(buildPool); + BUF_POOL_BACKEND(refreshPool); + BUF_POOL_BACKEND(stopPool); + BUF_POOL_BACKEND(deletePool); + virBufferTrim(&poolbuf, ",", -1); + + BUF_VOL_BACKEND(buildVol); + BUF_VOL_BACKEND(buildVolFrom); + BUF_VOL_BACKEND(createVol); + BUF_VOL_BACKEND(refreshVol); + BUF_VOL_BACKEND(deleteVol); + BUF_VOL_BACKEND(resizeVol); + BUF_VOL_BACKEND(uploadVol); + BUF_VOL_BACKEND(downloadVol); + BUF_VOL_BACKEND(wipeVol); + virBufferTrim(&volbuf, ",", -1); + + if (virBufferCheckError(&poolbuf) < 0 || + virBufferCheckError(&volbuf) < 0) + goto error; + + poolstr = virBufferContentAndReset(&poolbuf); + volstr = virBufferContentAndReset(&volbuf); + virCapabilitiesAddStoragePool(caps, backend->type, poolstr, volstr); + VIR_FREE(poolstr); + VIR_FREE(volstr); + } return caps; + + error: + virBufferFreeAndReset(&poolbuf); + virBufferFreeAndReset(&volbuf); + virObjectUnref(caps); + return NULL; } -- 2.20.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list