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(a)redhat.com>
---
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