Given that nvram & loader elements can now be backed by a non-local
source too, adjust all steps leading to generation of
QEMU command line.
Signed-off-by: Prerna Saxena <saxenap.ltc(a)gmail.com>
---
src/qemu/qemu_cgroup.c | 13 +++++++++----
src/qemu/qemu_command.c | 21 ++++++++++++++++-----
src/qemu/qemu_domain.c | 31 +++++++++++++++++++++---------
src/qemu/qemu_driver.c | 7 ++++---
src/qemu/qemu_process.c | 42 ++++++++++++++++++++++++++++-------------
src/security/security_dac.c | 6 ++++--
src/security/security_selinux.c | 6 ++++--
7 files changed, 88 insertions(+), 38 deletions(-)
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index d88eb78..2068eb0 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -580,16 +580,21 @@ qemuSetupMemoryCgroup(virDomainObjPtr vm)
static int
qemuSetupFirmwareCgroup(virDomainObjPtr vm)
{
+ virStorageSourcePtr src = NULL;
+
if (!vm->def->os.loader)
return 0;
- if (vm->def->os.loader->path &&
- qemuSetupImagePathCgroup(vm, vm->def->os.loader->path,
- vm->def->os.loader->readonly ==
VIR_TRISTATE_BOOL_YES) < 0)
+ src = vm->def->os.loader->src;
+
+ if (src->type == VIR_STORAGE_TYPE_FILE &&
+ qemuSetupImagePathCgroup(vm, src->path,
+ src->readonly == VIR_TRISTATE_BOOL_YES) < 0)
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 08f67a4..e9d6e4b 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -9260,6 +9260,7 @@ qemuBuildDomainLoaderCommandLine(virCommandPtr cmd,
virDomainLoaderDefPtr loader = def->os.loader;
virBuffer buf = VIR_BUFFER_INITIALIZER;
int unit = 0;
+ char *source = NULL;
if (!loader)
return;
@@ -9267,7 +9268,7 @@ qemuBuildDomainLoaderCommandLine(virCommandPtr cmd,
switch ((virDomainLoader) loader->type) {
case VIR_DOMAIN_LOADER_TYPE_ROM:
virCommandAddArg(cmd, "-bios");
- virCommandAddArg(cmd, loader->path);
+ virCommandAddArg(cmd, loader->src->path);
break;
case VIR_DOMAIN_LOADER_TYPE_PFLASH:
@@ -9279,9 +9280,14 @@ qemuBuildDomainLoaderCommandLine(virCommandPtr cmd,
NULL);
}
+ if (qemuGetDriveSourceString(loader->src, NULL, &source) < 0)
+ break;
+
virBufferAddLit(&buf, "file=");
- virQEMUBuildBufferEscapeComma(&buf, loader->path);
- virBufferAsprintf(&buf, ",if=pflash,format=raw,unit=%d", unit);
+ virQEMUBuildBufferEscapeComma(&buf, source);
+ free(source);
+ virBufferAsprintf(&buf, ",if=pflash,format=raw,unit=%d",
+ unit);
unit++;
if (loader->readonly) {
@@ -9294,9 +9300,14 @@ qemuBuildDomainLoaderCommandLine(virCommandPtr cmd,
if (loader->nvram) {
virBufferFreeAndReset(&buf);
+ if (qemuGetDriveSourceString(loader->nvram, NULL, &source) < 0)
+ break;
+
virBufferAddLit(&buf, "file=");
- virQEMUBuildBufferEscapeComma(&buf, loader->nvram);
- virBufferAsprintf(&buf, ",if=pflash,format=raw,unit=%d",
unit);
+ virQEMUBuildBufferEscapeComma(&buf, source);
+ virBufferAsprintf(&buf, ",if=pflash,format=raw,unit=%d",
+ unit);
+ unit++;
virCommandAddArg(cmd, "-drive");
virCommandAddArgBuffer(cmd, &buf);
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 9bb6d8a..2d4e299 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -3318,6 +3318,9 @@ qemuDomainDefPostParse(virDomainDefPtr def,
* function shall not fail in that case. It will be re-run on VM startup
* with the capabilities populated. */
virQEMUCapsPtr qemuCaps = parseOpaque;
+ virDomainLoaderDefPtr ldr = NULL;
+ char *nvramPath = NULL;
+
int ret = -1;
if (def->os.bootloader || def->os.bootloaderArgs) {
@@ -3332,13 +3335,20 @@ qemuDomainDefPostParse(virDomainDefPtr def,
goto cleanup;
}
- if (def->os.loader &&
- def->os.loader->type == VIR_DOMAIN_LOADER_TYPE_PFLASH &&
- def->os.loader->readonly == VIR_TRISTATE_SWITCH_ON &&
- !def->os.loader->nvram) {
- if (virAsprintf(&def->os.loader->nvram, "%s/%s_VARS.fd",
+ ldr = def->os.loader;
+ if (ldr &&
+ ldr->type == VIR_DOMAIN_LOADER_TYPE_PFLASH &&
+ ldr->readonly == VIR_TRISTATE_SWITCH_ON &&
+ !ldr->nvram) {
+ if (virAsprintf(&nvramPath, "%s/%s_VARS.fd",
cfg->nvramDir, def->name) < 0)
goto cleanup;
+ ldr->nvram = virStorageSourceNewFromBackingAbsolute(nvramPath);
+ if (!ldr->nvram) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Unable to add NVRAM drive %s"), nvramPath);
+ goto cleanup;
+ }
}
if (qemuDomainDefAddDefaultDevices(def, qemuCaps) < 0)
@@ -10494,19 +10504,22 @@ qemuDomainSetupLoader(virQEMUDriverConfigPtr cfg
ATTRIBUTE_UNUSED,
VIR_DEBUG("Setting up loader");
- if (loader) {
+ if (loader && loader->src) {
switch ((virDomainLoader) loader->type) {
case VIR_DOMAIN_LOADER_TYPE_ROM:
- if (qemuDomainCreateDevice(loader->path, data, false) < 0)
+ if (loader->src->type == VIR_STORAGE_TYPE_FILE &&
+ qemuDomainCreateDevice(loader->src->path, data, false) < 0)
goto cleanup;
break;
case VIR_DOMAIN_LOADER_TYPE_PFLASH:
- if (qemuDomainCreateDevice(loader->path, data, false) < 0)
+ if (loader->src->type == VIR_STORAGE_TYPE_FILE &&
+ qemuDomainCreateDevice(loader->src->path, data, false) < 0)
goto cleanup;
if (loader->nvram &&
- qemuDomainCreateDevice(loader->nvram, data, false) < 0)
+ loader->nvram->type == VIR_STORAGE_TYPE_FILE &&
+ qemuDomainCreateDevice(loader->nvram->path, data, false) < 0)
goto cleanup;
break;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index c129321..9c491b2 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7540,12 +7540,13 @@ qemuDomainUndefineFlags(virDomainPtr dom,
if (vm->def->os.loader &&
vm->def->os.loader->nvram &&
- virFileExists(vm->def->os.loader->nvram)) {
+ vm->def->os.loader->nvram->type == VIR_STORAGE_TYPE_FILE &&
+ virFileExists(vm->def->os.loader->nvram->path)) {
if ((flags & VIR_DOMAIN_UNDEFINE_NVRAM)) {
- if (unlink(vm->def->os.loader->nvram) < 0) {
+ if (unlink(vm->def->os.loader->nvram->path) < 0) {
virReportSystemError(errno,
_("failed to remove nvram: %s"),
- vm->def->os.loader->nvram);
+ vm->def->os.loader->nvram->path);
goto endjob;
}
} else if (!(flags & VIR_DOMAIN_UNDEFINE_KEEP_NVRAM)) {
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 37876b8..e4c05e2 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -3994,25 +3994,41 @@ qemuPrepareNVRAM(virQEMUDriverConfigPtr cfg,
const char *master_nvram_path;
ssize_t r;
- if (!loader || !loader->nvram || virFileExists(loader->nvram))
+ /* return early if either loader is network-backed
+ * or NVRAM is already specified.
+ */
+ if (!loader || !loader->src || !loader->nvram ||
+ loader->type != VIR_DOMAIN_LOADER_TYPE_PFLASH ||
+ loader->src->type == VIR_STORAGE_TYPE_NETWORK ||
+ loader->nvram->type == VIR_STORAGE_TYPE_NETWORK)
+ return 0;
+
+ if (loader->nvram->type == VIR_STORAGE_TYPE_FILE &&
+ virFileExists(loader->nvram->path))
return 0;
master_nvram_path = loader->templt;
- if (!loader->templt) {
+ /* Even if a template is not specified, we associate "known" EFI firmware
+ * to their NVRAM templates.
+ * Ofcourse this only applies to local firmware paths, as it is diffcult
+ * for libvirt to parse all network paths.
+ */
+ if (!loader->templt && loader->src->type == VIR_STORAGE_TYPE_FILE)
{
size_t i;
for (i = 0; i < cfg->nfirmwares; i++) {
- if (STREQ(cfg->firmwares[i]->name, loader->path)) {
+ if (STREQ(cfg->firmwares[i]->name, loader->src->path)) {
master_nvram_path = cfg->firmwares[i]->nvram;
break;
}
}
}
- if (!master_nvram_path) {
- virReportError(VIR_ERR_OPERATION_FAILED,
- _("unable to find any master var store for "
- "loader: %s"), loader->path);
- goto cleanup;
+ if (!master_nvram_path && loader->nvram) {
+ /* There is no template description, but an NVRAM spec
+ * has already been provided.
+ * Trust the client to have generated the right spec here
+ */
+ return 0;
}
if ((srcFD = virFileOpenAs(master_nvram_path, O_RDONLY,
@@ -4022,13 +4038,13 @@ qemuPrepareNVRAM(virQEMUDriverConfigPtr cfg,
master_nvram_path);
goto cleanup;
}
- if ((dstFD = virFileOpenAs(loader->nvram,
+ if ((dstFD = virFileOpenAs(loader->nvram->path,
O_WRONLY | O_CREAT | O_EXCL,
S_IRUSR | S_IWUSR,
cfg->user, cfg->group, 0)) < 0) {
virReportSystemError(-dstFD,
_("Failed to create file '%s'"),
- loader->nvram);
+ loader->nvram->path);
goto cleanup;
}
created = true;
@@ -4046,7 +4062,7 @@ qemuPrepareNVRAM(virQEMUDriverConfigPtr cfg,
if (safewrite(dstFD, buf, r) < 0) {
virReportSystemError(errno,
_("Unable to write to file '%s'"),
- loader->nvram);
+ loader->nvram->path);
goto cleanup;
}
} while (r);
@@ -4060,7 +4076,7 @@ qemuPrepareNVRAM(virQEMUDriverConfigPtr cfg,
if (VIR_CLOSE(dstFD) < 0) {
virReportSystemError(errno,
_("Unable to close file '%s'"),
- loader->nvram);
+ loader->nvram->path);
goto cleanup;
}
@@ -4070,7 +4086,7 @@ qemuPrepareNVRAM(virQEMUDriverConfigPtr cfg,
* copy the file content. Roll back. */
if (ret < 0) {
if (created)
- unlink(loader->nvram);
+ unlink(loader->nvram->path);
}
VIR_FORCE_CLOSE(srcFD);
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index 8938e2d..3febea6 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -1604,7 +1604,8 @@ virSecurityDACRestoreAllLabel(virSecurityManagerPtr mgr,
}
if (def->os.loader && def->os.loader->nvram &&
- virSecurityDACRestoreFileLabel(priv, def->os.loader->nvram) < 0)
+ def->os.loader->nvram->type == VIR_STORAGE_TYPE_FILE &&
+ virSecurityDACRestoreFileLabel(priv, def->os.loader->nvram->path) <
0)
rc = -1;
return rc;
@@ -1732,8 +1733,9 @@ virSecurityDACSetAllLabel(virSecurityManagerPtr mgr,
return -1;
if (def->os.loader && def->os.loader->nvram &&
+ def->os.loader->nvram->type == VIR_STORAGE_TYPE_FILE &&
virSecurityDACSetOwnership(priv, NULL,
- def->os.loader->nvram, user, group) < 0)
+ def->os.loader->nvram->path, user, group)
< 0)
return -1;
if (def->os.kernel &&
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index 5f74ef7..bcda939 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -2459,7 +2459,8 @@ virSecuritySELinuxRestoreAllLabel(virSecurityManagerPtr mgr,
rc = -1;
if (def->os.loader && def->os.loader->nvram &&
- virSecuritySELinuxRestoreFileLabel(mgr, def->os.loader->nvram) < 0)
+ def->os.loader->nvram->type == VIR_STORAGE_TYPE_FILE &&
+ virSecuritySELinuxRestoreFileLabel(mgr, def->os.loader->nvram->path)
< 0)
rc = -1;
return rc;
@@ -2851,8 +2852,9 @@ virSecuritySELinuxSetAllLabel(virSecurityManagerPtr 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) < 0)
return -1;
--
1.8.1.2