From 63a833038f208e1f1e3ad26954b88e4039de929d Mon Sep 17 00:00:00 2001 From: Peter Krempa Date: Fri, 24 Sep 2021 18:47:59 +0200 Subject: [PATCH] qemu: command: Format netdev as JSON when QEMU_CAPS_NETDEV_JSON is present MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Base the JSON output on a regular capability flag rather than purely internal flag. This will prepare for the time when QEMU will accept JSON argumets for -netdev. For now the capability is not set (thus we for now don't have QMP schema validation) but that will be addressed later. To achieve this 'qemuBuildNetdevCommandlineFromJSON' is introduced and all callers of 'virQEMUBuildNetdevCommandlineFromJSON' are refactored to use the new helper. Signed-off-by: Peter Krempa Reviewed-by: Ján Tomko --- src/libvirt_private.syms | 1 + src/qemu/qemu_command.c | 55 ++++++++++++++++++++++++++-------------- src/util/virqemu.c | 2 +- src/util/virqemu.h | 4 +++ 4 files changed, 42 insertions(+), 20 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index fd0eea0777..a58f2e4552 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -3118,6 +3118,7 @@ virQEMUBuildBufferEscapeComma; virQEMUBuildCommandLineJSON; virQEMUBuildCommandLineJSONArrayBitmap; virQEMUBuildCommandLineJSONArrayNumbered; +virQEMUBuildCommandLineJSONArrayObjectsStr; virQEMUBuildDriveCommandlineFromJSON; virQEMUBuildNetdevCommandlineFromJSON; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 91ec991517..b6a8a391a8 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -183,6 +183,34 @@ qemuBuildObjectCommandlineFromJSON(virCommand *cmd, } +static int +qemuBuildNetdevCommandlineFromJSON(virCommand *cmd, + virJSONValue *props, + virQEMUCaps *qemuCaps) +{ + g_autofree char *arg = NULL; + + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NETDEV_JSON)) { + if (!(arg = virJSONValueToString(props, false))) + return -1; + } else { + const char *type = virJSONValueObjectGetString(props, "type"); + g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER; + + virBufferAsprintf(&buf, "%s,", type); + + if (virQEMUBuildCommandLineJSON(props, &buf, "type", + virQEMUBuildCommandLineJSONArrayObjectsStr) < 0) + return -1; + + arg = virBufferContentAndReset(&buf); + } + + virCommandAddArgList(cmd, "-netdev", arg, NULL); + return 0; +} + + /** * qemuBuildMasterKeyCommandLine: * @cmd: the command to modify @@ -8402,13 +8430,11 @@ qemuBuildInterfaceCommandLine(virQEMUDriver *driver, virNetDevVPortProfileOp vmop, bool standalone, size_t *nnicindexes, - int **nicindexes, - unsigned int flags) + int **nicindexes) { virDomainDef *def = vm->def; int ret = -1; g_autofree char *nic = NULL; - g_autofree char *host = NULL; g_autofree char *chardev = NULL; int *tapfd = NULL; size_t tapfdSize = 0; @@ -8662,12 +8688,9 @@ qemuBuildInterfaceCommandLine(virQEMUDriver *driver, slirpfdName, vdpafdName))) goto cleanup; - if (!(host = virQEMUBuildNetdevCommandlineFromJSON(hostnetprops, - (flags & QEMU_BUILD_COMMANDLINE_VALIDATE_KEEP_JSON)))) + if (qemuBuildNetdevCommandlineFromJSON(cmd, hostnetprops, qemuCaps) < 0) goto cleanup; - virCommandAddArgList(cmd, "-netdev", host, NULL); - /* Possible combinations: * * Old way: -netdev type=tap,id=netdev1 \ @@ -8740,8 +8763,7 @@ qemuBuildNetCommandLine(virQEMUDriver *driver, bool standalone, size_t *nnicindexes, int **nicindexes, - unsigned int *bootHostdevNet, - unsigned int flags) + unsigned int *bootHostdevNet) { size_t i; int last_good_net = -1; @@ -8765,7 +8787,7 @@ qemuBuildNetCommandLine(virQEMUDriver *driver, if (qemuBuildInterfaceCommandLine(driver, vm, logManager, secManager, cmd, net, qemuCaps, bootNet, vmop, standalone, nnicindexes, - nicindexes, flags) < 0) + nicindexes) < 0) goto error; last_good_net = i; @@ -9289,8 +9311,7 @@ qemuBuildChannelsCommandLine(virLogManager *logManager, virQEMUDriverConfig *cfg, const virDomainDef *def, virQEMUCaps *qemuCaps, - bool chardevStdioLogd, - unsigned int flags) + bool chardevStdioLogd) { size_t i; unsigned int cdevflags = QEMU_BUILD_CHARDEV_TCP_NOWAIT | @@ -9302,7 +9323,6 @@ qemuBuildChannelsCommandLine(virLogManager *logManager, virDomainChrDef *channel = def->channels[i]; g_autofree char *chardevstr = NULL; g_autoptr(virJSONValue) netdevprops = NULL; - g_autofree char *netdevstr = NULL; if (!(chardevstr = qemuBuildChrChardevStr(logManager, secManager, cmd, cfg, def, @@ -9319,11 +9339,8 @@ qemuBuildChannelsCommandLine(virLogManager *logManager, if (!(netdevprops = qemuBuildChannelGuestfwdNetdevProps(channel))) return -1; - if (!(netdevstr = virQEMUBuildNetdevCommandlineFromJSON(netdevprops, - (flags & QEMU_BUILD_COMMANDLINE_VALIDATE_KEEP_JSON)))) + if (qemuBuildNetdevCommandlineFromJSON(cmd, netdevprops, qemuCaps) < 0) return -1; - - virCommandAddArgList(cmd, "-netdev", netdevstr, NULL); break; case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO: @@ -10471,7 +10488,7 @@ qemuBuildCommandLine(virQEMUDriver *driver, if (qemuBuildNetCommandLine(driver, vm, logManager, secManager, cmd, qemuCaps, vmop, standalone, - nnicindexes, nicindexes, &bootHostdevNet, flags) < 0) + nnicindexes, nicindexes, &bootHostdevNet) < 0) return NULL; if (qemuBuildSmartcardCommandLine(logManager, secManager, cmd, cfg, def, qemuCaps, @@ -10487,7 +10504,7 @@ qemuBuildCommandLine(virQEMUDriver *driver, return NULL; if (qemuBuildChannelsCommandLine(logManager, secManager, cmd, cfg, def, qemuCaps, - chardevStdioLogd, flags) < 0) + chardevStdioLogd) < 0) return NULL; if (qemuBuildConsoleCommandLine(logManager, secManager, cmd, cfg, def, qemuCaps, diff --git a/src/util/virqemu.c b/src/util/virqemu.c index 644a1615dc..ff6e13b963 100644 --- a/src/util/virqemu.c +++ b/src/util/virqemu.c @@ -127,7 +127,7 @@ virQEMUBuildCommandLineJSONArrayNumbered(const char *key, * * guestfwd=tcp:10.0.2.1:4600-chardev:charchannel0,guestfwd=... */ -static int +int virQEMUBuildCommandLineJSONArrayObjectsStr(const char *key, virJSONValue *array, virBuffer *buf, diff --git a/src/util/virqemu.h b/src/util/virqemu.h index 70668faf47..b1fc3c8323 100644 --- a/src/util/virqemu.h +++ b/src/util/virqemu.h @@ -30,6 +30,10 @@ typedef int (*virQEMUBuildCommandLineJSONArrayFormatFunc)(const char *key, virJSONValue *array, virBuffer *buf, const char *skipKey); +int virQEMUBuildCommandLineJSONArrayObjectsStr(const char *key, + virJSONValue *array, + virBuffer *buf, + const char *skipKey); int virQEMUBuildCommandLineJSONArrayBitmap(const char *key, virJSONValue *array, virBuffer *buf,