diff mbox

[19/18] Introduce "xen-load-devices-state"

Message ID 1414134377-19665-20-git-send-email-wency@cn.fujitsu.com
State New
Headers show

Commit Message

Wen Congyang Oct. 24, 2014, 7:06 a.m. UTC
Introduce a "xen-load-devices-state" QAPI command that can be used to load
the state of all devices, but not the RAM or the block devices of the
VM.

We only have hmp commands savevm/loadvm, and qmp commands
xen-save-devices-state.

We use this new command for COLO:
1. suspend both primay vm and secondary vm
2. sync the state
3. resume both primary vm and secondary vm

In such case, we need to update all devices's state in any time.

Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
Cc: qemu-devl <qemu-devel@nongnu.org>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
---
 qapi-schema.json | 18 ++++++++++++++++++
 qmp-commands.hx  | 27 +++++++++++++++++++++++++++
 savevm.c         | 36 ++++++++++++++++++++++++++++++++++++
 3 files changed, 81 insertions(+)

Comments

Eric Blake Oct. 24, 2014, 2:04 p.m. UTC | #1
On 10/24/2014 01:06 AM, Wen Congyang wrote:
> Introduce a "xen-load-devices-state" QAPI command that can be used to load
> the state of all devices, but not the RAM or the block devices of the
> VM.
> 
> We only have hmp commands savevm/loadvm, and qmp commands
> xen-save-devices-state.
> 
> We use this new command for COLO:
> 1. suspend both primay vm and secondary vm
> 2. sync the state
> 3. resume both primary vm and secondary vm
> 
> In such case, we need to update all devices's state in any time.
> 
> Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
> Cc: qemu-devl <qemu-devel@nongnu.org>
> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> Cc: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  qapi-schema.json | 18 ++++++++++++++++++
>  qmp-commands.hx  | 27 +++++++++++++++++++++++++++
>  savevm.c         | 36 ++++++++++++++++++++++++++++++++++++
>  3 files changed, 81 insertions(+)
> 

> +#
> +# Since: 2.0
> +##
> +{ 'command': 'xen-load-devices-state', 'data': {'filename': 'str'} }

s/2.0/2.2/ - if you even get it in 2.2 (haven't we already passed soft
freeze, but this is a feature addition?)
Stefano Stabellini Oct. 25, 2014, 3:11 p.m. UTC | #2
On Fri, 24 Oct 2014, Wen Congyang wrote:
> Introduce a "xen-load-devices-state" QAPI command that can be used to load
> the state of all devices, but not the RAM or the block devices of the
> VM.
> 
> We only have hmp commands savevm/loadvm, and qmp commands
> xen-save-devices-state.
> 
> We use this new command for COLO:
> 1. suspend both primay vm and secondary vm
> 2. sync the state
> 3. resume both primary vm and secondary vm
> 
> In such case, we need to update all devices's state in any time.
> 
> Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
> Cc: qemu-devl <qemu-devel@nongnu.org>
> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> Cc: Paolo Bonzini <pbonzini@redhat.com>

The patch looks OK to me, far better than the previous version, but I am
no QMP expert.


>  qapi-schema.json | 18 ++++++++++++++++++
>  qmp-commands.hx  | 27 +++++++++++++++++++++++++++
>  savevm.c         | 36 ++++++++++++++++++++++++++++++++++++
>  3 files changed, 81 insertions(+)
> 
> diff --git a/qapi-schema.json b/qapi-schema.json
> index 391356f..c569856 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -4689,3 +4689,21 @@
>                'btn'     : 'InputBtnEvent',
>                'rel'     : 'InputMoveEvent',
>                'abs'     : 'InputMoveEvent' } }
> +
> +##
> +# @xen-load-devices-state:
> +#
> +# Load the state of all devices from file. The RAM and the block devices
> +# of the VM are not loaded by this command.
> +#
> +# @filename: the file to load the state of the devices from as binary
> +# data. See xen-save-devices-state.txt for a description of the binary
> +# format.
> +#
> +# Returns: Nothing on success
> +#          If @filename cannot be opened, OpenFileFailed
> +#          If an I/O error occurs while reading the file, IOError
> +#
> +# Since: 2.0
> +##
> +{ 'command': 'xen-load-devices-state', 'data': {'filename': 'str'} }
> diff --git a/qmp-commands.hx b/qmp-commands.hx
> index ed3ab92..b796be5 100644
> --- a/qmp-commands.hx
> +++ b/qmp-commands.hx
> @@ -586,6 +586,33 @@ Example:
>  EQMP
>  
>      {
> +        .name       = "xen-load-devices-state",
> +        .args_type  = "filename:F",
> +        .mhandler.cmd_new = qmp_marshal_input_xen_load_devices_state,
> +    },
> +
> +SQMP
> +xen-load-devices-state
> +-------
> +
> +Load the state of all devices from file. The RAM and the block devices
> +of the VM are not loaded by this command.
> +
> +Arguments:
> +
> +- "filename": the file to load the state of the devices from as binary
> +data. See xen-save-devices-state.txt for a description of the binary
> +format.
> +
> +Example:
> +
> +-> { "execute": "xen-load-devices-state",
> +     "arguments": { "filename": "/tmp/resume" } }
> +<- { "return": {} }
> +
> +EQMP
> +
> +    {
>          .name       = "xen-set-global-dirty-log",
>          .args_type  = "enable:b",
>          .mhandler.cmd_new = qmp_marshal_input_xen_set_global_dirty_log,
> diff --git a/savevm.c b/savevm.c
> index 22123be..3ebc01f 100644
> --- a/savevm.c
> +++ b/savevm.c
> @@ -41,6 +41,7 @@
>  #include "qemu/iov.h"
>  #include "block/snapshot.h"
>  #include "block/qapi.h"
> +#include "hw/xen/xen.h"
>  
>  #define SELF_ANNOUNCE_ROUNDS 5
>  
> @@ -802,6 +803,14 @@ int qemu_loadvm_state(QEMUFile *f)
>                  goto out;
>              }
>  
> +            /* Validate if it is a device's state */
> +            if (xen_enabled() && se->is_ram) {
> +                fprintf(stderr, "loadvm: %s RAM loading not allowed on Xen\n",
> +                        idstr);
> +                ret = -EINVAL;
> +                goto out;
> +            }
> +
>              /* Add entry */
>              le = g_malloc0(sizeof(*le));
>  
> @@ -1027,6 +1036,33 @@ void qmp_xen_save_devices_state(const char *filename, Error **errp)
>      }
>  }
>  
> +void qmp_xen_load_devices_state(const char *filename, Error **errp)
> +{
> +    QEMUFile *f;
> +    int saved_vm_running;
> +    int ret;
> +
> +    saved_vm_running = runstate_is_running();
> +    vm_stop(RUN_STATE_RESTORE_VM);
> +
> +    f = qemu_fopen(filename, "rb");
> +    if (!f) {
> +        error_setg_file_open(errp, errno, filename);
> +        goto out;
> +    }
> +
> +    ret = qemu_loadvm_state(f);
> +    qemu_fclose(f);
> +    if (ret < 0) {
> +        error_set(errp, QERR_IO_ERROR);
> +    }
> +
> +out:
> +    if (saved_vm_running) {
> +        vm_start();
> +    }
> +}
> +
>  int load_vmstate(const char *name)
>  {
>      BlockDriverState *bs, *bs_vm_state;
> -- 
> 1.9.3
> 
>
Wen Congyang Oct. 27, 2014, 1:26 a.m. UTC | #3
On 10/24/2014 10:04 PM, Eric Blake wrote:
> On 10/24/2014 01:06 AM, Wen Congyang wrote:
>> Introduce a "xen-load-devices-state" QAPI command that can be used to load
>> the state of all devices, but not the RAM or the block devices of the
>> VM.
>>
>> We only have hmp commands savevm/loadvm, and qmp commands
>> xen-save-devices-state.
>>
>> We use this new command for COLO:
>> 1. suspend both primay vm and secondary vm
>> 2. sync the state
>> 3. resume both primary vm and secondary vm
>>
>> In such case, we need to update all devices's state in any time.
>>
>> Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
>> Cc: qemu-devl <qemu-devel@nongnu.org>
>> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
>> Cc: Paolo Bonzini <pbonzini@redhat.com>
>> ---
>>  qapi-schema.json | 18 ++++++++++++++++++
>>  qmp-commands.hx  | 27 +++++++++++++++++++++++++++
>>  savevm.c         | 36 ++++++++++++++++++++++++++++++++++++
>>  3 files changed, 81 insertions(+)
>>
> 
>> +#
>> +# Since: 2.0
>> +##
>> +{ 'command': 'xen-load-devices-state', 'data': {'filename': 'str'} }
> 
> s/2.0/2.2/ - if you even get it in 2.2 (haven't we already passed soft
> freeze, but this is a feature addition?)
> 

I forgot to update it. I will update it in the next version. But this qmp
command is for COLO, so I don't post the next version until xen-4.5 is
released.

Thanks
Wen Congyang
diff mbox

Patch

diff --git a/qapi-schema.json b/qapi-schema.json
index 391356f..c569856 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -4689,3 +4689,21 @@ 
               'btn'     : 'InputBtnEvent',
               'rel'     : 'InputMoveEvent',
               'abs'     : 'InputMoveEvent' } }
+
+##
+# @xen-load-devices-state:
+#
+# Load the state of all devices from file. The RAM and the block devices
+# of the VM are not loaded by this command.
+#
+# @filename: the file to load the state of the devices from as binary
+# data. See xen-save-devices-state.txt for a description of the binary
+# format.
+#
+# Returns: Nothing on success
+#          If @filename cannot be opened, OpenFileFailed
+#          If an I/O error occurs while reading the file, IOError
+#
+# Since: 2.0
+##
+{ 'command': 'xen-load-devices-state', 'data': {'filename': 'str'} }
diff --git a/qmp-commands.hx b/qmp-commands.hx
index ed3ab92..b796be5 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -586,6 +586,33 @@  Example:
 EQMP
 
     {
+        .name       = "xen-load-devices-state",
+        .args_type  = "filename:F",
+        .mhandler.cmd_new = qmp_marshal_input_xen_load_devices_state,
+    },
+
+SQMP
+xen-load-devices-state
+-------
+
+Load the state of all devices from file. The RAM and the block devices
+of the VM are not loaded by this command.
+
+Arguments:
+
+- "filename": the file to load the state of the devices from as binary
+data. See xen-save-devices-state.txt for a description of the binary
+format.
+
+Example:
+
+-> { "execute": "xen-load-devices-state",
+     "arguments": { "filename": "/tmp/resume" } }
+<- { "return": {} }
+
+EQMP
+
+    {
         .name       = "xen-set-global-dirty-log",
         .args_type  = "enable:b",
         .mhandler.cmd_new = qmp_marshal_input_xen_set_global_dirty_log,
diff --git a/savevm.c b/savevm.c
index 22123be..3ebc01f 100644
--- a/savevm.c
+++ b/savevm.c
@@ -41,6 +41,7 @@ 
 #include "qemu/iov.h"
 #include "block/snapshot.h"
 #include "block/qapi.h"
+#include "hw/xen/xen.h"
 
 #define SELF_ANNOUNCE_ROUNDS 5
 
@@ -802,6 +803,14 @@  int qemu_loadvm_state(QEMUFile *f)
                 goto out;
             }
 
+            /* Validate if it is a device's state */
+            if (xen_enabled() && se->is_ram) {
+                fprintf(stderr, "loadvm: %s RAM loading not allowed on Xen\n",
+                        idstr);
+                ret = -EINVAL;
+                goto out;
+            }
+
             /* Add entry */
             le = g_malloc0(sizeof(*le));
 
@@ -1027,6 +1036,33 @@  void qmp_xen_save_devices_state(const char *filename, Error **errp)
     }
 }
 
+void qmp_xen_load_devices_state(const char *filename, Error **errp)
+{
+    QEMUFile *f;
+    int saved_vm_running;
+    int ret;
+
+    saved_vm_running = runstate_is_running();
+    vm_stop(RUN_STATE_RESTORE_VM);
+
+    f = qemu_fopen(filename, "rb");
+    if (!f) {
+        error_setg_file_open(errp, errno, filename);
+        goto out;
+    }
+
+    ret = qemu_loadvm_state(f);
+    qemu_fclose(f);
+    if (ret < 0) {
+        error_set(errp, QERR_IO_ERROR);
+    }
+
+out:
+    if (saved_vm_running) {
+        vm_start();
+    }
+}
+
 int load_vmstate(const char *name)
 {
     BlockDriverState *bs, *bs_vm_state;