This patch adds option to specify that a json qemu command argument is
optional without the need to use if's or ternary operators to pass the
list. Additionally all the modifier characters are documented to avoid
user confusion.
---
src/qemu/qemu_monitor_json.c | 122 +++++++++++++++++++++++++++++--------------
1 file changed, 84 insertions(+), 38 deletions(-)
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index f8ab975..04249c5 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -451,7 +451,28 @@ qemuMonitorJSONMakeCommandRaw(bool wrap, const char *cmdname, ...)
goto error;
}
- /* Keys look like s:name the first letter is a type code */
+ /* Keys look like s:name the first letter is a type code:
+ * Explanation of type codes:
+ * s: string value, must be non-null
+ * S: string value, signed, omitted if null
+ *
+ * i: signed integer value
+ * z: signed integer value, omitted if zero
+ *
+ * I: signed long integer value
+ * Z: integer value, signed, omitted if zero
+ *
+ * u: unsigned integer value
+ * p: unsigned integer value, omitted if zero
+ *
+ * U: unsigned long integer value (see below for quirks)
+ * P: unsigned long integer value, omitted if zero,
+ *
+ * d: double precision floating point number
+ * b: boolean value
+ * n: json null value
+ * a: json array
+ */
type = key[0];
key += 2;
@@ -461,9 +482,13 @@ qemuMonitorJSONMakeCommandRaw(bool wrap, const char *cmdname, ...)
/* This doesn't support maps, but no command uses those. */
switch (type) {
+ case 'S':
case 's': {
char *val = va_arg(args, char *);
if (!val) {
+ if (type == 'S')
+ continue;
+
virReportError(VIR_ERR_INTERNAL_ERROR,
_("argument key '%s' must not have null
value"),
key);
@@ -471,18 +496,38 @@ qemuMonitorJSONMakeCommandRaw(bool wrap, const char *cmdname, ...)
}
ret = virJSONValueObjectAppendString(jargs, key, val);
} break;
+
+ case 'z':
case 'i': {
int val = va_arg(args, int);
+
+ if (!val && type == 'z')
+ continue;
+
ret = virJSONValueObjectAppendNumberInt(jargs, key, val);
} break;
+
+ case 'p':
case 'u': {
unsigned int val = va_arg(args, unsigned int);
+
+ if (!val && type == 'p')
+ continue;
+
ret = virJSONValueObjectAppendNumberUint(jargs, key, val);
} break;
+
+ case 'Z':
case 'I': {
long long val = va_arg(args, long long);
+
+ if (!val && type == 'Z')
+ continue;
+
ret = virJSONValueObjectAppendNumberLong(jargs, key, val);
} break;
+
+ case 'P':
case 'U': {
/* qemu silently truncates numbers larger than LLONG_MAX,
* so passing the full range of unsigned 64 bit integers
@@ -490,23 +535,32 @@ qemuMonitorJSONMakeCommandRaw(bool wrap, const char *cmdname, ...)
* instead.
*/
long long val = va_arg(args, long long);
+
+ if (!val && type == 'P')
+ continue;
+
ret = virJSONValueObjectAppendNumberLong(jargs, key, val);
} break;
+
case 'd': {
double val = va_arg(args, double);
ret = virJSONValueObjectAppendNumberDouble(jargs, key, val);
} break;
+
case 'b': {
int val = va_arg(args, int);
ret = virJSONValueObjectAppendBoolean(jargs, key, val);
} break;
+
case 'n': {
ret = virJSONValueObjectAppendNull(jargs, key);
} break;
+
case 'a': {
virJSONValuePtr val = va_arg(args, virJSONValuePtr);
ret = virJSONValueObjectAppend(jargs, key, val);
} break;
+
default:
virReportError(VIR_ERR_INTERNAL_ERROR,
_("unsupported data type '%c' for arg
'%s'"), type, key - 2);
@@ -2193,19 +2247,14 @@ int qemuMonitorJSONChangeMedia(qemuMonitorPtr mon,
{
int ret;
virJSONValuePtr cmd;
- if (format)
- cmd = qemuMonitorJSONMakeCommand("change",
- "s:device", dev_name,
- "s:target", newmedia,
- "s:arg", format,
- NULL);
- else
- cmd = qemuMonitorJSONMakeCommand("change",
- "s:device", dev_name,
- "s:target", newmedia,
- NULL);
-
virJSONValuePtr reply = NULL;
+
+ cmd = qemuMonitorJSONMakeCommand("change",
+ "s:device", dev_name,
+ "s:target", newmedia,
+ "S:arg", format,
+ NULL);
+
if (!cmd)
return -1;
@@ -2771,8 +2820,7 @@ int qemuMonitorJSONGraphicsRelocate(qemuMonitorPtr mon,
"s:hostname", hostname,
"i:port", port,
"i:tls-port", tlsPort,
- (tlsSubject ?
"s:cert-subject" : NULL),
- (tlsSubject ? tlsSubject : NULL),
+ "S:cert-subject",
tlsSubject,
NULL);
virJSONValuePtr reply = NULL;
if (!cmd)
@@ -2909,8 +2957,8 @@ qemuMonitorJSONAddFd(qemuMonitorPtr mon, int fdset, int fd, const
char *name)
int ret;
virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("add-fd",
"i:fdset-id", fdset,
- name ? "s:opaque" : NULL,
- name, NULL);
+ "S:opaque", name,
+ NULL);
virJSONValuePtr reply = NULL;
if (!cmd)
return -1;
@@ -3304,8 +3352,7 @@ qemuMonitorJSONDiskSnapshot(qemuMonitorPtr mon, virJSONValuePtr
actions,
"s:device", device,
"s:snapshot-file", file,
"s:format", format,
- reuse ? "s:mode" : NULL,
- reuse ? "existing" : NULL,
+ "S:mode", reuse ? "existing"
: NULL,
NULL);
if (!cmd)
return -1;
@@ -3346,9 +3393,8 @@ qemuMonitorJSONDriveMirror(qemuMonitorPtr mon,
"s:target", file,
"U:speed", speed,
"s:sync", shallow ? "top" :
"full",
- "s:mode",
- reuse ? "existing" :
"absolute-paths",
- format ? "s:format" : NULL, format,
+ "s:mode", reuse ? "existing" :
"absolute-paths",
+ "S:format", format,
NULL);
if (!cmd)
return -1;
@@ -3547,7 +3593,7 @@ int qemuMonitorJSONSendKey(qemuMonitorPtr mon,
cmd = qemuMonitorJSONMakeCommand("send-key",
"a:keys", keys,
- holdtime ? "U:hold-time" : NULL,
holdtime,
+ "P:hold-time", holdtime,
NULL);
if (!cmd)
goto cleanup;
@@ -3726,31 +3772,31 @@ qemuMonitorJSONBlockJob(qemuMonitorPtr mon,
switch (mode) {
case BLOCK_JOB_ABORT:
cmd_name = modern ? "block-job-cancel" : "block_job_cancel";
- cmd = qemuMonitorJSONMakeCommand(cmd_name, "s:device", device, NULL);
+ cmd = qemuMonitorJSONMakeCommand(cmd_name,
+ "s:device", device,
+ NULL);
break;
+
case BLOCK_JOB_INFO:
cmd_name = "query-block-jobs";
cmd = qemuMonitorJSONMakeCommand(cmd_name, NULL);
break;
+
case BLOCK_JOB_SPEED:
cmd_name = modern ? "block-job-set-speed" :
"block_job_set_speed";
- cmd = qemuMonitorJSONMakeCommand(cmd_name, "s:device", device,
- modern ? "U:speed" :
"U:value",
- speed, NULL);
+ cmd = qemuMonitorJSONMakeCommand(cmd_name,
+ "s:device", device,
+ modern ? "U:speed" :
"U:value", speed,
+ NULL);
break;
+
case BLOCK_JOB_PULL:
cmd_name = modern ? "block-stream" : "block_stream";
- if (speed)
- cmd = qemuMonitorJSONMakeCommand(cmd_name,
- "s:device", device,
- "U:speed", speed,
- base ? "s:base" : NULL, base,
- NULL);
- else
- cmd = qemuMonitorJSONMakeCommand(cmd_name,
- "s:device", device,
- base ? "s:base" : NULL, base,
- NULL);
+ cmd = qemuMonitorJSONMakeCommand(cmd_name,
+ "s:device", device,
+ "P:speed", speed,
+ "S:base", base,
+ NULL);
break;
}
--
1.9.3