[libvirt] [PATCH v3 2/2] auto cold migration fallback at timeout

Hu Tao hutao at cn.fujitsu.com
Fri Dec 17 09:49:30 UTC 2010


On Fri, Dec 17, 2010 at 04:49:27PM +0800, Wen Congyang wrote:
> implement auto cold migration fallback at timeout
> 
> Signed-off-by: Wen Congyang <wency at cn.fujitsu.com>
> 
> ---
>  tools/virsh.c |   66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 66 insertions(+), 0 deletions(-)
> 
> diff --git a/tools/virsh.c b/tools/virsh.c
> index cbde085..b95c8fe 100644
> --- a/tools/virsh.c
> +++ b/tools/virsh.c
> @@ -3379,9 +3379,32 @@ static const vshCmdOptDef opts_migrate[] = {
>      {"desturi", VSH_OT_DATA, VSH_OFLAG_REQ, N_("connection URI of the destination host")},
>      {"migrateuri", VSH_OT_DATA, 0, N_("migration URI, usually can be omitted")},
>      {"dname", VSH_OT_DATA, 0, N_("rename to new name during migration (if supported)")},
> +    {"timeout", VSH_OT_INT, 0, N_("auto cold migration fallback when live migration timeouts(in seconds)")},
>      {NULL, 0, 0, NULL}
>  };
>  
> +static void migrateTimeoutHandler(void *data)
> +{
> +    virDomainPtr dom = (virDomainPtr)data;
> +    virDomainInfo info;
> +    unsigned int id;
> +
> +    id = virDomainGetID(dom);
> +    if (id == ((unsigned int)-1))
> +        return;
> +
> +    /* The error reason has been reported in virDomainGetInfo() and
> +     * virDomainSuspend() when it fails. So we do not check the return value.
> +     */
> +    if (virDomainGetInfo(dom, &info) == 0) {
> +        if (info.state == VIR_DOMAIN_SHUTOFF)
> +            return;
> +
> +        /* suspend the domain when migration timeouts. */
> +        virDomainSuspend(dom);
> +    }
> +}
> +
>  static int
>  cmdMigrate (vshControl *ctl, const vshCmd *cmd)
>  {
> @@ -3389,6 +3412,8 @@ cmdMigrate (vshControl *ctl, const vshCmd *cmd)
>      const char *desturi;
>      const char *migrateuri;
>      const char *dname;
> +    long long timeout;
> +    virTimerPtr migratetimer = NULL;
>      int flags = 0, found, ret = FALSE;
>  
>      if (!vshConnectionUsability (ctl, ctl->conn))
> @@ -3426,6 +3451,28 @@ cmdMigrate (vshControl *ctl, const vshCmd *cmd)
>      if (vshCommandOptBool (cmd, "copy-storage-inc"))
>          flags |= VIR_MIGRATE_NON_SHARED_INC;
>  
> +    timeout = vshCommandOptLongLong(cmd, "timeout", &found);
> +    if (found) {
> +        if (! flags & VIR_MIGRATE_LIVE) {
> +            vshError(ctl, "%s", _("migrate: Unexpected timeout for cold migration"));
> +            goto done;
> +        }
> +
> +        if (timeout < 1) {
> +            vshError(ctl, "%s", _("migrate: Invalid timeout"));
> +            goto done;
> +        }
> +
> +        migratetimer = virNewTimer(migrateTimeoutHandler, (void *)dom);
> +        if (!migratetimer)
> +            goto done;
> +
> +        if (virStartTimer() < 0) {

I thinks it's better to call this function at virsh initialization stage
and  stop it when virsh ends, then at anytime in the lifetime of virsh
we can call virAddTimer/virDelTimer to add/delete a timer.

> +            vshError(ctl, "%s", _("migrate: failed to start timer"));
> +            goto done;
> +        }
> +    }
> +
>      if ((flags & VIR_MIGRATE_PEER2PEER) ||
>          vshCommandOptBool (cmd, "direct")) {
>          /* For peer2peer migration or direct migration we only expect one URI
> @@ -3436,6 +3483,13 @@ cmdMigrate (vshControl *ctl, const vshCmd *cmd)
>              goto done;
>          }
>  
> +        if (migratetimer) {
> +            if (virAddTimer(migratetimer, timeout * 1000) < 0) {
> +                vshError(ctl, "%s", _("migrate: failed to add timer"));
> +                goto done;
> +            }
> +        }
> +
>          if (virDomainMigrateToURI (dom, desturi, flags, dname, 0) == 0)
>              ret = TRUE;
>      } else {
> @@ -3446,6 +3500,13 @@ cmdMigrate (vshControl *ctl, const vshCmd *cmd)
>          dconn = virConnectOpenAuth (desturi, virConnectAuthPtrDefault, 0);
>          if (!dconn) goto done;
>  
> +        if (migratetimer) {
> +            if (virAddTimer(migratetimer, timeout * 1000) < 0) {
> +                vshError(ctl, "%s", _("migrate: failed to add timer"));
> +                goto done;
> +            }
> +        }
> +
>          ddom = virDomainMigrate (dom, dconn, flags, dname, migrateuri, 0);
>          if (ddom) {
>              virDomainFree(ddom);
> @@ -3455,6 +3516,11 @@ cmdMigrate (vshControl *ctl, const vshCmd *cmd)
>      }
>  
>   done:
> +    if (migratetimer) {
> +        virStopTimer();

See above.

> +        virDelTimer(migratetimer);
> +        virFreeTimer(migratetimer);
> +    }
>      if (dom) virDomainFree (dom);
>      return ret;
>  }
> -- 
> 1.7.1

-- 
Thanks,
Hu Tao




More information about the libvir-list mailing list