Introduce a new function called qemuDomainDefValidatePSeriesFeature()
that will center all the PSeries validation done in qemu_command.c.
qemuDomainDefValidatePSeriesFeature() is then called during domain
define time, in qemuDomainDefValidateFeatures().
qemuxml2argvtest.c is also changed to include all the caps that now
are being validated in define time.
Signed-off-by: Daniel Henrique Barboza <danielhb413(a)gmail.com>
---
src/qemu/qemu_command.c | 68 +---------------------
src/qemu/qemu_domain.c | 118 ++++++++++++++++++++++++++++++++++++---
tests/qemuxml2argvtest.c | 43 +++++++++++++-
3 files changed, 152 insertions(+), 77 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 49a0dad8d4..12a9d47f44 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -7235,33 +7235,11 @@ qemuBuildMachineCommandLine(virCommandPtr cmd,
if (def->features[VIR_DOMAIN_FEATURE_HPT] == VIR_TRISTATE_SWITCH_ON) {
if (def->hpt_resizing != VIR_DOMAIN_HPT_RESIZING_NONE) {
- const char *str;
-
- 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;
- }
-
- virBufferAsprintf(&buf, ",resize-hpt=%s", str);
+ virBufferAsprintf(&buf, ",resize-hpt=%s",
+ virDomainHPTResizingTypeToString(def->hpt_resizing));
}
if (def->hpt_maxpagesize > 0) {
- if (!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;
- }
-
virBufferAsprintf(&buf, ",cap-hpt-max-page-size=%lluk",
def->hpt_maxpagesize);
}
@@ -7269,61 +7247,19 @@ qemuBuildMachineCommandLine(virCommandPtr cmd,
if (def->features[VIR_DOMAIN_FEATURE_HTM] != VIR_TRISTATE_SWITCH_ABSENT) {
const char *str;
-
- 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[VIR_DOMAIN_FEATURE_HTM]);
- if (!str) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("Invalid setting for HTM state"));
- return -1;
- }
-
virBufferAsprintf(&buf, ",cap-htm=%s", str);
}
if (def->features[VIR_DOMAIN_FEATURE_NESTED_HV] != VIR_TRISTATE_SWITCH_ABSENT) {
const char *str;
-
- 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[VIR_DOMAIN_FEATURE_NESTED_HV]);
- if (!str) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("Invalid setting for nested HV state"));
- return -1;
- }
-
virBufferAsprintf(&buf, ",cap-nested-hv=%s", str);
}
if (def->features[VIR_DOMAIN_FEATURE_CCF_ASSIST] != VIR_TRISTATE_SWITCH_ABSENT) {
const char *str;
-
- 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[VIR_DOMAIN_FEATURE_CCF_ASSIST]);
- if (!str) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("Invalid setting for ccf-assist state"));
- return -1;
- }
-
virBufferAsprintf(&buf, ",cap-ccf-assist=%s", str);
}
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 6f53e17b6a..e25b439a39 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -4812,6 +4812,114 @@ 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)
@@ -4839,16 +4947,8 @@ qemuDomainDefValidateFeatures(const virDomainDef *def,
case VIR_DOMAIN_FEATURE_HTM:
case VIR_DOMAIN_FEATURE_NESTED_HV:
case VIR_DOMAIN_FEATURE_CCF_ASSIST:
- if (def->features[i] != VIR_TRISTATE_SWITCH_ABSENT &&
- !qemuDomainIsPSeries(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);
+ if (qemuDomainDefValidatePSeriesFeature(def, qemuCaps, i) < 0)
return -1;
- }
break;
case VIR_DOMAIN_FEATURE_GIC:
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index ba4a92ec0a..cc1a82488e 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -1934,8 +1934,47 @@ mymain(void)
QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV,
QEMU_CAPS_MACHINE_PSERIES_CAP_CCF_ASSIST,
QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT);
- DO_TEST_FAILURE("pseries-features",
- QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE);
+
+ /* parse error: no QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT */
+ DO_TEST_PARSE_ERROR("pseries-features",
+ QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE,
+ QEMU_CAPS_MACHINE_PSERIES_CAP_HPT_MAX_PAGE_SIZE,
+ QEMU_CAPS_MACHINE_PSERIES_CAP_HTM,
+ QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV,
+ QEMU_CAPS_MACHINE_PSERIES_CAP_CCF_ASSIST);
+
+ /* parse error: no QEMU_CAPS_MACHINE_PSERIES_CAP_HPT_MAX_PAGE_SIZE */
+ DO_TEST_PARSE_ERROR("pseries-features",
+ QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE,
+ QEMU_CAPS_MACHINE_PSERIES_CAP_HTM,
+ QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV,
+ QEMU_CAPS_MACHINE_PSERIES_CAP_CCF_ASSIST,
+ QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT);
+
+ /* parse error: no QEMU_CAPS_MACHINE_PSERIES_CAP_HTM */
+ DO_TEST_PARSE_ERROR("pseries-features",
+ QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE,
+ QEMU_CAPS_MACHINE_PSERIES_CAP_HPT_MAX_PAGE_SIZE,
+ QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV,
+ QEMU_CAPS_MACHINE_PSERIES_CAP_CCF_ASSIST,
+ QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT);
+
+ /* parse error: no QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV */
+ DO_TEST_PARSE_ERROR("pseries-features",
+ QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE,
+ QEMU_CAPS_MACHINE_PSERIES_CAP_HPT_MAX_PAGE_SIZE,
+ QEMU_CAPS_MACHINE_PSERIES_CAP_HTM,
+ QEMU_CAPS_MACHINE_PSERIES_CAP_CCF_ASSIST,
+ QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT);
+
+ /* parse error: no QEMU_CAPS_MACHINE_PSERIES_CAP_CCF_ASSIST */
+ DO_TEST_PARSE_ERROR("pseries-features",
+ QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE,
+ QEMU_CAPS_MACHINE_PSERIES_CAP_HPT_MAX_PAGE_SIZE,
+ QEMU_CAPS_MACHINE_PSERIES_CAP_HTM,
+ QEMU_CAPS_MACHINE_PSERIES_CAP_NESTED_HV,
+ QEMU_CAPS_MACHINE_PSERIES_RESIZE_HPT);
+
DO_TEST_PARSE_ERROR("pseries-features-invalid-machine", NONE);
DO_TEST("pseries-serial-native",
--
2.23.0