[libvirt] [PATCH v2 02/11] Introduce NBD migration cookie
li guang
lig.fnst at cn.fujitsu.com
Tue Dec 18 08:11:44 UTC 2012
在 2012-12-10一的 20:27 +0100,Michal Privoznik写道:
> This migration cookie is meant for two purposes. The first is to be sent
> in begin phase from source to destination to let it know we support new
> implementation of VIR_MIGRATE_NON_SHARED_{DISK,INC} so destination can
> start NBD server. Then, the second purpose is, destination can let us
> know, on which port is NBD server running.
> ---
> src/qemu/qemu_migration.c | 117 ++++++++++++++++++++++++++++++++++++++++----
> 1 files changed, 106 insertions(+), 11 deletions(-)
>
> diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
> index 86060dc..8c1e873 100644
> --- a/src/qemu/qemu_migration.c
> +++ b/src/qemu/qemu_migration.c
> @@ -72,6 +72,7 @@ enum qemuMigrationCookieFlags {
> QEMU_MIGRATION_COOKIE_FLAG_LOCKSTATE,
> QEMU_MIGRATION_COOKIE_FLAG_PERSISTENT,
> QEMU_MIGRATION_COOKIE_FLAG_NETWORK,
> + QEMU_MIGRATION_COOKIE_FLAG_NBD,
>
> QEMU_MIGRATION_COOKIE_FLAG_LAST
> };
> @@ -79,13 +80,18 @@ enum qemuMigrationCookieFlags {
> VIR_ENUM_DECL(qemuMigrationCookieFlag);
> VIR_ENUM_IMPL(qemuMigrationCookieFlag,
> QEMU_MIGRATION_COOKIE_FLAG_LAST,
> - "graphics", "lockstate", "persistent", "network");
> + "graphics",
> + "lockstate",
> + "persistent",
> + "network",
> + "nbd");
>
> 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_NETWORK = (1 << QEMU_MIGRATION_COOKIE_FLAG_NETWORK),
> + QEMU_MIGRATION_COOKIE_NBD = (1 << QEMU_MIGRATION_COOKIE_FLAG_NBD),
> };
>
> typedef struct _qemuMigrationCookieGraphics qemuMigrationCookieGraphics;
> @@ -119,6 +125,17 @@ struct _qemuMigrationCookieNetwork {
> qemuMigrationCookieNetDataPtr net;
> };
>
> +typedef struct _qemuMigrationCookieNBD qemuMigrationCookieNBD;
> +typedef qemuMigrationCookieNBD *qemuMigrationCookieNBDPtr;
> +struct _qemuMigrationCookieNBD {
> + int port; /* on which port does NBD server listen for incoming data.
> + Zero value has special meaning - it is there just to let
> + destination know we (the source) do support NBD.
> + Negative one is meant to be sent when translating from
> + perform to finish phase to let destination know it's
> + safe to stop NBD server.*/
> +};
> +
> typedef struct _qemuMigrationCookie qemuMigrationCookie;
> typedef qemuMigrationCookie *qemuMigrationCookiePtr;
> struct _qemuMigrationCookie {
> @@ -147,6 +164,9 @@ struct _qemuMigrationCookie {
>
> /* If (flags & QEMU_MIGRATION_COOKIE_NETWORK) */
> qemuMigrationCookieNetworkPtr network;
> +
> + /* If (flags & QEMU_MIGRATION_COOKIE_NBD) */
> + qemuMigrationCookieNBDPtr nbd;
> };
>
> static void qemuMigrationCookieGraphicsFree(qemuMigrationCookieGraphicsPtr grap)
> @@ -192,6 +212,7 @@ static void qemuMigrationCookieFree(qemuMigrationCookiePtr mig)
> VIR_FREE(mig->name);
> VIR_FREE(mig->lockState);
> VIR_FREE(mig->lockDriver);
> + VIR_FREE(mig->nbd);
> VIR_FREE(mig);
> }
>
> @@ -492,6 +513,24 @@ qemuMigrationCookieAddNetwork(qemuMigrationCookiePtr mig,
> }
>
>
> +static int
> +qemuMigrationCookieAddNBD(qemuMigrationCookiePtr mig,
> + int nbdPort)
> +{
> + /* It is not a bug if there already is a NBD data */
> + if (!mig->nbd &&
> + VIR_ALLOC(mig->nbd) < 0) {
> + virReportOOMError();
> + return -1;
> + }
> +
> + mig->nbd->port = nbdPort;
> + mig->flags |= QEMU_MIGRATION_COOKIE_NBD;
> +
> + return 0;
> +}
> +
> +
> static void qemuMigrationCookieGraphicsXMLFormat(virBufferPtr buf,
> qemuMigrationCookieGraphicsPtr grap)
> {
> @@ -594,6 +633,13 @@ qemuMigrationCookieXMLFormat(virQEMUDriverPtr driver,
> if ((mig->flags & QEMU_MIGRATION_COOKIE_NETWORK) && mig->network)
> qemuMigrationCookieNetworkXMLFormat(buf, mig->network);
>
> + if ((mig->flags & QEMU_MIGRATION_COOKIE_NBD) && mig->nbd) {
> + virBufferAddLit(buf, " <nbd");
> + if (mig->nbd->port)
> + virBufferAsprintf(buf, " port='%d'", mig->nbd->port);
> + virBufferAddLit(buf, "/>\n");
> + }
> +
> virBufferAddLit(buf, "</qemu-migration>\n");
> return 0;
> }
> @@ -821,6 +867,12 @@ qemuMigrationCookieXMLParse(qemuMigrationCookiePtr mig,
> goto error;
> }
>
> + /* nbd is optional */
> + if (val == QEMU_MIGRATION_COOKIE_FLAG_NBD) {
> + VIR_FREE(str);
> + continue;
> + }
> +
> if ((flags & (1 << val)) == 0) {
> virReportError(VIR_ERR_INTERNAL_ERROR,
> _("Unsupported migration cookie feature %s"),
> @@ -873,6 +925,25 @@ qemuMigrationCookieXMLParse(qemuMigrationCookiePtr mig,
> (!(mig->network = qemuMigrationCookieNetworkXMLParse(ctxt))))
> goto error;
>
> + if (flags & QEMU_MIGRATION_COOKIE_NBD &&
> + virXPathBoolean("count(./nbd) > 0", ctxt)) {
> + char *port;
> +
> + if (VIR_ALLOC(mig->nbd) < 0) {
> + virReportOOMError();
> + goto error;
> + }
> +
> + port = virXPathString("string(./nbd/@port)", ctxt);
> + if (port &&
> + virStrToLong_i(port, NULL, 10, &mig->nbd->port) < 0) {
> + virReportError(VIR_ERR_INTERNAL_ERROR,
> + _("Malformed nbd port '%s'"),
> + port);
> + goto error;
> + }
> + }
> +
> return 0;
>
> error:
> @@ -911,6 +982,7 @@ static int
> qemuMigrationBakeCookie(qemuMigrationCookiePtr mig,
> virQEMUDriverPtr driver,
> virDomainObjPtr dom,
> + int nbdPort,
> char **cookieout,
> int *cookieoutlen,
> unsigned int flags)
> @@ -937,6 +1009,10 @@ qemuMigrationBakeCookie(qemuMigrationCookiePtr mig,
> return -1;
> }
>
> + if (flags & QEMU_MIGRATION_COOKIE_NBD &&
> + qemuMigrationCookieAddNBD(mig, nbdPort) < 0)
> + return -1;
> +
> if (!(*cookieout = qemuMigrationCookieXMLFormatStr(driver, mig)))
> return -1;
>
> @@ -1415,6 +1491,7 @@ char *qemuMigrationBegin(virQEMUDriverPtr driver,
> qemuMigrationCookiePtr mig = NULL;
> virDomainDefPtr def = NULL;
> qemuDomainObjPrivatePtr priv = vm->privateData;
> + unsigned int cookie_flags = QEMU_MIGRATION_COOKIE_LOCKSTATE;
>
> VIR_DEBUG("driver=%p, vm=%p, xmlin=%s, dname=%s,"
> " cookieout=%p, cookieoutlen=%p, flags=%lx",
> @@ -1434,12 +1511,20 @@ char *qemuMigrationBegin(virQEMUDriverPtr driver,
> if (!(flags & VIR_MIGRATE_UNSAFE) && !qemuMigrationIsSafe(vm->def))
> goto cleanup;
>
> + if (qemuCapsGet(priv->caps, QEMU_CAPS_NBD_SERVER)) {
> + /* TODO support NBD for TUNNELLED migration */
> + if (flags & VIR_MIGRATE_TUNNELLED)
> + VIR_DEBUG("NBD in tunnelled migration is currently not supported");
> + else
> + cookie_flags |= QEMU_MIGRATION_COOKIE_NBD;
> + }
> +
'if (flags & VIR_MIGRATE_NON_SHARED_INC ||
flags & VIR_MIGRATE_NON_SHARED_DISK)'
also required here.
> if (!(mig = qemuMigrationEatCookie(driver, vm, NULL, 0, 0)))
> goto cleanup;
>
> - if (qemuMigrationBakeCookie(mig, driver, vm,
> + if (qemuMigrationBakeCookie(mig, driver, vm, 0,
> cookieout, cookieoutlen,
> - QEMU_MIGRATION_COOKIE_LOCKSTATE) < 0)
> + cookie_flags) < 0)
> goto cleanup;
>
> if (xmlin) {
> @@ -1512,6 +1597,8 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
> bool tunnel = !!st;
> char *origname = NULL;
> char *xmlout = NULL;
> + int nbdPort = 0;
> + unsigned int cookie_flags = QEMU_MIGRATION_COOKIE_GRAPHICS;
>
> if (virTimeMillisNow(&now) < 0)
> return -1;
> @@ -1589,7 +1676,8 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
> origname = NULL;
>
> if (!(mig = qemuMigrationEatCookie(driver, vm, cookiein, cookieinlen,
> - QEMU_MIGRATION_COOKIE_LOCKSTATE)))
> + QEMU_MIGRATION_COOKIE_LOCKSTATE |
> + QEMU_MIGRATION_COOKIE_NBD)))
> goto cleanup;
>
> if (qemuMigrationJobStart(driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN) < 0)
> @@ -1640,8 +1728,12 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
> VIR_DEBUG("Received no lockstate");
> }
>
> - if (qemuMigrationBakeCookie(mig, driver, vm, cookieout, cookieoutlen,
> - QEMU_MIGRATION_COOKIE_GRAPHICS) < 0) {
> + /* dummy place holder for real work */
> + nbdPort = 0;
> + cookie_flags |= QEMU_MIGRATION_COOKIE_NBD;
> +
> + if (qemuMigrationBakeCookie(mig, driver, vm, nbdPort,
> + cookieout, cookieoutlen, cookie_flags) < 0) {
> /* We could tear down the whole guest here, but
> * cookie data is (so far) non-critical, so that
> * seems a little harsh. We'll just warn for now.
> @@ -2150,7 +2242,8 @@ qemuMigrationRun(virQEMUDriverPtr driver,
> }
>
> if (!(mig = qemuMigrationEatCookie(driver, vm, cookiein, cookieinlen,
> - QEMU_MIGRATION_COOKIE_GRAPHICS)))
> + QEMU_MIGRATION_COOKIE_GRAPHICS |
> + QEMU_MIGRATION_COOKIE_NBD)))
> goto cleanup;
>
> if (qemuDomainMigrateGraphicsRelocate(driver, vm, mig) < 0)
> @@ -2296,9 +2389,10 @@ cleanup:
> }
>
> if (ret == 0 &&
> - qemuMigrationBakeCookie(mig, driver, vm, cookieout, cookieoutlen,
> + qemuMigrationBakeCookie(mig, driver, vm, -1, cookieout, cookieoutlen,
> QEMU_MIGRATION_COOKIE_PERSISTENT |
> - QEMU_MIGRATION_COOKIE_NETWORK) < 0) {
> + QEMU_MIGRATION_COOKIE_NETWORK |
> + QEMU_MIGRATION_COOKIE_NBD) < 0) {
> VIR_WARN("Unable to encode migration cookie");
> }
>
> @@ -3233,7 +3327,7 @@ qemuMigrationFinish(virQEMUDriverPtr driver,
>
> qemuDomainCleanupRemove(vm, qemuMigrationPrepareCleanup);
>
> - cookie_flags = QEMU_MIGRATION_COOKIE_NETWORK;
> + cookie_flags = QEMU_MIGRATION_COOKIE_NETWORK | QEMU_MIGRATION_COOKIE_NBD;
> if (flags & VIR_MIGRATE_PERSIST_DEST)
> cookie_flags |= QEMU_MIGRATION_COOKIE_PERSISTENT;
>
> @@ -3377,7 +3471,8 @@ qemuMigrationFinish(virQEMUDriverPtr driver,
> VIR_DOMAIN_EVENT_STOPPED_FAILED);
> }
>
> - if (qemuMigrationBakeCookie(mig, driver, vm, cookieout, cookieoutlen, 0) < 0)
> + if (qemuMigrationBakeCookie(mig, driver, vm, 0,
> + cookieout, cookieoutlen, 0) < 0)
> VIR_WARN("Unable to encode migration cookie");
>
> endjob:
--
regards!
li guang
More information about the libvir-list
mailing list