From 220751091f7a23791134b653306dd460524d8a6d Mon Sep 17 00:00:00 2001 From: Peter Krempa Date: Thu, 14 May 2020 09:41:48 +0200 Subject: [PATCH] virQEMUBuildCommandLineJSON: Allow skipping certain keys Allow reusing this for formatting of netdev_add arguments into -netdev. We need to be able to skip the 'type' property as it's used without the prefix by our generator. Add infrastructure which allows skipping property with a specific name. Signed-off-by: Peter Krempa Reviewed-by: Eric Blake --- src/util/virqemu.c | 30 +++++++++++++++++++++--------- src/util/virqemu.h | 10 +++++++--- tests/qemucommandutiltest.c | 2 +- 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/src/util/virqemu.c b/src/util/virqemu.c index 78a9e0480b..0e6fa412bc 100644 --- a/src/util/virqemu.c +++ b/src/util/virqemu.c @@ -36,6 +36,7 @@ VIR_LOG_INIT("util.qemu"); struct virQEMUCommandLineJSONIteratorData { const char *prefix; virBufferPtr buf; + const char *skipKey; virQEMUBuildCommandLineJSONArrayFormatFunc arrayFunc; }; @@ -44,6 +45,7 @@ static int virQEMUBuildCommandLineJSONRecurse(const char *key, virJSONValuePtr value, virBufferPtr buf, + const char *skipKey, virQEMUBuildCommandLineJSONArrayFormatFunc arrayFunc, bool nested); @@ -52,7 +54,8 @@ virQEMUBuildCommandLineJSONRecurse(const char *key, int virQEMUBuildCommandLineJSONArrayBitmap(const char *key, virJSONValuePtr array, - virBufferPtr buf) + virBufferPtr buf, + const char *skipKey G_GNUC_UNUSED) { ssize_t pos = -1; ssize_t end; @@ -80,7 +83,8 @@ virQEMUBuildCommandLineJSONArrayBitmap(const char *key, int virQEMUBuildCommandLineJSONArrayNumbered(const char *key, virJSONValuePtr array, - virBufferPtr buf) + virBufferPtr buf, + const char *skipKey) { virJSONValuePtr member; size_t i; @@ -91,7 +95,7 @@ virQEMUBuildCommandLineJSONArrayNumbered(const char *key, prefix = g_strdup_printf("%s.%zu", key, i); - if (virQEMUBuildCommandLineJSONRecurse(prefix, member, buf, + if (virQEMUBuildCommandLineJSONRecurse(prefix, member, buf, skipKey, virQEMUBuildCommandLineJSONArrayNumbered, true) < 0) return 0; @@ -109,15 +113,20 @@ virQEMUBuildCommandLineJSONIterate(const char *key, { struct virQEMUCommandLineJSONIteratorData *data = opaque; + if (STREQ_NULLABLE(key, data->skipKey)) + return 0; + if (data->prefix) { g_autofree char *tmpkey = NULL; tmpkey = g_strdup_printf("%s.%s", data->prefix, key); return virQEMUBuildCommandLineJSONRecurse(tmpkey, value, data->buf, + data->skipKey, data->arrayFunc, false); } else { return virQEMUBuildCommandLineJSONRecurse(key, value, data->buf, + data->skipKey, data->arrayFunc, false); } } @@ -127,10 +136,11 @@ static int virQEMUBuildCommandLineJSONRecurse(const char *key, virJSONValuePtr value, virBufferPtr buf, + const char *skipKey, virQEMUBuildCommandLineJSONArrayFormatFunc arrayFunc, bool nested) { - struct virQEMUCommandLineJSONIteratorData data = { key, buf, arrayFunc }; + struct virQEMUCommandLineJSONIteratorData data = { key, buf, skipKey, arrayFunc }; virJSONType type = virJSONValueGetType(value); virJSONValuePtr elem; bool tmp; @@ -170,14 +180,14 @@ virQEMUBuildCommandLineJSONRecurse(const char *key, return -1; } - if (!arrayFunc || arrayFunc(key, value, buf) < 0) { + if (!arrayFunc || arrayFunc(key, value, buf, skipKey) < 0) { /* fallback, treat the array as a non-bitmap, adding the key * for each member */ for (i = 0; i < virJSONValueArraySize(value); i++) { elem = virJSONValueArrayGet((virJSONValuePtr)value, i); /* recurse to avoid duplicating code */ - if (virQEMUBuildCommandLineJSONRecurse(key, elem, buf, + if (virQEMUBuildCommandLineJSONRecurse(key, elem, buf, skipKey, arrayFunc, true) < 0) return -1; } @@ -205,6 +215,7 @@ virQEMUBuildCommandLineJSONRecurse(const char *key, * virQEMUBuildCommandLineJSON: * @value: json object containing the value * @buf: otuput buffer + * @skipKey: name of key that will be handled separately by caller * @arrayFunc: array formatter function to allow for different syntax * * Formats JSON value object into command line parameters suitable for use with @@ -215,9 +226,10 @@ virQEMUBuildCommandLineJSONRecurse(const char *key, int virQEMUBuildCommandLineJSON(virJSONValuePtr value, virBufferPtr buf, + const char *skipKey, virQEMUBuildCommandLineJSONArrayFormatFunc array) { - if (virQEMUBuildCommandLineJSONRecurse(NULL, value, buf, array, false) < 0) + if (virQEMUBuildCommandLineJSONRecurse(NULL, value, buf, skipKey, array, false) < 0) return -1; virBufferTrim(buf, ","); @@ -243,7 +255,7 @@ virQEMUBuildObjectCommandlineFromJSONInternal(virBufferPtr buf, if (props) { virBufferAddLit(buf, ","); - if (virQEMUBuildCommandLineJSON(props, buf, + if (virQEMUBuildCommandLineJSON(props, buf, NULL, virQEMUBuildCommandLineJSONArrayBitmap) < 0) return -1; } @@ -270,7 +282,7 @@ virQEMUBuildDriveCommandlineFromJSON(virJSONValuePtr srcdef) virBuffer buf = VIR_BUFFER_INITIALIZER; char *ret = NULL; - if (virQEMUBuildCommandLineJSON(srcdef, &buf, + if (virQEMUBuildCommandLineJSON(srcdef, &buf, NULL, virQEMUBuildCommandLineJSONArrayNumbered) < 0) goto cleanup; diff --git a/src/util/virqemu.h b/src/util/virqemu.h index 227325e80e..9d3db7c2a2 100644 --- a/src/util/virqemu.h +++ b/src/util/virqemu.h @@ -29,16 +29,20 @@ typedef int (*virQEMUBuildCommandLineJSONArrayFormatFunc)(const char *key, virJSONValuePtr array, - virBufferPtr buf); + virBufferPtr buf, + const char *skipKey); int virQEMUBuildCommandLineJSONArrayBitmap(const char *key, virJSONValuePtr array, - virBufferPtr buf); + virBufferPtr buf, + const char *skipKey); int virQEMUBuildCommandLineJSONArrayNumbered(const char *key, virJSONValuePtr array, - virBufferPtr buf); + virBufferPtr buf, + const char *skipKey); int virQEMUBuildCommandLineJSON(virJSONValuePtr value, virBufferPtr buf, + const char *skipKey, virQEMUBuildCommandLineJSONArrayFormatFunc array); int virQEMUBuildObjectCommandlineFromJSON(virBufferPtr buf, diff --git a/tests/qemucommandutiltest.c b/tests/qemucommandutiltest.c index c5b3e7b735..923776e642 100644 --- a/tests/qemucommandutiltest.c +++ b/tests/qemucommandutiltest.c @@ -47,7 +47,7 @@ testQemuCommandBuildFromJSON(const void *opaque) return -1; } - if (virQEMUBuildCommandLineJSON(val, &buf, data->arrayfunc) < 0) { + if (virQEMUBuildCommandLineJSON(val, &buf, NULL, data->arrayfunc) < 0) { fprintf(stderr, "\nvirQEMUBuildCommandlineJSON failed process JSON:\n%s\n", data->props);