From d6b6aec4091a11e5429aac4d56ad0295c5316375 Mon Sep 17 00:00:00 2001 From: Anthony PERARD Date: Thu, 9 Jun 2016 16:56:17 +0100 Subject: [PATCH 1/2] exec: Fix qemu_ram_block_from_host for Xen Since f615f39 (exec: remove ram_addr argument from qemu_ram_block_from_host), migration under Xen is likely to fail, with a SEGV of QEMU. But the commit only reveal a bug with the calculation of the offset value in qemu_ram_block_from_host(). This patch calculates the offset from the ram_addr as qemu_ram_addr_from_host() will later calculate the ram_addr from the offset. Signed-off-by: Anthony PERARD Acked-by: Paolo Bonzini Signed-off-by: Stefano Stabellini --- exec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exec.c b/exec.c index a9d465b289..4f3818c561 100644 --- a/exec.c +++ b/exec.c @@ -1935,7 +1935,7 @@ RAMBlock *qemu_ram_block_from_host(void *ptr, bool round_offset, ram_addr = xen_ram_addr_from_mapcache(ptr); block = qemu_get_ram_block(ram_addr); if (block) { - *offset = (host - block->host); + *offset = ram_addr - block->offset; } rcu_read_unlock(); return block; From 88c16567d2cd23da328787187910b013ee43ebca Mon Sep 17 00:00:00 2001 From: Wen Congyang Date: Fri, 3 Jun 2016 17:58:34 +0800 Subject: [PATCH 2/2] Introduce "xen-load-devices-state" 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 primary 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' state in any time. Signed-off-by: Wen Congyang Signed-off-by: Changlong Xie Reviewed-by: Anthony PERARD Reviewed-by: Dr. David Alan Gilbert Signed-off-by: Stefano Stabellini --- migration/savevm.c | 37 +++++++++++++++++++++++++++++++++++++ qapi-schema.json | 14 ++++++++++++++ qmp-commands.hx | 27 +++++++++++++++++++++++++++ 3 files changed, 78 insertions(+) diff --git a/migration/savevm.c b/migration/savevm.c index 6c21231131..ae2ef8b5d4 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -31,6 +31,7 @@ #include "hw/boards.h" #include "hw/hw.h" #include "hw/qdev.h" +#include "hw/xen/xen.h" #include "net/net.h" #include "monitor/monitor.h" #include "sysemu/sysemu.h" @@ -1754,6 +1755,12 @@ qemu_loadvm_section_start_full(QEMUFile *f, MigrationIncomingState *mis) return -EINVAL; } + /* Validate if it is a device's state */ + if (xen_enabled() && se->is_ram) { + error_report("loadvm: %s RAM loading not allowed on Xen", idstr); + return -EINVAL; + } + /* Add entry */ le = g_malloc0(sizeof(*le)); @@ -2064,6 +2071,36 @@ void qmp_xen_save_devices_state(const char *filename, Error **errp) } } +void qmp_xen_load_devices_state(const char *filename, Error **errp) +{ + QEMUFile *f; + QIOChannelFile *ioc; + int ret; + + /* Guest must be paused before loading the device state; the RAM state + * will already have been loaded by xc + */ + if (runstate_is_running()) { + error_setg(errp, "Cannot update device state while vm is running"); + return; + } + vm_stop(RUN_STATE_RESTORE_VM); + + ioc = qio_channel_file_new_path(filename, O_RDONLY | O_BINARY, 0, errp); + if (!ioc) { + return; + } + f = qemu_fopen_channel_input(QIO_CHANNEL(ioc)); + + migration_incoming_state_new(f); + ret = qemu_loadvm_state(f); + qemu_fclose(f); + if (ret < 0) { + error_setg(errp, QERR_IO_ERROR); + } + migration_incoming_state_destroy(); +} + int load_vmstate(const char *name) { BlockDriverState *bs, *bs_vm_state; diff --git a/qapi-schema.json b/qapi-schema.json index 8483bdfcce..48c3a6f5cd 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -4200,6 +4200,20 @@ { 'enum': 'ReplayMode', 'data': [ 'none', 'record', 'play' ] } +## +# @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. +# +# Since: 2.7 +## +{ 'command': 'xen-load-devices-state', 'data': {'filename': 'str'} } + ## # @GICCapability: # diff --git a/qmp-commands.hx b/qmp-commands.hx index 28801a28fb..780e7f2e87 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -584,6 +584,33 @@ Example: "arguments": { "filename": "/tmp/save" } } <- { "return": {} } +EQMP + + { + .name = "xen-load-devices-state", + .args_type = "filename:F", + .mhandler.cmd_new = qmp_marshal_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 {