提交 f744b831 编写于 作者: P Peter Krempa

qemu: json: Add format strings for optional command arguments

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.
上级 68226749
...@@ -451,7 +451,30 @@ qemuMonitorJSONMakeCommandRaw(bool wrap, const char *cmdname, ...) ...@@ -451,7 +451,30 @@ qemuMonitorJSONMakeCommandRaw(bool wrap, const char *cmdname, ...)
goto error; 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, omitted if null
*
* i: signed integer value
* z: signed integer value, omitted if zero
*
* I: signed long integer value
* Z: signed long integer value, 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
*
* b: boolean value
* B: boolean value, omitted if false
*
* d: double precision floating point number
* n: json null value
* a: json array
*/
type = key[0]; type = key[0];
key += 2; key += 2;
...@@ -461,9 +484,13 @@ qemuMonitorJSONMakeCommandRaw(bool wrap, const char *cmdname, ...) ...@@ -461,9 +484,13 @@ qemuMonitorJSONMakeCommandRaw(bool wrap, const char *cmdname, ...)
/* This doesn't support maps, but no command uses those. */ /* This doesn't support maps, but no command uses those. */
switch (type) { switch (type) {
case 'S':
case 's': { case 's': {
char *val = va_arg(args, char *); char *val = va_arg(args, char *);
if (!val) { if (!val) {
if (type == 'S')
continue;
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("argument key '%s' must not have null value"), _("argument key '%s' must not have null value"),
key); key);
...@@ -471,18 +498,38 @@ qemuMonitorJSONMakeCommandRaw(bool wrap, const char *cmdname, ...) ...@@ -471,18 +498,38 @@ qemuMonitorJSONMakeCommandRaw(bool wrap, const char *cmdname, ...)
} }
ret = virJSONValueObjectAppendString(jargs, key, val); ret = virJSONValueObjectAppendString(jargs, key, val);
} break; } break;
case 'z':
case 'i': { case 'i': {
int val = va_arg(args, int); int val = va_arg(args, int);
if (!val && type == 'z')
continue;
ret = virJSONValueObjectAppendNumberInt(jargs, key, val); ret = virJSONValueObjectAppendNumberInt(jargs, key, val);
} break; } break;
case 'p':
case 'u': { case 'u': {
unsigned int val = va_arg(args, unsigned int); unsigned int val = va_arg(args, unsigned int);
if (!val && type == 'p')
continue;
ret = virJSONValueObjectAppendNumberUint(jargs, key, val); ret = virJSONValueObjectAppendNumberUint(jargs, key, val);
} break; } break;
case 'Z':
case 'I': { case 'I': {
long long val = va_arg(args, long long); long long val = va_arg(args, long long);
if (!val && type == 'Z')
continue;
ret = virJSONValueObjectAppendNumberLong(jargs, key, val); ret = virJSONValueObjectAppendNumberLong(jargs, key, val);
} break; } break;
case 'P':
case 'U': { case 'U': {
/* qemu silently truncates numbers larger than LLONG_MAX, /* qemu silently truncates numbers larger than LLONG_MAX,
* so passing the full range of unsigned 64 bit integers * so passing the full range of unsigned 64 bit integers
...@@ -490,23 +537,37 @@ qemuMonitorJSONMakeCommandRaw(bool wrap, const char *cmdname, ...) ...@@ -490,23 +537,37 @@ qemuMonitorJSONMakeCommandRaw(bool wrap, const char *cmdname, ...)
* instead. * instead.
*/ */
long long val = va_arg(args, long long); long long val = va_arg(args, long long);
if (!val && type == 'P')
continue;
ret = virJSONValueObjectAppendNumberLong(jargs, key, val); ret = virJSONValueObjectAppendNumberLong(jargs, key, val);
} break; } break;
case 'd': { case 'd': {
double val = va_arg(args, double); double val = va_arg(args, double);
ret = virJSONValueObjectAppendNumberDouble(jargs, key, val); ret = virJSONValueObjectAppendNumberDouble(jargs, key, val);
} break; } break;
case 'B':
case 'b': { case 'b': {
int val = va_arg(args, int); int val = va_arg(args, int);
if (!val && type == 'B')
continue;
ret = virJSONValueObjectAppendBoolean(jargs, key, val); ret = virJSONValueObjectAppendBoolean(jargs, key, val);
} break; } break;
case 'n': { case 'n': {
ret = virJSONValueObjectAppendNull(jargs, key); ret = virJSONValueObjectAppendNull(jargs, key);
} break; } break;
case 'a': { case 'a': {
virJSONValuePtr val = va_arg(args, virJSONValuePtr); virJSONValuePtr val = va_arg(args, virJSONValuePtr);
ret = virJSONValueObjectAppend(jargs, key, val); ret = virJSONValueObjectAppend(jargs, key, val);
} break; } break;
default: default:
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("unsupported data type '%c' for arg '%s'"), type, key - 2); _("unsupported data type '%c' for arg '%s'"), type, key - 2);
...@@ -2203,19 +2264,14 @@ int qemuMonitorJSONChangeMedia(qemuMonitorPtr mon, ...@@ -2203,19 +2264,14 @@ int qemuMonitorJSONChangeMedia(qemuMonitorPtr mon,
{ {
int ret; int ret;
virJSONValuePtr cmd; 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; virJSONValuePtr reply = NULL;
cmd = qemuMonitorJSONMakeCommand("change",
"s:device", dev_name,
"s:target", newmedia,
"S:arg", format,
NULL);
if (!cmd) if (!cmd)
return -1; return -1;
...@@ -2781,8 +2837,7 @@ int qemuMonitorJSONGraphicsRelocate(qemuMonitorPtr mon, ...@@ -2781,8 +2837,7 @@ int qemuMonitorJSONGraphicsRelocate(qemuMonitorPtr mon,
"s:hostname", hostname, "s:hostname", hostname,
"i:port", port, "i:port", port,
"i:tls-port", tlsPort, "i:tls-port", tlsPort,
(tlsSubject ? "s:cert-subject" : NULL), "S:cert-subject", tlsSubject,
(tlsSubject ? tlsSubject : NULL),
NULL); NULL);
virJSONValuePtr reply = NULL; virJSONValuePtr reply = NULL;
if (!cmd) if (!cmd)
...@@ -2919,8 +2974,8 @@ qemuMonitorJSONAddFd(qemuMonitorPtr mon, int fdset, int fd, const char *name) ...@@ -2919,8 +2974,8 @@ qemuMonitorJSONAddFd(qemuMonitorPtr mon, int fdset, int fd, const char *name)
int ret; int ret;
virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("add-fd", virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("add-fd",
"i:fdset-id", fdset, "i:fdset-id", fdset,
name ? "s:opaque" : NULL, "S:opaque", name,
name, NULL); NULL);
virJSONValuePtr reply = NULL; virJSONValuePtr reply = NULL;
if (!cmd) if (!cmd)
return -1; return -1;
...@@ -3314,8 +3369,7 @@ qemuMonitorJSONDiskSnapshot(qemuMonitorPtr mon, virJSONValuePtr actions, ...@@ -3314,8 +3369,7 @@ qemuMonitorJSONDiskSnapshot(qemuMonitorPtr mon, virJSONValuePtr actions,
"s:device", device, "s:device", device,
"s:snapshot-file", file, "s:snapshot-file", file,
"s:format", format, "s:format", format,
reuse ? "s:mode" : NULL, "S:mode", reuse ? "existing" : NULL,
reuse ? "existing" : NULL,
NULL); NULL);
if (!cmd) if (!cmd)
return -1; return -1;
...@@ -3356,9 +3410,8 @@ qemuMonitorJSONDriveMirror(qemuMonitorPtr mon, ...@@ -3356,9 +3410,8 @@ qemuMonitorJSONDriveMirror(qemuMonitorPtr mon,
"s:target", file, "s:target", file,
"U:speed", speed, "U:speed", speed,
"s:sync", shallow ? "top" : "full", "s:sync", shallow ? "top" : "full",
"s:mode", "s:mode", reuse ? "existing" : "absolute-paths",
reuse ? "existing" : "absolute-paths", "S:format", format,
format ? "s:format" : NULL, format,
NULL); NULL);
if (!cmd) if (!cmd)
return -1; return -1;
...@@ -3557,8 +3610,8 @@ int qemuMonitorJSONSendKey(qemuMonitorPtr mon, ...@@ -3557,8 +3610,8 @@ int qemuMonitorJSONSendKey(qemuMonitorPtr mon,
cmd = qemuMonitorJSONMakeCommand("send-key", cmd = qemuMonitorJSONMakeCommand("send-key",
"a:keys", keys, "a:keys", keys,
holdtime ? "U:hold-time" : NULL, holdtime, "P:hold-time", holdtime,
NULL); NULL);
if (!cmd) if (!cmd)
goto cleanup; goto cleanup;
...@@ -3736,31 +3789,31 @@ qemuMonitorJSONBlockJob(qemuMonitorPtr mon, ...@@ -3736,31 +3789,31 @@ qemuMonitorJSONBlockJob(qemuMonitorPtr mon,
switch (mode) { switch (mode) {
case BLOCK_JOB_ABORT: case BLOCK_JOB_ABORT:
cmd_name = modern ? "block-job-cancel" : "block_job_cancel"; 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; break;
case BLOCK_JOB_INFO: case BLOCK_JOB_INFO:
cmd_name = "query-block-jobs"; cmd_name = "query-block-jobs";
cmd = qemuMonitorJSONMakeCommand(cmd_name, NULL); cmd = qemuMonitorJSONMakeCommand(cmd_name, NULL);
break; break;
case BLOCK_JOB_SPEED: case BLOCK_JOB_SPEED:
cmd_name = modern ? "block-job-set-speed" : "block_job_set_speed"; cmd_name = modern ? "block-job-set-speed" : "block_job_set_speed";
cmd = qemuMonitorJSONMakeCommand(cmd_name, "s:device", device, cmd = qemuMonitorJSONMakeCommand(cmd_name,
modern ? "U:speed" : "U:value", "s:device", device,
speed, NULL); modern ? "U:speed" : "U:value", speed,
NULL);
break; break;
case BLOCK_JOB_PULL: case BLOCK_JOB_PULL:
cmd_name = modern ? "block-stream" : "block_stream"; cmd_name = modern ? "block-stream" : "block_stream";
if (speed) cmd = qemuMonitorJSONMakeCommand(cmd_name,
cmd = qemuMonitorJSONMakeCommand(cmd_name, "s:device", device,
"s:device", device, "P:speed", speed,
"U:speed", speed, "S:base", base,
base ? "s:base" : NULL, base, NULL);
NULL);
else
cmd = qemuMonitorJSONMakeCommand(cmd_name,
"s:device", device,
base ? "s:base" : NULL, base,
NULL);
break; break;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册