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(a)gmail.com>
---
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