conf: introduce virDomainDefBootOrderPostParse

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.

Now it will also be run on domains created by other means than XML
parsing, since it will be run even for code paths that did not supply
the bootHash table before.

Signed-off-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
Ján Tomko 2018-05-28 14:31:50 +02:00
parent 8e5e5a95a5
commit 5b75a4a80d
5 changed files with 76 additions and 15 deletions

View File

@ -4939,10 +4939,76 @@ 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
virDomainDefBootOrderPostParse(virDomainDefPtr def)
{
virHashTablePtr bootHash = NULL;
int ret = -1;
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 +5019,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 +5031,11 @@ virDomainDefPostParseCommon(virDomainDefPtr def,
if (virDomainDefRejectDuplicatePanics(def) < 0)
return -1;
if (def->os.type == VIR_DOMAIN_OSTYPE_HVM &&
!(data->xmlopt->config.features & VIR_DOMAIN_DEF_FEATURE_NO_BOOT_ORDER) &&
virDomainDefBootOrderPostParse(def) < 0)
return -1;
if (virDomainDefPostParseTimer(def) < 0)
return -1;

View File

@ -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'/>

View File

@ -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>

View File

@ -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/>

View File

@ -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/5.91/x86_64/os </cmdline>
<boot dev='hd'/>
</os>
<clock offset='variable' adjustment='0' basis='utc'/>
<on_poweroff>destroy</on_poweroff>