We can now replace the existing NVRAM file on startup when
the API requests this.
Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
---
src/qemu/qemu_driver.c | 24 ++++++++++++++++++------
src/qemu/qemu_process.c | 8 +++++---
src/qemu/qemu_process.h | 1 +
src/qemu/qemu_saveimage.c | 9 +++++++--
src/qemu/qemu_saveimage.h | 1 +
src/qemu/qemu_snapshot.c | 6 +++++-
6 files changed, 37 insertions(+), 12 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 698f57f00e..4831a81a78 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -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();
@@ -5754,11 +5757,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();
@@ -5820,7 +5827,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);
@@ -6029,6 +6036,7 @@ qemuDomainObjRestore(virConnectPtr conn,
const char *path,
bool start_paused,
bool bypass_cache,
+ bool reset_nvram,
qemuDomainAsyncJob asyncJob)
{
g_autoptr(virDomainDef) def = NULL;
@@ -6087,7 +6095,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);
@@ -6299,11 +6307,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
@@ -6328,7 +6338,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)
@@ -6380,7 +6391,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();
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index bc7c2a4dbc..659fba8672 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -4411,7 +4411,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;
@@ -4423,7 +4424,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;
@@ -6973,7 +6975,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) {
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index 1b1cc489f0..f6c0d63d11 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -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,
diff --git a/src/qemu/qemu_saveimage.c b/src/qemu/qemu_saveimage.c
index 557ee2cd21..c0139041eb 100644
--- a/src/qemu/qemu_saveimage.c
+++ b/src/qemu/qemu_saveimage.c
@@ -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) {
diff --git a/src/qemu/qemu_saveimage.h b/src/qemu/qemu_saveimage.h
index 45c5f35e11..a0daa4ad2b 100644
--- a/src/qemu/qemu_saveimage.h
+++ b/src/qemu/qemu_saveimage.h
@@ -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);
diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c
index 1887c70708..a99f1246e0 100644
--- a/src/qemu/qemu_snapshot.c
+++ b/src/qemu/qemu_snapshot.c
@@ -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
--
2.34.1