qemu: add two qemu caps for lsi and virtio-scsi SCSI controllers

Rename qemuDefaultScsiControllerModel to qemuCheckScsiControllerModel.
When scsi model is given explicitly in XML(model > 0) checking if the
underlying QEMU supports it or not first, raise an error on checking
failure.
When the model is not given(mode <= 0), return LSI by default, if
the QEMU doesn't support it, raise an error.
This commit is contained in:
Guannan Ren 2012-08-08 15:06:33 +08:00
parent 8694c716ae
commit 015c603bcd
4 changed files with 100 additions and 38 deletions

View File

@ -469,19 +469,58 @@ static int qemuAssignDeviceDiskAliasFixed(virDomainDiskDefPtr disk)
} }
static int static int
qemuDefaultScsiControllerModel(virDomainDefPtr def) { qemuCheckScsiControllerModel(virDomainDefPtr def,
virBitmapPtr qemuCaps,
int *model)
{
if (*model > 0) {
switch (*model) {
case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC:
if (!qemuCapsGet(qemuCaps, QEMU_CAPS_SCSI_LSI)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("This QEMU doesn't support "
"lsi scsi controller"));
return -1;
}
break;
case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI:
if (!qemuCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_SCSI_PCI)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("This QEMU doesn't support "
"virtio scsi controller"));
return -1;
}
break;
case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_IBMVSCSI:
/*TODO: need checking work here if necessary */
break;
default:
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Unsupported controller model: %s"),
virDomainControllerModelSCSITypeToString(*model));
return -1;
}
} else {
if (STREQ(def->os.arch, "ppc64") && if (STREQ(def->os.arch, "ppc64") &&
STREQ(def->os.machine, "pseries")) { STREQ(def->os.machine, "pseries")) {
return VIR_DOMAIN_CONTROLLER_MODEL_SCSI_IBMVSCSI; *model = VIR_DOMAIN_CONTROLLER_MODEL_SCSI_IBMVSCSI;
} else if (qemuCapsGet(qemuCaps, QEMU_CAPS_SCSI_LSI)) {
*model = VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC;
} else { } else {
return VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC; virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to determine model for scsi controller"));
return -1;
} }
}
return 0;
} }
/* Our custom -drive naming scheme used with id= */ /* Our custom -drive naming scheme used with id= */
static int static int
qemuAssignDeviceDiskAliasCustom(virDomainDefPtr def, qemuAssignDeviceDiskAliasCustom(virDomainDefPtr def,
virDomainDiskDefPtr disk) virDomainDiskDefPtr disk,
virBitmapPtr qemuCaps)
{ {
const char *prefix = virDomainDiskBusTypeToString(disk->bus); const char *prefix = virDomainDiskBusTypeToString(disk->bus);
int controllerModel = -1; int controllerModel = -1;
@ -491,11 +530,10 @@ qemuAssignDeviceDiskAliasCustom(virDomainDefPtr def,
controllerModel = controllerModel =
virDomainDiskFindControllerModel(def, disk, virDomainDiskFindControllerModel(def, disk,
VIR_DOMAIN_CONTROLLER_TYPE_SCSI); VIR_DOMAIN_CONTROLLER_TYPE_SCSI);
}
if (controllerModel == -1 || if ((qemuCheckScsiControllerModel(def, qemuCaps, &controllerModel)) < 0)
controllerModel == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_AUTO) return -1;
controllerModel = qemuDefaultScsiControllerModel(def); }
if (disk->bus != VIR_DOMAIN_DISK_BUS_SCSI || if (disk->bus != VIR_DOMAIN_DISK_BUS_SCSI ||
controllerModel == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC) { controllerModel == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC) {
@ -533,7 +571,7 @@ qemuAssignDeviceDiskAlias(virDomainDefPtr vmdef,
{ {
if (qemuCapsGet(qemuCaps, QEMU_CAPS_DRIVE)) { if (qemuCapsGet(qemuCaps, QEMU_CAPS_DRIVE)) {
if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE))
return qemuAssignDeviceDiskAliasCustom(vmdef, def); return qemuAssignDeviceDiskAliasCustom(vmdef, def, qemuCaps);
else else
return qemuAssignDeviceDiskAliasFixed(def); return qemuAssignDeviceDiskAliasFixed(def);
} else { } else {
@ -850,13 +888,24 @@ qemuAssignSpaprVIOAddress(virDomainDefPtr def, virDomainDeviceInfoPtr info,
return 0; return 0;
} }
int qemuDomainAssignSpaprVIOAddresses(virDomainDefPtr def) int qemuDomainAssignSpaprVIOAddresses(virDomainDefPtr def,
virBitmapPtr qemuCaps)
{ {
int i, rc; int i, rc = -1;
int model; int model;
virBitmapPtr localCaps = NULL;
/* Default values match QEMU. See spapr_(llan|vscsi|vty).c */ /* Default values match QEMU. See spapr_(llan|vscsi|vty).c */
if (!qemuCaps) {
/* need to get information from real environment */
if (qemuCapsExtractVersionInfo(def->emulator, def->os.arch,
false, NULL,
&localCaps) < 0)
goto cleanup;
qemuCaps = localCaps;
}
for (i = 0 ; i < def->nnets; i++) { for (i = 0 ; i < def->nnets; i++) {
if (def->nets[i]->model && if (def->nets[i]->model &&
STREQ(def->nets[i]->model, "spapr-vlan")) STREQ(def->nets[i]->model, "spapr-vlan"))
@ -864,21 +913,24 @@ int qemuDomainAssignSpaprVIOAddresses(virDomainDefPtr def)
rc = qemuAssignSpaprVIOAddress(def, &def->nets[i]->info, rc = qemuAssignSpaprVIOAddress(def, &def->nets[i]->info,
0x1000ul); 0x1000ul);
if (rc) if (rc)
return rc; goto cleanup;
} }
for (i = 0 ; i < def->ncontrollers; i++) { for (i = 0 ; i < def->ncontrollers; i++) {
model = def->controllers[i]->model; model = def->controllers[i]->model;
if (model == -1 && if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI) {
def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI) rc = qemuCheckScsiControllerModel(def, qemuCaps, &model);
model = qemuDefaultScsiControllerModel(def); if (rc)
goto cleanup;
}
if (model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_IBMVSCSI && if (model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_IBMVSCSI &&
def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI) def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI)
def->controllers[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO; def->controllers[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO;
rc = qemuAssignSpaprVIOAddress(def, &def->controllers[i]->info, rc = qemuAssignSpaprVIOAddress(def, &def->controllers[i]->info,
0x2000ul); 0x2000ul);
if (rc) if (rc)
return rc; goto cleanup;
} }
for (i = 0 ; i < def->nserials; i++) { for (i = 0 ; i < def->nserials; i++) {
@ -890,12 +942,16 @@ int qemuDomainAssignSpaprVIOAddresses(virDomainDefPtr def)
rc = qemuAssignSpaprVIOAddress(def, &def->serials[i]->info, rc = qemuAssignSpaprVIOAddress(def, &def->serials[i]->info,
0x30000000ul); 0x30000000ul);
if (rc) if (rc)
return rc; goto cleanup;
} }
/* No other devices are currently supported on spapr-vio */ /* No other devices are currently supported on spapr-vio */
return 0; rc = 0;
cleanup:
qemuCapsFree(localCaps);
return rc;
} }
#define QEMU_PCI_ADDRESS_LAST_SLOT 31 #define QEMU_PCI_ADDRESS_LAST_SLOT 31
@ -1059,7 +1115,7 @@ int qemuDomainAssignAddresses(virDomainDefPtr def,
{ {
int rc; int rc;
rc = qemuDomainAssignSpaprVIOAddresses(def); rc = qemuDomainAssignSpaprVIOAddresses(def, qemuCaps);
if (rc) if (rc)
return rc; return rc;
@ -2433,9 +2489,8 @@ qemuBuildDriveDevStr(virDomainDefPtr def,
controllerModel = controllerModel =
virDomainDiskFindControllerModel(def, disk, virDomainDiskFindControllerModel(def, disk,
VIR_DOMAIN_CONTROLLER_TYPE_SCSI); VIR_DOMAIN_CONTROLLER_TYPE_SCSI);
if (controllerModel == -1 || if ((qemuCheckScsiControllerModel(def, qemuCaps, &controllerModel)) < 0)
controllerModel == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_AUTO) goto error;
controllerModel = qemuDefaultScsiControllerModel(def);
if (controllerModel == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC) { if (controllerModel == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC) {
if (disk->info.addr.drive.target != 0) { if (disk->info.addr.drive.target != 0) {
@ -2764,10 +2819,9 @@ qemuBuildControllerDevStr(virDomainDefPtr domainDef,
switch (def->type) { switch (def->type) {
case VIR_DOMAIN_CONTROLLER_TYPE_SCSI: case VIR_DOMAIN_CONTROLLER_TYPE_SCSI:
model = def->model; model = def->model;
if (model == -1 || if ((qemuCheckScsiControllerModel(domainDef, qemuCaps, &model)) < 0)
model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_AUTO) { return NULL;
model = qemuDefaultScsiControllerModel(domainDef);
}
switch (model) { switch (model) {
case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI: case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI:
virBufferAddLit(&buf, "virtio-scsi-pci"); virBufferAddLit(&buf, "virtio-scsi-pci");

View File

@ -180,7 +180,8 @@ virDomainDefPtr qemuParseCommandLinePid(virCapsPtr caps,
int qemuDomainAssignAddresses(virDomainDefPtr def, int qemuDomainAssignAddresses(virDomainDefPtr def,
virBitmapPtr qemuCaps, virBitmapPtr qemuCaps,
virDomainObjPtr); virDomainObjPtr);
int qemuDomainAssignSpaprVIOAddresses(virDomainDefPtr def); int qemuDomainAssignSpaprVIOAddresses(virDomainDefPtr def,
virBitmapPtr qemuCaps);
int qemuDomainAssignPCIAddresses(virDomainDefPtr def, int qemuDomainAssignPCIAddresses(virDomainDefPtr def,
virBitmapPtr qemuCaps, virBitmapPtr qemuCaps,

View File

@ -3120,7 +3120,8 @@ qemuProcessReconnect(void *opaque)
} }
if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE))
qemuDomainAssignAddresses(obj->def, priv->qemuCaps, obj); if ((qemuDomainAssignAddresses(obj->def, priv->qemuCaps, obj)) < 0)
goto error;
if (virSecurityManagerReserveLabel(driver->securityManager, obj->def, obj->pid) < 0) if (virSecurityManagerReserveLabel(driver->securityManager, obj->def, obj->pid) < 0)
goto error; goto error;
@ -3585,7 +3586,8 @@ int qemuProcessStart(virConnectPtr conn,
*/ */
if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
VIR_DEBUG("Assigning domain PCI addresses"); VIR_DEBUG("Assigning domain PCI addresses");
qemuDomainAssignAddresses(vm->def, priv->qemuCaps, vm); if ((qemuDomainAssignAddresses(vm->def, priv->qemuCaps, vm)) < 0)
goto cleanup;
} }
VIR_DEBUG("Building emulator command line"); VIR_DEBUG("Building emulator command line");
@ -4267,7 +4269,8 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
*/ */
if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
VIR_DEBUG("Assigning domain PCI addresses"); VIR_DEBUG("Assigning domain PCI addresses");
qemuDomainAssignAddresses(vm->def, priv->qemuCaps, vm); if ((qemuDomainAssignAddresses(vm->def, priv->qemuCaps, vm)) < 0)
goto cleanup;
} }
if ((timestamp = virTimeStringNow()) == NULL) { if ((timestamp = virTimeStringNow()) == NULL) {

View File

@ -458,16 +458,19 @@ mymain(void)
DO_TEST("disk-usb-device", DO_TEST("disk-usb-device",
QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG); QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG);
DO_TEST("disk-scsi-device", DO_TEST("disk-scsi-device",
QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG); QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG,
QEMU_CAPS_SCSI_LSI);
DO_TEST("disk-scsi-device-auto", DO_TEST("disk-scsi-device-auto",
QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG); QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG,
QEMU_CAPS_SCSI_LSI);
DO_TEST("disk-scsi-disk-split", DO_TEST("disk-scsi-disk-split",
QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG,
QEMU_CAPS_SCSI_CD); QEMU_CAPS_SCSI_CD, QEMU_CAPS_SCSI_LSI, QEMU_CAPS_VIRTIO_SCSI_PCI);
DO_TEST("disk-scsi-vscsi", DO_TEST("disk-scsi-vscsi",
QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG); QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG);
DO_TEST("disk-scsi-virtio-scsi", DO_TEST("disk-scsi-virtio-scsi",
QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG); QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG,
QEMU_CAPS_VIRTIO_SCSI_PCI);
DO_TEST("disk-sata-device", DO_TEST("disk-sata-device",
QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE,
QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_ICH9_AHCI); QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_ICH9_AHCI);
@ -497,7 +500,8 @@ mymain(void)
DO_TEST("disk-scsi-lun-passthrough", DO_TEST("disk-scsi-lun-passthrough",
QEMU_CAPS_DRIVE, QEMU_CAPS_DRIVE,
QEMU_CAPS_DEVICE, QEMU_CAPS_DEVICE,
QEMU_CAPS_SCSI_BLOCK, QEMU_CAPS_VIRTIO_BLK_SG_IO); QEMU_CAPS_SCSI_BLOCK, QEMU_CAPS_VIRTIO_BLK_SG_IO,
QEMU_CAPS_SCSI_LSI, QEMU_CAPS_VIRTIO_SCSI_PCI);
DO_TEST("graphics-vnc", NONE); DO_TEST("graphics-vnc", NONE);
DO_TEST("graphics-vnc-socket", NONE); DO_TEST("graphics-vnc-socket", NONE);
@ -757,7 +761,7 @@ mymain(void)
DO_TEST("multifunction-pci-device", DO_TEST("multifunction-pci-device",
QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG,
QEMU_CAPS_PCI_MULTIFUNCTION); QEMU_CAPS_PCI_MULTIFUNCTION, QEMU_CAPS_SCSI_LSI);
DO_TEST("monitor-json", QEMU_CAPS_DEVICE, DO_TEST("monitor-json", QEMU_CAPS_DEVICE,
QEMU_CAPS_CHARDEV, QEMU_CAPS_MONITOR_JSON, QEMU_CAPS_NODEFCONFIG); QEMU_CAPS_CHARDEV, QEMU_CAPS_MONITOR_JSON, QEMU_CAPS_NODEFCONFIG);