[PATCH 01/15] qemu: introducing qemu_validate.c/h

Daniel Henrique Barboza danielhb413 at gmail.com
Thu Mar 26 21:31:11 UTC 2020


While moving validations from qemu_command to qemu_domain,
it was suggested that we should instead move them to a new
file [1] because qemu_domain is already too crowded.

This patch introduces a new file to host such validations from
the QEMU driver. And to get things started, let's move
qemuDomainDefValidateFeatures() to this new file.

Signed-off-by: Daniel Henrique Barboza <danielhb413 at gmail.com>
---
 po/POTFILES.in           |   1 +
 src/qemu/Makefile.inc.am |   2 +
 src/qemu/qemu_domain.c   | 286 +-----------------------------------
 src/qemu/qemu_validate.c | 310 +++++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_validate.h |  29 ++++
 5 files changed, 344 insertions(+), 284 deletions(-)
 create mode 100644 src/qemu/qemu_validate.c
 create mode 100644 src/qemu/qemu_validate.h

diff --git a/po/POTFILES.in b/po/POTFILES.in
index 6103d4ca4a..c60f355f7f 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -170,6 +170,7 @@
 @SRCDIR@/src/qemu/qemu_qapi.c
 @SRCDIR@/src/qemu/qemu_slirp.c
 @SRCDIR@/src/qemu/qemu_tpm.c
+ at SRCDIR@/src/qemu/qemu_validate.c
 @SRCDIR@/src/qemu/qemu_vhost_user.c
 @SRCDIR@/src/qemu/qemu_vhost_user_gpu.c
 @SRCDIR@/src/qemu/qemu_virtiofs.c
diff --git a/src/qemu/Makefile.inc.am b/src/qemu/Makefile.inc.am
index 51cd79879d..1291b07124 100644
--- a/src/qemu/Makefile.inc.am
+++ b/src/qemu/Makefile.inc.am
@@ -73,6 +73,8 @@ QEMU_DRIVER_SOURCES = \
 	qemu/qemu_checkpoint.h \
 	qemu/qemu_backup.c \
 	qemu/qemu_backup.h \
+	qemu/qemu_validate.c \
+	qemu/qemu_validate.h \
 	$(NULL)
 
 
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 7d29f3f114..c4f36b000b 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -36,6 +36,7 @@
 #include "qemu_extdevice.h"
 #include "qemu_blockjob.h"
 #include "qemu_checkpoint.h"
+#include "qemu_validate.h"
 #include "viralloc.h"
 #include "virlog.h"
 #include "virerror.h"
@@ -5039,289 +5040,6 @@ qemuDomainDefGetVcpuHotplugGranularity(const virDomainDef *def)
 #define QEMU_MAX_VCPUS_WITHOUT_EIM 255
 
 
-static int
-qemuDomainDefValidatePSeriesFeature(const virDomainDef *def,
-                                    virQEMUCapsPtr qemuCaps,
-                                    int feature)
-{
-    const char *str;
-
-    if (def->features[feature] != VIR_TRISTATE_SWITCH_ABSENT &&
-        !qemuDomainIsPSeries(def)) {
-        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                       _("The '%s' feature is not supported for "
-                         "architecture '%s' or machine type '%s'"),
-                       virDomainFeatureTypeToString(feature),
-                       virArchToString(def->os.arch),
-                       def->os.machine);
-        return -1;
-    }
-
-    if (def->features[feature] == VIR_TRISTATE_SWITCH_ABSENT)
-        return 0;
-
-    switch (feature) {
-    case VIR_DOMAIN_FEATURE_HPT:
-        if (def->features[feature] != VIR_TRISTATE_SWITCH_ON)
-            break;
-
-        if (def->hpt_resizing != VIR_DOMAIN_HPT_RESIZING_NONE) {
-            if (!virQEMUCapsGet(qemuCaps,
-                                QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT)) {
-                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                               _("HTP resizing is not supported by this "
-                                "QEMU binary"));
-                return -1;
-            }
-
-            str = virDomainHPTResizingTypeToString(def->hpt_resizing);
-            if (!str) {
-                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                               _("Invalid setting for HPT resizing"));
-                return -1;
-            }
-        }
-
-        if (def->hpt_maxpagesize > 0 &&
-            !virQEMUCapsGet(qemuCaps,
-                            QEMU_CAPS_MACHINE_PSERIES_CAP_HPT_MAX_PAGE_SIZE)) {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                           _("Configuring the page size for HPT guests "
-                             "is not supported by this QEMU binary"));
-            return -1;
-        }
-        break;
-
-    case VIR_DOMAIN_FEATURE_HTM:
-        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_PSERIES_CAP_HTM)) {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                           _("HTM configuration is not supported by this "
-                             "QEMU binary"));
-            return -1;
-        }
-
-        str = virTristateSwitchTypeToString(def->features[feature]);
-        if (!str) {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                           _("Invalid setting for HTM state"));
-            return -1;
-        }
-
-        break;
-
-    case VIR_DOMAIN_FEATURE_NESTED_HV:
-        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV)) {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                           _("Nested HV configuration is not supported by "
-                             "this QEMU binary"));
-            return -1;
-        }
-
-        str = virTristateSwitchTypeToString(def->features[feature]);
-        if (!str) {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                           _("Invalid setting for nested HV state"));
-            return -1;
-        }
-
-        break;
-
-    case VIR_DOMAIN_FEATURE_CCF_ASSIST:
-        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_PSERIES_CAP_CCF_ASSIST)) {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                           _("ccf-assist configuration is not supported by "
-                           "this QEMU binary"));
-            return -1;
-        }
-
-        str = virTristateSwitchTypeToString(def->features[feature]);
-        if (!str) {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                           _("Invalid setting for ccf-assist state"));
-            return -1;
-        }
-
-        break;
-    }
-
-    return 0;
-}
-
-static int
-qemuDomainDefValidateFeatures(const virDomainDef *def,
-                              virQEMUCapsPtr qemuCaps)
-{
-    size_t i;
-
-    for (i = 0; i < VIR_DOMAIN_FEATURE_LAST; i++) {
-        const char *featureName = virDomainFeatureTypeToString(i);
-
-        switch ((virDomainFeature) i) {
-        case VIR_DOMAIN_FEATURE_IOAPIC:
-            if (def->features[i] != VIR_DOMAIN_IOAPIC_NONE) {
-                if (!ARCH_IS_X86(def->os.arch)) {
-                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                                   _("The '%s' feature is not supported for "
-                                     "architecture '%s' or machine type '%s'"),
-                                   featureName,
-                                   virArchToString(def->os.arch),
-                                   def->os.machine);
-                    return -1;
-                }
-
-                if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_KERNEL_IRQCHIP)) {
-                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                                   _("I/O APIC tuning is not supported by "
-                                     "this QEMU binary"));
-                    return -1;
-                }
-
-                switch ((virDomainIOAPIC) def->features[i]) {
-                case VIR_DOMAIN_IOAPIC_QEMU:
-                    if (!virQEMUCapsGet(qemuCaps,
-                                        QEMU_CAPS_MACHINE_KERNEL_IRQCHIP_SPLIT)) {
-                        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                                       _("split I/O APIC is not supported by this "
-                                         "QEMU binary"));
-                        return -1;
-                    }
-                    break;
-                case VIR_DOMAIN_IOAPIC_KVM:
-                case VIR_DOMAIN_IOAPIC_NONE:
-                case VIR_DOMAIN_IOAPIC_LAST:
-                    break;
-                }
-            }
-            break;
-
-        case VIR_DOMAIN_FEATURE_HPT:
-        case VIR_DOMAIN_FEATURE_HTM:
-        case VIR_DOMAIN_FEATURE_NESTED_HV:
-        case VIR_DOMAIN_FEATURE_CCF_ASSIST:
-            if (qemuDomainDefValidatePSeriesFeature(def, qemuCaps, i) < 0)
-                return -1;
-            break;
-
-        case VIR_DOMAIN_FEATURE_GIC:
-            if (def->features[i] == VIR_TRISTATE_SWITCH_ON &&
-                !qemuDomainIsARMVirt(def)) {
-                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                               _("The '%s' feature is not supported for "
-                                 "architecture '%s' or machine type '%s'"),
-                               featureName,
-                               virArchToString(def->os.arch),
-                               def->os.machine);
-                return -1;
-            }
-            break;
-
-        case VIR_DOMAIN_FEATURE_SMM:
-            if (def->features[i] != VIR_TRISTATE_SWITCH_ABSENT &&
-                !virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_SMM_OPT)) {
-                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                               _("smm is not available with this QEMU binary"));
-                return -1;
-            }
-            break;
-
-        case VIR_DOMAIN_FEATURE_KVM:
-            if (def->kvm_features[VIR_DOMAIN_KVM_DEDICATED] == VIR_TRISTATE_SWITCH_ON &&
-                (!def->cpu || def->cpu->mode != VIR_CPU_MODE_HOST_PASSTHROUGH)) {
-                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                               _("kvm-hint-dedicated=on is only applicable "
-                                 "for cpu host-passthrough"));
-                return -1;
-            }
-            break;
-
-        case VIR_DOMAIN_FEATURE_VMPORT:
-            if (def->features[i] != VIR_TRISTATE_SWITCH_ABSENT &&
-                !virQEMUCapsSupportsVmport(qemuCaps, def)) {
-
-                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                               _("vmport is not available "
-                                 "with this QEMU binary"));
-                return -1;
-            }
-            break;
-
-        case VIR_DOMAIN_FEATURE_VMCOREINFO:
-            if (def->features[i] == VIR_TRISTATE_SWITCH_ON &&
-                !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VMCOREINFO)) {
-                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                              _("vmcoreinfo is not available "
-                                "with this QEMU binary"));
-                return -1;
-            }
-            break;
-
-        case VIR_DOMAIN_FEATURE_APIC:
-            /* The kvm_pv_eoi feature is x86-only. */
-            if (def->features[i] != VIR_TRISTATE_SWITCH_ABSENT &&
-                def->apic_eoi != VIR_TRISTATE_SWITCH_ABSENT &&
-                !ARCH_IS_X86(def->os.arch)) {
-                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                               _("The 'eoi' attribute of the '%s' feature "
-                                 "is not supported for architecture '%s' or "
-                                 "machine type '%s'"),
-                                 featureName,
-                                 virArchToString(def->os.arch),
-                                 def->os.machine);
-                 return -1;
-            }
-            break;
-
-        case VIR_DOMAIN_FEATURE_PVSPINLOCK:
-            if (def->features[i] != VIR_TRISTATE_SWITCH_ABSENT &&
-                !ARCH_IS_X86(def->os.arch)) {
-                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                               _("The '%s' feature is not supported for "
-                                 "architecture '%s' or machine type '%s'"),
-                                 featureName,
-                                 virArchToString(def->os.arch),
-                                 def->os.machine);
-                 return -1;
-            }
-            break;
-
-        case VIR_DOMAIN_FEATURE_HYPERV:
-            if (def->features[i] != VIR_TRISTATE_SWITCH_ABSENT &&
-                !ARCH_IS_X86(def->os.arch) && !qemuDomainIsARMVirt(def)) {
-                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                               _("Hyperv features are not supported for "
-                                 "architecture '%s' or machine type '%s'"),
-                                 virArchToString(def->os.arch),
-                                 def->os.machine);
-                 return -1;
-            }
-            break;
-
-        case VIR_DOMAIN_FEATURE_PMU:
-            if (def->features[i] == VIR_TRISTATE_SWITCH_OFF &&
-                ARCH_IS_PPC64(def->os.arch)) {
-                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                               _("PMU is always enabled for architecture '%s'"),
-                                 virArchToString(def->os.arch));
-                 return -1;
-            }
-            break;
-
-        case VIR_DOMAIN_FEATURE_ACPI:
-        case VIR_DOMAIN_FEATURE_PAE:
-        case VIR_DOMAIN_FEATURE_HAP:
-        case VIR_DOMAIN_FEATURE_VIRIDIAN:
-        case VIR_DOMAIN_FEATURE_PRIVNET:
-        case VIR_DOMAIN_FEATURE_CAPABILITIES:
-        case VIR_DOMAIN_FEATURE_MSRS:
-        case VIR_DOMAIN_FEATURE_LAST:
-            break;
-        }
-    }
-
-    return 0;
-}
-
-
 static int
 qemuDomainDefValidateMemory(const virDomainDef *def,
                             virQEMUCapsPtr qemuCaps)
@@ -6036,7 +5754,7 @@ qemuDomainDefValidate(const virDomainDef *def,
         return -1;
     }
 
-    if (qemuDomainDefValidateFeatures(def, qemuCaps) < 0)
+    if (qemuValidateDomainDefFeatures(def, qemuCaps) < 0)
         return -1;
 
     if (qemuDomainDefValidateMemory(def, qemuCaps) < 0)
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
new file mode 100644
index 0000000000..8f4c5af582
--- /dev/null
+++ b/src/qemu/qemu_validate.c
@@ -0,0 +1,310 @@
+/*
+ * qemu_validate.c: QEMU general validation functions
+ *
+ * Copyright IBM Corp, 2020
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "qemu_validate.h"
+#include "qemu_domain.h"
+
+#define VIR_FROM_THIS VIR_FROM_QEMU
+
+
+static int
+qemuValidateDomainDefPSeriesFeature(const virDomainDef *def,
+                                    virQEMUCapsPtr qemuCaps,
+                                    int feature)
+{
+    const char *str;
+
+    if (def->features[feature] != VIR_TRISTATE_SWITCH_ABSENT &&
+        !qemuDomainIsPSeries(def)) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("The '%s' feature is not supported for "
+                         "architecture '%s' or machine type '%s'"),
+                       virDomainFeatureTypeToString(feature),
+                       virArchToString(def->os.arch),
+                       def->os.machine);
+        return -1;
+    }
+
+    if (def->features[feature] == VIR_TRISTATE_SWITCH_ABSENT)
+        return 0;
+
+    switch (feature) {
+    case VIR_DOMAIN_FEATURE_HPT:
+        if (def->features[feature] != VIR_TRISTATE_SWITCH_ON)
+            break;
+
+        if (def->hpt_resizing != VIR_DOMAIN_HPT_RESIZING_NONE) {
+            if (!virQEMUCapsGet(qemuCaps,
+                                QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT)) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                               _("HTP resizing is not supported by this "
+                                "QEMU binary"));
+                return -1;
+            }
+
+            str = virDomainHPTResizingTypeToString(def->hpt_resizing);
+            if (!str) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                               _("Invalid setting for HPT resizing"));
+                return -1;
+            }
+        }
+
+        if (def->hpt_maxpagesize > 0 &&
+            !virQEMUCapsGet(qemuCaps,
+                            QEMU_CAPS_MACHINE_PSERIES_CAP_HPT_MAX_PAGE_SIZE)) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                           _("Configuring the page size for HPT guests "
+                             "is not supported by this QEMU binary"));
+            return -1;
+        }
+        break;
+
+    case VIR_DOMAIN_FEATURE_HTM:
+        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_PSERIES_CAP_HTM)) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                           _("HTM configuration is not supported by this "
+                             "QEMU binary"));
+            return -1;
+        }
+
+        str = virTristateSwitchTypeToString(def->features[feature]);
+        if (!str) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                           _("Invalid setting for HTM state"));
+            return -1;
+        }
+
+        break;
+
+    case VIR_DOMAIN_FEATURE_NESTED_HV:
+        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV)) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                           _("Nested HV configuration is not supported by "
+                             "this QEMU binary"));
+            return -1;
+        }
+
+        str = virTristateSwitchTypeToString(def->features[feature]);
+        if (!str) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                           _("Invalid setting for nested HV state"));
+            return -1;
+        }
+
+        break;
+
+    case VIR_DOMAIN_FEATURE_CCF_ASSIST:
+        if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_PSERIES_CAP_CCF_ASSIST)) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                           _("ccf-assist configuration is not supported by "
+                           "this QEMU binary"));
+            return -1;
+        }
+
+        str = virTristateSwitchTypeToString(def->features[feature]);
+        if (!str) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                           _("Invalid setting for ccf-assist state"));
+            return -1;
+        }
+
+        break;
+    }
+
+    return 0;
+}
+
+
+int
+qemuValidateDomainDefFeatures(const virDomainDef *def,
+                              virQEMUCapsPtr qemuCaps)
+{
+    size_t i;
+
+    for (i = 0; i < VIR_DOMAIN_FEATURE_LAST; i++) {
+        const char *featureName = virDomainFeatureTypeToString(i);
+
+        switch ((virDomainFeature) i) {
+        case VIR_DOMAIN_FEATURE_IOAPIC:
+            if (def->features[i] != VIR_DOMAIN_IOAPIC_NONE) {
+                if (!ARCH_IS_X86(def->os.arch)) {
+                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                                   _("The '%s' feature is not supported for "
+                                     "architecture '%s' or machine type '%s'"),
+                                   featureName,
+                                   virArchToString(def->os.arch),
+                                   def->os.machine);
+                    return -1;
+                }
+
+                if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_KERNEL_IRQCHIP)) {
+                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                                   _("I/O APIC tuning is not supported by "
+                                     "this QEMU binary"));
+                    return -1;
+                }
+
+                switch ((virDomainIOAPIC) def->features[i]) {
+                case VIR_DOMAIN_IOAPIC_QEMU:
+                    if (!virQEMUCapsGet(qemuCaps,
+                                        QEMU_CAPS_MACHINE_KERNEL_IRQCHIP_SPLIT)) {
+                        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                                       _("split I/O APIC is not supported by this "
+                                         "QEMU binary"));
+                        return -1;
+                    }
+                    break;
+                case VIR_DOMAIN_IOAPIC_KVM:
+                case VIR_DOMAIN_IOAPIC_NONE:
+                case VIR_DOMAIN_IOAPIC_LAST:
+                    break;
+                }
+            }
+            break;
+
+        case VIR_DOMAIN_FEATURE_HPT:
+        case VIR_DOMAIN_FEATURE_HTM:
+        case VIR_DOMAIN_FEATURE_NESTED_HV:
+        case VIR_DOMAIN_FEATURE_CCF_ASSIST:
+            if (qemuValidateDomainDefPSeriesFeature(def, qemuCaps, i) < 0)
+                return -1;
+            break;
+
+        case VIR_DOMAIN_FEATURE_GIC:
+            if (def->features[i] == VIR_TRISTATE_SWITCH_ON &&
+                !qemuDomainIsARMVirt(def)) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                               _("The '%s' feature is not supported for "
+                                 "architecture '%s' or machine type '%s'"),
+                               featureName,
+                               virArchToString(def->os.arch),
+                               def->os.machine);
+                return -1;
+            }
+            break;
+
+        case VIR_DOMAIN_FEATURE_SMM:
+            if (def->features[i] != VIR_TRISTATE_SWITCH_ABSENT &&
+                !virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_SMM_OPT)) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                               _("smm is not available with this QEMU binary"));
+                return -1;
+            }
+            break;
+
+        case VIR_DOMAIN_FEATURE_KVM:
+            if (def->kvm_features[VIR_DOMAIN_KVM_DEDICATED] == VIR_TRISTATE_SWITCH_ON &&
+                (!def->cpu || def->cpu->mode != VIR_CPU_MODE_HOST_PASSTHROUGH)) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                               _("kvm-hint-dedicated=on is only applicable "
+                                 "for cpu host-passthrough"));
+                return -1;
+            }
+            break;
+
+        case VIR_DOMAIN_FEATURE_VMPORT:
+            if (def->features[i] != VIR_TRISTATE_SWITCH_ABSENT &&
+                !virQEMUCapsSupportsVmport(qemuCaps, def)) {
+
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                               _("vmport is not available "
+                                 "with this QEMU binary"));
+                return -1;
+            }
+            break;
+
+        case VIR_DOMAIN_FEATURE_VMCOREINFO:
+            if (def->features[i] == VIR_TRISTATE_SWITCH_ON &&
+                !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VMCOREINFO)) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                              _("vmcoreinfo is not available "
+                                "with this QEMU binary"));
+                return -1;
+            }
+            break;
+
+        case VIR_DOMAIN_FEATURE_APIC:
+            /* The kvm_pv_eoi feature is x86-only. */
+            if (def->features[i] != VIR_TRISTATE_SWITCH_ABSENT &&
+                def->apic_eoi != VIR_TRISTATE_SWITCH_ABSENT &&
+                !ARCH_IS_X86(def->os.arch)) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                               _("The 'eoi' attribute of the '%s' feature "
+                                 "is not supported for architecture '%s' or "
+                                 "machine type '%s'"),
+                                 featureName,
+                                 virArchToString(def->os.arch),
+                                 def->os.machine);
+                 return -1;
+            }
+            break;
+
+        case VIR_DOMAIN_FEATURE_PVSPINLOCK:
+            if (def->features[i] != VIR_TRISTATE_SWITCH_ABSENT &&
+                !ARCH_IS_X86(def->os.arch)) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                               _("The '%s' feature is not supported for "
+                                 "architecture '%s' or machine type '%s'"),
+                                 featureName,
+                                 virArchToString(def->os.arch),
+                                 def->os.machine);
+                 return -1;
+            }
+            break;
+
+        case VIR_DOMAIN_FEATURE_HYPERV:
+            if (def->features[i] != VIR_TRISTATE_SWITCH_ABSENT &&
+                !ARCH_IS_X86(def->os.arch) && !qemuDomainIsARMVirt(def)) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                               _("Hyperv features are not supported for "
+                                 "architecture '%s' or machine type '%s'"),
+                                 virArchToString(def->os.arch),
+                                 def->os.machine);
+                 return -1;
+            }
+            break;
+
+        case VIR_DOMAIN_FEATURE_PMU:
+            if (def->features[i] == VIR_TRISTATE_SWITCH_OFF &&
+                ARCH_IS_PPC64(def->os.arch)) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                               _("PMU is always enabled for architecture '%s'"),
+                                 virArchToString(def->os.arch));
+                 return -1;
+            }
+            break;
+
+        case VIR_DOMAIN_FEATURE_ACPI:
+        case VIR_DOMAIN_FEATURE_PAE:
+        case VIR_DOMAIN_FEATURE_HAP:
+        case VIR_DOMAIN_FEATURE_VIRIDIAN:
+        case VIR_DOMAIN_FEATURE_PRIVNET:
+        case VIR_DOMAIN_FEATURE_CAPABILITIES:
+        case VIR_DOMAIN_FEATURE_MSRS:
+        case VIR_DOMAIN_FEATURE_LAST:
+            break;
+        }
+    }
+
+    return 0;
+}
diff --git a/src/qemu/qemu_validate.h b/src/qemu/qemu_validate.h
new file mode 100644
index 0000000000..ed269f29e4
--- /dev/null
+++ b/src/qemu/qemu_validate.h
@@ -0,0 +1,29 @@
+/*
+ * qemu_validate.h: QEMU general validation functions
+ *
+ * Copyright IBM Corp, 2020
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <glib-object.h>
+
+#include "domain_conf.h"
+#include "qemu_capabilities.h"
+
+int qemuValidateDomainDefFeatures(const virDomainDef *def,
+                                  virQEMUCapsPtr qemuCaps);
-- 
2.25.1





More information about the libvir-list mailing list