This patch implements previous extension in qemu driver.
That is, during prepare phase check for every source to be accessible.
If not, but marked as optional, simply VIR_FREE the source.
Moreover, if migration is persistent, we must check inactive xml,
which is transfered at the finish phase, as well.
---
src/qemu/qemu_migration.c | 47 +++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 45 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index ef48d65..f794ffd 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -1039,6 +1039,44 @@ cleanup:
return rv;
}
+/* qemuCheckDisksPresence:
+ * @def domain definition
+ *
+ * Iterate over domain disks and check if source exists.
+ * If not and:
+ * - it's marked as optional, free() it.
+ * - it's not optional, throw an error.
+ *
+ * Returns 0 on success (all remaining disks/sources exist),
+ * -1 on failure.
+ */
+static int
+qemuCheckDisksPresence(virDomainDefPtr def) {
+ int ret = -1;
+ int i;
+ virDomainDiskDefPtr disk;
+
+ for (i = 0; i < def->ndisks; i++) {
+ disk = def->disks[i];
+
+ if (virFileExists(disk->src))
+ continue;
+
+ if (!disk->migration ||
+ (disk->migration->optional != VIR_DOMAIN_DEVICE_MIGRATION_OPT_YES)) {
+ qemuReportError(VIR_ERR_NO_SOURCE,
+ _("no such file %s"),
+ disk->src);
+ goto cleanup;
+ }
+
+ VIR_FREE(disk->src);
+ }
+
+ ret = 0;
+cleanup:
+ return ret;
+}
/* Prepare is the first step, and it runs on the destination host.
*/
@@ -1087,6 +1125,9 @@ qemuMigrationPrepareAny(struct qemud_driver *driver,
if (virDomainObjIsDuplicate(&driver->domains, def, 1) < 0)
goto cleanup;
+ if (qemuCheckDisksPresence(def) < 0)
+ goto cleanup;
+
if (!(vm = virDomainAssignDef(driver->caps,
&driver->domains,
def, true))) {
@@ -2578,9 +2619,11 @@ qemuMigrationFinish(struct qemud_driver *driver,
if (vm->persistent)
newVM = 0;
vm->persistent = 1;
- if (mig->persistent)
+ if (mig->persistent) {
+ if (qemuCheckDisksPresence(mig->persistent) < 0)
+ goto endjob;
vm->newDef = vmdef = mig->persistent;
- else
+ } else
vmdef = virDomainObjGetPersistentDef(driver->caps, vm);
if (virDomainSaveConfig(driver->configDir, vmdef) < 0) {
/* Hmpf. Migration was successful, but making it persistent
--
1.7.3.4