diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 0b7275f9a3..52aee2b020 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -4682,6 +4682,48 @@ virDomainDefPostParse(virDomainDefPtr def, } +/** + * virDomainDiskAddressDiskBusCompatibility: + * @bus: disk bus type + * @addressType: disk address type + * + * Check if the specified disk address type @addressType is compatible + * with the specified disk bus type @bus. This function checks + * compatibility with the bus types SATA, SCSI, FDC, and IDE only, + * because only these are handled in common code. + * + * Returns true if compatible or can't be decided in common code, + * false if known to be not compatible. + */ +static bool +virDomainDiskAddressDiskBusCompatibility(virDomainDiskBus bus, + virDomainDeviceAddressType addressType) +{ + if (addressType == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) + return true; + + switch (bus) { + case VIR_DOMAIN_DISK_BUS_IDE: + case VIR_DOMAIN_DISK_BUS_FDC: + case VIR_DOMAIN_DISK_BUS_SCSI: + case VIR_DOMAIN_DISK_BUS_SATA: + return addressType == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE; + case VIR_DOMAIN_DISK_BUS_VIRTIO: + case VIR_DOMAIN_DISK_BUS_XEN: + case VIR_DOMAIN_DISK_BUS_USB: + case VIR_DOMAIN_DISK_BUS_UML: + case VIR_DOMAIN_DISK_BUS_SD: + case VIR_DOMAIN_DISK_BUS_LAST: + return true; + } + + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unexpected bus type '%d'"), + bus); + return true; +} + + static int virDomainDiskDefValidate(const virDomainDiskDef *disk) { @@ -4699,6 +4741,20 @@ virDomainDiskDefValidate(const virDomainDiskDef *disk) } } + /* Reject disks with a bus type that is not compatible with the + * given address type. The function considers only buses that are + * handled in common code. For other bus types it's not possible + * to decide compatibility in common code. + */ + if (!virDomainDiskAddressDiskBusCompatibility(disk->bus, disk->info.type)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Invalid address type '%s' for the disk '%s' with the bus type '%s'"), + virDomainDeviceAddressTypeToString(disk->info.type), + disk->dst, + virDomainDiskBusTypeToString(disk->bus)); + return -1; + } + return 0; }