diff mbox

[14/17] add new RanState RAN_STATE_FLIPPING_MIGRATE

Message ID 1382412341-1173-15-git-send-email-lilei@linux.vnet.ibm.com
State New
Headers show

Commit Message

Lei Li Oct. 22, 2013, 3:25 a.m. UTC
Introduce new RanState RAN_STATE_FLIPPING_MIGRATE and
add it to runstate_needs_reset().

Signed-off-by: Lei Li <lilei@linux.vnet.ibm.com>
---
 qapi-schema.json |   11 +++++++----
 vl.c             |   12 +++++++++++-
 2 files changed, 18 insertions(+), 5 deletions(-)

Comments

Eric Blake Oct. 22, 2013, 3:51 a.m. UTC | #1
On 10/22/2013 04:25 AM, Lei Li wrote:
> Introduce new RanState RAN_STATE_FLIPPING_MIGRATE and
> add it to runstate_needs_reset().
> 
> Signed-off-by: Lei Li <lilei@linux.vnet.ibm.com>
> ---
>  qapi-schema.json |   11 +++++++----
>  vl.c             |   12 +++++++++++-
>  2 files changed, 18 insertions(+), 5 deletions(-)
> 
> diff --git a/qapi-schema.json b/qapi-schema.json
> index 523a5b2..8178d0c 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -176,12 +176,15 @@
>  # @watchdog: the watchdog action is configured to pause and has been triggered
>  #
>  # @guest-panicked: guest has been panicked as a result of guest OS panic
> +#
> +# @flipping-migrate: guest is paused to start unix_page_flipping migration
> +# process

We probably ought to enhance the docs to mention '(since 1.8)' for this
field (and likewise for other enum values added after the original
introduction of the enum).

Last time we added a new user-visible runstate, it broke migration with
older libvirt versions that weren't prepared to see the new state (hmm,
I need to check if libvirt has fixed that in the meantime; adding a
cc...).  Paolo's advice at the time was that it is okay to require a new
libvirt when using a new qemu, and that libvirt should be taught to
treat all unknown RunState as if they were 'running'; although for this
particular addition it might be nicer to have libvirt lump 'inmigrate'
and 'flipping-migrate' to the same usage.

>  ##
>  { 'enum': 'RunState',
> -  'data': [ 'debug', 'inmigrate', 'internal-error', 'io-error', 'paused',
> -            'postmigrate', 'prelaunch', 'finish-migrate', 'restore-vm',
> -            'running', 'save-vm', 'shutdown', 'suspended', 'watchdog',
> -            'guest-panicked' ] }
> +  'data': [ 'debug', 'flipping-migrate', 'inmigrate', 'internal-error',
> +            'io-error', 'paused', 'postmigrate', 'prelaunch', 'finish-migrate',
> +            'restore-vm', 'running', 'save-vm', 'shutdown', 'suspended',
> +            'watchdog', 'guest-panicked' ] }
>
Lei Li Oct. 22, 2013, 6:28 a.m. UTC | #2
On 10/22/2013 11:51 AM, Eric Blake wrote:
> On 10/22/2013 04:25 AM, Lei Li wrote:
>> Introduce new RanState RAN_STATE_FLIPPING_MIGRATE and
>> add it to runstate_needs_reset().
>>
>> Signed-off-by: Lei Li <lilei@linux.vnet.ibm.com>
>> ---
>>   qapi-schema.json |   11 +++++++----
>>   vl.c             |   12 +++++++++++-
>>   2 files changed, 18 insertions(+), 5 deletions(-)
>>
>> diff --git a/qapi-schema.json b/qapi-schema.json
>> index 523a5b2..8178d0c 100644
>> --- a/qapi-schema.json
>> +++ b/qapi-schema.json
>> @@ -176,12 +176,15 @@
>>   # @watchdog: the watchdog action is configured to pause and has been triggered
>>   #
>>   # @guest-panicked: guest has been panicked as a result of guest OS panic
>> +#
>> +# @flipping-migrate: guest is paused to start unix_page_flipping migration
>> +# process
> We probably ought to enhance the docs to mention '(since 1.8)' for this
> field (and likewise for other enum values added after the original
> introduction of the enum).

Hi Eric,

Sure, will do.

BTW, I was hoping this feature could be accepted and merged to QEMU 1.7
release.

>
> Last time we added a new user-visible runstate, it broke migration with
> older libvirt versions that weren't prepared to see the new state (hmm,
> I need to check if libvirt has fixed that in the meantime; adding a
> cc...).  Paolo's advice at the time was that it is okay to require a new
> libvirt when using a new qemu, and that libvirt should be taught to
> treat all unknown RunState as if they were 'running'; although for this
> particular addition it might be nicer to have libvirt lump 'inmigrate'
> and 'flipping-migrate' to the same usage.

I am not sure whether these two runstate could be lumped with same usage
in libvirt. Whatever, looks like 'inmigrate' has a transition from 'prelaunch'
to it in QEMU, which reminds me that it may need to add another transition
from 'prelaunch' to 'flipping-migrate' too.

>
>>   ##
>>   { 'enum': 'RunState',
>> -  'data': [ 'debug', 'inmigrate', 'internal-error', 'io-error', 'paused',
>> -            'postmigrate', 'prelaunch', 'finish-migrate', 'restore-vm',
>> -            'running', 'save-vm', 'shutdown', 'suspended', 'watchdog',
>> -            'guest-panicked' ] }
>> +  'data': [ 'debug', 'flipping-migrate', 'inmigrate', 'internal-error',
>> +            'io-error', 'paused', 'postmigrate', 'prelaunch', 'finish-migrate',
>> +            'restore-vm', 'running', 'save-vm', 'shutdown', 'suspended',
>> +            'watchdog', 'guest-panicked' ] }
>>   
>
Eric Blake Oct. 22, 2013, 8:10 a.m. UTC | #3
On 10/22/2013 07:28 AM, Lei Li wrote:

>>>   # @guest-panicked: guest has been panicked as a result of guest OS
>>> panic
>>> +#
>>> +# @flipping-migrate: guest is paused to start unix_page_flipping
>>> migration
>>> +# process
>> We probably ought to enhance the docs to mention '(since 1.8)' for this
>> field (and likewise for other enum values added after the original
>> introduction of the enum).
> 
> Hi Eric,
> 
> Sure, will do.
> 
> BTW, I was hoping this feature could be accepted and merged to QEMU 1.7
> release.

http://wiki.qemu.org/Planning/1.7
Soft freeze has already happened, so it's up to the maintainers whether
there is still time to be adding this feature in 1.7 - but yes, that
would affect the tag you list in your docs.
Paolo Bonzini Oct. 24, 2013, 2:11 p.m. UTC | #4
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Il 22/10/2013 09:10, Eric Blake ha scritto:
> http://wiki.qemu.org/Planning/1.7 Soft freeze has already
> happened, so it's up to the maintainers whether there is still time
> to be adding this feature in 1.7 - but yes, that would affect the
> tag you list in your docs.

No, this is a 1.8 feature at this point.

Paolo
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQIcBAEBAgAGBQJSaSqeAAoJEBvWZb6bTYby7sAP+gPF35M0+8YW/ujlDjXqezYw
gjtpSjKJSLx5mF4l9cA9SrQQFSkikfT/5QUZnMfjCXzWobH2y07FdUIfYR+Y5vB0
Op7Ywf01qLOgX1/qZaikZVDLYmduir1qk6Dxp85epGoVJpCC9natLkT3bPIAkB4S
Mvl2oDEnOQD5b5W5gVe80UvLIMOYW1CtJD87u6OiOm4pMVtpOp8xz02ToRO6xSSx
/PjMYY07kWlOGrMkPw/BUX92crxEfzarzhd4OrIfVhEr5l0H9axY2WJKxdMsXREI
TRL77GhqFHKz8O8uAh0G5Y1MKoX3/6mxIA1qSoMyTlDI4+qWVZwt5pJjmJjiGW58
HmsigFdBfvPqDwLCrnIrQd1aRS5oHzL++AncctlbXqayDo4IT+0lM29RBHM1obwO
GlxePNzbiKljvAyJfvIoJlUkfFvXHLZ1a94+AWXiZCcb+gRUcMw7hxmnPmyMr92X
bYkY/ZEtd8FLj+4weFAwWnrAosyp0UC4qF9y9zk9WXjUqz52KPWwVP3M10ElxjQs
XBHGmlf3+eQu1mPYf1yWO57nwHSNisnCktQ9aSiupkYJl2rBwu/qizSyfRlEV+uW
pJ++Uia29527JcYtVVM2u0FcaM5i+ZWVcD/4KVy6lFFQBK7Rt9wmhcAgfd06ynkV
1G+niTsF24mzfoVxcvPD
=BgUk
-----END PGP SIGNATURE-----
Paolo Bonzini Oct. 24, 2013, 2:13 p.m. UTC | #5
Il 22/10/2013 04:25, Lei Li ha scritto:
> Introduce new RanState RAN_STATE_FLIPPING_MIGRATE and
> add it to runstate_needs_reset().

I am not sure about the name; for one thing, the new state would apply
also to postcopy migration.

But the code looks ok.

Paolo

> Signed-off-by: Lei Li <lilei@linux.vnet.ibm.com>
> ---
>  qapi-schema.json |   11 +++++++----
>  vl.c             |   12 +++++++++++-
>  2 files changed, 18 insertions(+), 5 deletions(-)
> 
> diff --git a/qapi-schema.json b/qapi-schema.json
> index 523a5b2..8178d0c 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -176,12 +176,15 @@
>  # @watchdog: the watchdog action is configured to pause and has been triggered
>  #
>  # @guest-panicked: guest has been panicked as a result of guest OS panic
> +#
> +# @flipping-migrate: guest is paused to start unix_page_flipping migration
> +# process
>  ##
>  { 'enum': 'RunState',
> -  'data': [ 'debug', 'inmigrate', 'internal-error', 'io-error', 'paused',
> -            'postmigrate', 'prelaunch', 'finish-migrate', 'restore-vm',
> -            'running', 'save-vm', 'shutdown', 'suspended', 'watchdog',
> -            'guest-panicked' ] }
> +  'data': [ 'debug', 'flipping-migrate', 'inmigrate', 'internal-error',
> +            'io-error', 'paused', 'postmigrate', 'prelaunch', 'finish-migrate',
> +            'restore-vm', 'running', 'save-vm', 'shutdown', 'suspended',
> +            'watchdog', 'guest-panicked' ] }
>  
>  ##
>  # @SnapshotInfo
> diff --git a/vl.c b/vl.c
> index b42ac67..fcdf981 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -601,6 +601,7 @@ static const RunStateTransition runstate_transitions_def[] = {
>  
>      { RUN_STATE_PAUSED, RUN_STATE_RUNNING },
>      { RUN_STATE_PAUSED, RUN_STATE_FINISH_MIGRATE },
> +    { RUN_STATE_PAUSED, RUN_STATE_FLIPPING_MIGRATE },
>  
>      { RUN_STATE_POSTMIGRATE, RUN_STATE_RUNNING },
>      { RUN_STATE_POSTMIGRATE, RUN_STATE_FINISH_MIGRATE },
> @@ -624,23 +625,31 @@ static const RunStateTransition runstate_transitions_def[] = {
>      { RUN_STATE_RUNNING, RUN_STATE_SHUTDOWN },
>      { RUN_STATE_RUNNING, RUN_STATE_WATCHDOG },
>      { RUN_STATE_RUNNING, RUN_STATE_GUEST_PANICKED },
> +    { RUN_STATE_RUNNING, RUN_STATE_FLIPPING_MIGRATE },
>  
>      { RUN_STATE_SAVE_VM, RUN_STATE_RUNNING },
>  
>      { RUN_STATE_SHUTDOWN, RUN_STATE_PAUSED },
>      { RUN_STATE_SHUTDOWN, RUN_STATE_FINISH_MIGRATE },
> +    { RUN_STATE_SHUTDOWN, RUN_STATE_FLIPPING_MIGRATE },
>  
>      { RUN_STATE_DEBUG, RUN_STATE_SUSPENDED },
>      { RUN_STATE_RUNNING, RUN_STATE_SUSPENDED },
>      { RUN_STATE_SUSPENDED, RUN_STATE_RUNNING },
>      { RUN_STATE_SUSPENDED, RUN_STATE_FINISH_MIGRATE },
> +    { RUN_STATE_SUSPENDED, RUN_STATE_FLIPPING_MIGRATE },
>  
>      { RUN_STATE_WATCHDOG, RUN_STATE_RUNNING },
>      { RUN_STATE_WATCHDOG, RUN_STATE_FINISH_MIGRATE },
> +    { RUN_STATE_WATCHDOG, RUN_STATE_FLIPPING_MIGRATE },
>  
>      { RUN_STATE_GUEST_PANICKED, RUN_STATE_PAUSED },
>      { RUN_STATE_GUEST_PANICKED, RUN_STATE_FINISH_MIGRATE },
>      { RUN_STATE_GUEST_PANICKED, RUN_STATE_DEBUG },
> +    { RUN_STATE_GUEST_PANICKED, RUN_STATE_FLIPPING_MIGRATE },
> +
> +    { RUN_STATE_FLIPPING_MIGRATE, RUN_STATE_RUNNING },
> +    { RUN_STATE_FLIPPING_MIGRATE, RUN_STATE_POSTMIGRATE },
>  
>      { RUN_STATE_MAX, RUN_STATE_MAX },
>  };
> @@ -687,7 +696,8 @@ bool runstate_needs_reset(void)
>  {
>      return runstate_check(RUN_STATE_INTERNAL_ERROR) ||
>          runstate_check(RUN_STATE_SHUTDOWN) ||
> -        runstate_check(RUN_STATE_GUEST_PANICKED);
> +        runstate_check(RUN_STATE_GUEST_PANICKED) ||
> +        runstate_check(RUN_STATE_FLIPPING_MIGRATE);
>  }
>  
>  StatusInfo *qmp_query_status(Error **errp)
>
Paolo Bonzini Oct. 24, 2013, 2:16 p.m. UTC | #6
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Il 22/10/2013 04:51, Eric Blake ha scritto:
> 
> Last time we added a new user-visible runstate, it broke migration
> with older libvirt versions that weren't prepared to see the new
> state (hmm, I need to check if libvirt has fixed that in the
> meantime; adding a cc...).  Paolo's advice at the time was that it
> is okay to require a new libvirt when using a new qemu, and that
> libvirt should be taught to treat all unknown RunState as if they
> were 'running'; although for this particular addition it might be
> nicer to have libvirt lump 'inmigrate' and 'flipping-migrate' to
> the same usage.

This is not a problem in this case, because the new runstate will only
appear after enabling a new migration capability.  Only new libvirt
will be able to enable the capability and thus reach the new runstate.

Poalo
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQIcBAEBAgAGBQJSaSu2AAoJEBvWZb6bTYbycoUP/RDsMA/62ukPU1stvKhoOPLK
+Zi9OOSd8tIAAkHD0rDS5pQePklZ2AqKmOpJujRHhavGA/kKcMhL+79dK22UJSWn
fQPgxiivylZcFWbhF97H9eW27Vmw5la1Ob2onq2g+KY/AvL5yrEpBrN60XipHtrd
uPM2yWlERSlKcQj0nrTv5Oz3p2k9jWQrGzWX16cC+nFAaR9K/D+afOyl/3ZvixKw
ekiIIxStoJQGCogU/rJp1nJcenJfKSOofNKPU8xKkpexK4pw+W1u9GZMaAgzXLRO
Q6p3R6raIRT42Hf820ASHsWeHYak2gYmZ+5FaKGPyjAL/iwKyr4FRp7uGXobN9sD
ziMX5gaXreVdBh8CIOqDrOGa7BNoEkId2sJrrjwmmD418uZNOGK/xdcPa+mFlc8Q
GkJ4y844OckkyLhqQnuVtCVtxGlNCU3Y/XHfTKELdTm1m1jdTdoNnBGFXD1IyTxU
9yPYfQRAeRy7yPEXqQw0qc7ZUj/fhqPPzijwpPrvmFvzAouUZjlpE6QoriiBGzRx
Csq+uwpJ2bsWOC5BGvxhrhNE4F9yhWGkotxod6gvULkOLkm/4Cg5/8aNSeYzInsm
UtJ5+oZD6jzOVW5brkFosoUvWzr6vJEvwoh7DVz5sVkAH/u93WR8jlG+NsTw5fTY
+hthfn5l153w5JDikLyV
=q1Ww
-----END PGP SIGNATURE-----
Lei Li Oct. 25, 2013, 4:30 a.m. UTC | #7
On 10/24/2013 10:13 PM, Paolo Bonzini wrote:
> Il 22/10/2013 04:25, Lei Li ha scritto:
>> Introduce new RanState RAN_STATE_FLIPPING_MIGRATE and
>> add it to runstate_needs_reset().
> I am not sure about the name; for one thing, the new state would apply
> also to postcopy migration.

About the name, how about 'live-upgrade'?

OK, I'll add the transition between postcopy and this new state.
And should it also apply from 'prelaunch' to 'flipping-migrate' too?


>
> But the code looks ok.
>
> Paolo
>
>> Signed-off-by: Lei Li <lilei@linux.vnet.ibm.com>
>> ---
>>   qapi-schema.json |   11 +++++++----
>>   vl.c             |   12 +++++++++++-
>>   2 files changed, 18 insertions(+), 5 deletions(-)
>>
>> diff --git a/qapi-schema.json b/qapi-schema.json
>> index 523a5b2..8178d0c 100644
>> --- a/qapi-schema.json
>> +++ b/qapi-schema.json
>> @@ -176,12 +176,15 @@
>>   # @watchdog: the watchdog action is configured to pause and has been triggered
>>   #
>>   # @guest-panicked: guest has been panicked as a result of guest OS panic
>> +#
>> +# @flipping-migrate: guest is paused to start unix_page_flipping migration
>> +# process
>>   ##
>>   { 'enum': 'RunState',
>> -  'data': [ 'debug', 'inmigrate', 'internal-error', 'io-error', 'paused',
>> -            'postmigrate', 'prelaunch', 'finish-migrate', 'restore-vm',
>> -            'running', 'save-vm', 'shutdown', 'suspended', 'watchdog',
>> -            'guest-panicked' ] }
>> +  'data': [ 'debug', 'flipping-migrate', 'inmigrate', 'internal-error',
>> +            'io-error', 'paused', 'postmigrate', 'prelaunch', 'finish-migrate',
>> +            'restore-vm', 'running', 'save-vm', 'shutdown', 'suspended',
>> +            'watchdog', 'guest-panicked' ] }
>>   
>>   ##
>>   # @SnapshotInfo
>> diff --git a/vl.c b/vl.c
>> index b42ac67..fcdf981 100644
>> --- a/vl.c
>> +++ b/vl.c
>> @@ -601,6 +601,7 @@ static const RunStateTransition runstate_transitions_def[] = {
>>   
>>       { RUN_STATE_PAUSED, RUN_STATE_RUNNING },
>>       { RUN_STATE_PAUSED, RUN_STATE_FINISH_MIGRATE },
>> +    { RUN_STATE_PAUSED, RUN_STATE_FLIPPING_MIGRATE },
>>   
>>       { RUN_STATE_POSTMIGRATE, RUN_STATE_RUNNING },
>>       { RUN_STATE_POSTMIGRATE, RUN_STATE_FINISH_MIGRATE },
>> @@ -624,23 +625,31 @@ static const RunStateTransition runstate_transitions_def[] = {
>>       { RUN_STATE_RUNNING, RUN_STATE_SHUTDOWN },
>>       { RUN_STATE_RUNNING, RUN_STATE_WATCHDOG },
>>       { RUN_STATE_RUNNING, RUN_STATE_GUEST_PANICKED },
>> +    { RUN_STATE_RUNNING, RUN_STATE_FLIPPING_MIGRATE },
>>   
>>       { RUN_STATE_SAVE_VM, RUN_STATE_RUNNING },
>>   
>>       { RUN_STATE_SHUTDOWN, RUN_STATE_PAUSED },
>>       { RUN_STATE_SHUTDOWN, RUN_STATE_FINISH_MIGRATE },
>> +    { RUN_STATE_SHUTDOWN, RUN_STATE_FLIPPING_MIGRATE },
>>   
>>       { RUN_STATE_DEBUG, RUN_STATE_SUSPENDED },
>>       { RUN_STATE_RUNNING, RUN_STATE_SUSPENDED },
>>       { RUN_STATE_SUSPENDED, RUN_STATE_RUNNING },
>>       { RUN_STATE_SUSPENDED, RUN_STATE_FINISH_MIGRATE },
>> +    { RUN_STATE_SUSPENDED, RUN_STATE_FLIPPING_MIGRATE },
>>   
>>       { RUN_STATE_WATCHDOG, RUN_STATE_RUNNING },
>>       { RUN_STATE_WATCHDOG, RUN_STATE_FINISH_MIGRATE },
>> +    { RUN_STATE_WATCHDOG, RUN_STATE_FLIPPING_MIGRATE },
>>   
>>       { RUN_STATE_GUEST_PANICKED, RUN_STATE_PAUSED },
>>       { RUN_STATE_GUEST_PANICKED, RUN_STATE_FINISH_MIGRATE },
>>       { RUN_STATE_GUEST_PANICKED, RUN_STATE_DEBUG },
>> +    { RUN_STATE_GUEST_PANICKED, RUN_STATE_FLIPPING_MIGRATE },
>> +
>> +    { RUN_STATE_FLIPPING_MIGRATE, RUN_STATE_RUNNING },
>> +    { RUN_STATE_FLIPPING_MIGRATE, RUN_STATE_POSTMIGRATE },
>>   
>>       { RUN_STATE_MAX, RUN_STATE_MAX },
>>   };
>> @@ -687,7 +696,8 @@ bool runstate_needs_reset(void)
>>   {
>>       return runstate_check(RUN_STATE_INTERNAL_ERROR) ||
>>           runstate_check(RUN_STATE_SHUTDOWN) ||
>> -        runstate_check(RUN_STATE_GUEST_PANICKED);
>> +        runstate_check(RUN_STATE_GUEST_PANICKED) ||
>> +        runstate_check(RUN_STATE_FLIPPING_MIGRATE);
>>   }
>>   
>>   StatusInfo *qmp_query_status(Error **errp)
>>
>
Paolo Bonzini Oct. 25, 2013, 7:31 a.m. UTC | #8
Il 25/10/2013 05:30, Lei Li ha scritto:
>>>
>> I am not sure about the name; for one thing, the new state would apply
>> also to postcopy migration.
> 
> About the name, how about 'live-upgrade'?
> 
> OK, I'll add the transition between postcopy and this new state.

Note I didn't mean "postmigrate".

For a description of postcopy, see my answer to the cover letter ("patch
0").  The new state means "somebody else has newer contents of the
memory".  Perhaps "stale"?

> And should it also apply from 'prelaunch' to 'flipping-migrate' too?

Yes, it should.  Good catch!

Paolo
Lei Li Oct. 25, 2013, 12:16 p.m. UTC | #9
On 10/25/2013 03:31 PM, Paolo Bonzini wrote:
> Il 25/10/2013 05:30, Lei Li ha scritto:
>>> I am not sure about the name; for one thing, the new state would apply
>>> also to postcopy migration.
>> About the name, how about 'live-upgrade'?
>>
>> OK, I'll add the transition between postcopy and this new state.
> Note I didn't mean "postmigrate".
>
> For a description of postcopy, see my answer to the cover letter ("patch

Yes, I've realized that I misunderstood it...

> 0").  The new state means "somebody else has newer contents of the
> memory".  Perhaps "stale"?
>> And should it also apply from 'prelaunch' to 'flipping-migrate' too?
> Yes, it should.  Good catch!
>
> Paolo
>
diff mbox

Patch

diff --git a/qapi-schema.json b/qapi-schema.json
index 523a5b2..8178d0c 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -176,12 +176,15 @@ 
 # @watchdog: the watchdog action is configured to pause and has been triggered
 #
 # @guest-panicked: guest has been panicked as a result of guest OS panic
+#
+# @flipping-migrate: guest is paused to start unix_page_flipping migration
+# process
 ##
 { 'enum': 'RunState',
-  'data': [ 'debug', 'inmigrate', 'internal-error', 'io-error', 'paused',
-            'postmigrate', 'prelaunch', 'finish-migrate', 'restore-vm',
-            'running', 'save-vm', 'shutdown', 'suspended', 'watchdog',
-            'guest-panicked' ] }
+  'data': [ 'debug', 'flipping-migrate', 'inmigrate', 'internal-error',
+            'io-error', 'paused', 'postmigrate', 'prelaunch', 'finish-migrate',
+            'restore-vm', 'running', 'save-vm', 'shutdown', 'suspended',
+            'watchdog', 'guest-panicked' ] }
 
 ##
 # @SnapshotInfo
diff --git a/vl.c b/vl.c
index b42ac67..fcdf981 100644
--- a/vl.c
+++ b/vl.c
@@ -601,6 +601,7 @@  static const RunStateTransition runstate_transitions_def[] = {
 
     { RUN_STATE_PAUSED, RUN_STATE_RUNNING },
     { RUN_STATE_PAUSED, RUN_STATE_FINISH_MIGRATE },
+    { RUN_STATE_PAUSED, RUN_STATE_FLIPPING_MIGRATE },
 
     { RUN_STATE_POSTMIGRATE, RUN_STATE_RUNNING },
     { RUN_STATE_POSTMIGRATE, RUN_STATE_FINISH_MIGRATE },
@@ -624,23 +625,31 @@  static const RunStateTransition runstate_transitions_def[] = {
     { RUN_STATE_RUNNING, RUN_STATE_SHUTDOWN },
     { RUN_STATE_RUNNING, RUN_STATE_WATCHDOG },
     { RUN_STATE_RUNNING, RUN_STATE_GUEST_PANICKED },
+    { RUN_STATE_RUNNING, RUN_STATE_FLIPPING_MIGRATE },
 
     { RUN_STATE_SAVE_VM, RUN_STATE_RUNNING },
 
     { RUN_STATE_SHUTDOWN, RUN_STATE_PAUSED },
     { RUN_STATE_SHUTDOWN, RUN_STATE_FINISH_MIGRATE },
+    { RUN_STATE_SHUTDOWN, RUN_STATE_FLIPPING_MIGRATE },
 
     { RUN_STATE_DEBUG, RUN_STATE_SUSPENDED },
     { RUN_STATE_RUNNING, RUN_STATE_SUSPENDED },
     { RUN_STATE_SUSPENDED, RUN_STATE_RUNNING },
     { RUN_STATE_SUSPENDED, RUN_STATE_FINISH_MIGRATE },
+    { RUN_STATE_SUSPENDED, RUN_STATE_FLIPPING_MIGRATE },
 
     { RUN_STATE_WATCHDOG, RUN_STATE_RUNNING },
     { RUN_STATE_WATCHDOG, RUN_STATE_FINISH_MIGRATE },
+    { RUN_STATE_WATCHDOG, RUN_STATE_FLIPPING_MIGRATE },
 
     { RUN_STATE_GUEST_PANICKED, RUN_STATE_PAUSED },
     { RUN_STATE_GUEST_PANICKED, RUN_STATE_FINISH_MIGRATE },
     { RUN_STATE_GUEST_PANICKED, RUN_STATE_DEBUG },
+    { RUN_STATE_GUEST_PANICKED, RUN_STATE_FLIPPING_MIGRATE },
+
+    { RUN_STATE_FLIPPING_MIGRATE, RUN_STATE_RUNNING },
+    { RUN_STATE_FLIPPING_MIGRATE, RUN_STATE_POSTMIGRATE },
 
     { RUN_STATE_MAX, RUN_STATE_MAX },
 };
@@ -687,7 +696,8 @@  bool runstate_needs_reset(void)
 {
     return runstate_check(RUN_STATE_INTERNAL_ERROR) ||
         runstate_check(RUN_STATE_SHUTDOWN) ||
-        runstate_check(RUN_STATE_GUEST_PANICKED);
+        runstate_check(RUN_STATE_GUEST_PANICKED) ||
+        runstate_check(RUN_STATE_FLIPPING_MIGRATE);
 }
 
 StatusInfo *qmp_query_status(Error **errp)