[libvirt PATCH 3/4] qemu: wire up support for resetting NVRAM

Daniel P. Berrangé berrange at redhat.com
Mon Feb 7 12:37:09 UTC 2022


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

Signed-off-by: Daniel P. Berrangé <berrange at 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




More information about the libvir-list mailing list