|
|
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 |
|