aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2017-06-13 13:51:29 +0100
committerPeter Maydell <peter.maydell@linaro.org>2017-06-13 13:51:29 +0100
commit735286a4f88255e1463d42ce28d8d14181fd32d4 (patch)
tree5200eac6b4fb709bdee16bc1bb1f3dea228b766d
parente0b4891ae6647b0009b5c0f877255e6723bffed8 (diff)
parent6666c96aac9151568736226dec99aa8acb14d07c (diff)
Merge remote-tracking branch 'remotes/juanquintela/tags/migration/20170613' into staging
migration/next for 20170613 # gpg: Signature made Tue 13 Jun 2017 10:01:45 BST # gpg: using RSA key 0xF487EF185872D723 # gpg: Good signature from "Juan Quintela <quintela@redhat.com>" # gpg: aka "Juan Quintela <quintela@trasno.org>" # Primary key fingerprint: 1899 FF8E DEBF 58CC EE03 4B82 F487 EF18 5872 D723 * remotes/juanquintela/tags/migration/20170613: migration: Move migration.h to migration/ migration: Move remaining exported functions to migration/misc.h migration: create global_state.c migration: ram_control_* are implemented in qemu_file migration: Commands are only used inside migration.c migration: Move constants to savevm.h migration: Move dump_vmsate_json_to_file() to misc.h migration: Split registration functions from vmstate.h migration: Move self_announce_delay() to misc.h migration: Remove MigrationState from migration_channel_incomming() ram: Now POSTCOPY_ACTIVE is the same that STATUS_ACTIVE ram: Print block stats also in the complete case migration: Don't try to set *errp directly migration: isolate return path on src Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--hw/i386/pc_piix.c3
-rw-r--r--hw/net/virtio-net.c1
-rw-r--r--hw/net/vmxnet3.c1
-rw-r--r--hw/ppc/spapr.c4
-rw-r--r--hw/s390x/s390-skeys.c1
-rw-r--r--hw/s390x/s390-virtio-ccw.c1
-rw-r--r--hw/xen/xen-common.c3
-rw-r--r--include/migration/global_state.h25
-rw-r--r--include/migration/misc.h26
-rw-r--r--include/migration/register.h56
-rw-r--r--include/migration/vmstate.h50
-rw-r--r--migration/Makefile.objs2
-rw-r--r--migration/block.c3
-rw-r--r--migration/channel.c7
-rw-r--r--migration/channel.h3
-rw-r--r--migration/colo-comm.c2
-rw-r--r--migration/colo.c2
-rw-r--r--migration/exec.c4
-rw-r--r--migration/fd.c4
-rw-r--r--migration/global_state.c140
-rw-r--r--migration/migration.c226
-rw-r--r--migration/migration.h (renamed from include/migration/migration.h)65
-rw-r--r--migration/postcopy-ram.c2
-rw-r--r--migration/qemu-file.c2
-rw-r--r--migration/qemu-file.h17
-rw-r--r--migration/ram.c3
-rw-r--r--migration/rdma.c2
-rw-r--r--migration/savevm.c5
-rw-r--r--migration/savevm.h15
-rw-r--r--migration/socket.c5
-rw-r--r--migration/tls.c4
-rw-r--r--migration/trace-events4
-rw-r--r--migration/vmstate-types.c2
-rw-r--r--migration/vmstate.c3
-rw-r--r--qdev-monitor.c2
-rw-r--r--slirp/slirp.c1
-rw-r--r--tests/test-vmstate.c3
-rw-r--r--ui/spice-core.c2
-rw-r--r--vl.c2
39 files changed, 380 insertions, 323 deletions
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 2234bd0461..46a2bc41ab 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -52,7 +52,8 @@
#include <xen/hvm/hvm_info_table.h>
#include "hw/xen/xen_pt.h"
#endif
-#include "migration/migration.h"
+#include "migration/global_state.h"
+#include "migration/misc.h"
#include "kvm_i386.h"
#include "sysemu/numa.h"
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 9a3d769aa2..91eddaf93b 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -25,6 +25,7 @@
#include "qapi/qmp/qjson.h"
#include "qapi-event.h"
#include "hw/virtio/virtio-access.h"
+#include "migration/misc.h"
#define VIRTIO_NET_VM_VERSION 11
diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
index 4df31101ec..a19a7a31dd 100644
--- a/hw/net/vmxnet3.c
+++ b/hw/net/vmxnet3.c
@@ -26,6 +26,7 @@
#include "qemu/bswap.h"
#include "hw/pci/msix.h"
#include "hw/pci/msi.h"
+#include "migration/register.h"
#include "vmxnet3.h"
#include "vmxnet_debug.h"
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index b2951d7618..e877d45db8 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -38,7 +38,9 @@
#include "sysemu/cpus.h"
#include "sysemu/hw_accel.h"
#include "kvm_ppc.h"
-#include "migration/migration.h"
+#include "migration/misc.h"
+#include "migration/global_state.h"
+#include "migration/register.h"
#include "mmu-hash64.h"
#include "mmu-book3s-v3.h"
#include "qom/cpu.h"
diff --git a/hw/s390x/s390-skeys.c b/hw/s390x/s390-skeys.c
index 35e7f6316f..c0de3b0c35 100644
--- a/hw/s390x/s390-skeys.c
+++ b/hw/s390x/s390-skeys.c
@@ -15,6 +15,7 @@
#include "hw/s390x/storage-keys.h"
#include "qemu/error-report.h"
#include "sysemu/kvm.h"
+#include "migration/register.h"
#define S390_SKEYS_BUFFER_SIZE 131072 /* Room for 128k storage keys */
#define S390_SKEYS_SAVE_FLAG_EOS 0x01
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index a806345276..41ca6668e2 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -28,6 +28,7 @@
#include "ipl.h"
#include "hw/s390x/s390-virtio-ccw.h"
#include "hw/s390x/css-bridge.h"
+#include "migration/register.h"
static const char *const reset_dev_types[] = {
TYPE_VIRTUAL_CSS_BRIDGE,
diff --git a/hw/xen/xen-common.c b/hw/xen/xen-common.c
index 0bed5770c9..d3fa705a82 100644
--- a/hw/xen/xen-common.c
+++ b/hw/xen/xen-common.c
@@ -13,7 +13,8 @@
#include "qmp-commands.h"
#include "chardev/char.h"
#include "sysemu/accel.h"
-#include "migration/migration.h"
+#include "migration/misc.h"
+#include "migration/global_state.h"
//#define DEBUG_XEN
diff --git a/include/migration/global_state.h b/include/migration/global_state.h
new file mode 100644
index 0000000000..90faea72b4
--- /dev/null
+++ b/include/migration/global_state.h
@@ -0,0 +1,25 @@
+/*
+ * Global State configuration
+ *
+ * Copyright (c) 2014-2017 Red Hat Inc
+ *
+ * Authors:
+ * Juan Quintela <quintela@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef QEMU_MIGRATION_GLOBAL_STATE_H
+#define QEMU_MIGRATION_GLOBAL_STATE_H
+
+#include "sysemu/sysemu.h"
+
+void register_global_state(void);
+void global_state_set_optional(void);
+int global_state_store(void);
+void global_state_store_running(void);
+bool global_state_received(void);
+RunState global_state_get_runstate(void);
+
+#endif
diff --git a/include/migration/misc.h b/include/migration/misc.h
index d7892b7956..d5a433afdb 100644
--- a/include/migration/misc.h
+++ b/include/migration/misc.h
@@ -26,4 +26,30 @@ void blk_mig_init(void);
static inline void blk_mig_init(void) {}
#endif
+#define SELF_ANNOUNCE_ROUNDS 5
+
+static inline
+int64_t self_announce_delay(int round)
+{
+ assert(round < SELF_ANNOUNCE_ROUNDS && round > 0);
+ /* delay 50ms, 150ms, 250ms, ... */
+ return 50 + (SELF_ANNOUNCE_ROUNDS - round - 1) * 100;
+}
+
+/* migration/savevm.c */
+
+void dump_vmstate_json_to_file(FILE *out_fp);
+void savevm_skip_section_footers(void);
+void savevm_skip_configuration(void);
+
+/* migration/migration.c */
+void qemu_start_incoming_migration(const char *uri, Error **errp);
+bool migration_is_idle(void);
+void add_migration_state_change_notifier(Notifier *notify);
+void remove_migration_state_change_notifier(Notifier *notify);
+bool migration_in_setup(MigrationState *);
+bool migration_has_finished(MigrationState *);
+bool migration_has_failed(MigrationState *);
+/* ...and after the device transmission */
+bool migration_in_postcopy_after_devices(MigrationState *);
#endif
diff --git a/include/migration/register.h b/include/migration/register.h
new file mode 100644
index 0000000000..717c6175b5
--- /dev/null
+++ b/include/migration/register.h
@@ -0,0 +1,56 @@
+/*
+ * QEMU migration vmstate registration
+ *
+ * Copyright IBM, Corp. 2008
+ *
+ * Authors:
+ * Anthony Liguori <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef MIGRATION_REGISTER_H
+#define MIGRATION_REGISTER_H
+
+typedef void SaveStateHandler(QEMUFile *f, void *opaque);
+typedef int LoadStateHandler(QEMUFile *f, void *opaque, int version_id);
+
+typedef struct SaveVMHandlers {
+ /* This runs inside the iothread lock. */
+ SaveStateHandler *save_state;
+
+ void (*cleanup)(void *opaque);
+ int (*save_live_complete_postcopy)(QEMUFile *f, void *opaque);
+ int (*save_live_complete_precopy)(QEMUFile *f, void *opaque);
+
+ /* This runs both outside and inside the iothread lock. */
+ bool (*is_active)(void *opaque);
+
+ /* This runs outside the iothread lock in the migration case, and
+ * within the lock in the savevm case. The callback had better only
+ * use data that is local to the migration thread or protected
+ * by other locks.
+ */
+ int (*save_live_iterate)(QEMUFile *f, void *opaque);
+
+ /* This runs outside the iothread lock! */
+ int (*save_live_setup)(QEMUFile *f, void *opaque);
+ void (*save_live_pending)(QEMUFile *f, void *opaque,
+ uint64_t threshold_size,
+ uint64_t *non_postcopiable_pending,
+ uint64_t *postcopiable_pending);
+ LoadStateHandler *load_state;
+} SaveVMHandlers;
+
+int register_savevm_live(DeviceState *dev,
+ const char *idstr,
+ int instance_id,
+ int version_id,
+ SaveVMHandlers *ops,
+ void *opaque);
+
+void unregister_savevm(DeviceState *dev, const char *idstr, void *opaque);
+
+#endif
diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
index 8a3e9e6088..79a4b350a8 100644
--- a/include/migration/vmstate.h
+++ b/include/migration/vmstate.h
@@ -29,45 +29,7 @@
#include "migration/qjson.h"
-typedef void SaveStateHandler(QEMUFile *f, void *opaque);
typedef int LoadStateHandler(QEMUFile *f, void *opaque, int version_id);
-
-typedef struct SaveVMHandlers {
- /* This runs inside the iothread lock. */
- SaveStateHandler *save_state;
-
- void (*cleanup)(void *opaque);
- int (*save_live_complete_postcopy)(QEMUFile *f, void *opaque);
- int (*save_live_complete_precopy)(QEMUFile *f, void *opaque);
-
- /* This runs both outside and inside the iothread lock. */
- bool (*is_active)(void *opaque);
-
- /* This runs outside the iothread lock in the migration case, and
- * within the lock in the savevm case. The callback had better only
- * use data that is local to the migration thread or protected
- * by other locks.
- */
- int (*save_live_iterate)(QEMUFile *f, void *opaque);
-
- /* This runs outside the iothread lock! */
- int (*save_live_setup)(QEMUFile *f, void *opaque);
- void (*save_live_pending)(QEMUFile *f, void *opaque,
- uint64_t threshold_size,
- uint64_t *non_postcopiable_pending,
- uint64_t *postcopiable_pending);
- LoadStateHandler *load_state;
-} SaveVMHandlers;
-
-int register_savevm_live(DeviceState *dev,
- const char *idstr,
- int instance_id,
- int version_id,
- SaveVMHandlers *ops,
- void *opaque);
-
-void unregister_savevm(DeviceState *dev, const char *idstr, void *opaque);
-
typedef struct VMStateInfo VMStateInfo;
typedef struct VMStateDescription VMStateDescription;
typedef struct VMStateField VMStateField;
@@ -1010,8 +972,6 @@ extern const VMStateInfo vmstate_info_qtailq;
#define VMSTATE_END_OF_LIST() \
{}
-#define SELF_ANNOUNCE_ROUNDS 5
-
int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
void *opaque, int version_id);
void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd,
@@ -1043,16 +1003,6 @@ void vmstate_register_ram(struct MemoryRegion *memory, DeviceState *dev);
void vmstate_unregister_ram(struct MemoryRegion *memory, DeviceState *dev);
void vmstate_register_ram_global(struct MemoryRegion *memory);
-static inline
-int64_t self_announce_delay(int round)
-{
- assert(round < SELF_ANNOUNCE_ROUNDS && round > 0);
- /* delay 50ms, 150ms, 250ms, ... */
- return 50 + (SELF_ANNOUNCE_ROUNDS - round - 1) * 100;
-}
-
-void dump_vmstate_json_to_file(FILE *out_fp);
-
bool vmstate_check_only_migratable(const VMStateDescription *vmsd);
#endif
diff --git a/migration/Makefile.objs b/migration/Makefile.objs
index 90f8c1f177..1c7770da46 100644
--- a/migration/Makefile.objs
+++ b/migration/Makefile.objs
@@ -2,7 +2,7 @@ common-obj-y += migration.o socket.o fd.o exec.o
common-obj-y += tls.o channel.o savevm.o
common-obj-y += colo-comm.o colo.o colo-failover.o
common-obj-y += vmstate.o vmstate-types.o page_cache.o
-common-obj-y += qemu-file.o
+common-obj-y += qemu-file.o global_state.o
common-obj-y += qemu-file-channel.o
common-obj-y += xbzrle.o postcopy-ram.o
common-obj-y += qjson.o
diff --git a/migration/block.c b/migration/block.c
index 114cedbfd0..ae06975199 100644
--- a/migration/block.c
+++ b/migration/block.c
@@ -25,7 +25,8 @@
#include "qemu/timer.h"
#include "block.h"
#include "migration/misc.h"
-#include "migration/migration.h"
+#include "migration.h"
+#include "migration/register.h"
#include "sysemu/blockdev.h"
#include "qemu-file.h"
#include "migration/vmstate.h"
diff --git a/migration/channel.c b/migration/channel.c
index eae1d9e28a..3b7252f5a2 100644
--- a/migration/channel.c
+++ b/migration/channel.c
@@ -13,15 +13,16 @@
#include "qemu/osdep.h"
#include "channel.h"
#include "tls.h"
-#include "migration/migration.h"
+#include "migration.h"
#include "qemu-file-channel.h"
#include "trace.h"
#include "qapi/error.h"
#include "io/channel-tls.h"
-void migration_channel_process_incoming(MigrationState *s,
- QIOChannel *ioc)
+void migration_channel_process_incoming(QIOChannel *ioc)
{
+ MigrationState *s = migrate_get_current();
+
trace_migration_set_incoming_channel(
ioc, object_get_typename(OBJECT(ioc)));
diff --git a/migration/channel.h b/migration/channel.h
index 2e0a7e33cc..e4b40579a1 100644
--- a/migration/channel.h
+++ b/migration/channel.h
@@ -18,8 +18,7 @@
#include "io/channel.h"
-void migration_channel_process_incoming(MigrationState *s,
- QIOChannel *ioc);
+void migration_channel_process_incoming(QIOChannel *ioc);
void migration_channel_connect(MigrationState *s,
QIOChannel *ioc,
diff --git a/migration/colo-comm.c b/migration/colo-comm.c
index 8bfdf6825a..b61aa19a38 100644
--- a/migration/colo-comm.c
+++ b/migration/colo-comm.c
@@ -12,7 +12,7 @@
*/
#include "qemu/osdep.h"
-#include "migration/migration.h"
+#include "migration.h"
#include "migration/colo.h"
#include "migration/vmstate.h"
#include "trace.h"
diff --git a/migration/colo.c b/migration/colo.c
index 111b715546..45e9b46289 100644
--- a/migration/colo.c
+++ b/migration/colo.c
@@ -14,7 +14,7 @@
#include "qemu/timer.h"
#include "sysemu/sysemu.h"
#include "qemu-file-channel.h"
-#include "migration/migration.h"
+#include "migration.h"
#include "qemu-file.h"
#include "savevm.h"
#include "migration/colo.h"
diff --git a/migration/exec.c b/migration/exec.c
index 9077024286..b1de44543a 100644
--- a/migration/exec.c
+++ b/migration/exec.c
@@ -22,7 +22,7 @@
#include "qemu-common.h"
#include "channel.h"
#include "exec.h"
-#include "migration/migration.h"
+#include "migration.h"
#include "io/channel-command.h"
#include "trace.h"
@@ -49,7 +49,7 @@ static gboolean exec_accept_incoming_migration(QIOChannel *ioc,
GIOCondition condition,
gpointer opaque)
{
- migration_channel_process_incoming(migrate_get_current(), ioc);
+ migration_channel_process_incoming(ioc);
object_unref(OBJECT(ioc));
return FALSE; /* unregister */
}
diff --git a/migration/fd.c b/migration/fd.c
index 0077a505a3..b2384bf133 100644
--- a/migration/fd.c
+++ b/migration/fd.c
@@ -19,7 +19,7 @@
#include "qemu-common.h"
#include "channel.h"
#include "fd.h"
-#include "migration/migration.h"
+#include "migration.h"
#include "monitor/monitor.h"
#include "io/channel-util.h"
#include "trace.h"
@@ -49,7 +49,7 @@ static gboolean fd_accept_incoming_migration(QIOChannel *ioc,
GIOCondition condition,
gpointer opaque)
{
- migration_channel_process_incoming(migrate_get_current(), ioc);
+ migration_channel_process_incoming(ioc);
object_unref(OBJECT(ioc));
return FALSE; /* unregister */
}
diff --git a/migration/global_state.c b/migration/global_state.c
new file mode 100644
index 0000000000..16ac63fb92
--- /dev/null
+++ b/migration/global_state.c
@@ -0,0 +1,140 @@
+/*
+ * Global State configuration
+ *
+ * Copyright (c) 2014-2017 Red Hat Inc
+ *
+ * Authors:
+ * Juan Quintela <quintela@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/cutils.h"
+#include "qemu/error-report.h"
+#include "qapi/error.h"
+#include "qapi/util.h"
+#include "migration/global_state.h"
+#include "migration/vmstate.h"
+#include "sysemu/sysemu.h"
+#include "trace.h"
+
+typedef struct {
+ bool optional;
+ uint32_t size;
+ uint8_t runstate[100];
+ RunState state;
+ bool received;
+} GlobalState;
+
+static GlobalState global_state;
+
+int global_state_store(void)
+{
+ if (!runstate_store((char *)global_state.runstate,
+ sizeof(global_state.runstate))) {
+ error_report("runstate name too big: %s", global_state.runstate);
+ trace_migrate_state_too_big();
+ return -EINVAL;
+ }
+ return 0;
+}
+
+void global_state_store_running(void)
+{
+ const char *state = RunState_lookup[RUN_STATE_RUNNING];
+ strncpy((char *)global_state.runstate,
+ state, sizeof(global_state.runstate));
+}
+
+bool global_state_received(void)
+{
+ return global_state.received;
+}
+
+RunState global_state_get_runstate(void)
+{
+ return global_state.state;
+}
+
+void global_state_set_optional(void)
+{
+ global_state.optional = true;
+}
+
+static bool global_state_needed(void *opaque)
+{
+ GlobalState *s = opaque;
+ char *runstate = (char *)s->runstate;
+
+ /* If it is not optional, it is mandatory */
+
+ if (s->optional == false) {
+ return true;
+ }
+
+ /* If state is running or paused, it is not needed */
+
+ if (strcmp(runstate, "running") == 0 ||
+ strcmp(runstate, "paused") == 0) {
+ return false;
+ }
+
+ /* for any other state it is needed */
+ return true;
+}
+
+static int global_state_post_load(void *opaque, int version_id)
+{
+ GlobalState *s = opaque;
+ Error *local_err = NULL;
+ int r;
+ char *runstate = (char *)s->runstate;
+
+ s->received = true;
+ trace_migrate_global_state_post_load(runstate);
+
+ r = qapi_enum_parse(RunState_lookup, runstate, RUN_STATE__MAX,
+ -1, &local_err);
+
+ if (r == -1) {
+ if (local_err) {
+ error_report_err(local_err);
+ }
+ return -EINVAL;
+ }
+ s->state = r;
+
+ return 0;
+}
+
+static void global_state_pre_save(void *opaque)
+{
+ GlobalState *s = opaque;
+
+ trace_migrate_global_state_pre_save((char *)s->runstate);
+ s->size = strlen((char *)s->runstate) + 1;
+}
+
+static const VMStateDescription vmstate_globalstate = {
+ .name = "globalstate",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .post_load = global_state_post_load,
+ .pre_save = global_state_pre_save,
+ .needed = global_state_needed,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(size, GlobalState),
+ VMSTATE_BUFFER(runstate, GlobalState),
+ VMSTATE_END_OF_LIST()
+ },
+};
+
+void register_global_state(void)
+{
+ /* We would use it independently that we receive it */
+ strcpy((char *)&global_state.runstate, "");
+ global_state.received = false;
+ vmstate_register(NULL, 0, &vmstate_globalstate, &global_state);
+}
diff --git a/migration/migration.c b/migration/migration.c
index fc95acbde6..8ef6d6c412 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -23,7 +23,9 @@
#include "socket.h"
#include "rdma.h"
#include "ram.h"
-#include "migration/migration.h"
+#include "migration/global_state.h"
+#include "migration/misc.h"
+#include "migration.h"
#include "savevm.h"
#include "qemu-file-channel.h"
#include "qemu-file.h"
@@ -86,6 +88,18 @@ static NotifierList migration_state_notifiers =
static bool deferred_incoming;
+/* Messages sent on the return path from destination to source */
+enum mig_rp_message_type {
+ MIG_RP_MSG_INVALID = 0, /* Must be 0 */
+ MIG_RP_MSG_SHUT, /* sibling will not send any more RP messages */
+ MIG_RP_MSG_PONG, /* Response to a PING; data (seq: be32 ) */
+
+ MIG_RP_MSG_REQ_PAGES_ID, /* data (start: be64, len: be32, id: string) */
+ MIG_RP_MSG_REQ_PAGES, /* data (start: be64, len: be32) */
+
+ MIG_RP_MSG_MAX
+};
+
/* When we add fault tolerance, we could have several
migrations at once. For now we don't need to add
dynamic creation of migration */
@@ -152,126 +166,6 @@ void migration_incoming_state_destroy(void)
qemu_event_destroy(&mis->main_thread_load_event);
}
-
-typedef struct {
- bool optional;
- uint32_t size;
- uint8_t runstate[100];
- RunState state;
- bool received;
-} GlobalState;
-
-static GlobalState global_state;
-
-int global_state_store(void)
-{
- if (!runstate_store((char *)global_state.runstate,
- sizeof(global_state.runstate))) {
- error_report("runstate name too big: %s", global_state.runstate);
- trace_migrate_state_too_big();
- return -EINVAL;
- }
- return 0;
-}
-
-void global_state_store_running(void)
-{
- const char *state = RunState_lookup[RUN_STATE_RUNNING];
- strncpy((char *)global_state.runstate,
- state, sizeof(global_state.runstate));
-}
-
-static bool global_state_received(void)
-{
- return global_state.received;
-}
-
-static RunState global_state_get_runstate(void)
-{
- return global_state.state;
-}
-
-void global_state_set_optional(void)
-{
- global_state.optional = true;
-}
-
-static bool global_state_needed(void *opaque)
-{
- GlobalState *s = opaque;
- char *runstate = (char *)s->runstate;
-
- /* If it is not optional, it is mandatory */
-
- if (s->optional == false) {
- return true;
- }
-
- /* If state is running or paused, it is not needed */
-
- if (strcmp(runstate, "running") == 0 ||
- strcmp(runstate, "paused") == 0) {
- return false;
- }
-
- /* for any other state it is needed */
- return true;
-}
-
-static int global_state_post_load(void *opaque, int version_id)
-{
- GlobalState *s = opaque;
- Error *local_err = NULL;
- int r;
- char *runstate = (char *)s->runstate;
-
- s->received = true;
- trace_migrate_global_state_post_load(runstate);
-
- r = qapi_enum_parse(RunState_lookup, runstate, RUN_STATE__MAX,
- -1, &local_err);
-
- if (r == -1) {
- if (local_err) {
- error_report_err(local_err);
- }
- return -EINVAL;
- }
- s->state = r;
-
- return 0;
-}
-
-static void global_state_pre_save(void *opaque)
-{
- GlobalState *s = opaque;
-
- trace_migrate_global_state_pre_save((char *)s->runstate);
- s->size = strlen((char *)s->runstate) + 1;
-}
-
-static const VMStateDescription vmstate_globalstate = {
- .name = "globalstate",
- .version_id = 1,
- .minimum_version_id = 1,
- .post_load = global_state_post_load,
- .pre_save = global_state_pre_save,
- .needed = global_state_needed,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32(size, GlobalState),
- VMSTATE_BUFFER(runstate, GlobalState),
- VMSTATE_END_OF_LIST()
- },
-};
-
-void register_global_state(void)
-{
- /* We would use it independently that we receive it */
- strcpy((char *)&global_state.runstate, "");
- global_state.received = false;
- vmstate_register(NULL, 0, &vmstate_globalstate, &global_state);
-}
-
static void migrate_generate_event(int new_state)
{
if (migrate_use_events()) {
@@ -292,6 +186,23 @@ static void deferred_incoming_migration(Error **errp)
deferred_incoming = true;
}
+/*
+ * Send a message on the return channel back to the source
+ * of the migration.
+ */
+static void migrate_send_rp_message(MigrationIncomingState *mis,
+ enum mig_rp_message_type message_type,
+ uint16_t len, void *data)
+{
+ trace_migrate_send_rp_message((int)message_type, len);
+ qemu_mutex_lock(&mis->rp_mutex);
+ qemu_put_be16(mis->to_src_file, (unsigned int)message_type);
+ qemu_put_be16(mis->to_src_file, len);
+ qemu_put_buffer(mis->to_src_file, data, len);
+ qemu_fflush(mis->to_src_file);
+ qemu_mutex_unlock(&mis->rp_mutex);
+}
+
/* Request a range of pages from the source VM at the given
* start address.
* rbname: Name of the RAMBlock to request the page in, if NULL it's the same
@@ -462,23 +373,6 @@ void migration_fd_process_incoming(QEMUFile *f)
}
/*
- * Send a message on the return channel back to the source
- * of the migration.
- */
-void migrate_send_rp_message(MigrationIncomingState *mis,
- enum mig_rp_message_type message_type,
- uint16_t len, void *data)
-{
- trace_migrate_send_rp_message((int)message_type, len);
- qemu_mutex_lock(&mis->rp_mutex);
- qemu_put_be16(mis->to_src_file, (unsigned int)message_type);
- qemu_put_be16(mis->to_src_file, len);
- qemu_put_buffer(mis->to_src_file, data, len);
- qemu_fflush(mis->to_src_file);
- qemu_mutex_unlock(&mis->rp_mutex);
-}
-
-/*
* Send a 'SHUT' message on the return channel with the given value
* to indicate that we've finished with the RP. Non-0 value indicates
* error.
@@ -627,6 +521,17 @@ static void populate_ram_info(MigrationInfo *info, MigrationState *s)
}
}
+static void populate_disk_info(MigrationInfo *info)
+{
+ if (blk_mig_active()) {
+ info->has_disk = true;
+ info->disk = g_malloc0(sizeof(*info->disk));
+ info->disk->transferred = blk_mig_bytes_transferred();
+ info->disk->remaining = blk_mig_bytes_remaining();
+ info->disk->total = blk_mig_bytes_total();
+ }
+}
+
MigrationInfo *qmp_query_migrate(Error **errp)
{
MigrationInfo *info = g_malloc0(sizeof(*info));
@@ -642,28 +547,8 @@ MigrationInfo *qmp_query_migrate(Error **errp)
break;
case MIGRATION_STATUS_ACTIVE:
case MIGRATION_STATUS_CANCELLING:
- info->has_status = true;
- info->has_total_time = true;
- info->total_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME)
- - s->total_time;
- info->has_expected_downtime = true;
- info->expected_downtime = s->expected_downtime;
- info->has_setup_time = true;
- info->setup_time = s->setup_time;
-
- populate_ram_info(info, s);
-
- if (blk_mig_active()) {
- info->has_disk = true;
- info->disk = g_malloc0(sizeof(*info->disk));
- info->disk->transferred = blk_mig_bytes_transferred();
- info->disk->remaining = blk_mig_bytes_remaining();
- info->disk->total = blk_mig_bytes_total();
- }
-
- break;
case MIGRATION_STATUS_POSTCOPY_ACTIVE:
- /* Mostly the same as active; TODO add some postcopy stats */
+ /* TODO add some postcopy stats */
info->has_status = true;
info->has_total_time = true;
info->total_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME)
@@ -674,15 +559,7 @@ MigrationInfo *qmp_query_migrate(Error **errp)
info->setup_time = s->setup_time;
populate_ram_info(info, s);
-
- if (blk_mig_active()) {
- info->has_disk = true;
- info->disk = g_malloc0(sizeof(*info->disk));
- info->disk->transferred = blk_mig_bytes_transferred();
- info->disk->remaining = blk_mig_bytes_remaining();
- info->disk->total = blk_mig_bytes_total();
- }
-
+ populate_disk_info(info);
break;
case MIGRATION_STATUS_COLO:
info->has_status = true;
@@ -1179,7 +1056,7 @@ bool migration_is_blocked(Error **errp)
}
if (migration_blockers) {
- *errp = error_copy(migration_blockers->data);
+ error_propagate(errp, error_copy(migration_blockers->data));
return true;
}
@@ -1857,13 +1734,12 @@ static void migration_completion(MigrationState *s, int current_active_state,
* cleaning everything else up (since if there are no failures
* it will wait for the destination to send it's status in
* a SHUT command).
- * Postcopy opens rp if enabled (even if it's not avtivated)
*/
- if (migrate_postcopy_ram()) {
+ if (s->rp_state.from_dst_file) {
int rp_error;
- trace_migration_completion_postcopy_end_before_rp();
+ trace_migration_return_path_end_before();
rp_error = await_return_path_close_on_source(s);
- trace_migration_completion_postcopy_end_after_rp(rp_error);
+ trace_migration_return_path_end_after(rp_error);
if (rp_error) {
goto fail_invalidate;
}
@@ -1938,13 +1814,15 @@ static void *migration_thread(void *opaque)
qemu_savevm_state_header(s->to_dst_file);
- if (migrate_postcopy_ram()) {
+ if (s->to_dst_file) {
/* Now tell the dest that it should open its end so it can reply */
qemu_savevm_send_open_return_path(s->to_dst_file);
/* And do a ping that will make stuff easier to debug */
qemu_savevm_send_ping(s->to_dst_file, 1);
+ }
+ if (migrate_postcopy_ram()) {
/*
* Tell the destination that we *might* want to do postcopy later;
* if the other end can't do postcopy it should fail now, nice and
diff --git a/include/migration/migration.h b/migration/migration.h
index 79b5484d65..601e4ab354 100644
--- a/include/migration/migration.h
+++ b/migration/migration.h
@@ -22,33 +22,6 @@
#include "exec/cpu-common.h"
#include "qemu/coroutine_int.h"
-#define QEMU_VM_FILE_MAGIC 0x5145564d
-#define QEMU_VM_FILE_VERSION_COMPAT 0x00000002
-#define QEMU_VM_FILE_VERSION 0x00000003
-
-#define QEMU_VM_EOF 0x00
-#define QEMU_VM_SECTION_START 0x01
-#define QEMU_VM_SECTION_PART 0x02
-#define QEMU_VM_SECTION_END 0x03
-#define QEMU_VM_SECTION_FULL 0x04
-#define QEMU_VM_SUBSECTION 0x05
-#define QEMU_VM_VMDESCRIPTION 0x06
-#define QEMU_VM_CONFIGURATION 0x07
-#define QEMU_VM_COMMAND 0x08
-#define QEMU_VM_SECTION_FOOTER 0x7e
-
-/* Messages sent on the return path from destination to source */
-enum mig_rp_message_type {
- MIG_RP_MSG_INVALID = 0, /* Must be 0 */
- MIG_RP_MSG_SHUT, /* sibling will not send any more RP messages */
- MIG_RP_MSG_PONG, /* Response to a PING; data (seq: be32 ) */
-
- MIG_RP_MSG_REQ_PAGES_ID, /* data (start: be64, len: be32, id: string) */
- MIG_RP_MSG_REQ_PAGES, /* data (start: be64, len: be32) */
-
- MIG_RP_MSG_MAX
-};
-
/* State for the incoming migration */
struct MigrationIncomingState {
QEMUFile *from_src_file;
@@ -149,26 +122,16 @@ void migrate_set_state(int *state, int old_state, int new_state);
void migration_fd_process_incoming(QEMUFile *f);
-void qemu_start_incoming_migration(const char *uri, Error **errp);
-
uint64_t migrate_max_downtime(void);
void migrate_fd_error(MigrationState *s, const Error *error);
void migrate_fd_connect(MigrationState *s);
-void add_migration_state_change_notifier(Notifier *notify);
-void remove_migration_state_change_notifier(Notifier *notify);
MigrationState *migrate_init(void);
bool migration_is_blocked(Error **errp);
-bool migration_in_setup(MigrationState *);
-bool migration_is_idle(void);
-bool migration_has_finished(MigrationState *);
-bool migration_has_failed(MigrationState *);
/* True if outgoing migration has entered postcopy phase */
bool migration_in_postcopy(void);
-/* ...and after the device transmission */
-bool migration_in_postcopy_after_devices(MigrationState *);
MigrationState *migrate_get_current(void);
bool migrate_release_ram(void);
@@ -191,9 +154,6 @@ int migrate_decompress_threads(void);
bool migrate_use_events(void);
/* Sending on the return path - generic and then for each message type */
-void migrate_send_rp_message(MigrationIncomingState *mis,
- enum mig_rp_message_type message_type,
- uint16_t len, void *data);
void migrate_send_rp_shut(MigrationIncomingState *mis,
uint32_t value);
void migrate_send_rp_pong(MigrationIncomingState *mis,
@@ -201,29 +161,4 @@ void migrate_send_rp_pong(MigrationIncomingState *mis,
void migrate_send_rp_req_pages(MigrationIncomingState *mis, const char* rbname,
ram_addr_t start, size_t len);
-void ram_control_before_iterate(QEMUFile *f, uint64_t flags);
-void ram_control_after_iterate(QEMUFile *f, uint64_t flags);
-void ram_control_load_hook(QEMUFile *f, uint64_t flags, void *data);
-
-/* Whenever this is found in the data stream, the flags
- * will be passed to ram_control_load_hook in the incoming-migration
- * side. This lets before_ram_iterate/after_ram_iterate add
- * transport-specific sections to the RAM migration data.
- */
-#define RAM_SAVE_FLAG_HOOK 0x80
-
-#define RAM_SAVE_CONTROL_NOT_SUPP -1000
-#define RAM_SAVE_CONTROL_DELAYED -2000
-
-size_t ram_control_save_page(QEMUFile *f, ram_addr_t block_offset,
- ram_addr_t offset, size_t size,
- uint64_t *bytes_sent);
-
-void savevm_skip_section_footers(void);
-void register_global_state(void);
-void global_state_set_optional(void);
-void savevm_skip_configuration(void);
-int global_state_store(void);
-void global_state_store_running(void);
-
#endif
diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c
index 9c4188724e..c8c4500cc4 100644
--- a/migration/postcopy-ram.c
+++ b/migration/postcopy-ram.c
@@ -20,7 +20,7 @@
#include "qemu-common.h"
#include "exec/target_page.h"
-#include "migration/migration.h"
+#include "migration.h"
#include "qemu-file.h"
#include "savevm.h"
#include "postcopy-ram.h"
diff --git a/migration/qemu-file.c b/migration/qemu-file.c
index ab26f4eea9..e65c373341 100644
--- a/migration/qemu-file.c
+++ b/migration/qemu-file.c
@@ -28,7 +28,7 @@
#include "qemu/iov.h"
#include "qemu/sockets.h"
#include "qemu/coroutine.h"
-#include "migration/migration.h"
+#include "migration.h"
#include "qemu-file.h"
#include "trace.h"
diff --git a/migration/qemu-file.h b/migration/qemu-file.h
index 49fd6978ac..aae4e5ed36 100644
--- a/migration/qemu-file.h
+++ b/migration/qemu-file.h
@@ -156,5 +156,22 @@ void qemu_file_set_blocking(QEMUFile *f, bool block);
size_t qemu_get_counted_string(QEMUFile *f, char buf[256]);
+void ram_control_before_iterate(QEMUFile *f, uint64_t flags);
+void ram_control_after_iterate(QEMUFile *f, uint64_t flags);
+void ram_control_load_hook(QEMUFile *f, uint64_t flags, void *data);
+
+/* Whenever this is found in the data stream, the flags
+ * will be passed to ram_control_load_hook in the incoming-migration
+ * side. This lets before_ram_iterate/after_ram_iterate add
+ * transport-specific sections to the RAM migration data.
+ */
+#define RAM_SAVE_FLAG_HOOK 0x80
+
+#define RAM_SAVE_CONTROL_NOT_SUPP -1000
+#define RAM_SAVE_CONTROL_DELAYED -2000
+
+size_t ram_control_save_page(QEMUFile *f, ram_addr_t block_offset,
+ ram_addr_t offset, size_t size,
+ uint64_t *bytes_sent);
#endif
diff --git a/migration/ram.c b/migration/ram.c
index 9ffd0a5479..c1b4f4abf3 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -37,7 +37,8 @@
#include "qemu/main-loop.h"
#include "xbzrle.h"
#include "ram.h"
-#include "migration/migration.h"
+#include "migration.h"
+#include "migration/register.h"
#include "migration/misc.h"
#include "qemu-file.h"
#include "migration/vmstate.h"
diff --git a/migration/rdma.c b/migration/rdma.c
index e446c6fd6a..c6bc607a03 100644
--- a/migration/rdma.c
+++ b/migration/rdma.c
@@ -18,7 +18,7 @@
#include "qemu-common.h"
#include "qemu/cutils.h"
#include "rdma.h"
-#include "migration/migration.h"
+#include "migration.h"
#include "qemu-file.h"
#include "ram.h"
#include "qemu-file-channel.h"
diff --git a/migration/savevm.c b/migration/savevm.c
index 745caaebef..30cda2cb46 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -34,8 +34,11 @@
#include "net/net.h"
#include "sysemu/sysemu.h"
#include "qemu/timer.h"
-#include "migration/migration.h"
+#include "migration.h"
#include "migration/snapshot.h"
+#include "migration/misc.h"
+#include "migration/register.h"
+#include "migration/global_state.h"
#include "ram.h"
#include "qemu-file-channel.h"
#include "qemu-file.h"
diff --git a/migration/savevm.h b/migration/savevm.h
index eb4487771a..45b59c19bc 100644
--- a/migration/savevm.h
+++ b/migration/savevm.h
@@ -14,6 +14,21 @@
#ifndef MIGRATION_SAVEVM_H
#define MIGRATION_SAVEVM_H
+#define QEMU_VM_FILE_MAGIC 0x5145564d
+#define QEMU_VM_FILE_VERSION_COMPAT 0x00000002
+#define QEMU_VM_FILE_VERSION 0x00000003
+
+#define QEMU_VM_EOF 0x00
+#define QEMU_VM_SECTION_START 0x01
+#define QEMU_VM_SECTION_PART 0x02
+#define QEMU_VM_SECTION_END 0x03
+#define QEMU_VM_SECTION_FULL 0x04
+#define QEMU_VM_SUBSECTION 0x05
+#define QEMU_VM_VMDESCRIPTION 0x06
+#define QEMU_VM_CONFIGURATION 0x07
+#define QEMU_VM_COMMAND 0x08
+#define QEMU_VM_SECTION_FOOTER 0x7e
+
bool qemu_savevm_state_blocked(Error **errp);
void qemu_savevm_state_begin(QEMUFile *f);
void qemu_savevm_state_header(QEMUFile *f);
diff --git a/migration/socket.c b/migration/socket.c
index 85bfdccae1..757d3821a1 100644
--- a/migration/socket.c
+++ b/migration/socket.c
@@ -21,7 +21,7 @@
#include "qapi/error.h"
#include "channel.h"
#include "socket.h"
-#include "migration/migration.h"
+#include "migration.h"
#include "qemu-file.h"
#include "io/channel-socket.h"
#include "trace.h"
@@ -148,8 +148,7 @@ static gboolean socket_accept_incoming_migration(QIOChannel *ioc,
trace_migration_socket_incoming_accepted();
qio_channel_set_name(QIO_CHANNEL(sioc), "migration-socket-incoming");
- migration_channel_process_incoming(migrate_get_current(),
- QIO_CHANNEL(sioc));
+ migration_channel_process_incoming(QIO_CHANNEL(sioc));
object_unref(OBJECT(sioc));
out:
diff --git a/migration/tls.c b/migration/tls.c
index bae9acad6c..596e8790bd 100644
--- a/migration/tls.c
+++ b/migration/tls.c
@@ -20,7 +20,7 @@
#include "qemu/osdep.h"
#include "channel.h"
-#include "migration/migration.h"
+#include "migration.h"
#include "tls.h"
#include "io/channel-tls.h"
#include "crypto/tlscreds.h"
@@ -74,7 +74,7 @@ static void migration_tls_incoming_handshake(QIOTask *task,
error_report_err(err);
} else {
trace_migration_tls_incoming_handshake_complete();
- migration_channel_process_incoming(migrate_get_current(), ioc);
+ migration_channel_process_incoming(ioc);
}
object_unref(OBJECT(ioc));
}
diff --git a/migration/trace-events b/migration/trace-events
index 5b8ccf301c..38345be9c3 100644
--- a/migration/trace-events
+++ b/migration/trace-events
@@ -88,8 +88,8 @@ migrate_send_rp_message(int msg_type, uint16_t len) "%d: len %d"
migration_completion_file_err(void) ""
migration_completion_postcopy_end(void) ""
migration_completion_postcopy_end_after_complete(void) ""
-migration_completion_postcopy_end_before_rp(void) ""
-migration_completion_postcopy_end_after_rp(int rp_error) "%d"
+migration_return_path_end_before(void) ""
+migration_return_path_end_after(int rp_error) "%d"
migration_thread_after_loop(void) ""
migration_thread_file_err(void) ""
migration_thread_setup_complete(void) ""
diff --git a/migration/vmstate-types.c b/migration/vmstate-types.c
index 7287c6baa6..02f05a3359 100644
--- a/migration/vmstate-types.c
+++ b/migration/vmstate-types.c
@@ -14,7 +14,7 @@
#include "qemu-common.h"
#include "exec/cpu-common.h"
#include "qemu-file.h"
-#include "migration/migration.h"
+#include "migration.h"
#include "migration/vmstate.h"
#include "qemu/error-report.h"
#include "qemu/queue.h"
diff --git a/migration/vmstate.c b/migration/vmstate.c
index 51a19b668a..3226e8eb45 100644
--- a/migration/vmstate.c
+++ b/migration/vmstate.c
@@ -12,8 +12,9 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
-#include "migration/migration.h"
+#include "migration.h"
#include "migration/vmstate.h"
+#include "migration/savevm.h"
#include "qemu-file.h"
#include "qemu/bitops.h"
#include "qemu/error-report.h"
diff --git a/qdev-monitor.c b/qdev-monitor.c
index 3ecbf0bd25..8fd6df93d2 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -29,7 +29,7 @@
#include "qemu/error-report.h"
#include "qemu/help_option.h"
#include "sysemu/block-backend.h"
-#include "migration/migration.h"
+#include "migration/misc.h"
/*
* Aliases were a bad idea from the start. Let's keep them
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 23864938f7..1d6756821c 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -26,6 +26,7 @@
#include "qemu/timer.h"
#include "qemu/error-report.h"
#include "chardev/char-fe.h"
+#include "migration/register.h"
#include "slirp.h"
#include "hw/hw.h"
#include "qemu/cutils.h"
diff --git a/tests/test-vmstate.c b/tests/test-vmstate.c
index c52aff96d6..ee292c7bee 100644
--- a/tests/test-vmstate.c
+++ b/tests/test-vmstate.c
@@ -25,11 +25,12 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
-#include "migration/migration.h"
+#include "../migration/migration.h"
#include "migration/vmstate.h"
#include "migration/qemu-file-types.h"
#include "../migration/qemu-file.h"
#include "../migration/qemu-file-channel.h"
+#include "../migration/savevm.h"
#include "qemu/coroutine.h"
#include "io/channel-file.h"
diff --git a/ui/spice-core.c b/ui/spice-core.c
index 804abc5c0f..a087ad5da9 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -35,7 +35,7 @@
#include "qapi/qmp/qstring.h"
#include "qapi/qmp/qjson.h"
#include "qemu/notify.h"
-#include "migration/migration.h"
+#include "migration/misc.h"
#include "hw/hw.h"
#include "ui/spice-display.h"
#include "qapi-event.h"
diff --git a/vl.c b/vl.c
index be4dcf25ba..32db19e3b9 100644
--- a/vl.c
+++ b/vl.c
@@ -88,11 +88,11 @@ int main(int argc, char **argv)
#include "hw/block/block.h"
#include "migration/misc.h"
#include "migration/snapshot.h"
+#include "migration/global_state.h"
#include "sysemu/tpm.h"
#include "sysemu/dma.h"
#include "hw/audio/soundhw.h"
#include "audio/audio.h"
-#include "migration/migration.h"
#include "sysemu/cpus.h"
#include "migration/colo.h"
#include "sysemu/kvm.h"