[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