qemu: fix EFI nvram removal on domain undefine

When undefining a UEFI domain its nvram file has to be properly handled as
well.  It's mandatory to use one of --nvram and --keep-nvram options when
'virsh undefine <domain>' is issued for a UEFI domain.  To fix the bug as
reported, virsh should return an error message if neither option is used
and the nvram file should be removed when --nvram is given.

The cause of the problem is that when qemuDomainUndefineFlags() is invoked
on an inactive domain the path to its nvram file is empty.  This commit
aims to fix this by formatting and filling in the path in time for the
nvram removal code to run properly.

https://bugzilla.redhat.com/show_bug.cgi?id=1751596

Signed-off-by: Pavel Mores <pmores@redhat.com>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Pavel Mores 2019-10-15 10:31:22 +02:00 committed by Michal Privoznik
parent a4f979c06e
commit b5308a1205
3 changed files with 29 additions and 8 deletions

View File

@ -15441,16 +15441,24 @@ qemuDomainDiskIsMissingLocalOptional(virDomainDiskDefPtr disk)
}
int
qemuDomainNVRAMPathFormat(virQEMUDriverConfigPtr cfg,
virDomainDefPtr def,
char **path)
{
return virAsprintf(path, "%s/%s_VARS.fd", cfg->nvramDir, def->name);
}
int
qemuDomainNVRAMPathGenerate(virQEMUDriverConfigPtr cfg,
virDomainDefPtr def)
{
if (def->os.loader &&
def->os.loader->type == VIR_DOMAIN_LOADER_TYPE_PFLASH &&
def->os.loader->readonly == VIR_TRISTATE_SWITCH_ON &&
def->os.loader->readonly == VIR_TRISTATE_BOOL_YES &&
!def->os.loader->nvram) {
return virAsprintf(&def->os.loader->nvram, "%s/%s_VARS.fd",
cfg->nvramDir, def->name);
return qemuDomainNVRAMPathFormat(cfg, def, &def->os.loader->nvram);
}
return 0;

View File

@ -1207,6 +1207,11 @@ qemuDomainIsUsingNoShutdown(qemuDomainObjPrivatePtr priv);
bool
qemuDomainDiskIsMissingLocalOptional(virDomainDiskDefPtr disk);
int
qemuDomainNVRAMPathFormat(virQEMUDriverConfigPtr cfg,
virDomainDefPtr def,
char **path);
int
qemuDomainNVRAMPathGenerate(virQEMUDriverConfigPtr cfg,
virDomainDefPtr def);

View File

@ -7828,6 +7828,7 @@ qemuDomainUndefineFlags(virDomainPtr dom,
int nsnapshots;
int ncheckpoints;
virQEMUDriverConfigPtr cfg = NULL;
g_autofree char *nvram_path = NULL;
virCheckFlags(VIR_DOMAIN_UNDEFINE_MANAGED_SAVE |
VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA |
@ -7905,14 +7906,21 @@ qemuDomainUndefineFlags(virDomainPtr dom,
}
}
if (vm->def->os.loader &&
vm->def->os.loader->nvram &&
virFileExists(vm->def->os.loader->nvram)) {
if (vm->def->os.firmware == VIR_DOMAIN_OS_DEF_FIRMWARE_EFI) {
if (qemuDomainNVRAMPathFormat(cfg, vm->def, &nvram_path) < 0)
goto endjob;
} else {
if (vm->def->os.loader &&
VIR_STRDUP(nvram_path, vm->def->os.loader->nvram) < 0)
goto endjob;
}
if (nvram_path && virFileExists(nvram_path)) {
if ((flags & VIR_DOMAIN_UNDEFINE_NVRAM)) {
if (unlink(vm->def->os.loader->nvram) < 0) {
if (unlink(nvram_path) < 0) {
virReportSystemError(errno,
_("failed to remove nvram: %s"),
vm->def->os.loader->nvram);
nvram_path);
goto endjob;
}
} else if (!(flags & VIR_DOMAIN_UNDEFINE_KEEP_NVRAM)) {