]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
vmx: Add support for NVRAM configuration
authorSurya Gupta via Devel <devel@lists.libvirt.org>
Fri, 24 Apr 2026 13:53:25 +0000 (19:23 +0530)
committerPeter Krempa <pkrempa@redhat.com>
Mon, 4 May 2026 09:57:17 +0000 (11:57 +0200)
Some VMware guests specify NVRAM storage using the 'nvram' parameter.
If found, parse it and store it in the domain's os.loader.nvram field,
which gets formatted as:

  <os>
    <type arch='x86_64'>hvm</type>
    <nvram>[datastore] directory/dokuwiki.nvram</nvram>
  </os>

The NVRAM path uses the same transformation functions as disk paths
(ctx->parseFileName and ctx->formatFileName) to ensure consistent
handling of datastore-qualified paths.
The NVRAM is stored as a virStorageSource with type VIR_STORAGE_TYPE_FILE
to ensure compatibility with libvirt's existing firmware handling
infrastructure.

Signed-off-by: Surya Gupta <surygupt@redhat.com>
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
25 files changed:
src/conf/schemas/domaincommon.rng
src/vmx/vmx.c
tests/vmx2xmldata/case-insensitive-1.xml
tests/vmx2xmldata/case-insensitive-2.xml
tests/vmx2xmldata/esx-in-the-wild-1.xml
tests/vmx2xmldata/esx-in-the-wild-10.xml
tests/vmx2xmldata/esx-in-the-wild-11.xml
tests/vmx2xmldata/esx-in-the-wild-12.xml
tests/vmx2xmldata/esx-in-the-wild-13.xml
tests/vmx2xmldata/esx-in-the-wild-14.xml
tests/vmx2xmldata/esx-in-the-wild-15.xml
tests/vmx2xmldata/esx-in-the-wild-16.xml
tests/vmx2xmldata/esx-in-the-wild-17.xml
tests/vmx2xmldata/esx-in-the-wild-2.xml
tests/vmx2xmldata/esx-in-the-wild-3.xml
tests/vmx2xmldata/esx-in-the-wild-4.xml
tests/vmx2xmldata/esx-in-the-wild-5.xml
tests/vmx2xmldata/esx-in-the-wild-6.xml
tests/vmx2xmldata/esx-in-the-wild-7.xml
tests/vmx2xmldata/esx-in-the-wild-8.xml
tests/vmx2xmldata/esx-in-the-wild-9.xml
tests/vmx2xmldata/gsx-in-the-wild-1.xml
tests/vmx2xmldata/gsx-in-the-wild-2.xml
tests/vmx2xmldata/gsx-in-the-wild-3.xml
tests/vmx2xmldata/gsx-in-the-wild-4.xml

index c7f442a4c18145e07fbf35a774ec00f0b27ae6b3..8c03e14d374a97984f38560a6cc83559231c796f 100644 (file)
           <group>
             <ref name="diskSource"/>
           </group>
+          <group>
+            <ref name="vmwarePath"/>
+          </group>
         </choice>
       </optional>
     </element>
index 9160602418ef88228d249566c54d91b0af21790c..34214b4bf3a5ca371239df25ea138faf20f6f71f 100644 (file)
@@ -1416,6 +1416,7 @@ virVMXParseConfig(virVMXContext *ctx,
     long long coresPerSocket = 0;
     virCPUDef *cpu = NULL;
     char *firmware = NULL;
+    g_autofree char *nvram = NULL;
     size_t saved_ndisks = 0;
 
     if (ctx->parseFileName == NULL) {
@@ -2032,6 +2033,22 @@ virVMXParseConfig(virVMXContext *ctx,
             VIR_TRISTATE_BOOL_YES;
     }
 
+    /* vmx:nvram */
+    if (virVMXGetConfigString(conf, "nvram", &nvram, true) < 0) {
+        goto cleanup;
+    }
+
+    if (nvram != NULL) {
+        g_autoptr(virStorageSource) n = virStorageSourceNew();
+
+        def->os.loader = virDomainLoaderDefNew();
+
+        n->type = VIR_STORAGE_TYPE_FILE;
+        if (ctx->parseFileName(nvram, ctx->opaque, &(n->path), false) < 0)
+            goto cleanup;
+        def->os.loader->nvram = g_steal_pointer(&n);
+    }
+
     if (virDomainDefPostParse(def, VIR_DOMAIN_DEF_PARSE_ABI_UPDATE,
                               xmlopt, NULL) < 0)
         goto cleanup;
@@ -3802,6 +3819,16 @@ virVMXFormatConfig(virVMXContext *ctx, virDomainXMLOption *xmlopt, virDomainDef
     if (def->os.firmware == VIR_DOMAIN_OS_DEF_FIRMWARE_EFI)
         virBufferAddLit(&buffer, "firmware = \"efi\"\n");
 
+    /* vmx:nvram */
+    if (def->os.loader && def->os.loader->nvram && def->os.loader->nvram->path) {
+        g_autofree char *nvramPath = NULL;
+
+        nvramPath = ctx->formatFileName(def->os.loader->nvram->path, ctx->opaque);
+        if (nvramPath != NULL) {
+            virBufferAsprintf(&buffer, "nvram = \"%s\"\n", nvramPath);
+        }
+    }
+
     if (virtualHW_version >= 7) {
         if (hasSCSI) {
             virBufferAddLit(&buffer, "pciBridge0.present = \"true\"\n");
index 7cb6413941b6a6fa189df6490c02bbb2f4596f97..e854cc37cb2cadbc9c72071fc0f9b75e88b4bd95 100644 (file)
@@ -9,6 +9,7 @@
   </cputune>
   <os>
     <type arch='i686'>hvm</type>
+    <nvram>[datastore] directory/FEDORA11.NVRAM</nvram>
   </os>
   <clock offset='utc'/>
   <on_poweroff>destroy</on_poweroff>
index 188c3f3cd5e70a80a570ce19dd54a8dcc67c6015..f5c4446ab5536529e6a106ffc298da0bbf46b448 100644 (file)
@@ -9,6 +9,7 @@
   </cputune>
   <os>
     <type arch='i686'>hvm</type>
+    <nvram>[datastore] directory/fedora11.nvram</nvram>
   </os>
   <clock offset='utc'/>
   <on_poweroff>destroy</on_poweroff>
index c15275ccb9afe9d2f7d67245e5cf7c25c1f7bf0e..9ae28c8497b7cc3e12ec021cb0d1b127ac812dc8 100644 (file)
@@ -9,6 +9,7 @@
   </cputune>
   <os>
     <type arch='i686'>hvm</type>
+    <nvram>[datastore] directory/Fedora11.nvram</nvram>
   </os>
   <clock offset='utc'/>
   <on_poweroff>destroy</on_poweroff>
index 78129682bd89536102aec4755fd1525350e27380..1b1fdf06623fc00a44cb042537a4501b60ba1fd5 100644 (file)
@@ -10,6 +10,7 @@
   </cputune>
   <os>
     <type arch='x86_64'>hvm</type>
+    <nvram>[datastore] directory/windows2019biosvmware.nvram</nvram>
   </os>
   <cpu>
     <topology sockets='1' dies='1' clusters='1' cores='2' threads='1'/>
index 73befdeca0c648511cbf0290941b1d2a03a10904..0dd297af43f0cb467e8d6da2e1210988d62bbf2c 100644 (file)
@@ -9,6 +9,7 @@
   </cputune>
   <os>
     <type arch='x86_64'>hvm</type>
+    <nvram>[datastore] directory/esx6.7-rhel7.7-x86_64.nvram</nvram>
   </os>
   <clock offset='utc'/>
   <on_poweroff>destroy</on_poweroff>
index c5aad9067790161b782feede46bfe379c16d1684..ac83982b9b88625c2f1035cc34fe7169c79beb54 100644 (file)
@@ -13,6 +13,7 @@
       <feature enabled='yes' name='enrolled-keys'/>
       <feature enabled='yes' name='secure-boot'/>
     </firmware>
+    <nvram>[datastore] directory/Auto-esx8.0-rhell9.3-efi-with-empty-cdrom.nvram</nvram>
   </os>
   <clock offset='utc'/>
   <on_poweroff>destroy</on_poweroff>
index e6ef947d501ffe468432c97a6f697e977fe83cdd..cef9fd4e48c967f6553d747ba10e97c116418d2d 100644 (file)
@@ -23,6 +23,7 @@ package:20.6.2
   </cputune>
   <os>
     <type arch='x86_64'>hvm</type>
+    <nvram>[datastore] directory/Test-Mig-VM-1 (01ce57d0-4e20-41a5-8b6c-bcbf49a032ec).nvram</nvram>
   </os>
   <clock offset='utc'/>
   <on_poweroff>destroy</on_poweroff>
index dd5c2434ee18c49c4626f239de1fad6cdea1459e..f10707d1d4127a4eb0efc92627a355d4a828964b 100644 (file)
@@ -7,6 +7,7 @@
   <vcpu placement='static'>12</vcpu>
   <os>
     <type arch='x86_64'>hvm</type>
+    <nvram>[datastore] directory/wild14.nvram</nvram>
   </os>
   <clock offset='utc'/>
   <on_poweroff>destroy</on_poweroff>
index 77b094e9d5b5d3779328ec50c5e3aab1efff1786..78d15e1538e66f58b4f1544e6ac15bc87ed91823 100644 (file)
@@ -9,6 +9,7 @@
   </cputune>
   <os>
     <type arch='x86_64'>hvm</type>
+    <nvram>[datastore] directory/dokuwiki.nvram</nvram>
   </os>
   <clock offset='utc'/>
   <on_poweroff>destroy</on_poweroff>
index 147bc0825a09578bc3d30ce153e66b976a57b0e0..51746dd77ef067b09d0df9215cf55fe4c3821117 100644 (file)
@@ -13,6 +13,7 @@
       <feature enabled='yes' name='enrolled-keys'/>
       <feature enabled='yes' name='secure-boot'/>
     </firmware>
+    <nvram>[datastore] directory/Auto-esx8.0-rhel9.4-efi-nvme-disk.nvram</nvram>
   </os>
   <clock offset='utc'/>
   <on_poweroff>destroy</on_poweroff>
index ae66de7431e1cb3c5a639482a3bf75fb028ea4eb..725f21bdf60196a61ce90c43b01eed4f01cf4f82 100644 (file)
@@ -10,6 +10,7 @@
   </cputune>
   <os>
     <type arch='x86_64'>hvm</type>
+    <nvram>[datastore] directory/esx8.0-win11-with-second-disk-in-subfolder.nvram</nvram>
   </os>
   <clock offset='utc'/>
   <on_poweroff>destroy</on_poweroff>
index 59071b5d3a06ee8c0280519a84d7637e64a929e4..59c7087300eafefbff4515849826ebe7b043367e 100644 (file)
@@ -6,6 +6,7 @@
   <vcpu placement='static' cpuset='0-2,5-7'>4</vcpu>
   <os>
     <type arch='x86_64'>hvm</type>
+    <nvram>[datastore] directory/Debian1.nvram</nvram>
   </os>
   <clock offset='utc'/>
   <on_poweroff>destroy</on_poweroff>
index cbe8eceb373d8d3ddd6a2209393ba15b54677dd7..29c63d8d6bfdab5a9ecef8c4b90de72bf7b9da53 100644 (file)
@@ -6,6 +6,7 @@
   <vcpu placement='static' cpuset='0,3-5'>2</vcpu>
   <os>
     <type arch='x86_64'>hvm</type>
+    <nvram>[datastore] directory/Debian2.nvram</nvram>
   </os>
   <clock offset='utc'/>
   <on_poweroff>destroy</on_poweroff>
index a8a2ac6f9712ff9380f69e0d3c7db8806641e42a..82eccca1c4bb3eb0e39031a95bf41965e5ded993 100644 (file)
@@ -9,6 +9,7 @@
   </cputune>
   <os>
     <type arch='i686'>hvm</type>
+    <nvram>[datastore] directory/virtMonServ1.nvram</nvram>
   </os>
   <clock offset='utc'/>
   <on_poweroff>destroy</on_poweroff>
index 9eb975afe9e37e39744a542d357c45aa7ef1db57..c88e60bdc070411dca9fdb3eef83402fda78bcdb 100644 (file)
@@ -13,6 +13,7 @@
   </cputune>
   <os>
     <type arch='x86_64'>hvm</type>
+    <nvram>[datastore] directory/vmtest.nvram</nvram>
   </os>
   <clock offset='utc'/>
   <on_poweroff>destroy</on_poweroff>
index 51c74dd8a1ee58e0bcf4d58f5ac452071a766481..805f033561290fa3a55506eca0479ecbe846a5bb 100644 (file)
@@ -6,6 +6,7 @@
   <vcpu placement='static'>1</vcpu>
   <os>
     <type arch='x86_64'>hvm</type>
+    <nvram>[datastore] directory/el6-test.nvram</nvram>
   </os>
   <clock offset='utc'/>
   <on_poweroff>destroy</on_poweroff>
index c117bd62e5eb3e1d41eeec90e6d1f65390655223..b641574776b6f223363c81cbad2db9ccb5ec67d6 100644 (file)
@@ -6,6 +6,7 @@
   <vcpu placement='static'>1</vcpu>
   <os>
     <type arch='x86_64'>hvm</type>
+    <nvram>[datastore] directory/esx-rhel6-mini.nvram</nvram>
   </os>
   <clock offset='utc'/>
   <on_poweroff>destroy</on_poweroff>
index 47d22ced2ad0b3e3c450f4e32072c8d10c6455cb..f13e6f7448807c7281c3af156f2433c1a01ce088 100644 (file)
@@ -9,6 +9,7 @@
   </cputune>
   <os>
     <type arch='x86_64'>hvm</type>
+    <nvram>[datastore] directory/RHEL7_6.nvram</nvram>
   </os>
   <cpu>
     <topology sockets='4' dies='1' clusters='1' cores='2' threads='1'/>
index ee6be2527fd9a00865afd7e911c99c8ab80a05f0..6b4d878ab18a31a81ee0f2f488e2ff73c5c75ac5 100644 (file)
@@ -10,6 +10,7 @@
   </cputune>
   <os>
     <type arch='x86_64'>hvm</type>
+    <nvram>[datastore] directory/v2v-windows-kkulkarn.nvram</nvram>
   </os>
   <cpu>
     <topology sockets='4' dies='1' clusters='1' cores='4' threads='1'/>
index 62ec191c82a4a5259a836da66aaa7dd1cf71517e..f189ff79e40b95250102143f028c262d6e4aad27 100644 (file)
@@ -6,6 +6,7 @@
   <vcpu placement='static'>1</vcpu>
   <os>
     <type arch='i686'>hvm</type>
+    <nvram>[datastore] directory/Debian-System1.nvram</nvram>
   </os>
   <clock offset='utc'/>
   <on_poweroff>destroy</on_poweroff>
index 906e4657ca7f2c0316e094749d7d07dd60fcfb3a..d1c1bf39dff6f9e6cb6486433de810db244bff21 100644 (file)
@@ -6,6 +6,7 @@
   <vcpu placement='static'>1</vcpu>
   <os>
     <type arch='i686'>hvm</type>
+    <nvram>[datastore] directory/Server2.nvram</nvram>
   </os>
   <clock offset='utc'/>
   <on_poweroff>destroy</on_poweroff>
index 61812851e1ffa2f923b700a2e14dff487caae389..acc9d6ba5dc6e24ca5116cef31c369ae01cefe12 100644 (file)
@@ -6,6 +6,7 @@
   <vcpu placement='static'>1</vcpu>
   <os>
     <type arch='i686'>hvm</type>
+    <nvram>[datastore] directory/Debian-System3.nvram</nvram>
   </os>
   <clock offset='utc'/>
   <on_poweroff>destroy</on_poweroff>
index a65a7d137ffea1788980619ba55c57724aec4210..8c7322484662abb4c835038e200654dfb974d7ed 100644 (file)
@@ -6,6 +6,7 @@
   <vcpu placement='static'>1</vcpu>
   <os>
     <type arch='i686'>hvm</type>
+    <nvram>[datastore] directory/Debian-System4.nvram</nvram>
   </os>
   <clock offset='utc'/>
   <on_poweroff>destroy</on_poweroff>