The types for the special fields of the 'virtio-blk-pci' according to
QEMU are:
  iothread=<link<iothread>>
  ioeventfd=<bool>       - on/off (default: true)
  event_idx=<bool>       - on/off (default: true)
  scsi=<bool>            - on/off (default: false)
  num-queues=<uint16>    -  (default: 65535)
  queue-size=<uint16>    -  (default: 256)

For all disks we also use the following properties (based on 'scsi-hd'):
  device_id=<str>
  share-rw=<bool>        -  (default: false)
  drive=<str>            - Node name or ID of a block device to use as a backend
  chardev=<str>          - ID of a chardev to use as a backend  <-  
vhost-user-blk-pci
  bootindex=<int32>
  logical_block_size=<size> - A power of two between 512 B and 2 MiB (default: 
0)
  physical_block_size=<size> - A power of two between 512 B and 2 MiB (default: 
0)
  wwn=<uint64>           -  (default: 0)
  rotation_rate=<uint16> -  (default: 0)
  vendor=<str>
  product=<str>
  removable=<bool>       - on/off (default: false)
  write-cache=<OnOffAuto> - on/off/auto (default: "auto")
  cyls=<uint32>          -  (default: 0)
  heads=<uint32>         -  (default: 0)
  secs=<uint32>          -  (default: 0)
  bios-chs-trans=<BiosAtaTranslation> - Logical CHS translation algorithm, 
auto/none/lba/large/rechs (default: "auto") <- ide-hd
  serial=<str>
  werror=<BlockdevOnError> - Error handling policy, 
report/ignore/enospc/stop/auto (default: "auto")
  rerror=<BlockdevOnError> - Error handling policy, 
report/ignore/enospc/stop/auto (default: "auto")

The 'wwn' field is changed from a hex string to a number since qemu
actually treats it as a number.

Signed-off-by: Peter Krempa <pkre...@redhat.com>
---
 src/qemu/qemu_command.c                       | 360 +++++++-----------
 src/qemu/qemu_command.h                       |   8 +-
 src/qemu/qemu_hotplug.c                       |   6 +-
 .../disk-ide-wwn.x86_64-latest.args           |   2 +-
 .../disk-scsi-disk-wwn.x86_64-latest.args     |   4 +-
 .../disk-scsi.x86_64-latest.args              |   2 +-
 6 files changed, 146 insertions(+), 236 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index a13332f8f5..a8a93274c6 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -1995,31 +1995,6 @@ 
qemuBuildDiskFrontendAttributeErrorPolicy(virDomainDiskDef *disk,
 }


-static void
-qemuBuildDiskFrontendAttributes(virDomainDiskDef *disk,
-                                virBuffer *buf)
-{
-    /* generate geometry command string */
-    if (disk->geometry.cylinders > 0 &&
-        disk->geometry.heads > 0 &&
-        disk->geometry.sectors > 0) {
-        virBufferAsprintf(buf, ",cyls=%u,heads=%u,secs=%u",
-                          disk->geometry.cylinders,
-                          disk->geometry.heads,
-                          disk->geometry.sectors);
-
-        if (disk->geometry.trans != VIR_DOMAIN_DISK_TRANS_DEFAULT)
-            virBufferAsprintf(buf, ",bios-chs-trans=%s",
-                              
virDomainDiskGeometryTransTypeToString(disk->geometry.trans));
-    }
-
-    if (disk->serial) {
-        virBufferAddLit(buf, ",serial=");
-        virBufferEscape(buf, '\\', " ", "%s", disk->serial);
-    }
-}
-
-
 static char *
 qemuBuildDriveStr(virDomainDiskDef *disk,
                   virQEMUCaps *qemuCaps)
@@ -2092,82 +2067,46 @@ qemuBuildDriveStr(virDomainDiskDef *disk,
 }


-static int
-qemuBuildDriveDevCacheStr(virDomainDiskDef *disk,
-                          virBuffer *buf,
-                          virQEMUCaps *qemuCaps)
-{
-    bool wb;
-
-    if (disk->cachemode == VIR_DOMAIN_DISK_CACHE_DEFAULT)
-        return 0;
-
-    /* VIR_DOMAIN_DISK_DEVICE_LUN translates into 'scsi-block'
-     * where any caching setting makes no sense. */
-    if (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN)
-        return 0;
-
-    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DISK_WRITE_CACHE))
-        return 0;
-
-    if (qemuDomainDiskCachemodeFlags(disk->cachemode, &wb, NULL, NULL) < 0)
-        return -1;
-
-    virBufferStrcat(buf, ",write-cache=",
-                    
virTristateSwitchTypeToString(virTristateSwitchFromBool(wb)),
-                    NULL);
-
-    return 0;
-}
-
-
-char *
-qemuBuildDiskDeviceStr(const virDomainDef *def,
-                       virDomainDiskDef *disk,
-                       virQEMUCaps *qemuCaps)
+virJSONValue *
+qemuBuildDiskDeviceProps(const virDomainDef *def,
+                         virDomainDiskDef *disk,
+                         virQEMUCaps *qemuCaps)
 {
-    g_auto(virBuffer) opt = VIR_BUFFER_INITIALIZER;
-    const char *contAlias;
-    g_autofree char *backendAlias = NULL;
+    g_autoptr(virJSONValue) props = NULL;
+    const char *driver = NULL;
     g_autofree char *scsiVPDDeviceId = NULL;
-    int controllerModel;
+    virTristateSwitch shareRW = VIR_TRISTATE_SWITCH_ABSENT;
+    g_autofree char *chardev = NULL;
+    g_autofree char *drive = NULL;
+    unsigned int bootindex = 0;
+    unsigned int logical_block_size = 0;
+    unsigned int physical_block_size = 0;
+    g_autoptr(virJSONValue) wwn = NULL;
+    g_autofree char *serial = NULL;
+    virTristateSwitch removable = VIR_TRISTATE_SWITCH_ABSENT;
+    virTristateSwitch writeCache = VIR_TRISTATE_SWITCH_ABSENT;
+    const char *biosCHSTrans = NULL;
+    const char *wpolicy = NULL;
+    const char *rpolicy = NULL;

     switch ((virDomainDiskBus) disk->bus) {
     case VIR_DOMAIN_DISK_BUS_IDE:
+    case VIR_DOMAIN_DISK_BUS_SATA:
         if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM)
-            virBufferAddLit(&opt, "ide-cd");
+            driver = "ide-cd";
         else
-            virBufferAddLit(&opt, "ide-hd");
+            driver = "ide-hd";

-        /* When domain has builtin IDE controller we don't put it onto cmd
-         * line. Therefore we can't set its alias. In that case, use the
-         * default one. */
-        if (qemuDomainHasBuiltinIDE(def)) {
-            contAlias = "ide";
-        } else {
-            if (!(contAlias = virDomainControllerAliasFind(def,
-                                                           
VIR_DOMAIN_CONTROLLER_TYPE_IDE,
-                                                           
disk->info.addr.drive.controller)))
-                return NULL;
-        }
-        virBufferAsprintf(&opt, ",bus=%s.%d,unit=%d",
-                          contAlias,
-                          disk->info.addr.drive.bus,
-                          disk->info.addr.drive.unit);
         break;

     case VIR_DOMAIN_DISK_BUS_SCSI:
-        controllerModel = qemuDomainFindSCSIControllerModel(def, &disk->info);
-        if (controllerModel < 0)
-            return NULL;
-
         if (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) {
-            virBufferAddLit(&opt, "scsi-block");
+            driver = "scsi-block";
         } else {
             if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM)
-                virBufferAddLit(&opt, "scsi-cd");
+                driver = "scsi-cd";
             else
-                virBufferAddLit(&opt, "scsi-hd");
+                driver = "scsi-hd";

             /* qemu historically used the name of -drive as one of the device
              * ids in the Vital Product Data Device Identification page if
@@ -2184,116 +2123,56 @@ qemuBuildDiskDeviceStr(const virDomainDef *def,
             }
         }

-        if (!(contAlias = virDomainControllerAliasFind(def, 
VIR_DOMAIN_CONTROLLER_TYPE_SCSI,
-                                                       
disk->info.addr.drive.controller)))
-           return NULL;
-
-        switch ((virDomainControllerModelSCSI)controllerModel) {
-        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC:
-        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_NCR53C90:
-        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_DC390:
-        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_AM53C974:
-            virBufferAsprintf(&opt, ",bus=%s.%d,scsi-id=%d",
-                              contAlias,
-                              disk->info.addr.drive.bus,
-                              disk->info.addr.drive.unit);
-            break;
-
-        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_AUTO:
-        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_BUSLOGIC:
-        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSISAS1068:
-        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VMPVSCSI:
-        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_IBMVSCSI:
-        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI:
-        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSISAS1078:
-        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_TRANSITIONAL:
-        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_NON_TRANSITIONAL:
-            virBufferAsprintf(&opt, ",bus=%s.0,channel=%d,scsi-id=%d,lun=%d",
-                              contAlias,
-                              disk->info.addr.drive.bus,
-                              disk->info.addr.drive.target,
-                              disk->info.addr.drive.unit);
-            break;
-
-        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_DEFAULT:
-        case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LAST:
-            virReportError(VIR_ERR_INTERNAL_ERROR,
-                           _("Unexpected SCSI controller model %d"),
-                           controllerModel);
-            return NULL;
-        }
-
-        if (scsiVPDDeviceId)
-            virBufferStrcat(&opt, ",device_id=", scsiVPDDeviceId, NULL);
-
         break;

-    case VIR_DOMAIN_DISK_BUS_SATA:
-        if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM)
-            virBufferAddLit(&opt, "ide-cd");
-        else
-            virBufferAddLit(&opt, "ide-hd");
-
-        /* When domain has builtin SATA controller we don't put it onto cmd
-         * line. Therefore we can't set its alias. In that case, use the
-         * default one. */
-        if (qemuDomainIsQ35(def) &&
-            disk->info.addr.drive.controller == 0) {
-            contAlias = "ide";
-        } else {
-            if (!(contAlias = virDomainControllerAliasFind(def,
-                                                           
VIR_DOMAIN_CONTROLLER_TYPE_SATA,
-                                                           
disk->info.addr.drive.controller)))
-                return NULL;
-        }
-        virBufferAsprintf(&opt, ",bus=%s.%d",
-                          contAlias,
-                          disk->info.addr.drive.unit);
-        break;
+    case VIR_DOMAIN_DISK_BUS_VIRTIO: {
+        virTristateSwitch scsi = VIR_TRISTATE_SWITCH_ABSENT;
+        g_autofree char *iothread = NULL;

-    case VIR_DOMAIN_DISK_BUS_VIRTIO:
-        if (qemuBuildVirtioDevStr(&opt, qemuCaps, VIR_DOMAIN_DEVICE_DISK, 
disk) < 0)
-            return NULL;
+        if (disk->iothread > 0)
+            iothread = g_strdup_printf("iothread%u", disk->iothread);

-        if (disk->iothread)
-            virBufferAsprintf(&opt, ",iothread=iothread%u", disk->iothread);
-
-        qemuBuildIoEventFdStr(&opt, disk->ioeventfd, qemuCaps);
-        if (disk->event_idx) {
-            virBufferAsprintf(&opt, ",event_idx=%s",
-                              virTristateSwitchTypeToString(disk->event_idx));
-        }
-        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_BLK_SCSI) &&
-            !(virQEMUCapsGet(qemuCaps, 
QEMU_CAPS_VIRTIO_BLK_SCSI_DEFAULT_DISABLED) &&
-              disk->device != VIR_DOMAIN_DISK_DEVICE_LUN)) {
+        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_BLK_SCSI)) {
             /* if sg_io is true but the scsi option isn't supported,
              * that means it's just always on in this version of qemu.
              */
-            virBufferAsprintf(&opt, ",scsi=%s",
-                              (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN)
-                              ? "on" : "off");
+            if (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) {
+                scsi = VIR_TRISTATE_SWITCH_ON;
+            } else {
+                if (!virQEMUCapsGet(qemuCaps, 
QEMU_CAPS_VIRTIO_BLK_SCSI_DEFAULT_DISABLED))
+                    scsi = VIR_TRISTATE_SWITCH_OFF;
+            }
         }

-        if (disk->queues) {
-            virBufferAsprintf(&opt, ",num-queues=%u", disk->queues);
-        }
-        if (disk->queue_size > 0) {
-            virBufferAsprintf(&opt, ",queue-size=%u", disk->queue_size);
-        }
+        if (!(props = qemuBuildVirtioDevProps(VIR_DOMAIN_DEVICE_DISK, disk, 
qemuCaps)))
+            return NULL;

-        if (qemuBuildDeviceAddressStr(&opt, def, &disk->info) < 0)
+        if (virJSONValueObjectAdd(props,
+                                  "S:iothread", iothread,
+                                  "T:ioeventfd", disk->ioeventfd,
+                                  "T:event_idx", disk->event_idx,
+                                  "T:scsi", scsi,
+                                  "p:num-queues", disk->queues,
+                                  "p:queue-size", disk->queue_size,
+                                  NULL) < 0)
             return NULL;
+    }
         break;

     case VIR_DOMAIN_DISK_BUS_USB:
-        virBufferAddLit(&opt, "usb-storage");
+        driver = "usb-storage";
+
+        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_USB_STORAGE_REMOVABLE)) {
+            if (disk->removable == VIR_TRISTATE_SWITCH_ABSENT)
+                removable = VIR_TRISTATE_SWITCH_OFF;
+            else
+                removable = disk->removable;
+        }

-        if (qemuBuildDeviceAddressStr(&opt, def, &disk->info) < 0)
-            return NULL;
         break;

     case VIR_DOMAIN_DISK_BUS_FDC:
-        virBufferAsprintf(&opt, "floppy,unit=%d", disk->info.addr.drive.unit);
+        driver = "floppy";
         break;

     case VIR_DOMAIN_DISK_BUS_XEN:
@@ -2308,74 +2187,105 @@ qemuBuildDiskDeviceStr(const virDomainDef *def,
         return NULL;
     }

+    if (driver) {
+        if (virJSONValueObjectCreate(&props,
+                                     "s:driver", driver,
+                                     NULL) < 0)
+            return NULL;
+    }
+
+    if (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE)
+        disk->info.addr.drive.diskbus = disk->bus;
+
+    if (qemuBuildDeviceAddressProps(props, def, &disk->info) < 0)
+        return NULL;
+
     if (disk->src->shared &&
         virQEMUCapsGet(qemuCaps, QEMU_CAPS_DISK_SHARE_RW))
-        virBufferAddLit(&opt, ",share-rw=on");
+        shareRW = VIR_TRISTATE_SWITCH_ON;

     if (virStorageSourceGetActualType(disk->src) == 
VIR_STORAGE_TYPE_VHOST_USER) {
-        backendAlias = qemuDomainGetVhostUserChrAlias(disk->info.alias);
-
-        virBufferAsprintf(&opt, ",chardev=%s", backendAlias);
+        chardev = qemuDomainGetVhostUserChrAlias(disk->info.alias);
     } else {
-        if (qemuDomainDiskGetBackendAlias(disk, qemuCaps, &backendAlias) < 0)
+        if (qemuDomainDiskGetBackendAlias(disk, qemuCaps, &drive) < 0)
             return NULL;
-
-        if (backendAlias)
-            virBufferAsprintf(&opt, ",drive=%s", backendAlias);
     }

-    virBufferAsprintf(&opt, ",id=%s", disk->info.alias);
     /* bootindex for floppies is configured via the fdc controller */
-    if (disk->device != VIR_DOMAIN_DISK_DEVICE_FLOPPY &&
-        disk->info.effectiveBootIndex > 0)
-        virBufferAsprintf(&opt, ",bootindex=%u", 
disk->info.effectiveBootIndex);
+    if (disk->device != VIR_DOMAIN_DISK_DEVICE_FLOPPY)
+        bootindex = disk->info.effectiveBootIndex;
+
     if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BLOCKIO)) {
-        if (disk->blockio.logical_block_size > 0)
-            virBufferAsprintf(&opt, ",logical_block_size=%u",
-                              disk->blockio.logical_block_size);
-        if (disk->blockio.physical_block_size > 0)
-            virBufferAsprintf(&opt, ",physical_block_size=%u",
-                              disk->blockio.physical_block_size);
+        logical_block_size = disk->blockio.logical_block_size;
+        physical_block_size = disk->blockio.physical_block_size;
     }

     if (disk->wwn) {
-        if (STRPREFIX(disk->wwn, "0x"))
-            virBufferAsprintf(&opt, ",wwn=%s", disk->wwn);
-        else
-            virBufferAsprintf(&opt, ",wwn=0x%s", disk->wwn);
-    }
+        unsigned long long w = 0;

-    if (disk->rotation_rate)
-        virBufferAsprintf(&opt, ",rotation_rate=%u", disk->rotation_rate);
+        if (virStrToLong_ull(disk->wwn, NULL, 16, &w) < 0) {
+            virReportError(VIR_ERR_INVALID_ARG,
+                           _("Failed to parse wwn '%s' as number"), disk->wwn);
+            return NULL;
+        }

-    if (disk->vendor) {
-        virBufferAddLit(&opt, ",vendor=");
-        virQEMUBuildBufferEscapeComma(&opt, disk->vendor);
+        wwn = virJSONValueNewNumberUlong(w);
     }

-    if (disk->product) {
-        virBufferAddLit(&opt, ",product=");
-        virQEMUBuildBufferEscapeComma(&opt, disk->product);
-    }
+    if (disk->cachemode != VIR_DOMAIN_DISK_CACHE_DEFAULT) {
+        /* VIR_DOMAIN_DISK_DEVICE_LUN translates into 'scsi-block'
+         * where any caching setting makes no sense. */
+        if (disk->device != VIR_DOMAIN_DISK_DEVICE_LUN &&
+            virQEMUCapsGet(qemuCaps, QEMU_CAPS_DISK_WRITE_CACHE)) {
+            bool wb;

-    if (disk->bus == VIR_DOMAIN_DISK_BUS_USB) {
-        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_USB_STORAGE_REMOVABLE)) {
-            if (disk->removable == VIR_TRISTATE_SWITCH_ON)
-                virBufferAddLit(&opt, ",removable=on");
-            else
-                virBufferAddLit(&opt, ",removable=off");
+            if (qemuDomainDiskCachemodeFlags(disk->cachemode, &wb, NULL,
+                                             NULL) < 0)
+                return NULL;
+
+            writeCache = virTristateSwitchFromBool(wb);
         }
     }

-    if (qemuBuildDriveDevCacheStr(disk, &opt, qemuCaps) < 0)
-        return NULL;
+    if (disk->geometry.trans != VIR_DOMAIN_DISK_TRANS_DEFAULT)
+        biosCHSTrans = 
virDomainDiskGeometryTransTypeToString(disk->geometry.trans);

-    qemuBuildDiskFrontendAttributes(disk, &opt);
+    if (disk->serial) {
+        virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+        virBufferEscape(&buf, '\\', " ", "%s", disk->serial);
+        serial = virBufferContentAndReset(&buf);
+    }

     if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_STORAGE_WERROR))
-        qemuBuildDiskFrontendAttributeErrorPolicy(disk, &opt);
+        qemuBuildDiskGetErrorPolicy(disk, &wpolicy, &rpolicy);

-    return virBufferContentAndReset(&opt);
+    if (virJSONValueObjectAdd(props,
+                              "S:device_id", scsiVPDDeviceId,
+                              "T:share-rw", shareRW,
+                              "S:drive", drive,
+                              "S:chardev", chardev,
+                              "s:id", disk->info.alias,
+                              "p:bootindex", bootindex,
+                              "p:logical_block_size", logical_block_size,
+                              "p:physical_block_size", physical_block_size,
+                              "A:wwn", &wwn,
+                              "p:rotation_rate", disk->rotation_rate,
+                              "S:vendor", disk->vendor,
+                              "S:product", disk->product,
+                              "T:removable", removable,
+                              "S:write-cache", qemuOnOffAuto(writeCache),
+                              "p:cyls", disk->geometry.cylinders,
+                              "p:heads", disk->geometry.heads,
+                              "p:secs", disk->geometry.sectors,
+                              "S:bios-chs-trans", biosCHSTrans,
+                              "S:serial", serial,
+                              "S:werror", wpolicy,
+                              "S:rerror", rpolicy,
+                              NULL) < 0)
+        return NULL;
+
+    return g_steal_pointer(&props);
 }


@@ -2605,7 +2515,7 @@ qemuBuildDiskCommandLine(virCommand *cmd,
                          virDomainDiskDef *disk,
                          virQEMUCaps *qemuCaps)
 {
-    g_autofree char *optstr = NULL;
+    g_autoptr(virJSONValue) devprops = NULL;

     if (qemuBuildDiskSourceCommandLine(cmd, disk, qemuCaps) < 0)
         return -1;
@@ -2624,11 +2534,11 @@ qemuBuildDiskCommandLine(virCommand *cmd,
     if (qemuCommandAddExtDevice(cmd, &disk->info, qemuCaps) < 0)
         return -1;

-    virCommandAddArg(cmd, "-device");
+    if (!(devprops = qemuBuildDiskDeviceProps(def, disk, qemuCaps)))
+        return -1;

-    if (!(optstr = qemuBuildDiskDeviceStr(def, disk, qemuCaps)))
+    if (qemuBuildDeviceCommandlineFromJSON(cmd, devprops, qemuCaps) < 0)
         return -1;
-    virCommandAddArg(cmd, optstr);

     return 0;
 }
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index 5b1b727b84..18d4c4130b 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -134,10 +134,10 @@ qemuBlockStorageSourceChainData *
 qemuBuildStorageSourceChainAttachPrepareBlockdevTop(virStorageSource *top,
                                                     virStorageSource 
*backingStore);

-char
-*qemuBuildDiskDeviceStr(const virDomainDef *def,
-                        virDomainDiskDef *disk,
-                        virQEMUCaps *qemuCaps);
+virJSONValue *
+qemuBuildDiskDeviceProps(const virDomainDef *def,
+                         virDomainDiskDef *disk,
+                         virQEMUCaps *qemuCaps);

 char *
 qemuBuildVHostUserFsDevStr(virDomainFSDef *fs,
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 28cafd11d2..1b5f63f271 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -710,7 +710,7 @@ qemuDomainAttachDiskGeneric(virQEMUDriver *driver,
 {
     g_autoptr(qemuBlockStorageSourceChainData) data = NULL;
     qemuDomainObjPrivate *priv = vm->privateData;
-    g_autofree char *devstr = NULL;
+    g_autoptr(virJSONValue) devprops = NULL;
     bool blockdev = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV);
     bool extensionDeviceAttached = false;
     int rc;
@@ -772,7 +772,7 @@ qemuDomainAttachDiskGeneric(virQEMUDriver *driver,
         ignore_value(VIR_INSERT_ELEMENT(data->srcdata, 0, data->nsrcdata, 
backend));
     }

-    if (!(devstr = qemuBuildDiskDeviceStr(vm->def, disk, priv->qemuCaps)))
+    if (!(devprops = qemuBuildDiskDeviceProps(vm->def, disk, priv->qemuCaps)))
         goto rollback;

     if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
@@ -782,7 +782,7 @@ qemuDomainAttachDiskGeneric(virQEMUDriver *driver,
         extensionDeviceAttached = true;

     if (rc == 0)
-        rc = qemuMonitorAddDevice(priv->mon, devstr);
+        rc = qemuMonitorAddDeviceProps(priv->mon, &devprops);

     /* Setup throttling of disk via block_set_io_throttle QMP command. This
      * is a hack until the 'throttle' blockdev driver will support modification
diff --git a/tests/qemuxml2argvdata/disk-ide-wwn.x86_64-latest.args 
b/tests/qemuxml2argvdata/disk-ide-wwn.x86_64-latest.args
index 9a74262c15..8560754c24 100644
--- a/tests/qemuxml2argvdata/disk-ide-wwn.x86_64-latest.args
+++ b/tests/qemuxml2argvdata/disk-ide-wwn.x86_64-latest.args
@@ -29,7 +29,7 @@ XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \
 -device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \
 -blockdev 
'{"driver":"host_device","filename":"/dev/HostVG/QEMUGuest1","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 
ide-hd,bus=ide.0,unit=1,drive=libvirt-1-format,id=ide0-0-1,bootindex=1,wwn=0x5000c50015ea71ad,serial=WD-WMAP9A966149
 \
+-device 
ide-hd,bus=ide.0,unit=1,drive=libvirt-1-format,id=ide0-0-1,bootindex=1,wwn=5764824127192592813,serial=WD-WMAP9A966149
 \
 -audiodev id=audio1,driver=none \
 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x2 \
 -sandbox 
on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
diff --git a/tests/qemuxml2argvdata/disk-scsi-disk-wwn.x86_64-latest.args 
b/tests/qemuxml2argvdata/disk-scsi-disk-wwn.x86_64-latest.args
index 7648bfdc4e..887d2219af 100644
--- a/tests/qemuxml2argvdata/disk-scsi-disk-wwn.x86_64-latest.args
+++ b/tests/qemuxml2argvdata/disk-scsi-disk-wwn.x86_64-latest.args
@@ -31,10 +31,10 @@ XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \
 -device lsi,id=scsi1,bus=pci.0,addr=0x3 \
 -blockdev 
'{"driver":"host_device","filename":"/dev/HostVG/QEMUGuest1","node-name":"libvirt-2-storage","auto-read-only":true,"discard":"unmap"}'
 \
 -blockdev 
'{"node-name":"libvirt-2-format","read-only":true,"driver":"raw","file":"libvirt-2-storage"}'
 \
--device 
scsi-cd,bus=scsi0.0,channel=0,scsi-id=1,lun=0,device_id=WD-WMAP9A966149,drive=libvirt-2-format,id=scsi0-0-1-0,wwn=0x5000c50015ea71ac,serial=WD-WMAP9A966149
 \
+-device 
scsi-cd,bus=scsi0.0,channel=0,scsi-id=1,lun=0,device_id=WD-WMAP9A966149,drive=libvirt-2-format,id=scsi0-0-1-0,wwn=5764824127192592812,serial=WD-WMAP9A966149
 \
 -blockdev 
'{"driver":"host_device","filename":"/dev/HostVG/QEMUGuest2","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=scsi0.0,channel=0,scsi-id=0,lun=0,device_id=drive-scsi0-0-0-0,drive=libvirt-1-format,id=scsi0-0-0-0,bootindex=1,wwn=0x5000c50015ea71ad
 \
+-device 
scsi-hd,bus=scsi0.0,channel=0,scsi-id=0,lun=0,device_id=drive-scsi0-0-0-0,drive=libvirt-1-format,id=scsi0-0-0-0,bootindex=1,wwn=5764824127192592813
 \
 -audiodev id=audio1,driver=none \
 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4 \
 -sandbox 
on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
diff --git a/tests/qemuxml2argvdata/disk-scsi.x86_64-latest.args 
b/tests/qemuxml2argvdata/disk-scsi.x86_64-latest.args
index bcd998a968..d9971582ac 100644
--- a/tests/qemuxml2argvdata/disk-scsi.x86_64-latest.args
+++ b/tests/qemuxml2argvdata/disk-scsi.x86_64-latest.args
@@ -43,7 +43,7 @@ XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \
 -device 
scsi-hd,bus=scsi1.0,channel=0,scsi-id=0,lun=0,device_id=abcdefghijklmn,drive=libvirt-4-format,id=scsi1-0-0-0,serial=abcdefghijklmn
 \
 -blockdev 
'{"driver":"file","filename":"/tmp/scsidisk3.img","node-name":"libvirt-3-storage","auto-read-only":true,"discard":"unmap"}'
 \
 -blockdev 
'{"node-name":"libvirt-3-format","read-only":false,"driver":"raw","file":"libvirt-3-storage"}'
 \
--device 
scsi-hd,bus=scsi2.0,channel=0,scsi-id=0,lun=0,device_id=drive-scsi2-0-0-0,drive=libvirt-3-format,id=scsi2-0-0-0,wwn=0x5000c50015ea71ac
 \
+-device 
scsi-hd,bus=scsi2.0,channel=0,scsi-id=0,lun=0,device_id=drive-scsi2-0-0-0,drive=libvirt-3-format,id=scsi2-0-0-0,wwn=5764824127192592812
 \
 -blockdev 
'{"driver":"file","filename":"/tmp/scsidisk4.img","node-name":"libvirt-2-storage","auto-read-only":true,"discard":"unmap"}'
 \
 -blockdev 
'{"node-name":"libvirt-2-format","read-only":false,"driver":"raw","file":"libvirt-2-storage"}'
 \
 -device 
scsi-hd,bus=scsi3.0,channel=0,scsi-id=0,lun=0,device_id=drive-scsi3-0-0-0,drive=libvirt-2-format,id=scsi3-0-0-0
 \
-- 
2.31.1

Reply via email to