From: Rohit Kumar <rohit.kumar3(a)nutanix.com>
Currently, libvirt allows only local filepaths to specify the location
of the 'nvram' image. Changing it to virStorageSource type will allow
to support remote storage for nvram.
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>
Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
---
src/conf/domain_conf.c | 16 +++++++++++++---
src/conf/domain_conf.h | 2 +-
src/qemu/qemu_cgroup.c | 3 ++-
src/qemu/qemu_command.c | 2 +-
src/qemu/qemu_domain.c | 10 +++++++---
src/qemu/qemu_driver.c | 5 +++--
src/qemu/qemu_firmware.c | 18 +++++++++++++-----
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 | 3 ++-
13 files changed, 59 insertions(+), 27 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 5d0d436a40..252e34dd2a 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -3576,7 +3576,7 @@ virDomainLoaderDefFree(virDomainLoaderDef *loader)
return;
g_free(loader->path);
- g_free(loader->nvram);
+ virObjectUnref(loader->nvram);
g_free(loader->nvramTemplate);
g_free(loader);
}
@@ -18340,6 +18340,7 @@ virDomainDefParseBootLoaderOptions(virDomainDef *def,
{
xmlNodePtr loader_node = virXPathNode("./os/loader[1]", ctxt);
const bool fwAutoSelect = def->os.firmware != VIR_DOMAIN_OS_DEF_FIRMWARE_NONE;
+ g_autofree char *nvramPath = NULL;
if (!loader_node)
return 0;
@@ -18351,7 +18352,13 @@ virDomainDefParseBootLoaderOptions(virDomainDef *def,
fwAutoSelect) < 0)
return -1;
- def->os.loader->nvram = virXPathString("string(./os/nvram[1])",
ctxt);
+ if ((nvramPath = virXPathString("string(./os/nvram[1])", ctxt))) {
+ def->os.loader->nvram = virStorageSourceNew();
+ def->os.loader->nvram->path = g_steal_pointer(&nvramPath);
+ def->os.loader->nvram->type = VIR_STORAGE_TYPE_FILE;
+ def->os.loader->nvram->format = VIR_STORAGE_FILE_RAW;
+ }
+
if (!fwAutoSelect)
def->os.loader->nvramTemplate =
virXPathString("string(./os/nvram[1]/@template)", ctxt);
@@ -27118,7 +27125,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 e7e0f24443..9ec81067c6 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2253,7 +2253,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..64baed14e6 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)
+ virStorageSourceIsLocalStorage(vm->def->os.loader->nvram) &&
+ 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 7dc09fc101..952336bafc 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -9668,7 +9668,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 86dbf7cb01..1ee3cc3922 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -4678,8 +4678,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 = virStorageSourceNew();
+ def->os.loader->nvram->type = VIR_STORAGE_TYPE_FILE;
+ def->os.loader->nvram->format = VIR_STORAGE_FILE_RAW;
+ qemuDomainNVRAMPathFormat(cfg, def, &def->os.loader->nvram->path);
+ }
if (qemuDomainDefAddDefaultDevices(driver, def, qemuCaps) < 0)
return -1;
@@ -11332,7 +11336,7 @@ qemuDomainInitializePflashStorageSource(virDomainObj *vm)
pflash1 = virStorageSourceNew();
pflash1->type = VIR_STORAGE_TYPE_FILE;
pflash1->format = VIR_STORAGE_FILE_RAW;
- pflash1->path = g_strdup(def->os.loader->nvram);
+ pflash1->path = g_strdup(def->os.loader->nvram->path);
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 0c6645ed89..c32e3cc8fe 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6731,8 +6731,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
&&
+ virStorageSourceIsLocalStorage(vm->def->os.loader->nvram)) {
+ 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..dd4273f73a 100644
--- a/src/qemu/qemu_firmware.c
+++ b/src/qemu/qemu_firmware.c
@@ -1192,13 +1192,17 @@ 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 = virStorageSourceNew();
+ def->os.loader->nvram->type = VIR_STORAGE_TYPE_FILE;
+ def->os.loader->nvram->format = VIR_STORAGE_FILE_RAW;
+ 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 +1368,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 &&
+ virStorageSourceIsLocalStorage(def->os.loader->nvram) &&
+ 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..9e133587b7 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 &&
+ virStorageSourceIsLocalStorage(loader->nvram))
+ *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 1593ca7933..dab298085f 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -4400,7 +4400,8 @@ qemuPrepareNVRAM(virQEMUDriver *driver,
struct qemuPrepareNVRAMHelperData data;
if (!loader || !loader->nvram ||
- (virFileExists(loader->nvram) && !reset_nvram))
+ !virStorageSourceIsLocalStorage(loader->nvram) ||
+ (virFileExists(loader->nvram->path) && !reset_nvram))
return 0;
master_nvram_path = loader->nvramTemplate;
@@ -4432,7 +4433,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 69c462de8b..03661efda1 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -1975,7 +1975,8 @@ virSecurityDACRestoreAllLabel(virSecurityManager *mgr,
}
if (def->os.loader && def->os.loader->nvram &&
- virSecurityDACRestoreFileLabel(mgr, def->os.loader->nvram) < 0)
+ virStorageSourceIsLocalStorage(def->os.loader->nvram) &&
+ virSecurityDACRestoreFileLabel(mgr, def->os.loader->nvram->path) <
0)
rc = -1;
if (def->os.kernel &&
@@ -2186,8 +2187,9 @@ virSecurityDACSetAllLabel(virSecurityManager *mgr,
}
if (def->os.loader && def->os.loader->nvram &&
+ virStorageSourceIsLocalStorage(def->os.loader->nvram) &&
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..e026212b13 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)
+ virStorageSourceIsLocalStorage(def->os.loader->nvram) &&
+ 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 &&
+ virStorageSourceIsLocalStorage(def->os.loader->nvram) &&
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 107f217246..2ddf293c2c 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
&&
+ virStorageSourceIsLocalStorage(ctl->def->os.loader->nvram))
+ 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..e249980195 100644
--- a/src/vbox/vbox_common.c
+++ b/src/vbox/vbox_common.c
@@ -992,7 +992,8 @@ 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);
+ if (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.35.3