Internally format the SCSI controller properties into JSON, but convert it back to a string so that we for now change just the SCSI controller. The change in tests is expected as the 'reg' field for a spapr-vio address is expected to be a number: $ qemu-system-ppc64 -device spapr-vscsi,help spapr-vscsi options: reg=<uint32> - (default: 4294967295) The hand-rolled generator used hex representation but that will not be possible on the monitor via JSON. The properties of 'virtio-scsi' have following types according to QEMU: iothread=<link<iothread>> num_queues=<uint32> - (default: 4294967295) cmd_per_lun=<uint32> - (default: 128) max_sectors=<uint32> - (default: 65535) ioeventfd=<bool> - on/off (default: true) Signed-off-by: Peter Krempa <pkrempa@xxxxxxxxxx> --- src/qemu/qemu_command.c | 81 ++++++++++--------- .../disk-scsi.x86_64-latest.args | 2 +- .../pseries-vio-user-assigned.args | 4 +- tests/qemuxml2argvdata/pseries-vio.args | 4 +- .../tpm-emulator-spapr.ppc64-latest.args | 4 +- 5 files changed, 49 insertions(+), 46 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 31fd9a540d..7e3e526fa5 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -1304,17 +1304,6 @@ qemuBuildRomProps(virJSONValue *props, } -static int -qemuBuildIoEventFdStr(virBuffer *buf, - virTristateSwitch use, - virQEMUCaps *qemuCaps G_GNUC_UNUSED) -{ - if (use) - virBufferAsprintf(buf, ",ioeventfd=%s", - virTristateSwitchTypeToString(use)); - return 0; -} - /** * qemuBuildSecretInfoProps: * @secinfo: pointer to the secret info object @@ -2867,40 +2856,37 @@ qemuBuildUSBControllerDevStr(const virDomainDef *domainDef, } -static char * -qemuBuildControllerSCSIDevStr(const virDomainDef *domainDef, - virDomainControllerDef *def, - virQEMUCaps *qemuCaps) +static virJSONValue * +qemuBuildControllerSCSIDevProps(const virDomainDef *domainDef, + virDomainControllerDef *def, + virQEMUCaps *qemuCaps) { - g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER; + g_autoptr(virJSONValue) props = NULL; + g_autofree char *iothread = NULL; const char *driver = NULL; switch ((virDomainControllerModelSCSI) def->model) { case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI: case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_TRANSITIONAL: case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_NON_TRANSITIONAL: - if (qemuBuildVirtioDevStr(&buf, qemuCaps, VIR_DOMAIN_DEVICE_CONTROLLER, def) < 0) { + if (!(props = qemuBuildVirtioDevProps(VIR_DOMAIN_DEVICE_CONTROLLER, def, + qemuCaps))) return NULL; - } - - if (def->iothread) { - virBufferAsprintf(&buf, ",iothread=iothread%u", - def->iothread); - } - - virBufferAsprintf(&buf, ",id=%s", def->info.alias); - if (def->queues) - virBufferAsprintf(&buf, ",num_queues=%u", def->queues); + if (def->iothread > 0) + iothread = g_strdup_printf("iothread%u", def->iothread); - if (def->cmd_per_lun) - virBufferAsprintf(&buf, ",cmd_per_lun=%u", def->cmd_per_lun); - - if (def->max_sectors) - virBufferAsprintf(&buf, ",max_sectors=%u", def->max_sectors); - - qemuBuildIoEventFdStr(&buf, def->ioeventfd, qemuCaps); + if (virJSONValueObjectAdd(props, + "S:iothread", iothread, + "s:id", def->info.alias, + "p:num_queues", def->queues, + "p:cmd_per_lun", def->cmd_per_lun, + "p:max_sectors", def->max_sectors, + "T:ioeventfd", def->ioeventfd, + NULL) < 0) + return NULL; break; + case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC: driver = "lsi"; break; @@ -2937,13 +2923,18 @@ qemuBuildControllerSCSIDevStr(const virDomainDef *domainDef, return NULL; } - if (driver) - virBufferAsprintf(&buf, "%s,id=%s", driver, def->info.alias); + if (driver) { + if (virJSONValueObjectCreate(&props, + "s:driver", driver, + "s:id", def->info.alias, + NULL) < 0) + return NULL; + } - if (qemuBuildDeviceAddressStr(&buf, domainDef, &def->info) < 0) + if (qemuBuildDeviceAddressProps(props, domainDef, &def->info) < 0) return NULL; - return virBufferContentAndReset(&buf); + return g_steal_pointer(&props); } @@ -3059,13 +3050,25 @@ qemuBuildControllerDevStr(const virDomainDef *domainDef, char **devstr) { g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER; + g_autoptr(virJSONValue) props = NULL; + const char *driver = NULL; *devstr = NULL; switch ((virDomainControllerType)def->type) { case VIR_DOMAIN_CONTROLLER_TYPE_SCSI: - if (!(*devstr = qemuBuildControllerSCSIDevStr(domainDef, def, qemuCaps))) + if (!(props = qemuBuildControllerSCSIDevProps(domainDef, def, qemuCaps))) + return -1; + + driver = virJSONValueObjectGetString(props, "driver"); + + virBufferAsprintf(&buf, "%s,", driver); + + if (virQEMUBuildCommandLineJSON(props, &buf, "driver", NULL) < 0) return -1; + + *devstr = virBufferContentAndReset(&buf); + return 0; case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL: diff --git a/tests/qemuxml2argvdata/disk-scsi.x86_64-latest.args b/tests/qemuxml2argvdata/disk-scsi.x86_64-latest.args index d9971582ac..79b66da881 100644 --- a/tests/qemuxml2argvdata/disk-scsi.x86_64-latest.args +++ b/tests/qemuxml2argvdata/disk-scsi.x86_64-latest.args @@ -30,7 +30,7 @@ XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \ -device lsi,id=scsi0,bus=pci.0,addr=0x2 \ -device megasas,id=scsi1,bus=pci.0,addr=0x3 \ -device mptsas1068,id=scsi2,bus=pci.0,addr=0x4 \ --device spapr-vscsi,id=scsi3,reg=0x00002000 \ +-device spapr-vscsi,id=scsi3,reg=8192 \ -device pvscsi,id=scsi4,bus=pci.0,addr=0x5 \ -blockdev '{"driver":"host_device","filename":"/dev/HostVG/QEMUGuest1","node-name":"libvirt-6-storage","auto-read-only":true,"discard":"unmap"}' \ -blockdev '{"node-name":"libvirt-6-format","read-only":false,"driver":"raw","file":"libvirt-6-storage"}' \ diff --git a/tests/qemuxml2argvdata/pseries-vio-user-assigned.args b/tests/qemuxml2argvdata/pseries-vio-user-assigned.args index 5295cfaca4..dfc3ad0d1b 100644 --- a/tests/qemuxml2argvdata/pseries-vio-user-assigned.args +++ b/tests/qemuxml2argvdata/pseries-vio-user-assigned.args @@ -24,8 +24,8 @@ QEMU_AUDIO_DRV=none \ -rtc base=utc \ -no-shutdown \ -boot strict=on \ --device spapr-vscsi,id=scsi0,reg=0x00002000 \ --device spapr-vscsi,id=scsi1,reg=0x30000000 \ +-device spapr-vscsi,id=scsi0,reg=8192 \ +-device spapr-vscsi,id=scsi1,reg=805306368 \ -usb \ -drive file=/tmp/scsidisk.img,format=raw,if=none,id=drive-scsi1-0-0-0 \ -device scsi-hd,bus=scsi1.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi1-0-0-0,id=scsi1-0-0-0,bootindex=1 \ diff --git a/tests/qemuxml2argvdata/pseries-vio.args b/tests/qemuxml2argvdata/pseries-vio.args index f179e89cd2..a8e18fae5a 100644 --- a/tests/qemuxml2argvdata/pseries-vio.args +++ b/tests/qemuxml2argvdata/pseries-vio.args @@ -24,8 +24,8 @@ QEMU_AUDIO_DRV=none \ -rtc base=utc \ -no-shutdown \ -boot strict=on \ --device spapr-vscsi,id=scsi0,reg=0x00002000 \ --device spapr-vscsi,id=scsi1,reg=0x00003000 \ +-device spapr-vscsi,id=scsi0,reg=8192 \ +-device spapr-vscsi,id=scsi1,reg=12288 \ -usb \ -drive file=/tmp/scsidisk.img,format=raw,if=none,id=drive-scsi1-0-0-0 \ -device scsi-hd,bus=scsi1.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi1-0-0-0,id=scsi1-0-0-0,bootindex=1 \ diff --git a/tests/qemuxml2argvdata/tpm-emulator-spapr.ppc64-latest.args b/tests/qemuxml2argvdata/tpm-emulator-spapr.ppc64-latest.args index 29151a0084..04d632c091 100644 --- a/tests/qemuxml2argvdata/tpm-emulator-spapr.ppc64-latest.args +++ b/tests/qemuxml2argvdata/tpm-emulator-spapr.ppc64-latest.args @@ -26,8 +26,8 @@ XDG_CONFIG_HOME=/tmp/lib/domain--1-TPM-VM/.config \ -no-shutdown \ -boot menu=on,strict=on \ -device pci-ohci,id=usb,bus=pci.0,addr=0x1 \ --device spapr-vscsi,id=scsi0,reg=0x00002000 \ --device spapr-vscsi,id=scsi1,reg=0x00003000 \ +-device spapr-vscsi,id=scsi0,reg=8192 \ +-device spapr-vscsi,id=scsi1,reg=12288 \ -blockdev '{"driver":"file","filename":"/tmp/scsidisk.img","node-name":"libvirt-1-storage","auto-read-only":true,"discard":"unmap"}' \ -blockdev '{"node-name":"libvirt-1-format","read-only":false,"driver":"raw","file":"libvirt-1-storage"}' \ -device scsi-hd,bus=scsi1.0,channel=0,scsi-id=0,lun=0,device_id=drive-scsi1-0-0-0,drive=libvirt-1-format,id=scsi1-0-0-0,bootindex=1 \ -- 2.31.1