For any disk controller model which is not "lsilogic", the command line will be like: -drive file=/dev/sda,if=none,id=drive-scsi0-0-3-0,format=raw \ -device scsi-disk,bus=scsi0.0,channel=0,scsi-id=3,lun=0,i\ drive=drive-scsi0-0-3-0,id=scsi0-0-3-0 The relationship between the libvirt address attrs and the qdev properties are (controller model is not "lsilogic"; strings inside <> represent libvirt adress attrs): bus=scsi<controller>.0 channel=<bus> scsi-id=<target> lun=<unit> * src/qemu/qemu_command.h: (New param "virDomainDefPtr def" for function qemuBuildDriveDevStr; new param "virDomainDefPtr vmdef" for function qemuAssignDeviceDiskAlias. Both for virDomainDiskFindControllerModel's use). * src/qemu/qemu_command.c: - New param "virDomainDefPtr def" for qemuAssignDeviceDiskAliasCustom. For virDomainDiskFindControllerModel's use, if the disk bus is "scsi" and the controller model is not "lsilogic", "target" is one part of the alias name. - According change on qemuAssignDeviceDiskAlias and qemuBuildDriveDevStr * src/qemu/qemu_hotplug.c: - Changes to be consistent with declarations of qemuAssignDeviceDiskAlias qemuBuildDriveDevStr, and qemuBuildControllerDevStr. * tests/qemuxml2argvdata/qemuxml2argv-pseries-vio-user-assigned.args, tests/qemuxml2argvdata/qemuxml2argv-pseries-vio.args: Update the generated command line. --- src/qemu/qemu_command.c | 124 +++++++++++++++++--- src/qemu/qemu_command.h | 7 +- src/qemu/qemu_hotplug.c | 12 +- .../qemuxml2argv-pseries-vio-user-assigned.args | 13 ++- .../qemuxml2argvdata/qemuxml2argv-pseries-vio.args | 13 ++- 5 files changed, 142 insertions(+), 27 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 63f6a05..58a1d80 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -472,15 +472,39 @@ qemuDefaultScsiControllerModel(virDomainDefPtr def) { } /* Our custom -drive naming scheme used with id= */ -static int qemuAssignDeviceDiskAliasCustom(virDomainDiskDefPtr disk) +static int +qemuAssignDeviceDiskAliasCustom(virDomainDefPtr def, + virDomainDiskDefPtr disk) { const char *prefix = virDomainDiskBusTypeToString(disk->bus); + int controllerModel = -1; + if (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE) { - if (virAsprintf(&disk->info.alias, "%s%d-%d-%d", prefix, - disk->info.addr.drive.controller, - disk->info.addr.drive.bus, - disk->info.addr.drive.unit) < 0) - goto no_memory; + if (disk->bus == VIR_DOMAIN_DISK_BUS_SCSI) { + controllerModel = + virDomainDiskFindControllerModel(def, disk, + VIR_DOMAIN_CONTROLLER_TYPE_SCSI); + } + + if (controllerModel == -1 || + controllerModel == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_AUTO) + controllerModel = qemuDefaultScsiControllerModel(def); + + if (disk->bus != VIR_DOMAIN_DISK_BUS_SCSI || + controllerModel == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC) { + if (virAsprintf(&disk->info.alias, "%s%d-%d-%d", prefix, + disk->info.addr.drive.controller, + disk->info.addr.drive.bus, + disk->info.addr.drive.unit) < 0) + goto no_memory; + } else { + if (virAsprintf(&disk->info.alias, "%s%d-%d-%d-%d", prefix, + disk->info.addr.drive.controller, + disk->info.addr.drive.bus, + disk->info.addr.drive.target, + disk->info.addr.drive.unit) < 0) + goto no_memory; + } } else { int idx = virDiskNameToIndex(disk->dst); if (virAsprintf(&disk->info.alias, "%s-disk%d", prefix, idx) < 0) @@ -496,11 +520,13 @@ no_memory: int -qemuAssignDeviceDiskAlias(virDomainDiskDefPtr def, virBitmapPtr qemuCaps) +qemuAssignDeviceDiskAlias(virDomainDefPtr vmdef, + virDomainDiskDefPtr def, + virBitmapPtr qemuCaps) { if (qemuCapsGet(qemuCaps, QEMU_CAPS_DRIVE)) { if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) - return qemuAssignDeviceDiskAliasCustom(def); + return qemuAssignDeviceDiskAliasCustom(vmdef, def); else return qemuAssignDeviceDiskAliasFixed(def); } else { @@ -611,7 +637,7 @@ qemuAssignDeviceAliases(virDomainDefPtr def, virBitmapPtr qemuCaps) int i; for (i = 0; i < def->ndisks ; i++) { - if (qemuAssignDeviceDiskAlias(def->disks[i], qemuCaps) < 0) + if (qemuAssignDeviceDiskAlias(def, def->disks[i], qemuCaps) < 0) return -1; } if (qemuCapsGet(qemuCaps, QEMU_CAPS_NET_NAME) || @@ -1841,6 +1867,11 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED, _("Only 1 %s bus is supported"), bus); goto error; } + if (disk->info.addr.drive.target != 0) { + qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("target must be 0 for controller fdc")); + goto error; + } unitid = disk->info.addr.drive.unit; break; @@ -2087,13 +2118,15 @@ error: char * -qemuBuildDriveDevStr(virDomainDiskDefPtr disk, +qemuBuildDriveDevStr(virDomainDefPtr def, + virDomainDiskDefPtr disk, int bootindex, virBitmapPtr qemuCaps) { virBuffer opt = VIR_BUFFER_INITIALIZER; const char *bus = virDomainDiskQEMUBusTypeToString(disk->bus); int idx = virDiskNameToIndex(disk->dst); + int controllerModel; if (idx < 0) { qemuReportError(VIR_ERR_INTERNAL_ERROR, @@ -2105,7 +2138,8 @@ qemuBuildDriveDevStr(virDomainDiskDefPtr disk, /* make sure that both the bus and the qemu binary support * type='lun' (SG_IO). */ - if (disk->bus != VIR_DOMAIN_DISK_BUS_VIRTIO) { + if (disk->bus != VIR_DOMAIN_DISK_BUS_VIRTIO && + disk->bus != VIR_DOMAIN_DISK_BUS_SCSI) { qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("disk device='lun' is not supported for bus='%s'"), bus); @@ -2126,19 +2160,74 @@ qemuBuildDriveDevStr(virDomainDiskDefPtr disk, switch (disk->bus) { case VIR_DOMAIN_DISK_BUS_IDE: + if (disk->info.addr.drive.target != 0) { + qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("target must be 0 for ide controller")); + goto error; + } virBufferAddLit(&opt, "ide-drive"); virBufferAsprintf(&opt, ",bus=ide.%d,unit=%d", disk->info.addr.drive.bus, disk->info.addr.drive.unit); break; case VIR_DOMAIN_DISK_BUS_SCSI: - virBufferAddLit(&opt, "scsi-disk"); - virBufferAsprintf(&opt, ",bus=scsi%d.%d,scsi-id=%d", - disk->info.addr.drive.controller, - disk->info.addr.drive.bus, - disk->info.addr.drive.unit); + controllerModel = + virDomainDiskFindControllerModel(def, disk, + VIR_DOMAIN_CONTROLLER_TYPE_SCSI); + if (controllerModel == -1 || + controllerModel == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_AUTO) + controllerModel = qemuDefaultScsiControllerModel(def); + + if (controllerModel == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC) { + if (disk->info.addr.drive.target != 0) { + qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("target must be 0 for leagacy controller " + "model 'lsilogic'")); + goto error; + } + + virBufferAddLit(&opt, "scsi-disk"); + virBufferAsprintf(&opt, ",bus=scsi%d.%d,scsi-id=%d", + disk->info.addr.drive.controller, + disk->info.addr.drive.bus, + disk->info.addr.drive.unit); + } else { + if (!qemuCapsGet(qemuCaps, QEMU_CAPS_SCSI_DISK_CHANNEL)) { + if (disk->info.addr.drive.target > 7) { + qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("This QEMU doesn't support target " + "greater than 7")); + goto error; + } + + if ((disk->info.addr.drive.bus != disk->info.addr.drive.unit) && + (disk->info.addr.drive.bus != 0)) { + qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("This QEMU only supports both bus and " + "unit are equal to 0")); + goto error; + } + } + + virBufferAddLit(&opt, "scsi-disk"); + virBufferAsprintf(&opt, ",bus=scsi%d.0,channel=%d,scsi-id=%d,lun=%d", + disk->info.addr.drive.controller, + disk->info.addr.drive.bus, + disk->info.addr.drive.target, + disk->info.addr.drive.unit); + } break; case VIR_DOMAIN_DISK_BUS_SATA: + if (disk->info.addr.drive.bus != 0) { + qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("bus must be 0 for ide controller")); + goto error; + } + if (disk->info.addr.drive.target != 0) { + qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("target must be 0 for ide controller")); + goto error; + } virBufferAddLit(&opt, "ide-drive"); virBufferAsprintf(&opt, ",bus=ahci%d.%d", disk->info.addr.drive.controller, @@ -2332,6 +2421,7 @@ qemuBuildUSBControllerDevStr(virDomainControllerDefPtr def, int model, caps; model = def->model; + if (model == -1) model = VIR_DOMAIN_CONTROLLER_MODEL_USB_PIIX3_UHCI; @@ -4492,7 +4582,7 @@ qemuBuildCommandLine(virConnectPtr conn, } else { virCommandAddArg(cmd, "-device"); - if (!(optstr = qemuBuildDriveDevStr(disk, bootindex, + if (!(optstr = qemuBuildDriveDevStr(def, disk, bootindex, qemuCaps))) goto error; virCommandAddArg(cmd, optstr); diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h index 2f8b5ba..6ace8f3 100644 --- a/src/qemu/qemu_command.h +++ b/src/qemu/qemu_command.h @@ -90,7 +90,8 @@ char *qemuBuildFSStr(virDomainFSDefPtr fs, virBitmapPtr qemuCaps); /* Current, best practice */ -char * qemuBuildDriveDevStr(virDomainDiskDefPtr disk, +char * qemuBuildDriveDevStr(virDomainDefPtr def, + virDomainDiskDefPtr disk, int bootindex, virBitmapPtr qemuCaps); char * qemuBuildFSDevStr(virDomainFSDefPtr fs, @@ -201,7 +202,9 @@ int qemuAssignDevicePCISlots(virDomainDefPtr def, qemuDomainPCIAddressSetPtr ad int qemuAssignDeviceAliases(virDomainDefPtr def, virBitmapPtr qemuCaps); int qemuDomainNetVLAN(virDomainNetDefPtr def); int qemuAssignDeviceNetAlias(virDomainDefPtr def, virDomainNetDefPtr net, int idx); -int qemuAssignDeviceDiskAlias(virDomainDiskDefPtr def, virBitmapPtr qemuCaps); +int qemuAssignDeviceDiskAlias(virDomainDefPtr vmdef, + virDomainDiskDefPtr def, + virBitmapPtr qemuCaps); int qemuAssignDeviceHostdevAlias(virDomainDefPtr def, virDomainHostdevDefPtr hostdev, int idx); int qemuAssignDeviceControllerAlias(virDomainControllerDefPtr controller); int qemuAssignDeviceRedirdevAlias(virDomainDefPtr def, virDomainRedirdevDefPtr redirdev, int idx); diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 3dd7c0a..4127362 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -226,13 +226,13 @@ int qemuDomainAttachPciDiskDevice(virConnectPtr conn, if (qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, &disk->info) < 0) goto error; releaseaddr = true; - if (qemuAssignDeviceDiskAlias(disk, priv->qemuCaps) < 0) + if (qemuAssignDeviceDiskAlias(vm->def, disk, priv->qemuCaps) < 0) goto error; if (!(drivestr = qemuBuildDriveStr(conn, disk, false, priv->qemuCaps))) goto error; - if (!(devstr = qemuBuildDriveDevStr(disk, 0, priv->qemuCaps))) + if (!(devstr = qemuBuildDriveDevStr(NULL, disk, 0, priv->qemuCaps))) goto error; } @@ -461,9 +461,9 @@ int qemuDomainAttachSCSIDisk(virConnectPtr conn, } if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { - if (qemuAssignDeviceDiskAlias(disk, priv->qemuCaps) < 0) + if (qemuAssignDeviceDiskAlias(vm->def, disk, priv->qemuCaps) < 0) goto error; - if (!(devstr = qemuBuildDriveDevStr(disk, 0, priv->qemuCaps))) + if (!(devstr = qemuBuildDriveDevStr(vm->def, disk, 0, priv->qemuCaps))) goto error; } @@ -583,11 +583,11 @@ int qemuDomainAttachUsbMassstorageDevice(virConnectPtr conn, } if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { - if (qemuAssignDeviceDiskAlias(disk, priv->qemuCaps) < 0) + if (qemuAssignDeviceDiskAlias(vm->def, disk, priv->qemuCaps) < 0) goto error; if (!(drivestr = qemuBuildDriveStr(conn, disk, false, priv->qemuCaps))) goto error; - if (!(devstr = qemuBuildDriveDevStr(disk, 0, priv->qemuCaps))) + if (!(devstr = qemuBuildDriveDevStr(NULL, disk, 0, priv->qemuCaps))) goto error; } diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pseries-vio-user-assigned.args b/tests/qemuxml2argvdata/qemuxml2argv-pseries-vio-user-assigned.args index e939e1b..fad4346 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-pseries-vio-user-assigned.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-pseries-vio-user-assigned.args @@ -1 +1,12 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu-system-ppc64 -S -M pseries -m 512 -smp 1 -nographic -nodefconfig -nodefaults -chardev socket,id=charmonitor,path=/tmp/test-monitor,server,nowait -mon chardev=charmonitor,id=monitor,mode=readline -no-acpi -boot c -device spapr-vscsi,id=scsi0,reg=0x2000 -device spapr-vscsi,id=scsi1,reg=0x30000000 -drive file=/tmp/scsidisk.img,if=none,id=drive-scsi1-0-0 -device scsi-disk,bus=scsi1.0,scsi-id=0,drive=drive-scsi1-0-0,id=scsi1-0-0 -chardev pty,id=charserial0 -device spapr-vty,chardev=charserial0,reg=0x20000000 -chardev pty,id=charserial1 -device spapr-vty,chardev=charserial1,reg=0x30001000 -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu-system-ppc64 \ +-S -M pseries -m 512 -smp 1 -nographic -nodefconfig -nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/test-monitor,server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=readline -no-acpi -boot c \ +-device spapr-vscsi,id=scsi0,reg=0x2000 \ +-device spapr-vscsi,id=scsi1,reg=0x30000000 \ +-drive file=/tmp/scsidisk.img,if=none,id=drive-scsi1-0-0-0 \ +-device scsi-disk,bus=scsi1.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi1-0-0-0,id=scsi1-0-0-0 \ +-chardev pty,id=charserial0 \ +-device spapr-vty,chardev=charserial0,reg=0x20000000 \ +-chardev pty,id=charserial1 \ +-device spapr-vty,chardev=charserial1,reg=0x30001000 -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pseries-vio.args b/tests/qemuxml2argvdata/qemuxml2argv-pseries-vio.args index 5fe0c88..a75b428 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-pseries-vio.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-pseries-vio.args @@ -1 +1,12 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu-system-ppc64 -S -M pseries -m 512 -smp 1 -nographic -nodefconfig -nodefaults -chardev socket,id=charmonitor,path=/tmp/test-monitor,server,nowait -mon chardev=charmonitor,id=monitor,mode=readline -no-acpi -boot c -device spapr-vscsi,id=scsi0,reg=0x2000 -device spapr-vscsi,id=scsi1,reg=0x3000 -drive file=/tmp/scsidisk.img,if=none,id=drive-scsi1-0-0 -device scsi-disk,bus=scsi1.0,scsi-id=0,drive=drive-scsi1-0-0,id=scsi1-0-0 -chardev pty,id=charserial0 -device spapr-vty,chardev=charserial0,reg=0x30000000 -chardev pty,id=charserial1 -device spapr-vty,chardev=charserial1,reg=0x30001000 -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu-system-ppc64 \ +-S -M pseries -m 512 -smp 1 -nographic -nodefconfig -nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/test-monitor,server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=readline -no-acpi -boot c \ +-device spapr-vscsi,id=scsi0,reg=0x2000 \ +-device spapr-vscsi,id=scsi1,reg=0x3000 \ +-drive file=/tmp/scsidisk.img,if=none,id=drive-scsi1-0-0-0 \ +-device scsi-disk,bus=scsi1.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi1-0-0-0,id=scsi1-0-0-0 \ +-chardev pty,id=charserial0 \ +-device spapr-vty,chardev=charserial0,reg=0x30000000 \ +-chardev pty,id=charserial1 \ +-device spapr-vty,chardev=charserial1,reg=0x30001000 -usb -- 1.7.7.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list