qemu: Build command line for the new address format

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.
This commit is contained in:
Osier Yang 2012-02-28 11:39:43 +08:00
parent 05fbe728ee
commit c56fe7f1d6
5 changed files with 142 additions and 27 deletions

View File

@ -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 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 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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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