Currently, libvirt allows only local filepaths to specify
a NVRAM disk. Since, VMs can migrate across hosts, so making
it to virStorageSource type would help in uninturrupted access
NVRAM disks over network.
Signed-off-by: Prerna Saxena <prerna.saxena(a)nutanix.com>
Signed-off-by: Florian Schmidt <flosch(a)nutanix.com>
Signed-off-by: Rohit Kumar <rohit.kumar3(a)nutanix.com>
---
src/conf/domain_conf.c | 13 ++++++++++---
src/conf/domain_conf.h | 2 +-
src/qemu/qemu_cgroup.c | 3 ++-
src/qemu/qemu_command.c | 2 +-
src/qemu/qemu_domain.c | 14 ++++++++------
src/qemu/qemu_driver.c | 5 +++--
src/qemu/qemu_firmware.c | 17 ++++++++++++-----
src/qemu/qemu_namespace.c | 5 +++--
src/qemu/qemu_process.c | 5 +++--
src/security/security_dac.c | 6 ++++--
src/security/security_selinux.c | 6 ++++--
src/security/virt-aa-helper.c | 5 +++--
src/vbox/vbox_common.c | 2 +-
13 files changed, 55 insertions(+), 30 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 5dd269b283..b83c2f0e6a 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -3540,7 +3540,7 @@ virDomainLoaderDefFree(virDomainLoaderDef *loader)
return;
g_free(loader->path);
- g_free(loader->nvram);
+ virObjectUnref(loader->nvram);
g_free(loader->nvramTemplate);
g_free(loader);
}
@@ -18266,7 +18266,11 @@ virDomainDefParseBootLoaderOptions(virDomainDef *def,
fwAutoSelect) < 0)
return -1;
- def->os.loader->nvram = virXPathString("string(./os/nvram[1])",
ctxt);
+ if (virXPathNode("./os/nvram[1]", ctxt)) {
+ def->os.loader->nvram = g_new0(virStorageSource, 1);
+ def->os.loader->nvram->path =
virXPathString("string(./os/nvram[1])", ctxt);
+ def->os.loader->nvram->type = VIR_STORAGE_TYPE_FILE;
+ }
if (!fwAutoSelect)
def->os.loader->nvramTemplate =
virXPathString("string(./os/nvram[1]/@template)", ctxt);
@@ -26971,7 +26975,10 @@ virDomainLoaderDefFormat(virBuffer *buf,
virXMLFormatElementInternal(buf, "loader", &loaderAttrBuf,
&loaderChildBuf, false, false);
virBufferEscapeString(&nvramAttrBuf, " template='%s'",
loader->nvramTemplate);
- virBufferEscapeString(&nvramChildBuf, "%s", loader->nvram);
+ if (loader->nvram) {
+ if (loader->nvram->type == VIR_STORAGE_TYPE_FILE)
+ virBufferEscapeString(&nvramChildBuf, "%s",
loader->nvram->path);
+ }
virXMLFormatElementInternal(buf, "nvram", &nvramAttrBuf,
&nvramChildBuf, false, false);
}
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 694491cd63..eecee1075c 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2234,7 +2234,7 @@ struct _virDomainLoaderDef {
virTristateBool readonly;
virDomainLoader type;
virTristateBool secure;
- char *nvram; /* path to non-volatile RAM */
+ virStorageSource *nvram;
char *nvramTemplate; /* user override of path to master nvram */
};
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index aa0c927578..d46c9ff36a 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -581,7 +581,8 @@ qemuSetupFirmwareCgroup(virDomainObj *vm)
return -1;
if (vm->def->os.loader->nvram &&
- qemuSetupImagePathCgroup(vm, vm->def->os.loader->nvram, false) < 0)
+ vm->def->os.loader->nvram->type == VIR_STORAGE_TYPE_FILE &&
+ qemuSetupImagePathCgroup(vm, vm->def->os.loader->nvram->path, false)
< 0)
return -1;
return 0;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index bb45954108..1393d4fc22 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -9648,7 +9648,7 @@ qemuBuildDomainLoaderPflashCommandLine(virCommand *cmd,
if (loader->nvram) {
virBufferAddLit(&buf, "file=");
- virQEMUBuildBufferEscapeComma(&buf, loader->nvram);
+ virQEMUBuildBufferEscapeComma(&buf, loader->nvram->path);
virBufferAsprintf(&buf, ",if=pflash,format=raw,unit=%d", unit);
virCommandAddArg(cmd, "-drive");
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index a4334de158..70e96cc5a5 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -4663,8 +4663,12 @@ qemuDomainDefPostParse(virDomainDef *def,
}
if (virDomainDefHasOldStyleROUEFI(def) &&
- !def->os.loader->nvram)
- qemuDomainNVRAMPathFormat(cfg, def, &def->os.loader->nvram);
+ (!def->os.loader->nvram || !def->os.loader->nvram->path)) {
+ if (!def->os.loader->nvram)
+ def->os.loader->nvram = g_new0(virStorageSource, 1);
+ def->os.loader->nvram->type = VIR_STORAGE_TYPE_FILE;
+ qemuDomainNVRAMPathFormat(cfg, def, &def->os.loader->nvram->path);
+ }
if (qemuDomainDefAddDefaultDevices(driver, def, qemuCaps) < 0)
return -1;
@@ -11349,11 +11353,9 @@ qemuDomainInitializePflashStorageSource(virDomainObj *vm)
if (def->os.loader->nvram) {
- pflash1 = virStorageSourceNew();
- pflash1->type = VIR_STORAGE_TYPE_FILE;
+ if (!(pflash1 = virStorageSourceCopy(def->os.loader->nvram, false)))
+ return -1;
pflash1->format = VIR_STORAGE_FILE_RAW;
- pflash1->path = g_strdup(def->os.loader->nvram);
- pflash1->readonly = false;
pflash1->nodeformat = g_strdup("libvirt-pflash1-format");
pflash1->nodestorage = g_strdup("libvirt-pflash1-storage");
}
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 8c0e36e9b2..2b2bd8d20c 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6615,8 +6615,9 @@ qemuDomainUndefineFlags(virDomainPtr dom,
}
}
- if (vm->def->os.loader && vm->def->os.loader->nvram) {
- nvram_path = g_strdup(vm->def->os.loader->nvram);
+ if (vm->def->os.loader && vm->def->os.loader->nvram
&&
+ vm->def->os.loader->nvram->type == VIR_STORAGE_TYPE_FILE) {
+ nvram_path = g_strdup(vm->def->os.loader->nvram->path);
} else if (vm->def->os.firmware == VIR_DOMAIN_OS_DEF_FIRMWARE_EFI) {
qemuDomainNVRAMPathFormat(cfg, vm->def, &nvram_path);
}
diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c
index 51223faadf..6556a613a8 100644
--- a/src/qemu/qemu_firmware.c
+++ b/src/qemu/qemu_firmware.c
@@ -1192,13 +1192,16 @@ qemuFirmwareEnableFeatures(virQEMUDriver *driver,
VIR_FREE(def->os.loader->nvramTemplate);
def->os.loader->nvramTemplate =
g_strdup(flash->nvram_template.filename);
- if (!def->os.loader->nvram)
- qemuDomainNVRAMPathFormat(cfg, def, &def->os.loader->nvram);
+ if (!def->os.loader->nvram) {
+ def->os.loader->nvram = g_new0(virStorageSource, 1);
+ def->os.loader->nvram->type = VIR_STORAGE_TYPE_FILE;
+ qemuDomainNVRAMPathFormat(cfg, def,
&def->os.loader->nvram->path);
+ }
VIR_DEBUG("decided on firmware '%s' template '%s' NVRAM
'%s'",
def->os.loader->path,
def->os.loader->nvramTemplate,
- def->os.loader->nvram);
+ def->os.loader->nvram->path);
break;
case QEMU_FIRMWARE_DEVICE_KERNEL:
@@ -1364,8 +1367,12 @@ qemuFirmwareFillDomain(virQEMUDriver *driver,
* its path in domain XML) but no template for NVRAM was
* specified and the varstore doesn't exist ... */
if (!virDomainDefHasOldStyleROUEFI(def) ||
- def->os.loader->nvramTemplate ||
- (!reset_nvram && virFileExists(def->os.loader->nvram)))
+ def->os.loader->nvramTemplate)
+ return 0;
+
+ if (!reset_nvram && def->os.loader->nvram &&
+ def->os.loader->nvram->type == VIR_STORAGE_TYPE_FILE
+ && virFileExists(def->os.loader->nvram->path))
return 0;
/* ... then we want to consult JSON FW descriptors first,
diff --git a/src/qemu/qemu_namespace.c b/src/qemu/qemu_namespace.c
index 23681b14a4..18a24635ad 100644
--- a/src/qemu/qemu_namespace.c
+++ b/src/qemu/qemu_namespace.c
@@ -572,8 +572,9 @@ qemuDomainSetupLoader(virDomainObj *vm,
case VIR_DOMAIN_LOADER_TYPE_PFLASH:
*paths = g_slist_prepend(*paths, g_strdup(loader->path));
- if (loader->nvram)
- *paths = g_slist_prepend(*paths, g_strdup(loader->nvram));
+ if (loader->nvram &&
+ loader->nvram->type == VIR_STORAGE_TYPE_FILE)
+ *paths = g_slist_prepend(*paths, g_strdup(loader->nvram->path));
break;
case VIR_DOMAIN_LOADER_TYPE_NONE:
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 2e11d24be2..e53a26c6fd 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -4472,7 +4472,8 @@ qemuPrepareNVRAM(virQEMUDriver *driver,
struct qemuPrepareNVRAMHelperData data;
if (!loader || !loader->nvram ||
- (virFileExists(loader->nvram) && !reset_nvram))
+ loader->nvram->type != VIR_STORAGE_TYPE_FILE ||
+ (virFileExists(loader->nvram->path) && !reset_nvram))
return 0;
master_nvram_path = loader->nvramTemplate;
@@ -4504,7 +4505,7 @@ qemuPrepareNVRAM(virQEMUDriver *driver,
data.srcFD = srcFD;
data.srcPath = master_nvram_path;
- if (virFileRewrite(loader->nvram,
+ if (virFileRewrite(loader->nvram->path,
S_IRUSR | S_IWUSR,
cfg->user, cfg->group,
qemuPrepareNVRAMHelper,
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index e9e316551e..66c36c57a3 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -1971,7 +1971,8 @@ virSecurityDACRestoreAllLabel(virSecurityManager *mgr,
}
if (def->os.loader && def->os.loader->nvram &&
- virSecurityDACRestoreFileLabel(mgr, def->os.loader->nvram) < 0)
+ def->os.loader->nvram->type == VIR_STORAGE_TYPE_FILE &&
+ virSecurityDACRestoreFileLabel(mgr, def->os.loader->nvram->path) <
0)
rc = -1;
if (def->os.kernel &&
@@ -2182,8 +2183,9 @@ virSecurityDACSetAllLabel(virSecurityManager *mgr,
}
if (def->os.loader && def->os.loader->nvram &&
+ def->os.loader->nvram->type == VIR_STORAGE_TYPE_FILE &&
virSecurityDACSetOwnership(mgr, NULL,
- def->os.loader->nvram,
+ def->os.loader->nvram->path,
user, group, true) < 0)
return -1;
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index 6f02baf2ce..1b6b67e8c7 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -2806,7 +2806,8 @@ virSecuritySELinuxRestoreAllLabel(virSecurityManager *mgr,
}
if (def->os.loader && def->os.loader->nvram &&
- virSecuritySELinuxRestoreFileLabel(mgr, def->os.loader->nvram, true) <
0)
+ def->os.loader->nvram->type == VIR_STORAGE_TYPE_FILE &&
+ virSecuritySELinuxRestoreFileLabel(mgr, def->os.loader->nvram->path,
true) < 0)
rc = -1;
if (def->os.kernel &&
@@ -3212,8 +3213,9 @@ virSecuritySELinuxSetAllLabel(virSecurityManager *mgr,
/* This is different than kernel or initrd. The nvram store
* is really a disk, qemu can read and write to it. */
if (def->os.loader && def->os.loader->nvram &&
+ def->os.loader->nvram->type == VIR_STORAGE_TYPE_FILE &&
secdef && secdef->imagelabel &&
- virSecuritySELinuxSetFilecon(mgr, def->os.loader->nvram,
+ virSecuritySELinuxSetFilecon(mgr, def->os.loader->nvram->path,
secdef->imagelabel, true) < 0)
return -1;
diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c
index 1f1cce8b3d..d4eb8b08c9 100644
--- a/src/security/virt-aa-helper.c
+++ b/src/security/virt-aa-helper.c
@@ -1006,8 +1006,9 @@ get_files(vahControl * ctl)
if (vah_add_file(&buf, ctl->def->os.loader->path, "rk") !=
0)
goto cleanup;
- if (ctl->def->os.loader && ctl->def->os.loader->nvram)
- if (vah_add_file(&buf, ctl->def->os.loader->nvram, "rwk")
!= 0)
+ if (ctl->def->os.loader && ctl->def->os.loader->nvram
&&
+ ctl->def->os.loader->nvram->type = VIR_STORAGE_TYPE_FILE)
+ if (vah_add_file(&buf, ctl->def->os.loader->nvram->path,
"rwk") != 0)
goto cleanup;
for (i = 0; i < ctl->def->ngraphics; i++) {
diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c
index 34e555644c..214d5e84b8 100644
--- a/src/vbox/vbox_common.c
+++ b/src/vbox/vbox_common.c
@@ -992,7 +992,7 @@ vboxSetBootDeviceOrder(virDomainDef *def, struct _vboxDriver *data,
VIR_DEBUG("def->os.loader->path %s",
def->os.loader->path);
VIR_DEBUG("def->os.loader->readonly %d",
def->os.loader->readonly);
VIR_DEBUG("def->os.loader->type %d",
def->os.loader->type);
- VIR_DEBUG("def->os.loader->nvram %s",
def->os.loader->nvram);
+ VIR_DEBUG("def->os.loader->nvram->path %s",
def->os.loader->nvram->path);
}
VIR_DEBUG("def->os.bootloader %s", def->os.bootloader);
VIR_DEBUG("def->os.bootloaderArgs %s", def->os.bootloaderArgs);
--
2.25.1