[Qemu-devel] [PATCH v7 22/23] migration/qmp: add command migrate-pause

Peter Xu posted 23 patches 7 years, 11 months ago
There is a newer version of this series
[Qemu-devel] [PATCH v7 22/23] migration/qmp: add command migrate-pause
Posted by Peter Xu 7 years, 11 months ago
It pauses an ongoing migration.  Currently it only supports postcopy.
Note that this command will work on either side of the migration.
Basically when we trigger this on one side, it'll interrupt the other
side as well since the other side will get notified on the disconnect
event.

However, it's still possible that the other side is not notified, for
example, when the network is totally broken, or due to some firewall
configuration changes.  In that case, we will also need to run the same
command on the other side so both sides will go into the paused state.

Signed-off-by: Peter Xu <peterx@redhat.com>
---
 migration/migration.c | 27 +++++++++++++++++++++++++++
 qapi/migration.json   | 16 ++++++++++++++++
 2 files changed, 43 insertions(+)

diff --git a/migration/migration.c b/migration/migration.c
index 180552329c..f31fcbb0d5 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -1448,6 +1448,33 @@ void qmp_migrate_recover(const char *uri, Error **errp)
     qemu_start_incoming_migration(uri, errp);
 }
 
+void qmp_migrate_pause(Error **errp)
+{
+    MigrationState *ms = migrate_get_current();
+    MigrationIncomingState *mis = migration_incoming_get_current();
+    int ret;
+
+    if (ms->state == MIGRATION_STATUS_POSTCOPY_ACTIVE) {
+        /* Source side, during postcopy */
+        ret = qemu_file_shutdown(ms->to_dst_file);
+        if (ret) {
+            error_setg(errp, "Failed to pause source migration");
+        }
+        return;
+    }
+
+    if (mis->state == MIGRATION_STATUS_POSTCOPY_ACTIVE) {
+        ret = qemu_file_shutdown(mis->from_src_file);
+        if (ret) {
+            error_setg(errp, "Failed to pause destination migration");
+        }
+        return;
+    }
+
+    error_setg(errp, "migrate-pause is currently only supported "
+               "during postcopy-active state");
+}
+
 bool migration_is_blocked(Error **errp)
 {
     if (qemu_savevm_state_blocked(errp)) {
diff --git a/qapi/migration.json b/qapi/migration.json
index 451d8c572b..b8827d5ace 100644
--- a/qapi/migration.json
+++ b/qapi/migration.json
@@ -1194,3 +1194,19 @@
 ##
 { 'command': 'migrate-recover', 'data': { 'uri': 'str' },
   'allow-oob': true }
+
+##
+# @migrate-pause:
+#
+# Pause a migration.  Currently it only supports postcopy.
+#
+# Returns: nothing.
+#
+# Example:
+#
+# -> { "execute": "migrate-pause" }
+# <- { "return": {} }
+#
+# Since: 2.12
+##
+{ 'command': 'migrate-pause', 'allow-oob': true }
-- 
2.14.3


Re: [Qemu-devel] [PATCH v7 22/23] migration/qmp: add command migrate-pause
Posted by Dr. David Alan Gilbert 7 years, 11 months ago
* Peter Xu (peterx@redhat.com) wrote:
> It pauses an ongoing migration.  Currently it only supports postcopy.
> Note that this command will work on either side of the migration.
> Basically when we trigger this on one side, it'll interrupt the other
> side as well since the other side will get notified on the disconnect
> event.
> 
> However, it's still possible that the other side is not notified, for
> example, when the network is totally broken, or due to some firewall
> configuration changes.  In that case, we will also need to run the same
> command on the other side so both sides will go into the paused state.
> 
> Signed-off-by: Peter Xu <peterx@redhat.com>
> ---
>  migration/migration.c | 27 +++++++++++++++++++++++++++
>  qapi/migration.json   | 16 ++++++++++++++++
>  2 files changed, 43 insertions(+)
> 
> diff --git a/migration/migration.c b/migration/migration.c
> index 180552329c..f31fcbb0d5 100644
> --- a/migration/migration.c
> +++ b/migration/migration.c
> @@ -1448,6 +1448,33 @@ void qmp_migrate_recover(const char *uri, Error **errp)
>      qemu_start_incoming_migration(uri, errp);
>  }
>  
> +void qmp_migrate_pause(Error **errp)
> +{
> +    MigrationState *ms = migrate_get_current();
> +    MigrationIncomingState *mis = migration_incoming_get_current();
> +    int ret;
> +
> +    if (ms->state == MIGRATION_STATUS_POSTCOPY_ACTIVE) {
> +        /* Source side, during postcopy */
> +        ret = qemu_file_shutdown(ms->to_dst_file);

How did this fix the race I mentioned last time?

Dave

> +        if (ret) {
> +            error_setg(errp, "Failed to pause source migration");
> +        }
> +        return;
> +    }
> +
> +    if (mis->state == MIGRATION_STATUS_POSTCOPY_ACTIVE) {
> +        ret = qemu_file_shutdown(mis->from_src_file);
> +        if (ret) {
> +            error_setg(errp, "Failed to pause destination migration");
> +        }
> +        return;
> +    }
> +
> +    error_setg(errp, "migrate-pause is currently only supported "
> +               "during postcopy-active state");
> +}
> +
>  bool migration_is_blocked(Error **errp)
>  {
>      if (qemu_savevm_state_blocked(errp)) {
> diff --git a/qapi/migration.json b/qapi/migration.json
> index 451d8c572b..b8827d5ace 100644
> --- a/qapi/migration.json
> +++ b/qapi/migration.json
> @@ -1194,3 +1194,19 @@
>  ##
>  { 'command': 'migrate-recover', 'data': { 'uri': 'str' },
>    'allow-oob': true }
> +
> +##
> +# @migrate-pause:
> +#
> +# Pause a migration.  Currently it only supports postcopy.
> +#
> +# Returns: nothing.
> +#
> +# Example:
> +#
> +# -> { "execute": "migrate-pause" }
> +# <- { "return": {} }
> +#
> +# Since: 2.12
> +##
> +{ 'command': 'migrate-pause', 'allow-oob': true }
> -- 
> 2.14.3
> 
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK

Re: [Qemu-devel] [PATCH v7 22/23] migration/qmp: add command migrate-pause
Posted by Peter Xu 7 years, 11 months ago
On Mon, Mar 12, 2018 at 05:36:09PM +0000, Dr. David Alan Gilbert wrote:
> * Peter Xu (peterx@redhat.com) wrote:
> > It pauses an ongoing migration.  Currently it only supports postcopy.
> > Note that this command will work on either side of the migration.
> > Basically when we trigger this on one side, it'll interrupt the other
> > side as well since the other side will get notified on the disconnect
> > event.
> > 
> > However, it's still possible that the other side is not notified, for
> > example, when the network is totally broken, or due to some firewall
> > configuration changes.  In that case, we will also need to run the same
> > command on the other side so both sides will go into the paused state.
> > 
> > Signed-off-by: Peter Xu <peterx@redhat.com>
> > ---
> >  migration/migration.c | 27 +++++++++++++++++++++++++++
> >  qapi/migration.json   | 16 ++++++++++++++++
> >  2 files changed, 43 insertions(+)
> > 
> > diff --git a/migration/migration.c b/migration/migration.c
> > index 180552329c..f31fcbb0d5 100644
> > --- a/migration/migration.c
> > +++ b/migration/migration.c
> > @@ -1448,6 +1448,33 @@ void qmp_migrate_recover(const char *uri, Error **errp)
> >      qemu_start_incoming_migration(uri, errp);
> >  }
> >  
> > +void qmp_migrate_pause(Error **errp)
> > +{
> > +    MigrationState *ms = migrate_get_current();
> > +    MigrationIncomingState *mis = migration_incoming_get_current();
> > +    int ret;
> > +
> > +    if (ms->state == MIGRATION_STATUS_POSTCOPY_ACTIVE) {
> > +        /* Source side, during postcopy */
> > +        ret = qemu_file_shutdown(ms->to_dst_file);
> 
> How did this fix the race I mentioned last time?

Ah sorry I missed that one.  I'll reply there.

-- 
Peter Xu