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