render / rpms / libvirt

Forked from rpms/libvirt 9 months ago
Clone
6ae9ed
From e07158fef33e27a1e76cf9e4e04884462a876ea8 Mon Sep 17 00:00:00 2001
6ae9ed
Message-Id: <e07158fef33e27a1e76cf9e4e04884462a876ea8@dist-git>
6ae9ed
From: Peter Krempa <pkrempa@redhat.com>
6ae9ed
Date: Tue, 2 Aug 2016 13:41:45 +0200
6ae9ed
Subject: [PATCH] util: qemu: Allow for different approaches to format JSON
6ae9ed
 arrays
6ae9ed
6ae9ed
For use with memory hotplug virQEMUBuildCommandLineJSONRecurse attempted
6ae9ed
to format JSON arrays as bitmap on the command line. Make the formatter
6ae9ed
function configurable so that it can be reused with different syntaxes
6ae9ed
of arrays such as numbered arrays for use with disk sources.
6ae9ed
6ae9ed
This patch extracts the code and adds a parameter for the function that
6ae9ed
will allow to plug in different formatters.
6ae9ed
6ae9ed
(cherry picked from commit b7eef33df20dc19b3c70285ee29dabd2ee7391fa)
6ae9ed
https://bugzilla.redhat.com/show_bug.cgi?id=1134878 [JSON backing]
6ae9ed
https://bugzilla.redhat.com/show_bug.cgi?id=1247521 [gluster multi-host]
6ae9ed
---
6ae9ed
 src/libvirt_private.syms    |  1 +
6ae9ed
 src/util/virqemu.c          | 73 ++++++++++++++++++++++++++++++---------------
6ae9ed
 src/util/virqemu.h          | 10 ++++++-
6ae9ed
 tests/qemucommandutiltest.c |  3 +-
6ae9ed
 4 files changed, 61 insertions(+), 26 deletions(-)
6ae9ed
6ae9ed
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
6ae9ed
index 70e40be..27bf269 100644
6ae9ed
--- a/src/libvirt_private.syms
6ae9ed
+++ b/src/libvirt_private.syms
6ae9ed
@@ -2194,6 +2194,7 @@ virProcessWait;
6ae9ed
 # util/virqemu.h
6ae9ed
 virQEMUBuildBufferEscapeComma;
6ae9ed
 virQEMUBuildCommandLineJSON;
6ae9ed
+virQEMUBuildCommandLineJSONArrayBitmap;
6ae9ed
 virQEMUBuildLuksOpts;
6ae9ed
 virQEMUBuildObjectCommandlineFromJSON;
6ae9ed
 
6ae9ed
diff --git a/src/util/virqemu.c b/src/util/virqemu.c
6ae9ed
index df665ad..3cc59e7 100644
6ae9ed
--- a/src/util/virqemu.c
6ae9ed
+++ b/src/util/virqemu.c
6ae9ed
@@ -36,6 +36,7 @@ VIR_LOG_INIT("util.qemu");
6ae9ed
 struct virQEMUCommandLineJSONIteratorData {
6ae9ed
     const char *prefix;
6ae9ed
     virBufferPtr buf;
6ae9ed
+    virQEMUBuildCommandLineJSONArrayFormatFunc arrayFunc;
6ae9ed
 };
6ae9ed
 
6ae9ed
 
6ae9ed
@@ -43,8 +44,41 @@ static int
6ae9ed
 virQEMUBuildCommandLineJSONRecurse(const char *key,
6ae9ed
                                    const virJSONValue *value,
6ae9ed
                                    virBufferPtr buf,
6ae9ed
+                                   virQEMUBuildCommandLineJSONArrayFormatFunc arrayFunc,
6ae9ed
                                    bool nested);
6ae9ed
 
6ae9ed
+
6ae9ed
+
6ae9ed
+int
6ae9ed
+virQEMUBuildCommandLineJSONArrayBitmap(const char *key,
6ae9ed
+                                       const virJSONValue *array,
6ae9ed
+                                       virBufferPtr buf)
6ae9ed
+{
6ae9ed
+    ssize_t pos = -1;
6ae9ed
+    ssize_t end;
6ae9ed
+    virBitmapPtr bitmap = NULL;
6ae9ed
+
6ae9ed
+    if (virJSONValueGetArrayAsBitmap(array, &bitmap) < 0)
6ae9ed
+        return -1;
6ae9ed
+
6ae9ed
+    while ((pos = virBitmapNextSetBit(bitmap, pos)) > -1) {
6ae9ed
+        if ((end = virBitmapNextClearBit(bitmap, pos)) < 0)
6ae9ed
+            end = virBitmapLastSetBit(bitmap) + 1;
6ae9ed
+
6ae9ed
+        if (end - 1 > pos) {
6ae9ed
+            virBufferAsprintf(buf, ",%s=%zd-%zd", key, pos, end - 1);
6ae9ed
+            pos = end;
6ae9ed
+        } else {
6ae9ed
+            virBufferAsprintf(buf, ",%s=%zd", key, pos);
6ae9ed
+        }
6ae9ed
+    }
6ae9ed
+
6ae9ed
+    virBitmapFree(bitmap);
6ae9ed
+
6ae9ed
+    return 0;
6ae9ed
+}
6ae9ed
+
6ae9ed
+
6ae9ed
 /* internal iterator to handle nested object formatting */
6ae9ed
 static int
6ae9ed
 virQEMUBuildCommandLineJSONIterate(const char *key,
6ae9ed
@@ -59,11 +93,13 @@ virQEMUBuildCommandLineJSONIterate(const char *key,
6ae9ed
         if (virAsprintf(&tmpkey, "%s.%s", data->prefix, key) < 0)
6ae9ed
             return -1;
6ae9ed
 
6ae9ed
-        ret = virQEMUBuildCommandLineJSONRecurse(tmpkey, value, data->buf, false);
6ae9ed
+        ret = virQEMUBuildCommandLineJSONRecurse(tmpkey, value, data->buf,
6ae9ed
+                                                 data->arrayFunc, false);
6ae9ed
 
6ae9ed
         VIR_FREE(tmpkey);
6ae9ed
     } else {
6ae9ed
-        ret = virQEMUBuildCommandLineJSONRecurse(key, value, data->buf, false);
6ae9ed
+        ret = virQEMUBuildCommandLineJSONRecurse(key, value, data->buf,
6ae9ed
+                                                 data->arrayFunc, false);
6ae9ed
     }
6ae9ed
 
6ae9ed
     return ret;
6ae9ed
@@ -74,13 +110,11 @@ static int
6ae9ed
 virQEMUBuildCommandLineJSONRecurse(const char *key,
6ae9ed
                                    const virJSONValue *value,
6ae9ed
                                    virBufferPtr buf,
6ae9ed
+                                   virQEMUBuildCommandLineJSONArrayFormatFunc arrayFunc,
6ae9ed
                                    bool nested)
6ae9ed
 {
6ae9ed
-    struct virQEMUCommandLineJSONIteratorData data = { key, buf };
6ae9ed
+    struct virQEMUCommandLineJSONIteratorData data = { key, buf, arrayFunc };
6ae9ed
     virJSONValuePtr elem;
6ae9ed
-    virBitmapPtr bitmap = NULL;
6ae9ed
-    ssize_t pos = -1;
6ae9ed
-    ssize_t end;
6ae9ed
     size_t i;
6ae9ed
 
6ae9ed
     if (!key && value->type != VIR_JSON_TYPE_OBJECT) {
6ae9ed
@@ -115,26 +149,15 @@ virQEMUBuildCommandLineJSONRecurse(const char *key,
6ae9ed
             return -1;
6ae9ed
         }
6ae9ed
 
6ae9ed
-        if (virJSONValueGetArrayAsBitmap(value, &bitmap) == 0) {
6ae9ed
-            while ((pos = virBitmapNextSetBit(bitmap, pos)) > -1) {
6ae9ed
-                if ((end = virBitmapNextClearBit(bitmap, pos)) < 0)
6ae9ed
-                    end = virBitmapLastSetBit(bitmap) + 1;
6ae9ed
-
6ae9ed
-                if (end - 1 > pos) {
6ae9ed
-                    virBufferAsprintf(buf, ",%s=%zd-%zd", key, pos, end - 1);
6ae9ed
-                    pos = end;
6ae9ed
-                } else {
6ae9ed
-                    virBufferAsprintf(buf, ",%s=%zd", key, pos);
6ae9ed
-                }
6ae9ed
-            }
6ae9ed
-        } else {
6ae9ed
+        if (!arrayFunc || arrayFunc(key, value, buf) < 0) {
6ae9ed
             /* fallback, treat the array as a non-bitmap, adding the key
6ae9ed
              * for each member */
6ae9ed
             for (i = 0; i < virJSONValueArraySize(value); i++) {
6ae9ed
                 elem = virJSONValueArrayGet((virJSONValuePtr)value, i);
6ae9ed
 
6ae9ed
                 /* recurse to avoid duplicating code */
6ae9ed
-                if (virQEMUBuildCommandLineJSONRecurse(key, elem, buf, true) < 0)
6ae9ed
+                if (virQEMUBuildCommandLineJSONRecurse(key, elem, buf,
6ae9ed
+                                                       arrayFunc, true) < 0)
6ae9ed
                     return -1;
6ae9ed
             }
6ae9ed
         }
6ae9ed
@@ -153,7 +176,6 @@ virQEMUBuildCommandLineJSONRecurse(const char *key,
6ae9ed
         return -1;
6ae9ed
     }
6ae9ed
 
6ae9ed
-    virBitmapFree(bitmap);
6ae9ed
     return 0;
6ae9ed
 }
6ae9ed
 
6ae9ed
@@ -162,6 +184,7 @@ virQEMUBuildCommandLineJSONRecurse(const char *key,
6ae9ed
  * virQEMUBuildCommandLineJSON:
6ae9ed
  * @value: json object containing the value
6ae9ed
  * @buf: otuput buffer
6ae9ed
+ * @arrayFunc: array formatter function to allow for different syntax
6ae9ed
  *
6ae9ed
  * Formats JSON value object into command line parameters suitable for use with
6ae9ed
  * qemu.
6ae9ed
@@ -170,9 +193,10 @@ virQEMUBuildCommandLineJSONRecurse(const char *key,
6ae9ed
  */
6ae9ed
 int
6ae9ed
 virQEMUBuildCommandLineJSON(const virJSONValue *value,
6ae9ed
-                            virBufferPtr buf)
6ae9ed
+                            virBufferPtr buf,
6ae9ed
+                            virQEMUBuildCommandLineJSONArrayFormatFunc array)
6ae9ed
 {
6ae9ed
-    return virQEMUBuildCommandLineJSONRecurse(NULL, value, buf, false);
6ae9ed
+    return virQEMUBuildCommandLineJSONRecurse(NULL, value, buf, array, false);
6ae9ed
 }
6ae9ed
 
6ae9ed
 
6ae9ed
@@ -186,7 +210,8 @@ virQEMUBuildObjectCommandlineFromJSON(const char *type,
6ae9ed
 
6ae9ed
     virBufferAsprintf(&buf, "%s,id=%s", type, alias);
6ae9ed
 
6ae9ed
-    if (virQEMUBuildCommandLineJSON(props, &buf) < 0)
6ae9ed
+    if (virQEMUBuildCommandLineJSON(props, &buf,
6ae9ed
+                                    virQEMUBuildCommandLineJSONArrayBitmap) < 0)
6ae9ed
         goto cleanup;
6ae9ed
 
6ae9ed
     if (virBufferCheckError(&buf) < 0)
6ae9ed
diff --git a/src/util/virqemu.h b/src/util/virqemu.h
6ae9ed
index efc6c42..801c35b 100644
6ae9ed
--- a/src/util/virqemu.h
6ae9ed
+++ b/src/util/virqemu.h
6ae9ed
@@ -29,8 +29,16 @@
6ae9ed
 # include "virjson.h"
6ae9ed
 # include "virstorageencryption.h"
6ae9ed
 
6ae9ed
+typedef int (*virQEMUBuildCommandLineJSONArrayFormatFunc)(const char *key,
6ae9ed
+                                                          const virJSONValue *array,
6ae9ed
+                                                          virBufferPtr buf);
6ae9ed
+int virQEMUBuildCommandLineJSONArrayBitmap(const char *key,
6ae9ed
+                                           const virJSONValue *array,
6ae9ed
+                                           virBufferPtr buf);
6ae9ed
+
6ae9ed
 int virQEMUBuildCommandLineJSON(const virJSONValue *value,
6ae9ed
-                                virBufferPtr buf);
6ae9ed
+                                virBufferPtr buf,
6ae9ed
+                                virQEMUBuildCommandLineJSONArrayFormatFunc array);
6ae9ed
 
6ae9ed
 char *virQEMUBuildObjectCommandlineFromJSON(const char *type,
6ae9ed
                                             const char *alias,
6ae9ed
diff --git a/tests/qemucommandutiltest.c b/tests/qemucommandutiltest.c
6ae9ed
index 4872ea3..a5e3153 100644
6ae9ed
--- a/tests/qemucommandutiltest.c
6ae9ed
+++ b/tests/qemucommandutiltest.c
6ae9ed
@@ -51,7 +51,8 @@ testQemuCommandBuildFromJSON(const void *opaque)
6ae9ed
         virAsprintf(&expect, ",%s", data->expectprops) < 0)
6ae9ed
         return -1;
6ae9ed
 
6ae9ed
-    if (virQEMUBuildCommandLineJSON(val, &buf) < 0) {
6ae9ed
+    if (virQEMUBuildCommandLineJSON(val, &buf,
6ae9ed
+                                    virQEMUBuildCommandLineJSONArrayBitmap) < 0) {
6ae9ed
         fprintf(stderr,
6ae9ed
                 "\nvirQEMUBuildCommandlineJSON failed process JSON:\n%s\n",
6ae9ed
                 data->props);
6ae9ed
-- 
6ae9ed
2.9.2
6ae9ed