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