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 <jfer...@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

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to