[libvirt] [PATCH v3 1/2] helper of copy-storage-* features
li guang
lig.fnst at cn.fujitsu.com
Fri Nov 9 02:00:37 UTC 2012
Hi, Eric
any comment on this patch?
在 2012-11-06二的 16:09 +0800,li guang写道:
> ping ...
> 在 2012-11-01四的 08:40 +0800,liguang写道:
> > 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 usage had been discussed before,
> > http://www.redhat.com/archives/libvir-list/2011-December/msg00451.html
> >
> > maybe there're some flaws:
> > - It did not handle more about complete situations
> > suggested by Daniel P. Berrange,
> > https://www.redhat.com/archives/libvir-list/2012-October/msg00407.html
> > but may try to take care of them later.
> > so, now only normal disk image files be handled.
> > - for creation of disk images, size was setting as 0xffffffff boldly,
> > hope it can consolidate qemu, haven't constructed a comfortable
> > idea to solve it.
> >
> > v2:
> > 1. handle disk encrytion case
> > 2. check kvm-img & qemu-img
> > 3. set disk image size to 0xfffffffK bytes blindly
> >
> > v3:
> > 1.use qemuImgBinary to create disk image
> > 2.set max size for different disk image format respectively
> > qcow and qcow2: 1PiB
> > qed:64TiB
> > raw:1TiB
> > from qemu's setting,
> > qcow and qcow2's max size is 2EiB,
> > qed's max size is 64TiB
> > raw's max size is 1TiB
> >
> > Signed-off-by: liguang <lig.fnst at cn.fujitsu.com>
> > ---
> > src/qemu/qemu_migration.c | 122 ++++++++++++++++++++++++++++++++++++++++++++-
> > 1 files changed, 120 insertions(+), 2 deletions(-)
> >
> > diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
> > index db69a0a..80abb51 100644
> > --- a/src/qemu/qemu_migration.c
> > +++ b/src/qemu/qemu_migration.c
> > @@ -49,6 +49,7 @@
> > #include "storage_file.h"
> > #include "viruri.h"
> > #include "hooks.h"
> > +#include "dirname.h"
> >
> >
> > #define VIR_FROM_THIS VIR_FROM_QEMU
> > @@ -70,6 +71,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 +79,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 +442,9 @@ 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:
> > @@ -721,6 +732,9 @@ qemuMigrationBakeCookie(qemuMigrationCookiePtr mig,
> > qemuMigrationCookieAddPersistent(mig, dom) < 0)
> > return -1;
> >
> > + if (flags & QEMU_MIGRATION_COOKIE_COPYSTORAGE)
> > + mig->flags |= QEMU_MIGRATION_COOKIE_COPYSTORAGE;
> > +
> > if (!(*cookieout = qemuMigrationCookieXMLFormatStr(driver, mig)))
> > return -1;
> >
> > @@ -1168,6 +1182,14 @@ char *qemuMigrationBegin(struct qemud_driver *driver,
> > QEMU_MIGRATION_COOKIE_LOCKSTATE) < 0)
> > goto cleanup;
> >
> > + if (flags & (VIR_MIGRATE_NON_SHARED_DISK |
> > + VIR_MIGRATE_NON_SHARED_INC)) {
> > + if (qemuMigrationBakeCookie(mig, driver, vm,
> > + cookieout, cookieoutlen,
> > + QEMU_MIGRATION_COOKIE_COPYSTORAGE) < 0)
> > + goto cleanup;
> > + }
> > +
> > if (xmlin) {
> > if (!(def = virDomainDefParseString(driver->caps, xmlin,
> > QEMU_EXPECTED_VIRT_TYPES,
> > @@ -1215,6 +1237,89 @@ qemuMigrationPrepareCleanup(struct qemud_driver *driver,
> > qemuDomainObjDiscardAsyncJob(driver, vm);
> > }
> >
> > +/*
> > + if gen_del is 1, find out disk images migration required,
> > + so try to generate them at target,
> > + if gen_del is 0, delete disk images generated before.
> > +*/
> > +static int qemuMigrationHandleDiskFiles(struct qemud_driver *driver,
> > + virDomainDefPtr def, int gen_del)
> > +{
> > + char *tmp_dir = NULL, *outbuf = NULL;
> > + char *img_tool = driver->qemuImgBinary;
> > + virCommandPtr cmd = NULL;
> > + int i, ret = -1;
> > +
> > + if (!def->ndisks)
> > + return 0;
> > +
> > + if (img_tool == NULL) {
> > + virReportError(VIR_ERR_INTERNAL_ERROR,
> > + "%s", _("unable to find kvm-img or qemu-img"));
> > + goto error;
> > + }
> > +
> > + for (i = 0; i < def->ndisks; i++) {
> > + if (STRNEQ(def->disks[i]->driverName, "qemu"))
> > + continue;
> > + if (def->disks[i]->src == NULL)
> > + continue;
> > + if (def->disks[i]->driverType == NULL)
> > + continue;
> > + if (virFileExists(def->disks[i]->src) && gen_del)
> > + continue;
> > + if (!gen_del && !virFileExists(def->disks[i]->src))
> > + continue;
> > + if ((tmp_dir = mdir_name(def->disks[i]->src)) == NULL)
> > + continue;
> > + if (!virFileExists(tmp_dir))
> > + if (virFileMakePath(tmp_dir) < 0)
> > + continue;
> > + if (gen_del) {
> > + cmd = virCommandNewArgList(img_tool, "create", "-f",
> > + def->disks[i]->driverType, def->disks[i]->src, NULL);
> > + if (STREQ(def->disks[i]->driverType, "qcow2") ||
> > + STREQ(def->disks[i]->driverType, "qcow"))
> > + virCommandAddArgFormat(cmd, "%lluK", 0xffffffffff);
> > + else if (STREQ(def->disks[i]->driverType, "qed"))
> > + virCommandAddArgFormat(cmd, "%llu", 0x400000000000);
> > + else if (STREQ(def->disks[i]->driverType, "raw"))
> > + virCommandAddArgFormat(cmd, "%llu", 0xffffffffff);
> > + else {
> > + virReportError(VIR_ERR_INTERNAL_ERROR,
> > + "%s", _("only suport qcow,qcow2,qed,raw format"));
> > + goto cleanup;
> > + }
> > + if (def->disks[i]->encryption)
> > + virCommandAddArgList(cmd, "-o", "encryption=on", NULL);
> > + virCommandSetOutputBuffer(cmd, &outbuf);
> > + if (virCommandRun(cmd, NULL) < 0) {
> > + virReportSystemError(errno, "%s", outbuf);
> > + goto cleanup;
> > + }
> > + } else {
> > + if (unlink(def->disks[i]->src) < 0) {
> > + virReportError(errno, "%s", _("fail to unlink disk image file"));
> > + goto cleanup;
> > + }
> > + }
> > + virCommandFree(cmd);
> > + VIR_FREE(tmp_dir);
> > + VIR_FREE(outbuf);
> > + }
> > +
> > + ret = 0;
> > +
> > +cleanup:
> > + if (ret < 0) {
> > + virCommandFree(cmd);
> > + VIR_FREE(tmp_dir);
> > + VIR_FREE(outbuf);
> > + }
> > +error:
> > + return ret;
> > +}
> > +
> > static int
> > qemuMigrationPrepareAny(struct qemud_driver *driver,
> > virConnectPtr dconn,
> > @@ -1308,6 +1413,15 @@ qemuMigrationPrepareAny(struct qemud_driver *driver,
> > /* virDomainAssignDef already set the error */
> > goto cleanup;
> > }
> > +
> > + if (!(mig = qemuMigrationEatCookie(driver, vm, cookiein, cookieinlen,
> > + QEMU_MIGRATION_COOKIE_COPYSTORAGE)))
> > + goto cleanup;
> > +
> > + if (mig->flags & QEMU_MIGRATION_COOKIE_COPYSTORAGE)
> > + if (qemuMigrationHandleDiskFiles(driver, def, 1) < 0)
> > + goto cleanup;
> > +
> > def = NULL;
> > priv = vm->privateData;
> > priv->origname = origname;
> > @@ -2929,7 +3043,7 @@ 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;
> >
> > VIR_DEBUG("driver=%p, dconn=%p, vm=%p, cookiein=%s, cookieinlen=%d, "
> > @@ -3088,7 +3202,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(driver, vm->def, 0);
> > if (qemuMigrationJobFinish(driver, vm) == 0) {
> > vm = NULL;
> > } else if (!vm->persistent && !virDomainObjIsActive(vm)) {
>
--
li guang lig.fnst at cn.fujitsu.com
linux kernel team at FNST, china
More information about the libvir-list
mailing list