qemu: wire up support for resetting NVRAM

We can now replace the existing NVRAM file on startup when
the API requests this.

Reviewed-by: Ján Tomko <jtomko@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
Daniel P. Berrangé 2022-02-03 16:10:45 +00:00
parent 12a658ecf7
commit 5413608dc2
6 changed files with 37 additions and 12 deletions

View File

@ -1589,7 +1589,8 @@ static virDomainPtr qemuDomainCreateXML(virConnectPtr conn,
virCheckFlags(VIR_DOMAIN_START_PAUSED |
VIR_DOMAIN_START_AUTODESTROY |
VIR_DOMAIN_START_VALIDATE, NULL);
VIR_DOMAIN_START_VALIDATE |
VIR_DOMAIN_START_RESET_NVRAM, NULL);
if (flags & VIR_DOMAIN_START_VALIDATE)
parse_flags |= VIR_DOMAIN_DEF_PARSE_VALIDATE_SCHEMA;
@ -1597,6 +1598,8 @@ static virDomainPtr qemuDomainCreateXML(virConnectPtr conn,
start_flags |= VIR_QEMU_PROCESS_START_PAUSED;
if (flags & VIR_DOMAIN_START_AUTODESTROY)
start_flags |= VIR_QEMU_PROCESS_START_AUTODESTROY;
if (flags & VIR_DOMAIN_START_RESET_NVRAM)
start_flags |= VIR_QEMU_PROCESS_START_RESET_NVRAM;
virNWFilterReadLockFilterUpdates();
@ -5753,11 +5756,15 @@ qemuDomainRestoreFlags(virConnectPtr conn,
virQEMUSaveData *data = NULL;
virFileWrapperFd *wrapperFd = NULL;
bool hook_taint = false;
bool reset_nvram = false;
virCheckFlags(VIR_DOMAIN_SAVE_BYPASS_CACHE |
VIR_DOMAIN_SAVE_RUNNING |
VIR_DOMAIN_SAVE_PAUSED, -1);
VIR_DOMAIN_SAVE_PAUSED |
VIR_DOMAIN_SAVE_RESET_NVRAM, -1);
if (flags & VIR_DOMAIN_SAVE_RESET_NVRAM)
reset_nvram = true;
virNWFilterReadLockFilterUpdates();
@ -5819,7 +5826,7 @@ qemuDomainRestoreFlags(virConnectPtr conn,
goto cleanup;
ret = qemuSaveImageStartVM(conn, driver, vm, &fd, data, path,
false, QEMU_ASYNC_JOB_START);
false, reset_nvram, QEMU_ASYNC_JOB_START);
qemuProcessEndJob(driver, vm);
@ -6028,6 +6035,7 @@ qemuDomainObjRestore(virConnectPtr conn,
const char *path,
bool start_paused,
bool bypass_cache,
bool reset_nvram,
qemuDomainAsyncJob asyncJob)
{
g_autoptr(virDomainDef) def = NULL;
@ -6086,7 +6094,7 @@ qemuDomainObjRestore(virConnectPtr conn,
virDomainObjAssignDef(vm, &def, true, NULL);
ret = qemuSaveImageStartVM(conn, driver, vm, &fd, data, path,
start_paused, asyncJob);
start_paused, reset_nvram, asyncJob);
cleanup:
virQEMUSaveDataFree(data);
@ -6298,11 +6306,13 @@ qemuDomainObjStart(virConnectPtr conn,
bool autodestroy = (flags & VIR_DOMAIN_START_AUTODESTROY) != 0;
bool bypass_cache = (flags & VIR_DOMAIN_START_BYPASS_CACHE) != 0;
bool force_boot = (flags & VIR_DOMAIN_START_FORCE_BOOT) != 0;
bool reset_nvram = (flags & VIR_DOMAIN_START_RESET_NVRAM) != 0;
unsigned int start_flags = VIR_QEMU_PROCESS_START_COLD;
qemuDomainObjPrivate *priv = vm->privateData;
start_flags |= start_paused ? VIR_QEMU_PROCESS_START_PAUSED : 0;
start_flags |= autodestroy ? VIR_QEMU_PROCESS_START_AUTODESTROY : 0;
start_flags |= reset_nvram ? VIR_QEMU_PROCESS_START_RESET_NVRAM : 0;
/*
* If there is a managed saved state restore it instead of starting
@ -6327,7 +6337,8 @@ qemuDomainObjStart(virConnectPtr conn,
priv->job.current->operation = VIR_DOMAIN_JOB_OPERATION_RESTORE;
ret = qemuDomainObjRestore(conn, driver, vm, managed_save,
start_paused, bypass_cache, asyncJob);
start_paused, bypass_cache,
reset_nvram, asyncJob);
if (ret == 0) {
if (unlink(managed_save) < 0)
@ -6379,7 +6390,8 @@ qemuDomainCreateWithFlags(virDomainPtr dom, unsigned int flags)
virCheckFlags(VIR_DOMAIN_START_PAUSED |
VIR_DOMAIN_START_AUTODESTROY |
VIR_DOMAIN_START_BYPASS_CACHE |
VIR_DOMAIN_START_FORCE_BOOT, -1);
VIR_DOMAIN_START_FORCE_BOOT |
VIR_DOMAIN_START_RESET_NVRAM, -1);
virNWFilterReadLockFilterUpdates();

View File

@ -4423,7 +4423,8 @@ qemuProcessUpdateCPU(virQEMUDriver *driver,
static int
qemuPrepareNVRAM(virQEMUDriver *driver,
virDomainObj *vm)
virDomainObj *vm,
bool reset_nvram)
{
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
int ret = -1;
@ -4435,7 +4436,8 @@ qemuPrepareNVRAM(virQEMUDriver *driver,
ssize_t r;
g_autofree char *tmp_dst_path = NULL;
if (!loader || !loader->nvram || virFileExists(loader->nvram))
if (!loader || !loader->nvram ||
(virFileExists(loader->nvram) && !reset_nvram))
return 0;
master_nvram_path = loader->templt;
@ -6981,7 +6983,7 @@ qemuProcessPrepareHost(virQEMUDriver *driver,
qemuProcessMakeDir(driver, vm, priv->channelTargetDir) < 0)
return -1;
if (qemuPrepareNVRAM(driver, vm) < 0)
if (qemuPrepareNVRAM(driver, vm, flags & VIR_QEMU_PROCESS_START_RESET_NVRAM) < 0)
return -1;
if (vm->def->vsock) {

View File

@ -79,6 +79,7 @@ typedef enum {
VIR_QEMU_PROCESS_START_PRETEND = 1 << 3,
VIR_QEMU_PROCESS_START_NEW = 1 << 4, /* internal, new VM is starting */
VIR_QEMU_PROCESS_START_GEN_VMID = 1 << 5, /* Generate a new VMID */
VIR_QEMU_PROCESS_START_RESET_NVRAM = 1 << 5, /* Re-initialize NVRAM from template */
} qemuProcessStartFlags;
int qemuProcessStart(virConnectPtr conn,

View File

@ -577,6 +577,7 @@ qemuSaveImageStartVM(virConnectPtr conn,
virQEMUSaveData *data,
const char *path,
bool start_paused,
bool reset_nvram,
qemuDomainAsyncJob asyncJob)
{
qemuDomainObjPrivate *priv = vm->privateData;
@ -590,6 +591,11 @@ qemuSaveImageStartVM(virConnectPtr conn,
virQEMUSaveHeader *header = &data->header;
g_autoptr(qemuDomainSaveCookie) cookie = NULL;
int rc = 0;
unsigned int start_flags = VIR_QEMU_PROCESS_START_PAUSED |
VIR_QEMU_PROCESS_START_GEN_VMID;
if (reset_nvram)
start_flags |= VIR_QEMU_PROCESS_START_RESET_NVRAM;
if (virSaveCookieParseString(data->cookie, (virObject **)&cookie,
virDomainXMLOptionGetSaveCookie(driver->xmlopt)) < 0)
@ -628,8 +634,7 @@ qemuSaveImageStartVM(virConnectPtr conn,
if (qemuProcessStart(conn, driver, vm, cookie ? cookie->cpu : NULL,
asyncJob, "stdio", *fd, path, NULL,
VIR_NETDEV_VPORT_PROFILE_OP_RESTORE,
VIR_QEMU_PROCESS_START_PAUSED |
VIR_QEMU_PROCESS_START_GEN_VMID) == 0)
start_flags) == 0)
started = true;
if (intermediatefd != -1) {

View File

@ -67,6 +67,7 @@ qemuSaveImageStartVM(virConnectPtr conn,
virQEMUSaveData *data,
const char *path,
bool start_paused,
bool reset_nvram,
qemuDomainAsyncJob asyncJob)
ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(5) ATTRIBUTE_NONNULL(6);

View File

@ -2243,7 +2243,11 @@ qemuSnapshotRevert(virDomainObj *vm,
virCheckFlags(VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING |
VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED |
VIR_DOMAIN_SNAPSHOT_REVERT_FORCE, -1);
VIR_DOMAIN_SNAPSHOT_REVERT_FORCE |
VIR_DOMAIN_SNAPSHOT_REVERT_RESET_NVRAM, -1);
if (flags & VIR_DOMAIN_SNAPSHOT_REVERT_RESET_NVRAM)
start_flags |= VIR_QEMU_PROCESS_START_RESET_NVRAM;
/* We have the following transitions, which create the following events:
* 1. inactive -> inactive: none