Rename qemuDefaultScsiControllerModel to qemuCheckScsiControllerModel. When scsi model is given explicitly in XML(model > 0) checking if the underlying QEMU support it or not first, raise error on checking failure. If the model is not given(mode <= 0), return lsi or virtio-scsi which is supported, lsi take the priority. --- src/qemu/qemu_capabilities.c | 7 +++ src/qemu/qemu_capabilities.h | 2 + src/qemu/qemu_command.c | 88 ++++++++++++++++++++++++++++++----------- src/qemu/qemu_command.h | 3 +- 4 files changed, 75 insertions(+), 25 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 85c49a2..8282ad8 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -169,6 +169,8 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST, "virtio-s390", "balloon-event", + "lsi", /*100*/ + "virtio-scsi-pci", ); struct qemu_feature_flags { @@ -1450,6 +1452,11 @@ qemuCapsParseDeviceStr(const char *str, virBitmapPtr flags) strstr(str, "name \"virtio-serial-s390\"")) qemuCapsSet(flags, QEMU_CAPS_VIRTIO_S390); + if (strstr(str, "name \"lsi53c895a\"")) + qemuCapsSet(flags, QEMU_CAPS_SCSI_LSI); + if (strstr(str, "name \"virtio-scsi-pci\"")) + qemuCapsSet(flags, QEMU_CAPS_VIRIO_SCSI_PCI); + /* Prefer -chardev spicevmc (detected earlier) over -device spicevmc */ if (!qemuCapsGet(flags, QEMU_CAPS_CHARDEV_SPICEVMC) && strstr(str, "name \"spicevmc\"")) diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index e8251dc..d2d68a9 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -135,6 +135,8 @@ enum qemuCapsFlags { QEMU_CAPS_NEC_USB_XHCI = 97, /* -device nec-usb-xhci */ QEMU_CAPS_VIRTIO_S390 = 98, /* -device virtio-*-s390 */ QEMU_CAPS_BALLOON_EVENT = 99, /* Async event for balloon changes */ + QEMU_CAPS_SCSI_LSI = 100, /* -device lsi */ + QEMU_CAPS_VIRIO_SCSI_PCI = 101, /* -device virtio-scsi-pci */ QEMU_CAPS_LAST, /* this must always be the last item */ }; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 6ad65a6..6a4578d 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -469,19 +469,60 @@ static int qemuAssignDeviceDiskAliasFixed(virDomainDiskDefPtr disk) } static int -qemuDefaultScsiControllerModel(virDomainDefPtr def) { - if (STREQ(def->os.arch, "ppc64") && - STREQ(def->os.machine, "pseries")) { - return VIR_DOMAIN_CONTROLLER_MODEL_SCSI_IBMVSCSI; +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_VIRIO_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 { - return VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC; + if (qemuCapsGet(qemuCaps, QEMU_CAPS_SCSI_LSI)) { + *model = VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC; + } else if (qemuCapsGet(qemuCaps, QEMU_CAPS_VIRIO_SCSI_PCI)) { + *model = VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI; + } else if (STREQ(def->os.arch, "ppc64") && + STREQ(def->os.machine, "pseries")) { + *model = VIR_DOMAIN_CONTROLLER_MODEL_SCSI_IBMVSCSI; + } else { + 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= */ static int qemuAssignDeviceDiskAliasCustom(virDomainDefPtr def, - virDomainDiskDefPtr disk) + virDomainDiskDefPtr disk, + virBitmapPtr qemuCaps) { const char *prefix = virDomainDiskBusTypeToString(disk->bus); int controllerModel = -1; @@ -491,11 +532,10 @@ qemuAssignDeviceDiskAliasCustom(virDomainDefPtr def, controllerModel = virDomainDiskFindControllerModel(def, disk, VIR_DOMAIN_CONTROLLER_TYPE_SCSI); - } - if (controllerModel == -1 || - controllerModel == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_AUTO) - controllerModel = qemuDefaultScsiControllerModel(def); + if ((qemuCheckScsiControllerModel(def, qemuCaps, &controllerModel)) < 0) + return -1; + } if (disk->bus != VIR_DOMAIN_DISK_BUS_SCSI || controllerModel == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC) { @@ -533,7 +573,7 @@ qemuAssignDeviceDiskAlias(virDomainDefPtr vmdef, { if (qemuCapsGet(qemuCaps, QEMU_CAPS_DRIVE)) { if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) - return qemuAssignDeviceDiskAliasCustom(vmdef, def); + return qemuAssignDeviceDiskAliasCustom(vmdef, def, qemuCaps); else return qemuAssignDeviceDiskAliasFixed(def); } else { @@ -850,9 +890,10 @@ qemuAssignSpaprVIOAddress(virDomainDefPtr def, virDomainDeviceInfoPtr info, return 0; } -int qemuDomainAssignSpaprVIOAddresses(virDomainDefPtr def) +int qemuDomainAssignSpaprVIOAddresses(virDomainDefPtr def, + virBitmapPtr qemuCaps) { - int i, rc; + int i, rc = -1; int model; /* Default values match QEMU. See spapr_(llan|vscsi|vty).c */ @@ -869,9 +910,10 @@ int qemuDomainAssignSpaprVIOAddresses(virDomainDefPtr def) for (i = 0 ; i < def->ncontrollers; i++) { model = def->controllers[i]->model; - if (model == -1 && - def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI) - model = qemuDefaultScsiControllerModel(def); + if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI) + if ((qemuCheckScsiControllerModel(def, qemuCaps, &model)) < 0) + return rc; + if (model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_IBMVSCSI && def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI) def->controllers[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO; @@ -1059,7 +1101,7 @@ int qemuDomainAssignAddresses(virDomainDefPtr def, { int rc; - rc = qemuDomainAssignSpaprVIOAddresses(def); + rc = qemuDomainAssignSpaprVIOAddresses(def, qemuCaps); if (rc) return rc; @@ -2434,9 +2476,8 @@ qemuBuildDriveDevStr(virDomainDefPtr def, controllerModel = virDomainDiskFindControllerModel(def, disk, VIR_DOMAIN_CONTROLLER_TYPE_SCSI); - if (controllerModel == -1 || - controllerModel == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_AUTO) - controllerModel = qemuDefaultScsiControllerModel(def); + if ((qemuCheckScsiControllerModel(def, qemuCaps, &controllerModel)) < 0) + goto error; if (controllerModel == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC) { if (disk->info.addr.drive.target != 0) { @@ -2765,10 +2806,9 @@ qemuBuildControllerDevStr(virDomainDefPtr domainDef, switch (def->type) { case VIR_DOMAIN_CONTROLLER_TYPE_SCSI: model = def->model; - if (model == -1 || - model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_AUTO) { - model = qemuDefaultScsiControllerModel(domainDef); - } + if ((qemuCheckScsiControllerModel(domainDef, qemuCaps, &model)) < 0) + return NULL; + switch (model) { case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI: virBufferAddLit(&buf, "virtio-scsi-pci"); diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h index 3ccf4d7..7068a81 100644 --- a/src/qemu/qemu_command.h +++ b/src/qemu/qemu_command.h @@ -178,7 +178,8 @@ virDomainDefPtr qemuParseCommandLinePid(virCapsPtr caps, int qemuDomainAssignAddresses(virDomainDefPtr def, virBitmapPtr qemuCaps, virDomainObjPtr); -int qemuDomainAssignSpaprVIOAddresses(virDomainDefPtr def); +int qemuDomainAssignSpaprVIOAddresses(virDomainDefPtr def, + virBitmapPtr qemuCaps); int qemuDomainAssignPCIAddresses(virDomainDefPtr def, virBitmapPtr qemuCaps, -- 1.7.7.6 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list