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@xxxxxxxxxxxxxx> --- 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; -- 1.7.2.5 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list