help to create disk images copy-storage-* required,
try to do non-shared migration without bothering to
create disk images at target by hand.
consider this situation:
1. non-shared migration
virsh migrate --copy-storage-all ...
2. migration fails
3. create disk images required
qemu-img create ...
4 migration run smoothly
so, try do remove step 2, 3, 4
this kind of use had been discussed before,
http://www.redhat.com/archives/libvir-list/2011-December/msg00451.html
It did not handle more about complete situations
suggested by Daniel P. Berrange,
https://www.redhat.com/archives/libvir-list/2012-October/msg00407.html
Signed-off-by: liguang <lig.fnst(a)cn.fujitsu.com>
---
src/libvirt_private.syms | 1 +
src/qemu/qemu_migration.c | 92 +++++++++++++++++++++++++++++++++++++++++++-
src/util/util.c | 17 ++++++++
src/util/util.h | 1 +
4 files changed, 108 insertions(+), 3 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index a8c81e7..a293184 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1202,6 +1202,7 @@ virArgvToString;
virAsprintf;
virBuildPathInternal;
virDirCreate;
+virDirOfFile;
virDoubleToStr;
virEnumFromString;
virEnumToString;
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index db69a0a..ac3e1c3 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -70,6 +70,7 @@ enum qemuMigrationCookieFlags {
QEMU_MIGRATION_COOKIE_FLAG_GRAPHICS,
QEMU_MIGRATION_COOKIE_FLAG_LOCKSTATE,
QEMU_MIGRATION_COOKIE_FLAG_PERSISTENT,
+ QEMU_MIGRATION_COOKIE_FLAG_COPYSTORAGE,
QEMU_MIGRATION_COOKIE_FLAG_LAST
};
@@ -77,12 +78,13 @@ enum qemuMigrationCookieFlags {
VIR_ENUM_DECL(qemuMigrationCookieFlag);
VIR_ENUM_IMPL(qemuMigrationCookieFlag,
QEMU_MIGRATION_COOKIE_FLAG_LAST,
- "graphics", "lockstate", "persistent");
+ "graphics", "lockstate", "persistent",
"copystorage");
enum qemuMigrationCookieFeatures {
QEMU_MIGRATION_COOKIE_GRAPHICS = (1 << QEMU_MIGRATION_COOKIE_FLAG_GRAPHICS),
QEMU_MIGRATION_COOKIE_LOCKSTATE = (1 <<
QEMU_MIGRATION_COOKIE_FLAG_LOCKSTATE),
QEMU_MIGRATION_COOKIE_PERSISTENT = (1 <<
QEMU_MIGRATION_COOKIE_FLAG_PERSISTENT),
+ QEMU_MIGRATION_COOKIE_COPYSTORAGE = (1 <<
QEMU_MIGRATION_COOKIE_FLAG_COPYSTORAGE),
};
typedef struct _qemuMigrationCookieGraphics qemuMigrationCookieGraphics;
@@ -439,6 +441,10 @@ qemuMigrationCookieXMLFormat(struct qemud_driver *driver,
virBufferAdjustIndent(buf, -2);
}
+ if (mig->flags & QEMU_MIGRATION_COOKIE_COPYSTORAGE)
+ virBufferAsprintf(buf, " <copystorage/>\n");
+
+
virBufferAddLit(buf, "</qemu-migration>\n");
return 0;
}
@@ -662,6 +668,11 @@ qemuMigrationCookieXMLParse(qemuMigrationCookiePtr mig,
VIR_FREE(nodes);
}
+ if ((flags & QEMU_MIGRATION_COOKIE_COPYSTORAGE)) {
+ if (virXPathBoolean("count(./copystorage) > 0", ctxt))
+ mig->flags |= QEMU_MIGRATION_COOKIE_COPYSTORAGE;
+ }
+
return 0;
error:
@@ -1215,6 +1226,60 @@ qemuMigrationPrepareCleanup(struct qemud_driver *driver,
qemuDomainObjDiscardAsyncJob(driver, vm);
}
+static int qemuMigrationHandleDiskFiles(const char *dom_xml, int pin)
+{
+ xmlDocPtr doc = NULL;
+ xmlXPathContextPtr ctxt = NULL;
+ xmlNodePtr *disks = NULL;
+ virCommandPtr cmd = NULL;
+ int i, nr, ret = -1;
+ char *file_name[] = {}, *file_fmt[] = {};
+ char *driver_name, *tmp_dir;
+
+ if (!(doc = virXMLParseStringCtxt(dom_xml, _("(domain_definition)"),
&ctxt)))
+ goto cleanup;
+
+ if ((nr = virXPathNodeSet("./devices/disk", ctxt, &disks)) <= 0)
+ goto cleanup;
+
+ for (i = 0; i < nr; i++) {
+ ctxt->node = disks[i];
+ driver_name = virXPathString("string(./driver/@name)", ctxt);
+ if (STRNEQ(driver_name, "qemu"))
+ continue;
+ file_fmt[i] = virXPathString("string(./driver/@type)", ctxt);
+ file_name[i] = virXPathString("string(./source/file)", ctxt);
+ if (virFileExists(file_name[i]) && !pin)
+ continue;
+ if ((tmp_dir = virDirOfFile(file_name[i])) == NULL)
+ continue;
+ if (!virFileExists(tmp_dir))
+ if (virFileMakePath(tmp_dir) < 0)
+ continue;
+ if (pin)
+ cmd = virCommandNewArgList("qemu-img", "create",
"-f",
+ file_fmt[i], file_name[i], ~0UL, NULL);
+ else
+ cmd = virCommandNewArgList("rm", "-f", file_name[i],
NULL);
+ if (virCommandRun(cmd, NULL) < 0) {
+ goto cleanup;
+ virReportSystemError(errno, "%s",
+ _("unable create disk images by qemu-img"));
+ }
+ }
+
+ ret = 0;
+
+cleanup:
+ xmlXPathFreeContext(ctxt);
+ xmlFreeDoc(doc);
+ VIR_FREE(disks);
+ virCommandFree(cmd);
+ VIR_FREE(driver_name);
+ VIR_FREE(tmp_dir);
+ return ret;
+}
+
static int
qemuMigrationPrepareAny(struct qemud_driver *driver,
virConnectPtr dconn,
@@ -1314,6 +1379,14 @@ qemuMigrationPrepareAny(struct qemud_driver *driver,
origname = NULL;
if (!(mig = qemuMigrationEatCookie(driver, vm, cookiein, cookieinlen,
+ QEMU_MIGRATION_COOKIE_COPYSTORAGE)))
+ goto cleanup;
+
+ if (mig->flags & QEMU_MIGRATION_COOKIE_COPYSTORAGE)
+ if (qemuMigrationHandleDiskFiles(dom_xml, 1) < 0)
+ goto cleanup;
+
+ if (!(mig = qemuMigrationEatCookie(driver, vm, cookiein, cookieinlen,
QEMU_MIGRATION_COOKIE_LOCKSTATE)))
goto cleanup;
@@ -1900,8 +1973,13 @@ qemuMigrationRun(struct qemud_driver *driver,
if (flags & VIR_MIGRATE_NON_SHARED_DISK)
migrate_flags |= QEMU_MONITOR_MIGRATE_NON_SHARED_DISK;
- if (flags & VIR_MIGRATE_NON_SHARED_INC)
+ if (flags & VIR_MIGRATE_NON_SHARED_INC) {
migrate_flags |= QEMU_MONITOR_MIGRATE_NON_SHARED_INC;
+ if (qemuMigrationBakeCookie(mig, driver, vm,
+ cookieout, cookieoutlen,
+ QEMU_MIGRATION_COOKIE_COPYSTORAGE) < 0)
+ goto cleanup;
+ }
/* connect to the destination qemu if needed */
if (spec->destType == MIGRATION_DEST_CONNECT_HOST &&
@@ -2929,14 +3007,18 @@ qemuMigrationFinish(struct qemud_driver *driver,
int newVM = 1;
qemuMigrationCookiePtr mig = NULL;
virErrorPtr orig_err = NULL;
- int cookie_flags = 0;
+ int cookie_flags = 0, migration_status = 0;
qemuDomainObjPrivatePtr priv = vm->privateData;
+ char *dom_xml = NULL;
VIR_DEBUG("driver=%p, dconn=%p, vm=%p, cookiein=%s, cookieinlen=%d, "
"cookieout=%p, cookieoutlen=%p, flags=%lx, retcode=%d",
driver, dconn, vm, NULLSTR(cookiein), cookieinlen,
cookieout, cookieoutlen, flags, retcode);
+ if (!(dom_xml = qemuDomainFormatXML(driver, vm, VIR_DOMAIN_XML_SECURE, false)))
+ goto cleanup;
+
if (!qemuMigrationJobIsActive(vm, QEMU_ASYNC_JOB_MIGRATION_IN))
goto cleanup;
@@ -3088,7 +3170,11 @@ qemuMigrationFinish(struct qemud_driver *driver,
if (qemuMigrationBakeCookie(mig, driver, vm, cookieout, cookieoutlen, 0) < 0)
VIR_WARN("Unable to encode migration cookie");
+ migration_status = 1;
+
endjob:
+ if (!migration_status)
+ qemuMigrationHandleDiskFiles(dom_xml, 0);
if (qemuMigrationJobFinish(driver, vm) == 0) {
vm = NULL;
} else if (!vm->persistent && !virDomainObjIsActive(vm)) {
diff --git a/src/util/util.c b/src/util/util.c
index 348c388..1f51a77 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -3108,3 +3108,20 @@ virValidateWWN(const char *wwn) {
return true;
}
+
+char *virDirOfFile(const char *file)
+{
+ char *p, *tmp;
+
+ if (file == NULL)
+ return NULL;
+ if ((tmp = strdup(file)) == NULL)
+ return NULL;
+ if ((p = strrchr(file, '/')) == NULL)
+ return getcwd(tmp, strlen(file));
+ if (strlen(p) == 0)
+ return NULL;
+ tmp[strlen(file) - strlen(p)] = '\0';
+
+ return tmp;
+}
diff --git a/src/util/util.h b/src/util/util.h
index 4316ab1..255b7b2 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -114,6 +114,7 @@ enum {
};
int virDirCreate(const char *path, mode_t mode, uid_t uid, gid_t gid,
unsigned int flags) ATTRIBUTE_RETURN_CHECK;
+char *virDirOfFile(const char *file) ATTRIBUTE_RETURN_CHECK;
int virFileMakePath(const char *path) ATTRIBUTE_RETURN_CHECK;
int virFileMakePathWithMode(const char *path,
mode_t mode) ATTRIBUTE_RETURN_CHECK;