qemuDomainChrDefValidate() has a lot of static helpers functions that needed to be moved as well. Other functions from qemuDomainDeviceDefValidate() that were also moved: - qemuValidateDomainSmartcardDef - qemuValidateDomainRNGDef - qemuValidateDomainRedirdevDef - qemuValidateDomainWatchdogDef Signed-off-by: Daniel Henrique Barboza <danielhb413@xxxxxxxxx> --- src/qemu/qemu_domain.c | 383 +-------------------------------------- src/qemu/qemu_validate.c | 373 ++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_validate.h | 11 ++ 3 files changed, 389 insertions(+), 378 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index caf5c5b73d..4726fa015d 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -5150,379 +5150,6 @@ qemuDomainDeviceDefValidateMemory(virDomainMemoryDefPtr mem, } -static int -qemuDomainChrSourceReconnectDefValidate(const virDomainChrSourceReconnectDef *def) -{ - if (def->enabled == VIR_TRISTATE_BOOL_YES && - def->timeout == 0) { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("chardev reconnect source timeout cannot be '0'")); - return -1; - } - - return 0; -} - - -static int -qemuDomainChrSourceDefValidate(const virDomainChrSourceDef *def, - virQEMUCapsPtr qemuCaps) -{ - switch ((virDomainChrType)def->type) { - case VIR_DOMAIN_CHR_TYPE_TCP: - if (qemuDomainChrSourceReconnectDefValidate(&def->data.tcp.reconnect) < 0) - return -1; - break; - - case VIR_DOMAIN_CHR_TYPE_UNIX: - if (qemuDomainChrSourceReconnectDefValidate(&def->data.nix.reconnect) < 0) - return -1; - break; - - case VIR_DOMAIN_CHR_TYPE_FILE: - if (def->data.file.append != VIR_TRISTATE_SWITCH_ABSENT && - !virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV_FILE_APPEND)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("append not supported in this QEMU binary")); - return -1; - } - break; - - case VIR_DOMAIN_CHR_TYPE_NULL: - case VIR_DOMAIN_CHR_TYPE_VC: - case VIR_DOMAIN_CHR_TYPE_PTY: - case VIR_DOMAIN_CHR_TYPE_DEV: - case VIR_DOMAIN_CHR_TYPE_PIPE: - case VIR_DOMAIN_CHR_TYPE_STDIO: - case VIR_DOMAIN_CHR_TYPE_UDP: - case VIR_DOMAIN_CHR_TYPE_SPICEVMC: - case VIR_DOMAIN_CHR_TYPE_SPICEPORT: - case VIR_DOMAIN_CHR_TYPE_NMDM: - case VIR_DOMAIN_CHR_TYPE_LAST: - break; - } - - if (def->logfile) { - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV_LOGFILE)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("logfile not supported in this QEMU binary")); - return -1; - } - } - - return 0; -} - - -static int -qemuDomainChrSerialTargetTypeToAddressType(int targetType) -{ - switch ((virDomainChrSerialTargetType)targetType) { - case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_ISA: - return VIR_DOMAIN_DEVICE_ADDRESS_TYPE_ISA; - case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_USB: - return VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB; - case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_PCI: - return VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; - case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_SPAPR_VIO: - return VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO; - case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_SYSTEM: - case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_SCLP: - case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_LAST: - case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_NONE: - break; - } - - return VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE; -} - - -static int -qemuDomainChrSerialTargetModelToTargetType(int targetModel) -{ - switch ((virDomainChrSerialTargetModel) targetModel) { - case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_ISA_SERIAL: - return VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_ISA; - case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_USB_SERIAL: - return VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_USB; - case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_PCI_SERIAL: - return VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_PCI; - case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_SPAPR_VTY: - return VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_SPAPR_VIO; - case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_PL011: - case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_16550A: - return VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_SYSTEM; - case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_SCLPCONSOLE: - case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_SCLPLMCONSOLE: - return VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_SCLP; - case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_NONE: - case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_LAST: - break; - } - - return VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_NONE; -} - - -static int -qemuDomainChrTargetDefValidate(const virDomainChrDef *chr) -{ - int expected; - - switch ((virDomainChrDeviceType)chr->deviceType) { - case VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL: - - /* Validate target type */ - switch ((virDomainChrSerialTargetType)chr->targetType) { - case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_ISA: - case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_USB: - case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_PCI: - case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_SPAPR_VIO: - - expected = qemuDomainChrSerialTargetTypeToAddressType(chr->targetType); - - if (chr->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && - chr->info.type != expected) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Target type '%s' requires address type '%s'"), - virDomainChrSerialTargetTypeToString(chr->targetType), - virDomainDeviceAddressTypeToString(expected)); - return -1; - } - break; - - case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_SYSTEM: - case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_SCLP: - if (chr->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Target type '%s' cannot have an " - "associated address"), - virDomainChrSerialTargetTypeToString(chr->targetType)); - return -1; - } - break; - - case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_NONE: - case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_LAST: - break; - } - - /* Validate target model */ - switch ((virDomainChrSerialTargetModel) chr->targetModel) { - case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_ISA_SERIAL: - case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_USB_SERIAL: - case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_PCI_SERIAL: - case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_SPAPR_VTY: - case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_PL011: - case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_SCLPCONSOLE: - case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_SCLPLMCONSOLE: - case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_16550A: - - expected = qemuDomainChrSerialTargetModelToTargetType(chr->targetModel); - - if (chr->targetType != expected) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Target model '%s' requires target type '%s'"), - virDomainChrSerialTargetModelTypeToString(chr->targetModel), - virDomainChrSerialTargetTypeToString(expected)); - return -1; - } - break; - - case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_NONE: - case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_LAST: - break; - } - break; - - case VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE: - case VIR_DOMAIN_CHR_DEVICE_TYPE_PARALLEL: - case VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL: - case VIR_DOMAIN_CHR_DEVICE_TYPE_LAST: - /* Nothing to do */ - break; - } - - return 0; -} - - -static int -qemuDomainChrDefValidate(const virDomainChrDef *dev, - const virDomainDef *def, - virQEMUCapsPtr qemuCaps) -{ - if (qemuDomainChrSourceDefValidate(dev->source, qemuCaps) < 0) - return -1; - - if (qemuDomainChrTargetDefValidate(dev) < 0) - return -1; - - if (dev->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_PARALLEL && - (ARCH_IS_S390(def->os.arch) || qemuDomainIsPSeries(def))) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("parallel ports are not supported")); - return -1; - } - - if (dev->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL) { - bool isCompatible = true; - - if (dev->targetType == VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_SYSTEM) { - if (dev->targetModel == VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_PL011 && - !qemuDomainIsARMVirt(def)) { - isCompatible = false; - } - if (dev->targetModel == VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_16550A && - !qemuDomainIsRISCVVirt(def)) { - isCompatible = false; - } - } - - if (!qemuDomainIsPSeries(def) && - (dev->targetType == VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_SPAPR_VIO || - dev->targetModel == VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_SPAPR_VTY)) { - isCompatible = false; - } - - if (!ARCH_IS_S390(def->os.arch) && - (dev->targetType == VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_SCLP || - dev->targetModel == VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_SCLPCONSOLE || - dev->targetModel == VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_SCLPLMCONSOLE)) { - isCompatible = false; - } - - if (!isCompatible) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Serial device with target type '%s' and " - "target model '%s' not compatible with guest " - "architecture or machine type"), - virDomainChrSerialTargetTypeToString(dev->targetType), - virDomainChrSerialTargetModelTypeToString(dev->targetModel)); - return -1; - } - } - - return 0; -} - - -static int -qemuDomainSmartcardDefValidate(const virDomainSmartcardDef *def, - virQEMUCapsPtr qemuCaps) -{ - switch (def->type) { - case VIR_DOMAIN_SMARTCARD_TYPE_HOST: - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CCID_EMULATED)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("this QEMU binary lacks smartcard host " - "mode support")); - return -1; - } - break; - - case VIR_DOMAIN_SMARTCARD_TYPE_HOST_CERTIFICATES: - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CCID_EMULATED)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("this QEMU binary lacks smartcard host " - "mode support")); - return -1; - } - break; - - case VIR_DOMAIN_SMARTCARD_TYPE_PASSTHROUGH: - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CCID_PASSTHRU)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("this QEMU binary lacks smartcard " - "passthrough mode support")); - return -1; - } - break; - - default: - virReportEnumRangeError(virDomainSmartcardType, def->type); - return -1; - } - - if (def->type == VIR_DOMAIN_SMARTCARD_TYPE_PASSTHROUGH && - qemuDomainChrSourceDefValidate(def->data.passthru, qemuCaps) < 0) - return -1; - - return 0; -} - - -static int -qemuDomainRNGDefValidate(const virDomainRNGDef *def, - virQEMUCapsPtr qemuCaps G_GNUC_UNUSED) -{ - if (def->backend == VIR_DOMAIN_RNG_BACKEND_EGD && - qemuDomainChrSourceDefValidate(def->source.chardev, qemuCaps) < 0) - return -1; - - return 0; -} - - -static int -qemuDomainRedirdevDefValidate(const virDomainRedirdevDef *def, - virQEMUCapsPtr qemuCaps) -{ - if (qemuDomainChrSourceDefValidate(def->source, qemuCaps) < 0) - return -1; - - return 0; -} - - -static int -qemuDomainWatchdogDefValidate(const virDomainWatchdogDef *dev, - const virDomainDef *def) -{ - switch ((virDomainWatchdogModel) dev->model) { - case VIR_DOMAIN_WATCHDOG_MODEL_I6300ESB: - if (dev->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && - dev->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("%s model of watchdog can go only on PCI bus"), - virDomainWatchdogModelTypeToString(dev->model)); - return -1; - } - break; - - case VIR_DOMAIN_WATCHDOG_MODEL_IB700: - if (dev->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && - dev->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_ISA) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("%s model of watchdog can go only on ISA bus"), - virDomainWatchdogModelTypeToString(dev->model)); - return -1; - } - break; - - case VIR_DOMAIN_WATCHDOG_MODEL_DIAG288: - if (dev->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("%s model of watchdog is virtual and cannot go on any bus."), - virDomainWatchdogModelTypeToString(dev->model)); - return -1; - } - if (!(ARCH_IS_S390(def->os.arch))) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("%s model of watchdog is allowed for s390 and s390x only"), - virDomainWatchdogModelTypeToString(dev->model)); - return -1; - } - break; - - case VIR_DOMAIN_WATCHDOG_MODEL_LAST: - break; - } - - return 0; -} - - int qemuDomainValidateActualNetDef(const virDomainNetDef *net, virQEMUCapsPtr qemuCaps) @@ -7609,23 +7236,23 @@ qemuDomainDeviceDefValidate(const virDomainDeviceDef *dev, break; case VIR_DOMAIN_DEVICE_CHR: - ret = qemuDomainChrDefValidate(dev->data.chr, def, qemuCaps); + ret = qemuValidateDomainChrDef(dev->data.chr, def, qemuCaps); break; case VIR_DOMAIN_DEVICE_SMARTCARD: - ret = qemuDomainSmartcardDefValidate(dev->data.smartcard, qemuCaps); + ret = qemuValidateDomainSmartcardDef(dev->data.smartcard, qemuCaps); break; case VIR_DOMAIN_DEVICE_RNG: - ret = qemuDomainRNGDefValidate(dev->data.rng, qemuCaps); + ret = qemuValidateDomainRNGDef(dev->data.rng, qemuCaps); break; case VIR_DOMAIN_DEVICE_REDIRDEV: - ret = qemuDomainRedirdevDefValidate(dev->data.redirdev, qemuCaps); + ret = qemuValidateDomainRedirdevDef(dev->data.redirdev, qemuCaps); break; case VIR_DOMAIN_DEVICE_WATCHDOG: - ret = qemuDomainWatchdogDefValidate(dev->data.watchdog, def); + ret = qemuValidateDomainWatchdogDef(dev->data.watchdog, def); break; case VIR_DOMAIN_DEVICE_HOSTDEV: diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 528170ac94..9b67c753c2 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -1158,3 +1158,376 @@ qemuValidateDomainDeviceDefNetwork(const virDomainNetDef *net, return 0; } + + +static int +qemuValidateDomainChrSourceReconnectDef(const virDomainChrSourceReconnectDef *def) +{ + if (def->enabled == VIR_TRISTATE_BOOL_YES && + def->timeout == 0) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("chardev reconnect source timeout cannot be '0'")); + return -1; + } + + return 0; +} + + +static int +qemuValidateChrSerialTargetTypeToAddressType(int targetType) +{ + switch ((virDomainChrSerialTargetType)targetType) { + case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_ISA: + return VIR_DOMAIN_DEVICE_ADDRESS_TYPE_ISA; + case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_USB: + return VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB; + case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_PCI: + return VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; + case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_SPAPR_VIO: + return VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO; + case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_SYSTEM: + case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_SCLP: + case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_LAST: + case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_NONE: + break; + } + + return VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE; +} + + +static int +qemuValidateChrSerialTargetModelToTargetType(int targetModel) +{ + switch ((virDomainChrSerialTargetModel) targetModel) { + case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_ISA_SERIAL: + return VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_ISA; + case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_USB_SERIAL: + return VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_USB; + case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_PCI_SERIAL: + return VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_PCI; + case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_SPAPR_VTY: + return VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_SPAPR_VIO; + case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_PL011: + case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_16550A: + return VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_SYSTEM; + case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_SCLPCONSOLE: + case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_SCLPLMCONSOLE: + return VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_SCLP; + case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_NONE: + case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_LAST: + break; + } + + return VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_NONE; +} + + +static int +qemuValidateDomainChrTargetDef(const virDomainChrDef *chr) +{ + int expected; + + switch ((virDomainChrDeviceType)chr->deviceType) { + case VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL: + + /* Validate target type */ + switch ((virDomainChrSerialTargetType)chr->targetType) { + case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_ISA: + case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_USB: + case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_PCI: + case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_SPAPR_VIO: + + expected = qemuValidateChrSerialTargetTypeToAddressType(chr->targetType); + + if (chr->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && + chr->info.type != expected) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target type '%s' requires address type '%s'"), + virDomainChrSerialTargetTypeToString(chr->targetType), + virDomainDeviceAddressTypeToString(expected)); + return -1; + } + break; + + case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_SYSTEM: + case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_SCLP: + if (chr->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target type '%s' cannot have an " + "associated address"), + virDomainChrSerialTargetTypeToString(chr->targetType)); + return -1; + } + break; + + case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_NONE: + case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_LAST: + break; + } + + /* Validate target model */ + switch ((virDomainChrSerialTargetModel) chr->targetModel) { + case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_ISA_SERIAL: + case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_USB_SERIAL: + case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_PCI_SERIAL: + case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_SPAPR_VTY: + case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_PL011: + case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_SCLPCONSOLE: + case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_SCLPLMCONSOLE: + case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_16550A: + + expected = qemuValidateChrSerialTargetModelToTargetType(chr->targetModel); + + if (chr->targetType != expected) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target model '%s' requires target type '%s'"), + virDomainChrSerialTargetModelTypeToString(chr->targetModel), + virDomainChrSerialTargetTypeToString(expected)); + return -1; + } + break; + + case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_NONE: + case VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_LAST: + break; + } + break; + + case VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE: + case VIR_DOMAIN_CHR_DEVICE_TYPE_PARALLEL: + case VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL: + case VIR_DOMAIN_CHR_DEVICE_TYPE_LAST: + /* Nothing to do */ + break; + } + + return 0; +} + + +static int +qemuValidateDomainChrSourceDef(const virDomainChrSourceDef *def, + virQEMUCapsPtr qemuCaps) +{ + switch ((virDomainChrType)def->type) { + case VIR_DOMAIN_CHR_TYPE_TCP: + if (qemuValidateDomainChrSourceReconnectDef(&def->data.tcp.reconnect) < 0) + return -1; + break; + + case VIR_DOMAIN_CHR_TYPE_UNIX: + if (qemuValidateDomainChrSourceReconnectDef(&def->data.nix.reconnect) < 0) + return -1; + break; + + case VIR_DOMAIN_CHR_TYPE_FILE: + if (def->data.file.append != VIR_TRISTATE_SWITCH_ABSENT && + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV_FILE_APPEND)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("append not supported in this QEMU binary")); + return -1; + } + break; + + case VIR_DOMAIN_CHR_TYPE_NULL: + case VIR_DOMAIN_CHR_TYPE_VC: + case VIR_DOMAIN_CHR_TYPE_PTY: + case VIR_DOMAIN_CHR_TYPE_DEV: + case VIR_DOMAIN_CHR_TYPE_PIPE: + case VIR_DOMAIN_CHR_TYPE_STDIO: + case VIR_DOMAIN_CHR_TYPE_UDP: + case VIR_DOMAIN_CHR_TYPE_SPICEVMC: + case VIR_DOMAIN_CHR_TYPE_SPICEPORT: + case VIR_DOMAIN_CHR_TYPE_NMDM: + case VIR_DOMAIN_CHR_TYPE_LAST: + break; + } + + if (def->logfile) { + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CHARDEV_LOGFILE)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("logfile not supported in this QEMU binary")); + return -1; + } + } + + return 0; +} + + +int +qemuValidateDomainChrDef(const virDomainChrDef *dev, + const virDomainDef *def, + virQEMUCapsPtr qemuCaps) +{ + if (qemuValidateDomainChrSourceDef(dev->source, qemuCaps) < 0) + return -1; + + if (qemuValidateDomainChrTargetDef(dev) < 0) + return -1; + + if (dev->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_PARALLEL && + (ARCH_IS_S390(def->os.arch) || qemuDomainIsPSeries(def))) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("parallel ports are not supported")); + return -1; + } + + if (dev->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL) { + bool isCompatible = true; + + if (dev->targetType == VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_SYSTEM) { + if (dev->targetModel == VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_PL011 && + !qemuDomainIsARMVirt(def)) { + isCompatible = false; + } + if (dev->targetModel == VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_16550A && + !qemuDomainIsRISCVVirt(def)) { + isCompatible = false; + } + } + + if (!qemuDomainIsPSeries(def) && + (dev->targetType == VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_SPAPR_VIO || + dev->targetModel == VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_SPAPR_VTY)) { + isCompatible = false; + } + + if (!ARCH_IS_S390(def->os.arch) && + (dev->targetType == VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_SCLP || + dev->targetModel == VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_SCLPCONSOLE || + dev->targetModel == VIR_DOMAIN_CHR_SERIAL_TARGET_MODEL_SCLPLMCONSOLE)) { + isCompatible = false; + } + + if (!isCompatible) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Serial device with target type '%s' and " + "target model '%s' not compatible with guest " + "architecture or machine type"), + virDomainChrSerialTargetTypeToString(dev->targetType), + virDomainChrSerialTargetModelTypeToString(dev->targetModel)); + return -1; + } + } + + return 0; +} + + +int +qemuValidateDomainSmartcardDef(const virDomainSmartcardDef *def, + virQEMUCapsPtr qemuCaps) +{ + switch (def->type) { + case VIR_DOMAIN_SMARTCARD_TYPE_HOST: + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CCID_EMULATED)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("this QEMU binary lacks smartcard host " + "mode support")); + return -1; + } + break; + + case VIR_DOMAIN_SMARTCARD_TYPE_HOST_CERTIFICATES: + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CCID_EMULATED)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("this QEMU binary lacks smartcard host " + "mode support")); + return -1; + } + break; + + case VIR_DOMAIN_SMARTCARD_TYPE_PASSTHROUGH: + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_CCID_PASSTHRU)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("this QEMU binary lacks smartcard " + "passthrough mode support")); + return -1; + } + break; + + default: + virReportEnumRangeError(virDomainSmartcardType, def->type); + return -1; + } + + if (def->type == VIR_DOMAIN_SMARTCARD_TYPE_PASSTHROUGH && + qemuValidateDomainChrSourceDef(def->data.passthru, qemuCaps) < 0) + return -1; + + return 0; +} + + +int +qemuValidateDomainRNGDef(const virDomainRNGDef *def, + virQEMUCapsPtr qemuCaps G_GNUC_UNUSED) +{ + if (def->backend == VIR_DOMAIN_RNG_BACKEND_EGD && + qemuValidateDomainChrSourceDef(def->source.chardev, qemuCaps) < 0) + return -1; + + return 0; +} + + +int +qemuValidateDomainRedirdevDef(const virDomainRedirdevDef *def, + virQEMUCapsPtr qemuCaps) +{ + if (qemuValidateDomainChrSourceDef(def->source, qemuCaps) < 0) + return -1; + + return 0; +} + + +int +qemuValidateDomainWatchdogDef(const virDomainWatchdogDef *dev, + const virDomainDef *def) +{ + switch ((virDomainWatchdogModel) dev->model) { + case VIR_DOMAIN_WATCHDOG_MODEL_I6300ESB: + if (dev->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && + dev->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("%s model of watchdog can go only on PCI bus"), + virDomainWatchdogModelTypeToString(dev->model)); + return -1; + } + break; + + case VIR_DOMAIN_WATCHDOG_MODEL_IB700: + if (dev->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && + dev->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_ISA) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("%s model of watchdog can go only on ISA bus"), + virDomainWatchdogModelTypeToString(dev->model)); + return -1; + } + break; + + case VIR_DOMAIN_WATCHDOG_MODEL_DIAG288: + if (dev->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("%s model of watchdog is virtual and cannot go on any bus."), + virDomainWatchdogModelTypeToString(dev->model)); + return -1; + } + if (!(ARCH_IS_S390(def->os.arch))) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("%s model of watchdog is allowed for s390 and s390x only"), + virDomainWatchdogModelTypeToString(dev->model)); + return -1; + } + break; + + case VIR_DOMAIN_WATCHDOG_MODEL_LAST: + break; + } + + return 0; +} diff --git a/src/qemu/qemu_validate.h b/src/qemu/qemu_validate.h index 437daebecd..d2238445be 100644 --- a/src/qemu/qemu_validate.h +++ b/src/qemu/qemu_validate.h @@ -30,3 +30,14 @@ int qemuValidateDomainDeviceDefAddress(const virDomainDeviceDef *dev, virQEMUCapsPtr qemuCaps); int qemuValidateDomainDeviceDefNetwork(const virDomainNetDef *net, virQEMUCapsPtr qemuCaps); +int qemuValidateDomainChrDef(const virDomainChrDef *dev, + const virDomainDef *def, + virQEMUCapsPtr qemuCaps); +int qemuValidateDomainSmartcardDef(const virDomainSmartcardDef *def, + virQEMUCapsPtr qemuCaps); +int qemuValidateDomainRNGDef(const virDomainRNGDef *def, + virQEMUCapsPtr qemuCaps); +int qemuValidateDomainRedirdevDef(const virDomainRedirdevDef *def, + virQEMUCapsPtr qemuCaps); +int qemuValidateDomainWatchdogDef(const virDomainWatchdogDef *dev, + const virDomainDef *def); -- 2.25.1