Move the check for boot elements into a separate function
and remove its dependency on the parser-supplied bootHash table.
Reconstructing the hash table from the domain definition
effectively duplicates the check for duplicate boot order
values, also present in virDomainDeviceBootParseXML.
Signed-off-by: Ján Tomko <jtomko(a)redhat.com>
---
src/conf/domain_conf.c | 89 +++++++++++++++++++++++-----
tests/qemuargv2xmldata/nomachine-aarch64.xml | 1 +
tests/qemuargv2xmldata/nomachine-ppc64.xml | 1 +
tests/qemuargv2xmldata/nomachine-x86_64.xml | 1 +
tests/sexpr2xmldata/sexpr2xml-fv-kernel.xml | 1 +
5 files changed, 78 insertions(+), 15 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index d6ac47c629..f087a3680f 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -4939,10 +4939,79 @@ virDomainDefPostParseCPU(virDomainDefPtr def)
}
+static int
+virDomainDefCollectBootOrder(virDomainDefPtr def ATTRIBUTE_UNUSED,
+ virDomainDeviceDefPtr dev ATTRIBUTE_UNUSED,
+ virDomainDeviceInfoPtr info,
+ void *data)
+{
+ virHashTablePtr bootHash = data;
+ char *order = NULL;
+ int ret = -1;
+
+ if (info->bootIndex == 0)
+ return 0;
+
+ if (virAsprintf(&order, "%u", info->bootIndex) < 0)
+ goto cleanup;
+
+ if (virHashLookup(bootHash, order)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("boot order '%s' used for more than one
device"),
+ order);
+ goto cleanup;
+ }
+
+ if (virHashAddEntry(bootHash, order, (void *) 1) < 0)
+ goto cleanup;
+
+ ret = 0;
+
+ cleanup:
+ VIR_FREE(order);
+ return ret;
+}
+
+
+static int
+virDomainDefCheckBootOrder(virDomainDefPtr def)
+{
+ virHashTablePtr bootHash = NULL;
+ int ret = -1;
+
+ if (def->os.type != VIR_DOMAIN_OSTYPE_HVM)
+ return 0;
+
+ if (!(bootHash = virHashCreate(5, NULL)))
+ goto cleanup;
+
+ if (virDomainDeviceInfoIterate(def, virDomainDefCollectBootOrder, bootHash) < 0)
+ goto cleanup;
+
+ if (def->os.nBootDevs > 0 && virHashSize(bootHash) > 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("per-device boot elements cannot be used"
+ " together with os/boot elements"));
+ goto cleanup;
+ }
+
+ if (def->os.nBootDevs == 0 && virHashSize(bootHash) == 0) {
+ def->os.nBootDevs = 1;
+ def->os.bootDevs[0] = VIR_DOMAIN_BOOT_DISK;
+ }
+
+ ret = 0;
+
+ cleanup:
+ virHashFree(bootHash);
+ return ret;
+}
+
+
static int
virDomainDefPostParseCommon(virDomainDefPtr def,
struct virDomainDefPostParseDeviceIteratorData *data,
- virHashTablePtr bootHash)
+ virHashTablePtr bootHash ATTRIBUTE_UNUSED)
{
size_t i;
@@ -4953,20 +5022,6 @@ virDomainDefPostParseCommon(virDomainDefPtr def,
return -1;
}
- if (def->os.type == VIR_DOMAIN_OSTYPE_HVM && bootHash) {
- if (def->os.nBootDevs > 0 && virHashSize(bootHash) > 0) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("per-device boot elements cannot be used"
- " together with os/boot elements"));
- return -1;
- }
-
- if (def->os.nBootDevs == 0 && virHashSize(bootHash) == 0) {
- def->os.nBootDevs = 1;
- def->os.bootDevs[0] = VIR_DOMAIN_BOOT_DISK;
- }
- }
-
if (virDomainVcpuDefPostParse(def) < 0)
return -1;
@@ -4979,6 +5034,10 @@ virDomainDefPostParseCommon(virDomainDefPtr def,
if (virDomainDefRejectDuplicatePanics(def) < 0)
return -1;
+ if (!(data->xmlopt->config.features & VIR_DOMAIN_DEF_FEATURE_NO_BOOT_ORDER)
&&
+ virDomainDefCheckBootOrder(def) < 0)
+ return -1;
+
if (virDomainDefPostParseTimer(def) < 0)
return -1;
diff --git a/tests/qemuargv2xmldata/nomachine-aarch64.xml
b/tests/qemuargv2xmldata/nomachine-aarch64.xml
index eb8f9db803..9492423389 100644
--- a/tests/qemuargv2xmldata/nomachine-aarch64.xml
+++ b/tests/qemuargv2xmldata/nomachine-aarch64.xml
@@ -6,6 +6,7 @@
<vcpu placement='static'>1</vcpu>
<os>
<type arch='aarch64' machine='virt'>hvm</type>
+ <boot dev='hd'/>
</os>
<features>
<gic version='2'/>
diff --git a/tests/qemuargv2xmldata/nomachine-ppc64.xml
b/tests/qemuargv2xmldata/nomachine-ppc64.xml
index 439f9e9ac6..1f15a950e3 100644
--- a/tests/qemuargv2xmldata/nomachine-ppc64.xml
+++ b/tests/qemuargv2xmldata/nomachine-ppc64.xml
@@ -6,6 +6,7 @@
<vcpu placement='static'>1</vcpu>
<os>
<type arch='ppc64' machine='pseries'>hvm</type>
+ <boot dev='hd'/>
</os>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
diff --git a/tests/qemuargv2xmldata/nomachine-x86_64.xml
b/tests/qemuargv2xmldata/nomachine-x86_64.xml
index 71a36f0833..33cde4c55a 100644
--- a/tests/qemuargv2xmldata/nomachine-x86_64.xml
+++ b/tests/qemuargv2xmldata/nomachine-x86_64.xml
@@ -6,6 +6,7 @@
<vcpu placement='static'>1</vcpu>
<os>
<type arch='x86_64' machine='pc-0.11'>hvm</type>
+ <boot dev='hd'/>
</os>
<features>
<acpi/>
diff --git a/tests/sexpr2xmldata/sexpr2xml-fv-kernel.xml
b/tests/sexpr2xmldata/sexpr2xml-fv-kernel.xml
index afb9030681..a3d54ae3c1 100644
--- a/tests/sexpr2xmldata/sexpr2xml-fv-kernel.xml
+++ b/tests/sexpr2xmldata/sexpr2xml-fv-kernel.xml
@@ -10,6 +10,7 @@
<kernel>/var/lib/xen/vmlinuz.2Dn2YT</kernel>
<initrd>/var/lib/xen/initrd.img.0u-Vhq</initrd>
<cmdline>
method=http://download.fedora.devel.redhat.com/pub/fedora/linux/core/test...
</cmdline>
+ <boot dev='hd'/>
</os>
<clock offset='variable' adjustment='0' basis='utc'/>
<on_poweroff>destroy</on_poweroff>
--
2.16.1