[PATCH] vl: transform QemuOpts device to JSON syntax device

Zhenzhong Duan posted 1 patch 2 years, 2 months ago
Test checkpatch passed
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20220224060653.74229-1-zhenzhong.duan@intel.com
Maintainers: Paolo Bonzini <pbonzini@redhat.com>
softmmu/vl.c | 23 ++++++++++++++---------
1 file changed, 14 insertions(+), 9 deletions(-)
[PATCH] vl: transform QemuOpts device to JSON syntax device
Posted by Zhenzhong Duan 2 years, 2 months ago
While there are mixed use of traditional -device option and JSON
syntax option, QEMU reports conflict, e.x:

/usr/libexec/qemu-kvm -nodefaults \
  -device '{"driver":"virtio-scsi-pci","id":"scsi0","bus":"pci.0","addr":"0x02.0"}' \
  -device virtio-scsi-pci,id=scsi1,bus=pci.0

It breaks with:

qemu-kvm: -device {"driver":"virtio-scsi-pci","id":"scsi0","bus":"pci.0","addr":"0x02.0"}: PCI: slot 2 function 0 not available for virtio-scsi-pci, in use by virtio-scsi-pci

But if we reformat first -device same as the second, so only same kind
of option for all the devices, it succeeds, vice versa. e.x:

/usr/libexec/qemu-kvm -nodefaults \
  -device virtio-scsi-pci,id=scsi0,bus=pci.0,addr=02.0 \
  -device virtio-scsi-pci,id=scsi1,bus=pci.0

Succeed!

Because both kind of options are inserted into their own list and
break the order in QEMU command line during BDF auto assign. Fix it
by transform QemuOpts into JSON syntax and insert in JSON device
list, so the order in QEMU command line kept.

Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
---
 softmmu/vl.c | 23 ++++++++++++++---------
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/softmmu/vl.c b/softmmu/vl.c
index 1fe028800fdf..3def40b5405e 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -3394,21 +3394,26 @@ void qemu_init(int argc, char **argv, char **envp)
                 qdict_put_str(machine_opts_dict, "usb", "on");
                 add_device_config(DEV_USB, optarg);
                 break;
-            case QEMU_OPTION_device:
+            case QEMU_OPTION_device: {
+                QObject *obj;
                 if (optarg[0] == '{') {
-                    QObject *obj = qobject_from_json(optarg, &error_fatal);
-                    DeviceOption *opt = g_new0(DeviceOption, 1);
-                    opt->opts = qobject_to(QDict, obj);
-                    loc_save(&opt->loc);
-                    assert(opt->opts != NULL);
-                    QTAILQ_INSERT_TAIL(&device_opts, opt, next);
+                    obj = qobject_from_json(optarg, &error_fatal);
                 } else {
-                    if (!qemu_opts_parse_noisily(qemu_find_opts("device"),
-                                                 optarg, true)) {
+                    opts = qemu_opts_parse_noisily(qemu_find_opts("device"),
+                                                   optarg, true);
+                    if (!opts) {
                         exit(1);
                     }
+                    obj = QOBJECT(qemu_opts_to_qdict(opts, NULL));
+                    qemu_opts_del(opts);
                 }
+                DeviceOption *opt = g_new0(DeviceOption, 1);
+                opt->opts = qobject_to(QDict, obj);
+                loc_save(&opt->loc);
+                assert(opt->opts != NULL);
+                QTAILQ_INSERT_TAIL(&device_opts, opt, next);
                 break;
+            }
             case QEMU_OPTION_smp:
                 machine_parse_property_opt(qemu_find_opts("smp-opts"),
                                            "smp", optarg);
-- 
2.25.1