qemuBuildDiskCommandLine: Generate via JSON

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 <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
Peter Krempa 2021-10-04 16:54:54 +02:00
parent d06e3000c4
commit dc481f11a6
6 changed files with 154 additions and 244 deletions

View File

@ -2002,31 +2002,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 * static char *
qemuBuildDriveStr(virDomainDiskDef *disk, qemuBuildDriveStr(virDomainDiskDef *disk,
virQEMUCaps *qemuCaps) virQEMUCaps *qemuCaps)
@ -2099,82 +2074,46 @@ qemuBuildDriveStr(virDomainDiskDef *disk,
} }
static int virJSONValue *
qemuBuildDriveDevCacheStr(virDomainDiskDef *disk, qemuBuildDiskDeviceProps(const virDomainDef *def,
virBuffer *buf, virDomainDiskDef *disk,
virQEMUCaps *qemuCaps) virQEMUCaps *qemuCaps)
{ {
bool wb; g_autoptr(virJSONValue) props = NULL;
const char *driver = NULL;
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)
{
g_auto(virBuffer) opt = VIR_BUFFER_INITIALIZER;
const char *contAlias;
g_autofree char *backendAlias = NULL;
g_autofree char *scsiVPDDeviceId = 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) { switch ((virDomainDiskBus) disk->bus) {
case VIR_DOMAIN_DISK_BUS_IDE: case VIR_DOMAIN_DISK_BUS_IDE:
case VIR_DOMAIN_DISK_BUS_SATA:
if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM)
virBufferAddLit(&opt, "ide-cd"); driver = "ide-cd";
else 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; break;
case VIR_DOMAIN_DISK_BUS_SCSI: case VIR_DOMAIN_DISK_BUS_SCSI:
controllerModel = qemuDomainFindSCSIControllerModel(def, &disk->info);
if (controllerModel < 0)
return NULL;
if (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) { if (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) {
virBufferAddLit(&opt, "scsi-block"); driver = "scsi-block";
} else { } else {
if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM)
virBufferAddLit(&opt, "scsi-cd"); driver = "scsi-cd";
else else
virBufferAddLit(&opt, "scsi-hd"); driver = "scsi-hd";
/* qemu historically used the name of -drive as one of the device /* qemu historically used the name of -drive as one of the device
* ids in the Vital Product Data Device Identification page if * ids in the Vital Product Data Device Identification page if
@ -2191,116 +2130,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; break;
case VIR_DOMAIN_DISK_BUS_SATA: case VIR_DOMAIN_DISK_BUS_VIRTIO: {
if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) virTristateSwitch scsi = VIR_TRISTATE_SWITCH_ABSENT;
virBufferAddLit(&opt, "ide-cd"); g_autofree char *iothread = NULL;
else
virBufferAddLit(&opt, "ide-hd");
/* When domain has builtin SATA controller we don't put it onto cmd if (disk->iothread > 0)
* line. Therefore we can't set its alias. In that case, use the iothread = g_strdup_printf("iothread%u", disk->iothread);
* 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: if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_BLK_SCSI)) {
if (qemuBuildVirtioDevStr(&opt, qemuCaps, VIR_DOMAIN_DEVICE_DISK, disk) < 0)
return NULL;
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 sg_io is true but the scsi option isn't supported, /* if sg_io is true but the scsi option isn't supported,
* that means it's just always on in this version of qemu. * that means it's just always on in this version of qemu.
*/ */
virBufferAsprintf(&opt, ",scsi=%s", if (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) {
(disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) scsi = VIR_TRISTATE_SWITCH_ON;
? "on" : "off"); } else {
if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_BLK_SCSI_DEFAULT_DISABLED))
scsi = VIR_TRISTATE_SWITCH_OFF;
}
} }
if (disk->queues) { if (!(props = qemuBuildVirtioDevProps(VIR_DOMAIN_DEVICE_DISK, disk, qemuCaps)))
virBufferAsprintf(&opt, ",num-queues=%u", disk->queues);
}
if (disk->queue_size > 0) {
virBufferAsprintf(&opt, ",queue-size=%u", disk->queue_size);
}
if (qemuBuildDeviceAddressStr(&opt, def, &disk->info) < 0)
return NULL; return NULL;
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; break;
case VIR_DOMAIN_DISK_BUS_USB: 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; break;
case VIR_DOMAIN_DISK_BUS_FDC: case VIR_DOMAIN_DISK_BUS_FDC:
virBufferAsprintf(&opt, "floppy,unit=%d", disk->info.addr.drive.unit); driver = "floppy";
break; break;
case VIR_DOMAIN_DISK_BUS_XEN: case VIR_DOMAIN_DISK_BUS_XEN:
@ -2315,74 +2194,105 @@ qemuBuildDiskDeviceStr(const virDomainDef *def,
return NULL; return NULL;
} }
if (disk->src->shared && if (driver) {
virQEMUCapsGet(qemuCaps, QEMU_CAPS_DISK_SHARE_RW)) if (virJSONValueObjectCreate(&props,
virBufferAddLit(&opt, ",share-rw=on"); "s:driver", driver,
NULL) < 0)
if (virStorageSourceGetActualType(disk->src) == VIR_STORAGE_TYPE_VHOST_USER) { return NULL;
backendAlias = qemuDomainGetVhostUserChrAlias(disk->info.alias); }
virBufferAsprintf(&opt, ",chardev=%s", backendAlias); if (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE)
} else { disk->info.addr.drive.diskbus = disk->bus;
if (qemuDomainDiskGetBackendAlias(disk, qemuCaps, &backendAlias) < 0)
if (qemuBuildDeviceAddressProps(props, def, &disk->info) < 0)
return NULL;
if (disk->src->shared &&
virQEMUCapsGet(qemuCaps, QEMU_CAPS_DISK_SHARE_RW))
shareRW = VIR_TRISTATE_SWITCH_ON;
if (virStorageSourceGetActualType(disk->src) == VIR_STORAGE_TYPE_VHOST_USER) {
chardev = qemuDomainGetVhostUserChrAlias(disk->info.alias);
} else {
if (qemuDomainDiskGetBackendAlias(disk, qemuCaps, &drive) < 0)
return NULL; 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 */ /* bootindex for floppies is configured via the fdc controller */
if (disk->device != VIR_DOMAIN_DISK_DEVICE_FLOPPY && if (disk->device != VIR_DOMAIN_DISK_DEVICE_FLOPPY)
disk->info.effectiveBootIndex > 0) bootindex = disk->info.effectiveBootIndex;
virBufferAsprintf(&opt, ",bootindex=%u", disk->info.effectiveBootIndex);
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BLOCKIO)) { if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BLOCKIO)) {
if (disk->blockio.logical_block_size > 0) logical_block_size = disk->blockio.logical_block_size;
virBufferAsprintf(&opt, ",logical_block_size=%u", physical_block_size = disk->blockio.physical_block_size;
disk->blockio.logical_block_size);
if (disk->blockio.physical_block_size > 0)
virBufferAsprintf(&opt, ",physical_block_size=%u",
disk->blockio.physical_block_size);
} }
if (disk->wwn) { if (disk->wwn) {
if (STRPREFIX(disk->wwn, "0x")) unsigned long long w = 0;
virBufferAsprintf(&opt, ",wwn=%s", disk->wwn);
else if (virStrToLong_ull(disk->wwn, NULL, 16, &w) < 0) {
virBufferAsprintf(&opt, ",wwn=0x%s", disk->wwn); virReportError(VIR_ERR_INVALID_ARG,
_("Failed to parse wwn '%s' as number"), disk->wwn);
return NULL;
}
wwn = virJSONValueNewNumberUlong(w);
} }
if (disk->rotation_rate) if (disk->cachemode != VIR_DOMAIN_DISK_CACHE_DEFAULT) {
virBufferAsprintf(&opt, ",rotation_rate=%u", disk->rotation_rate); /* 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->vendor) { if (qemuDomainDiskCachemodeFlags(disk->cachemode, &wb, NULL,
virBufferAddLit(&opt, ",vendor="); NULL) < 0)
virQEMUBuildBufferEscapeComma(&opt, disk->vendor); return NULL;
}
if (disk->product) { writeCache = virTristateSwitchFromBool(wb);
virBufferAddLit(&opt, ",product=");
virQEMUBuildBufferEscapeComma(&opt, disk->product);
}
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 (qemuBuildDriveDevCacheStr(disk, &opt, qemuCaps) < 0) if (disk->geometry.trans != VIR_DOMAIN_DISK_TRANS_DEFAULT)
return NULL; 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)) 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);
} }
@ -2613,7 +2523,7 @@ qemuBuildDiskCommandLine(virCommand *cmd,
virDomainDiskDef *disk, virDomainDiskDef *disk,
virQEMUCaps *qemuCaps) virQEMUCaps *qemuCaps)
{ {
g_autofree char *optstr = NULL; g_autoptr(virJSONValue) devprops = NULL;
if (qemuBuildDiskSourceCommandLine(cmd, disk, qemuCaps) < 0) if (qemuBuildDiskSourceCommandLine(cmd, disk, qemuCaps) < 0)
return -1; return -1;
@ -2632,11 +2542,11 @@ qemuBuildDiskCommandLine(virCommand *cmd,
if (qemuCommandAddExtDevice(cmd, &disk->info, qemuCaps) < 0) if (qemuCommandAddExtDevice(cmd, &disk->info, qemuCaps) < 0)
return -1; 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; return -1;
virCommandAddArg(cmd, optstr);
return 0; return 0;
} }

View File

@ -134,10 +134,10 @@ qemuBlockStorageSourceChainData *
qemuBuildStorageSourceChainAttachPrepareBlockdevTop(virStorageSource *top, qemuBuildStorageSourceChainAttachPrepareBlockdevTop(virStorageSource *top,
virStorageSource *backingStore); virStorageSource *backingStore);
char virJSONValue *
*qemuBuildDiskDeviceStr(const virDomainDef *def, qemuBuildDiskDeviceProps(const virDomainDef *def,
virDomainDiskDef *disk, virDomainDiskDef *disk,
virQEMUCaps *qemuCaps); virQEMUCaps *qemuCaps);
char * char *
qemuBuildVHostUserFsDevStr(virDomainFSDef *fs, qemuBuildVHostUserFsDevStr(virDomainFSDef *fs,

View File

@ -710,7 +710,7 @@ qemuDomainAttachDiskGeneric(virQEMUDriver *driver,
{ {
g_autoptr(qemuBlockStorageSourceChainData) data = NULL; g_autoptr(qemuBlockStorageSourceChainData) data = NULL;
qemuDomainObjPrivate *priv = vm->privateData; qemuDomainObjPrivate *priv = vm->privateData;
g_autofree char *devstr = NULL; g_autoptr(virJSONValue) devprops = NULL;
bool blockdev = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV); bool blockdev = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV);
bool extensionDeviceAttached = false; bool extensionDeviceAttached = false;
int rc; int rc;
@ -772,7 +772,7 @@ qemuDomainAttachDiskGeneric(virQEMUDriver *driver,
ignore_value(VIR_INSERT_ELEMENT(data->srcdata, 0, data->nsrcdata, backend)); 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; goto rollback;
if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
@ -782,7 +782,7 @@ qemuDomainAttachDiskGeneric(virQEMUDriver *driver,
extensionDeviceAttached = true; extensionDeviceAttached = true;
if (rc == 0) 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 /* Setup throttling of disk via block_set_io_throttle QMP command. This
* is a hack until the 'throttle' blockdev driver will support modification * is a hack until the 'throttle' blockdev driver will support modification

View File

@ -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 \ -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 '{"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"}' \ -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 \ -audiodev id=audio1,driver=none \
-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x2 \ -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x2 \
-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \

View File

@ -31,10 +31,10 @@ XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \
-device lsi,id=scsi1,bus=pci.0,addr=0x3 \ -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 '{"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"}' \ -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 '{"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"}' \ -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 \ -audiodev id=audio1,driver=none \
-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4 \ -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4 \
-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \

View File

@ -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 \ -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 '{"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"}' \ -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 '{"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"}' \ -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 \ -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 \