[PATCH v2] vmx: Add support for NVRAM configuration
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> --- src/vmx/vmx.c | 27 ++++++++++++++++++++++++ tests/vmx2xmldata/case-insensitive-1.xml | 1 + tests/vmx2xmldata/case-insensitive-2.xml | 1 + tests/vmx2xmldata/esx-in-the-wild-1.xml | 1 + tests/vmx2xmldata/esx-in-the-wild-10.xml | 1 + tests/vmx2xmldata/esx-in-the-wild-11.xml | 1 + tests/vmx2xmldata/esx-in-the-wild-12.xml | 1 + tests/vmx2xmldata/esx-in-the-wild-13.xml | 1 + tests/vmx2xmldata/esx-in-the-wild-14.xml | 1 + tests/vmx2xmldata/esx-in-the-wild-15.xml | 1 + tests/vmx2xmldata/esx-in-the-wild-16.xml | 1 + tests/vmx2xmldata/esx-in-the-wild-17.xml | 1 + tests/vmx2xmldata/esx-in-the-wild-2.xml | 1 + tests/vmx2xmldata/esx-in-the-wild-3.xml | 1 + tests/vmx2xmldata/esx-in-the-wild-4.xml | 1 + tests/vmx2xmldata/esx-in-the-wild-5.xml | 1 + tests/vmx2xmldata/esx-in-the-wild-6.xml | 1 + tests/vmx2xmldata/esx-in-the-wild-7.xml | 1 + tests/vmx2xmldata/esx-in-the-wild-8.xml | 1 + tests/vmx2xmldata/esx-in-the-wild-9.xml | 1 + tests/vmx2xmldata/gsx-in-the-wild-1.xml | 1 + tests/vmx2xmldata/gsx-in-the-wild-2.xml | 1 + tests/vmx2xmldata/gsx-in-the-wild-3.xml | 1 + tests/vmx2xmldata/gsx-in-the-wild-4.xml | 1 + 24 files changed, 50 insertions(+) diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c index 57dfd57cfc..4d21102861 100644 --- a/src/vmx/vmx.c +++ b/src/vmx/vmx.c @@ -1415,6 +1415,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) { @@ -2022,6 +2023,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; @@ -3738,6 +3755,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"); diff --git a/tests/vmx2xmldata/case-insensitive-1.xml b/tests/vmx2xmldata/case-insensitive-1.xml index 7cb6413941..e854cc37cb 100644 --- a/tests/vmx2xmldata/case-insensitive-1.xml +++ b/tests/vmx2xmldata/case-insensitive-1.xml @@ -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> diff --git a/tests/vmx2xmldata/case-insensitive-2.xml b/tests/vmx2xmldata/case-insensitive-2.xml index 188c3f3cd5..f5c4446ab5 100644 --- a/tests/vmx2xmldata/case-insensitive-2.xml +++ b/tests/vmx2xmldata/case-insensitive-2.xml @@ -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> diff --git a/tests/vmx2xmldata/esx-in-the-wild-1.xml b/tests/vmx2xmldata/esx-in-the-wild-1.xml index c15275ccb9..9ae28c8497 100644 --- a/tests/vmx2xmldata/esx-in-the-wild-1.xml +++ b/tests/vmx2xmldata/esx-in-the-wild-1.xml @@ -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> diff --git a/tests/vmx2xmldata/esx-in-the-wild-10.xml b/tests/vmx2xmldata/esx-in-the-wild-10.xml index 78129682bd..1b1fdf0662 100644 --- a/tests/vmx2xmldata/esx-in-the-wild-10.xml +++ b/tests/vmx2xmldata/esx-in-the-wild-10.xml @@ -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'/> diff --git a/tests/vmx2xmldata/esx-in-the-wild-11.xml b/tests/vmx2xmldata/esx-in-the-wild-11.xml index 8807a057d7..a0c1e05e90 100644 --- a/tests/vmx2xmldata/esx-in-the-wild-11.xml +++ b/tests/vmx2xmldata/esx-in-the-wild-11.xml @@ -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> diff --git a/tests/vmx2xmldata/esx-in-the-wild-12.xml b/tests/vmx2xmldata/esx-in-the-wild-12.xml index c5aad90677..ac83982b9b 100644 --- a/tests/vmx2xmldata/esx-in-the-wild-12.xml +++ b/tests/vmx2xmldata/esx-in-the-wild-12.xml @@ -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> diff --git a/tests/vmx2xmldata/esx-in-the-wild-13.xml b/tests/vmx2xmldata/esx-in-the-wild-13.xml index e6ef947d50..cef9fd4e48 100644 --- a/tests/vmx2xmldata/esx-in-the-wild-13.xml +++ b/tests/vmx2xmldata/esx-in-the-wild-13.xml @@ -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> diff --git a/tests/vmx2xmldata/esx-in-the-wild-14.xml b/tests/vmx2xmldata/esx-in-the-wild-14.xml index dd5c2434ee..f10707d1d4 100644 --- a/tests/vmx2xmldata/esx-in-the-wild-14.xml +++ b/tests/vmx2xmldata/esx-in-the-wild-14.xml @@ -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> diff --git a/tests/vmx2xmldata/esx-in-the-wild-15.xml b/tests/vmx2xmldata/esx-in-the-wild-15.xml index 77b094e9d5..78d15e1538 100644 --- a/tests/vmx2xmldata/esx-in-the-wild-15.xml +++ b/tests/vmx2xmldata/esx-in-the-wild-15.xml @@ -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> diff --git a/tests/vmx2xmldata/esx-in-the-wild-16.xml b/tests/vmx2xmldata/esx-in-the-wild-16.xml index 147bc0825a..51746dd77e 100644 --- a/tests/vmx2xmldata/esx-in-the-wild-16.xml +++ b/tests/vmx2xmldata/esx-in-the-wild-16.xml @@ -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> diff --git a/tests/vmx2xmldata/esx-in-the-wild-17.xml b/tests/vmx2xmldata/esx-in-the-wild-17.xml index ae66de7431..725f21bdf6 100644 --- a/tests/vmx2xmldata/esx-in-the-wild-17.xml +++ b/tests/vmx2xmldata/esx-in-the-wild-17.xml @@ -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> diff --git a/tests/vmx2xmldata/esx-in-the-wild-2.xml b/tests/vmx2xmldata/esx-in-the-wild-2.xml index 59071b5d3a..59c7087300 100644 --- a/tests/vmx2xmldata/esx-in-the-wild-2.xml +++ b/tests/vmx2xmldata/esx-in-the-wild-2.xml @@ -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> diff --git a/tests/vmx2xmldata/esx-in-the-wild-3.xml b/tests/vmx2xmldata/esx-in-the-wild-3.xml index cbe8eceb37..29c63d8d6b 100644 --- a/tests/vmx2xmldata/esx-in-the-wild-3.xml +++ b/tests/vmx2xmldata/esx-in-the-wild-3.xml @@ -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> diff --git a/tests/vmx2xmldata/esx-in-the-wild-4.xml b/tests/vmx2xmldata/esx-in-the-wild-4.xml index a8a2ac6f97..82eccca1c4 100644 --- a/tests/vmx2xmldata/esx-in-the-wild-4.xml +++ b/tests/vmx2xmldata/esx-in-the-wild-4.xml @@ -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> diff --git a/tests/vmx2xmldata/esx-in-the-wild-5.xml b/tests/vmx2xmldata/esx-in-the-wild-5.xml index 9eb975afe9..c88e60bdc0 100644 --- a/tests/vmx2xmldata/esx-in-the-wild-5.xml +++ b/tests/vmx2xmldata/esx-in-the-wild-5.xml @@ -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> diff --git a/tests/vmx2xmldata/esx-in-the-wild-6.xml b/tests/vmx2xmldata/esx-in-the-wild-6.xml index 51c74dd8a1..805f033561 100644 --- a/tests/vmx2xmldata/esx-in-the-wild-6.xml +++ b/tests/vmx2xmldata/esx-in-the-wild-6.xml @@ -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> diff --git a/tests/vmx2xmldata/esx-in-the-wild-7.xml b/tests/vmx2xmldata/esx-in-the-wild-7.xml index c117bd62e5..b641574776 100644 --- a/tests/vmx2xmldata/esx-in-the-wild-7.xml +++ b/tests/vmx2xmldata/esx-in-the-wild-7.xml @@ -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> diff --git a/tests/vmx2xmldata/esx-in-the-wild-8.xml b/tests/vmx2xmldata/esx-in-the-wild-8.xml index 47d22ced2a..f13e6f7448 100644 --- a/tests/vmx2xmldata/esx-in-the-wild-8.xml +++ b/tests/vmx2xmldata/esx-in-the-wild-8.xml @@ -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'/> diff --git a/tests/vmx2xmldata/esx-in-the-wild-9.xml b/tests/vmx2xmldata/esx-in-the-wild-9.xml index ee6be2527f..6b4d878ab1 100644 --- a/tests/vmx2xmldata/esx-in-the-wild-9.xml +++ b/tests/vmx2xmldata/esx-in-the-wild-9.xml @@ -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'/> diff --git a/tests/vmx2xmldata/gsx-in-the-wild-1.xml b/tests/vmx2xmldata/gsx-in-the-wild-1.xml index 62ec191c82..f189ff79e4 100644 --- a/tests/vmx2xmldata/gsx-in-the-wild-1.xml +++ b/tests/vmx2xmldata/gsx-in-the-wild-1.xml @@ -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> diff --git a/tests/vmx2xmldata/gsx-in-the-wild-2.xml b/tests/vmx2xmldata/gsx-in-the-wild-2.xml index 906e4657ca..d1c1bf39df 100644 --- a/tests/vmx2xmldata/gsx-in-the-wild-2.xml +++ b/tests/vmx2xmldata/gsx-in-the-wild-2.xml @@ -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> diff --git a/tests/vmx2xmldata/gsx-in-the-wild-3.xml b/tests/vmx2xmldata/gsx-in-the-wild-3.xml index 61812851e1..acc9d6ba5d 100644 --- a/tests/vmx2xmldata/gsx-in-the-wild-3.xml +++ b/tests/vmx2xmldata/gsx-in-the-wild-3.xml @@ -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> diff --git a/tests/vmx2xmldata/gsx-in-the-wild-4.xml b/tests/vmx2xmldata/gsx-in-the-wild-4.xml index a65a7d137f..8c73224846 100644 --- a/tests/vmx2xmldata/gsx-in-the-wild-4.xml +++ b/tests/vmx2xmldata/gsx-in-the-wild-4.xml @@ -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> -- 2.53.0
On Fri, Apr 24, 2026 at 19:23:25 +0530, Surya Gupta via Devel wrote:
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> --- src/vmx/vmx.c | 27 ++++++++++++++++++++++++ tests/vmx2xmldata/case-insensitive-1.xml | 1 + tests/vmx2xmldata/case-insensitive-2.xml | 1 + tests/vmx2xmldata/esx-in-the-wild-1.xml | 1 + tests/vmx2xmldata/esx-in-the-wild-10.xml | 1 + tests/vmx2xmldata/esx-in-the-wild-11.xml | 1 + tests/vmx2xmldata/esx-in-the-wild-12.xml | 1 + tests/vmx2xmldata/esx-in-the-wild-13.xml | 1 + tests/vmx2xmldata/esx-in-the-wild-14.xml | 1 + tests/vmx2xmldata/esx-in-the-wild-15.xml | 1 + tests/vmx2xmldata/esx-in-the-wild-16.xml | 1 + tests/vmx2xmldata/esx-in-the-wild-17.xml | 1 + tests/vmx2xmldata/esx-in-the-wild-2.xml | 1 + tests/vmx2xmldata/esx-in-the-wild-3.xml | 1 + tests/vmx2xmldata/esx-in-the-wild-4.xml | 1 + tests/vmx2xmldata/esx-in-the-wild-5.xml | 1 + tests/vmx2xmldata/esx-in-the-wild-6.xml | 1 + tests/vmx2xmldata/esx-in-the-wild-7.xml | 1 + tests/vmx2xmldata/esx-in-the-wild-8.xml | 1 + tests/vmx2xmldata/esx-in-the-wild-9.xml | 1 + tests/vmx2xmldata/gsx-in-the-wild-1.xml | 1 + tests/vmx2xmldata/gsx-in-the-wild-2.xml | 1 + tests/vmx2xmldata/gsx-in-the-wild-3.xml | 1 + tests/vmx2xmldata/gsx-in-the-wild-4.xml | 1 +
You didn't run the test suite [1]with this commit. 'virschematest' is broken ...
diff --git a/tests/vmx2xmldata/esx-in-the-wild-3.xml b/tests/vmx2xmldata/esx-in-the-wild-3.xml index cbe8eceb37..29c63d8d6b 100644 --- a/tests/vmx2xmldata/esx-in-the-wild-3.xml +++ b/tests/vmx2xmldata/esx-in-the-wild-3.xml @@ -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>
... as the 'vmware' syntax for nvram is not allowed in the schema. Following hunk needs to be added: diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng index c7f442a4c1..8c03e14d37 100644 --- a/src/conf/schemas/domaincommon.rng +++ b/src/conf/schemas/domaincommon.rng @@ -454,6 +454,9 @@ <group> <ref name="diskSource"/> </group> + <group> + <ref name="vmwarePath"/> + </group> </choice> </optional> </element> With that: Reviewed-by: Peter Krempa <pkrempa@redhat.com> I'll push the patch with the modification after the freeze is over. Make sure to run all tests for any further patch you post. [1]: https://www.libvirt.org/testing.html#unit-tests
Thanks Peter for the review, I'll make sure all tests pass before posting any future patches.
participants (3)
-
Peter Krempa -
Surya Gupta -
surygupt@redhat.com