The postParse callback is the correct place to generate default values
that should be present in offline XML.
Signed-off-by: Pavel Hrdina <phrdina(a)redhat.com>
---
src/qemu/qemu_domain.c | 10 ++++
src/qemu/qemu_process.c | 153 ++++++++++++++++++------------------------------
2 files changed, 68 insertions(+), 95 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 594063e..632cf47 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -1397,6 +1397,7 @@ qemuDomainDefPostParse(virDomainDefPtr def,
void *opaque)
{
virQEMUDriverPtr driver = opaque;
+ virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
virQEMUCapsPtr qemuCaps = NULL;
int ret = -1;
@@ -1412,6 +1413,15 @@ qemuDomainDefPostParse(virDomainDefPtr def,
return ret;
}
+ 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",
+ cfg->nvramDir, def->name) < 0)
+ goto cleanup;
+ }
+
/* check for emulator and create a default one if needed */
if (!def->emulator &&
!(def->emulator = virDomainDefGetDefaultEmulator(def, caps)))
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 3c496cb..958fae3 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -3878,7 +3878,6 @@ qemuProcessVerifyGuestCPU(virQEMUDriverPtr driver,
static int
qemuPrepareNVRAM(virQEMUDriverConfigPtr cfg,
- virCapsPtr caps,
virDomainObjPtr vm,
bool migrated)
{
@@ -3886,111 +3885,81 @@ qemuPrepareNVRAM(virQEMUDriverConfigPtr cfg,
int srcFD = -1;
int dstFD = -1;
virDomainLoaderDefPtr loader = vm->def->os.loader;
- bool generated = false;
bool created = false;
+ const char *master_nvram_path;
+ ssize_t r;
- /* Unless domain has RO loader of pflash type, we have
- * nothing to do here. If the loader is RW then it's not
- * using split code and vars feature, so no nvram file needs
- * to be created. */
- if (!loader || loader->type != VIR_DOMAIN_LOADER_TYPE_PFLASH ||
- loader->readonly != VIR_TRISTATE_SWITCH_ON)
+ if (!loader->nvram || !migrated)
return 0;
- /* If the nvram path is configured already, there's nothing
- * we need to do. Unless we are starting the destination side
- * of migration in which case nvram is configured in the
- * domain XML but the file doesn't exist yet. Moreover, after
- * the migration is completed, qemu will invoke a
- * synchronization write into the nvram file so we don't have
- * to take care about transmitting the real data on the other
- * side. */
- if (loader->nvram && !migrated)
+ if (virFileExists(loader->nvram))
return 0;
- /* Autogenerate nvram path if needed.*/
- if (!loader->nvram) {
- if (virAsprintf(&loader->nvram,
- "%s/%s_VARS.fd",
- cfg->nvramDir, vm->def->name) < 0)
- goto cleanup;
-
- generated = true;
-
- if (vm->persistent &&
- virDomainSaveConfig(cfg->configDir, caps, vm->def) < 0)
- goto cleanup;
- }
-
- if (!virFileExists(loader->nvram)) {
- const char *master_nvram_path = loader->templt;
- ssize_t r;
-
- if (!loader->templt) {
- size_t i;
- for (i = 0; i < cfg->nloader; i++) {
- if (STREQ(cfg->loader[i], loader->path)) {
- master_nvram_path = cfg->nvram[i];
- break;
- }
+ master_nvram_path = loader->templt;
+ if (!loader->templt) {
+ size_t i;
+ for (i = 0; i < cfg->nloader; i++) {
+ if (STREQ(cfg->loader[i], loader->path)) {
+ master_nvram_path = cfg->nvram[i];
+ 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 ((srcFD = virFileOpenAs(master_nvram_path, O_RDONLY,
- 0, -1, -1, 0)) < 0) {
- virReportSystemError(-srcFD,
- _("Failed to open file '%s'"),
- master_nvram_path);
- goto cleanup;
- }
- if ((dstFD = virFileOpenAs(loader->nvram,
- 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);
- goto cleanup;
- }
- created = true;
-
- do {
- char buf[1024];
+ if (!master_nvram_path) {
+ virReportError(VIR_ERR_OPERATION_FAILED,
+ _("unable to find any master var store for "
+ "loader: %s"), loader->path);
+ goto cleanup;
+ }
- if ((r = saferead(srcFD, buf, sizeof(buf))) < 0) {
- virReportSystemError(errno,
- _("Unable to read from file
'%s'"),
- master_nvram_path);
- goto cleanup;
- }
+ if ((srcFD = virFileOpenAs(master_nvram_path, O_RDONLY,
+ 0, -1, -1, 0)) < 0) {
+ virReportSystemError(-srcFD,
+ _("Failed to open file '%s'"),
+ master_nvram_path);
+ goto cleanup;
+ }
+ if ((dstFD = virFileOpenAs(loader->nvram,
+ 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);
+ goto cleanup;
+ }
+ created = true;
- if (safewrite(dstFD, buf, r) < 0) {
- virReportSystemError(errno,
- _("Unable to write to file
'%s'"),
- loader->nvram);
- goto cleanup;
- }
- } while (r);
+ do {
+ char buf[1024];
- if (VIR_CLOSE(srcFD) < 0) {
+ if ((r = saferead(srcFD, buf, sizeof(buf))) < 0) {
virReportSystemError(errno,
- _("Unable to close file '%s'"),
+ _("Unable to read from file '%s'"),
master_nvram_path);
goto cleanup;
}
- if (VIR_CLOSE(dstFD) < 0) {
+
+ if (safewrite(dstFD, buf, r) < 0) {
virReportSystemError(errno,
- _("Unable to close file '%s'"),
+ _("Unable to write to file '%s'"),
loader->nvram);
goto cleanup;
}
+ } while (r);
+
+ if (VIR_CLOSE(srcFD) < 0) {
+ virReportSystemError(errno,
+ _("Unable to close file '%s'"),
+ master_nvram_path);
+ goto cleanup;
+ }
+ if (VIR_CLOSE(dstFD) < 0) {
+ virReportSystemError(errno,
+ _("Unable to close file '%s'"),
+ loader->nvram);
+ goto cleanup;
}
ret = 0;
@@ -4000,8 +3969,6 @@ qemuPrepareNVRAM(virQEMUDriverConfigPtr cfg,
if (ret < 0) {
if (created)
unlink(loader->nvram);
- if (generated)
- VIR_FREE(loader->nvram);
}
VIR_FORCE_CLOSE(srcFD);
@@ -4421,13 +4388,6 @@ qemuProcessInit(virQEMUDriverPtr driver,
if (qemuProcessStartValidate(vm->def, priv->qemuCaps, migration, snap) < 0)
goto cleanup;
- /* Some things, paths, ... are generated here and we want them to persist.
- * Fill them in prior to setting the domain def as transient. */
- VIR_DEBUG("Generating paths");
-
- if (qemuPrepareNVRAM(cfg, caps, vm, migration) < 0)
- goto stop;
-
/* Do this upfront, so any part of the startup process can add
* runtime state to vm->def that won't be persisted. This let's us
* report implicit runtime defaults in the XML, like vnc listen/socket
@@ -4436,6 +4396,9 @@ qemuProcessInit(virQEMUDriverPtr driver,
if (virDomainObjSetDefTransient(caps, driver->xmlopt, vm, true) < 0)
goto stop;
+ if (qemuPrepareNVRAM(cfg, vm, migration) < 0)
+ goto stop;
+
vm->def->id = qemuDriverAllocateID(driver);
qemuDomainSetFakeReboot(driver, vm, false);
virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_STARTING_UP);
--
2.7.2