diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index a58f997621..569becb99d 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -4737,8 +4737,7 @@ virDomainDiskAddressDiskBusCompatibility(virDomainDiskBus bus, static int -virDomainDiskDefValidate(const virDomainDef *def, - const virDomainDiskDef *disk) +virDomainDiskDefValidate(const virDomainDiskDef *disk) { /* Validate LUN configuration */ if (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) { @@ -4768,24 +4767,6 @@ virDomainDiskDefValidate(const virDomainDef *def, return -1; } - if (disk->iothread > 0) { - if (disk->bus != VIR_DOMAIN_DISK_BUS_VIRTIO || - (disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI && - disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("IOThreads are only available for virtio pci and " - "virtio ccw disk")); - return -1; - } - - if (!virDomainIOThreadIDFind(def, disk->iothread)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Invalid IOThread id '%u' for disk '%s'"), - disk->iothread, disk->dst); - return -1; - } - } - return 0; } @@ -4836,48 +4817,13 @@ virDomainNetDefValidate(const virDomainNetDef *net) } -static int -virDomainControllerDefValidate(const virDomainDef *def, - const virDomainControllerDef *cont) -{ - if (cont->iothread > 0) { - if (cont->type != VIR_DOMAIN_CONTROLLER_TYPE_SCSI || - cont->model != VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("IOThreads are only supported for virtio-scsi " - "controllers, model is '%s'"), - virDomainControllerModelSCSITypeToString(cont->model)); - return -1; - } - - if (cont->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI && - cont->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("IOThreads are only available for virtio pci and " - "virtio ccw controllers")); - return -1; - } - - if (!virDomainIOThreadIDFind(def, cont->iothread)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Invalid IOThread id '%u' for controller '%s'"), - cont->iothread, - virDomainControllerTypeToString(cont->type)); - return -1; - } - } - - return 0; -} - - static int virDomainDeviceDefValidateInternal(const virDomainDeviceDef *dev, const virDomainDef *def) { switch ((virDomainDeviceType) dev->type) { case VIR_DOMAIN_DEVICE_DISK: - return virDomainDiskDefValidate(def, dev->data.disk); + return virDomainDiskDefValidate(dev->data.disk); case VIR_DOMAIN_DEVICE_REDIRDEV: return virDomainRedirdevDefValidate(def, dev->data.redirdev); @@ -4885,9 +4831,6 @@ virDomainDeviceDefValidateInternal(const virDomainDeviceDef *dev, case VIR_DOMAIN_DEVICE_NET: return virDomainNetDefValidate(dev->data.net); - case VIR_DOMAIN_DEVICE_CONTROLLER: - return virDomainControllerDefValidate(def, dev->data.controller); - case VIR_DOMAIN_DEVICE_LEASE: case VIR_DOMAIN_DEVICE_FS: case VIR_DOMAIN_DEVICE_INPUT: @@ -4895,6 +4838,7 @@ virDomainDeviceDefValidateInternal(const virDomainDeviceDef *dev, case VIR_DOMAIN_DEVICE_VIDEO: case VIR_DOMAIN_DEVICE_HOSTDEV: case VIR_DOMAIN_DEVICE_WATCHDOG: + case VIR_DOMAIN_DEVICE_CONTROLLER: case VIR_DOMAIN_DEVICE_GRAPHICS: case VIR_DOMAIN_DEVICE_HUB: case VIR_DOMAIN_DEVICE_SMARTCARD: diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 6545a93259..145a0127f2 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -1871,6 +1871,49 @@ qemuBuildDriveStr(virDomainDiskDefPtr disk, } +static bool +qemuCheckIOThreads(const virDomainDef *def, + virDomainDiskDefPtr disk) +{ + /* Right "type" of disk" */ + switch ((virDomainDiskBus)disk->bus) { + case VIR_DOMAIN_DISK_BUS_VIRTIO: + if (disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI && + disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("IOThreads only available for virtio pci and " + "virtio ccw disk")); + return false; + } + break; + + case VIR_DOMAIN_DISK_BUS_IDE: + case VIR_DOMAIN_DISK_BUS_FDC: + case VIR_DOMAIN_DISK_BUS_SCSI: + case VIR_DOMAIN_DISK_BUS_XEN: + case VIR_DOMAIN_DISK_BUS_USB: + case VIR_DOMAIN_DISK_BUS_UML: + case VIR_DOMAIN_DISK_BUS_SATA: + case VIR_DOMAIN_DISK_BUS_SD: + case VIR_DOMAIN_DISK_BUS_LAST: + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("IOThreads not available for bus %s target %s"), + virDomainDiskBusTypeToString(disk->bus), disk->dst); + return false; + } + + /* Can we find the disk iothread in the iothreadid list? */ + if (!virDomainIOThreadIDFind(def, disk->iothread)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Disk iothread '%u' not defined in iothreadid"), + disk->iothread); + return false; + } + + return true; +} + + char * qemuBuildDriveDevStr(const virDomainDef *def, virDomainDiskDefPtr disk, @@ -1889,6 +1932,9 @@ qemuBuildDriveDevStr(const virDomainDef *def, if (!qemuCheckCCWS390AddressSupport(def, disk->info, qemuCaps, disk->dst)) goto error; + if (disk->iothread && !qemuCheckIOThreads(def, disk)) + goto error; + switch (disk->bus) { case VIR_DOMAIN_DISK_BUS_IDE: if (disk->info.addr.drive.target != 0) { @@ -2521,6 +2567,52 @@ qemuBuildUSBControllerDevStr(virDomainControllerDefPtr def, } +/* qemuCheckSCSIControllerIOThreads: + * @domainDef: Pointer to domain def + * @def: Pointer to controller def + * @qemuCaps: Capabilities + * + * If this controller definition has iothreads set, let's make sure the + * configuration is right before adding to the command line + * + * Returns true if either supported or there are no iothreads for controller; + * otherwise, returns false if configuration is not quite right. + */ +static bool +qemuCheckSCSIControllerIOThreads(const virDomainDef *domainDef, + virDomainControllerDefPtr def) +{ + if (!def->iothread) + return true; + + if (def->model != VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("IOThreads only supported for virtio-scsi " + "controllers model is '%s'"), + virDomainControllerModelSCSITypeToString(def->model)); + return false; + } + + if (def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI && + def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("IOThreads only available for virtio pci and " + "virtio ccw controllers")); + return false; + } + + /* Can we find the controller iothread in the iothreadid list? */ + if (!virDomainIOThreadIDFind(domainDef, def->iothread)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("controller iothread '%u' not defined in iothreadid"), + def->iothread); + return false; + } + + return true; +} + + char * qemuBuildControllerDevStr(const virDomainDef *domainDef, virDomainControllerDefPtr def, @@ -2571,6 +2663,8 @@ qemuBuildControllerDevStr(const virDomainDef *domainDef, if (def->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) { virBufferAddLit(&buf, "virtio-scsi-ccw"); if (def->iothread) { + if (!qemuCheckSCSIControllerIOThreads(domainDef, def)) + goto error; virBufferAsprintf(&buf, ",iothread=iothread%u", def->iothread); } @@ -2583,6 +2677,8 @@ qemuBuildControllerDevStr(const virDomainDef *domainDef, } else { virBufferAddLit(&buf, "virtio-scsi-pci"); if (def->iothread) { + if (!qemuCheckSCSIControllerIOThreads(domainDef, def)) + goto error; virBufferAsprintf(&buf, ",iothread=iothread%u", def->iothread); }