160fe637bSDr. David Alan Gilbert /*
260fe637bSDr. David Alan Gilbert * QEMU live migration
360fe637bSDr. David Alan Gilbert *
460fe637bSDr. David Alan Gilbert * Copyright IBM, Corp. 2008
560fe637bSDr. David Alan Gilbert *
660fe637bSDr. David Alan Gilbert * Authors:
760fe637bSDr. David Alan Gilbert * Anthony Liguori <aliguori@us.ibm.com>
860fe637bSDr. David Alan Gilbert *
960fe637bSDr. David Alan Gilbert * This work is licensed under the terms of the GNU GPL, version 2. See
1060fe637bSDr. David Alan Gilbert * the COPYING file in the top-level directory.
1160fe637bSDr. David Alan Gilbert *
1260fe637bSDr. David Alan Gilbert * Contributions after 2012-01-13 are licensed under the terms of the
1360fe637bSDr. David Alan Gilbert * GNU GPL, version 2 or (at your option) any later version.
1460fe637bSDr. David Alan Gilbert */
1560fe637bSDr. David Alan Gilbert
161393a485SPeter Maydell #include "qemu/osdep.h"
17f348b6d1SVeronia Bahaa #include "qemu/cutils.h"
18d49b6836SMarkus Armbruster #include "qemu/error-report.h"
19db725815SMarkus Armbruster #include "qemu/main-loop.h"
20795c40b8SJuan Quintela #include "migration/blocker.h"
21f4dbe1bfSJuan Quintela #include "exec.h"
227fcac4a2SJuan Quintela #include "fd.h"
232a9e2e59SSteve Sistare #include "file.h"
2461e8b148SJuan Quintela #include "socket.h"
2554d31236SMarkus Armbruster #include "sysemu/runstate.h"
2646517dd4SMarkus Armbruster #include "sysemu/sysemu.h"
27b0c3cf94SClaudio Fontana #include "sysemu/cpu-throttle.h"
28e1a3eceeSJuan Quintela #include "rdma.h"
297b1e1a22SJuan Quintela #include "ram.h"
3084a899deSJuan Quintela #include "migration/global_state.h"
31c4b63b7cSJuan Quintela #include "migration/misc.h"
326666c96aSJuan Quintela #include "migration.h"
33947701ccSJuan Quintela #include "migration-stats.h"
3420a519a0SJuan Quintela #include "savevm.h"
3508a0aee1SJuan Quintela #include "qemu-file.h"
366720c2b3Smanish.mishra #include "channel.h"
37987772d9SJuan Quintela #include "migration/vmstate.h"
3860fe637bSDr. David Alan Gilbert #include "block/block.h"
39e688df6bSMarkus Armbruster #include "qapi/error.h"
409aca82baSJuan Quintela #include "qapi/clone-visitor.h"
4131e4c354SMax Reitz #include "qapi/qapi-visit-migration.h"
429aca82baSJuan Quintela #include "qapi/qapi-visit-sockets.h"
439af23989SMarkus Armbruster #include "qapi/qapi-commands-migration.h"
449af23989SMarkus Armbruster #include "qapi/qapi-events-migration.h"
45cc7a8ea7SMarkus Armbruster #include "qapi/qmp/qerror.h"
4615280c36SMarkus Armbruster #include "qapi/qmp/qnull.h"
47ab28bd23SPaolo Bonzini #include "qemu/rcu.h"
48be07b0acSJuan Quintela #include "postcopy-ram.h"
4960fe637bSDr. David Alan Gilbert #include "qemu/thread.h"
5060fe637bSDr. David Alan Gilbert #include "trace.h"
5151180423SJuan Quintela #include "exec/target_page.h"
5261b67d47SDaniel P. Berrange #include "io/channel-buffer.h"
5385a8578eSPeter Xu #include "io/channel-tls.h"
5435a6ed4fSzhanghailiang #include "migration/colo.h"
554ffdb337SPeter Xu #include "hw/boards.h"
569d18af93SPeter Xu #include "monitor/monitor.h"
5750510ea2SDr. David Alan Gilbert #include "net/announce.h"
58c7e0acd5SJens Freimann #include "qemu/queue.h"
59d32ca5adSJuan Quintela #include "multifd.h"
601b1f4ab6SJiang Jiacheng #include "threadinfo.h"
61b5eea99eSLukas Straub #include "qemu/yank.h"
626e8c25b4SAndrey Gruzdev #include "sysemu/cpus.h"
6339675fffSPeter Xu #include "yank_functions.h"
641b529d90SLaurent Vivier #include "sysemu/qtest.h"
651f0776f1SJuan Quintela #include "options.h"
6615699cf5SHyman Huang(黄勇) #include "sysemu/dirtylimit.h"
6772a8192eSHet Gala #include "qemu/sockets.h"
6806152b89SWilliam Roche #include "sysemu/kvm.h"
6960fe637bSDr. David Alan Gilbert
706835f5a1SSteve Sistare #define NOTIFIER_ELEM_INIT(array, elem) \
716835f5a1SSteve Sistare [elem] = NOTIFIER_WITH_RETURN_LIST_INITIALIZER((array)[elem])
726835f5a1SSteve Sistare
73dbea1c89SVladimir Sementsov-Ogievskiy #define INMIGRATE_DEFAULT_EXIT_ON_ERROR true
74dbea1c89SVladimir Sementsov-Ogievskiy
756835f5a1SSteve Sistare static NotifierWithReturnList migration_state_notifiers[] = {
766835f5a1SSteve Sistare NOTIFIER_ELEM_INIT(migration_state_notifiers, MIG_MODE_NORMAL),
776835f5a1SSteve Sistare NOTIFIER_ELEM_INIT(migration_state_notifiers, MIG_MODE_CPR_REBOOT),
786835f5a1SSteve Sistare };
7960fe637bSDr. David Alan Gilbert
80da6f1790SJuan Quintela /* Messages sent on the return path from destination to source */
81da6f1790SJuan Quintela enum mig_rp_message_type {
82da6f1790SJuan Quintela MIG_RP_MSG_INVALID = 0, /* Must be 0 */
83da6f1790SJuan Quintela MIG_RP_MSG_SHUT, /* sibling will not send any more RP messages */
84da6f1790SJuan Quintela MIG_RP_MSG_PONG, /* Response to a PING; data (seq: be32 ) */
85da6f1790SJuan Quintela
86da6f1790SJuan Quintela MIG_RP_MSG_REQ_PAGES_ID, /* data (start: be64, len: be32, id: string) */
87da6f1790SJuan Quintela MIG_RP_MSG_REQ_PAGES, /* data (start: be64, len: be32) */
88a335debbSPeter Xu MIG_RP_MSG_RECV_BITMAP, /* send recved_bitmap back to source */
8913955b89SPeter Xu MIG_RP_MSG_RESUME_ACK, /* tell source that we are ready to resume */
901b4adb10SAvihai Horon MIG_RP_MSG_SWITCHOVER_ACK, /* Tell source it's OK to do switchover */
91da6f1790SJuan Quintela
92da6f1790SJuan Quintela MIG_RP_MSG_MAX
93da6f1790SJuan Quintela };
94da6f1790SJuan Quintela
9560fe637bSDr. David Alan Gilbert /* When we add fault tolerance, we could have several
9660fe637bSDr. David Alan Gilbert migrations at once. For now we don't need to add
9760fe637bSDr. David Alan Gilbert dynamic creation of migration */
9860fe637bSDr. David Alan Gilbert
99e5cb7e76SPeter Xu static MigrationState *current_migration;
100e1b1b1bcSPeter Xu static MigrationIncomingState *current_incoming;
101e5cb7e76SPeter Xu
102fa3673e4SSteve Sistare static GSList *migration_blockers[MIG_MODE__MAX];
1033af8554bSDr. David Alan Gilbert
1048b0b29dcSPeter Xu static bool migration_object_check(MigrationState *ms, Error **errp);
1050331c8caSDr. David Alan Gilbert static int migration_maybe_pause(MigrationState *s,
1060331c8caSDr. David Alan Gilbert int *current_active_state,
1070331c8caSDr. David Alan Gilbert int new_state);
108892ae715SDr. David Alan Gilbert static void migrate_fd_cancel(MigrationState *s);
1097aa6070dSPeter Xu static bool close_return_path_on_source(MigrationState *s);
11063f64d77SFabiano Rosas static void migration_completion_end(MigrationState *s);
1118b0b29dcSPeter Xu
migration_downtime_start(MigrationState * s)112e22ffad0SPeter Xu static void migration_downtime_start(MigrationState *s)
113e22ffad0SPeter Xu {
1143e5f3bcdSPeter Xu trace_vmstate_downtime_checkpoint("src-downtime-start");
115e22ffad0SPeter Xu s->downtime_start = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
116e22ffad0SPeter Xu }
117e22ffad0SPeter Xu
migration_downtime_end(MigrationState * s)118e22ffad0SPeter Xu static void migration_downtime_end(MigrationState *s)
119e22ffad0SPeter Xu {
120e22ffad0SPeter Xu int64_t now = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
121e22ffad0SPeter Xu
122e22ffad0SPeter Xu /*
123e22ffad0SPeter Xu * If downtime already set, should mean that postcopy already set it,
124e22ffad0SPeter Xu * then that should be the real downtime already.
125e22ffad0SPeter Xu */
126e22ffad0SPeter Xu if (!s->downtime) {
127e22ffad0SPeter Xu s->downtime = now - s->downtime_start;
128e22ffad0SPeter Xu }
1293e5f3bcdSPeter Xu
1303e5f3bcdSPeter Xu trace_vmstate_downtime_checkpoint("src-downtime-end");
131e22ffad0SPeter Xu }
132e22ffad0SPeter Xu
migration_needs_multiple_sockets(void)133d6f74fd1SPeter Xu static bool migration_needs_multiple_sockets(void)
134f444eedaSPeter Xu {
13551b07548SJuan Quintela return migrate_multifd() || migrate_postcopy_preempt();
136f444eedaSPeter Xu }
137f444eedaSPeter Xu
transport_supports_multi_channels(MigrationAddress * addr)1383205bebdSAvihai Horon static bool transport_supports_multi_channels(MigrationAddress *addr)
139f444eedaSPeter Xu {
1403205bebdSAvihai Horon if (addr->transport == MIGRATION_ADDRESS_TYPE_SOCKET) {
1413205bebdSAvihai Horon SocketAddress *saddr = &addr->u.socket;
1423205bebdSAvihai Horon
143f427d90bSFabiano Rosas return (saddr->type == SOCKET_ADDRESS_TYPE_INET ||
144d95533e1SHet Gala saddr->type == SOCKET_ADDRESS_TYPE_UNIX ||
145f427d90bSFabiano Rosas saddr->type == SOCKET_ADDRESS_TYPE_VSOCK);
146f427d90bSFabiano Rosas } else if (addr->transport == MIGRATION_ADDRESS_TYPE_FILE) {
147f427d90bSFabiano Rosas return migrate_mapped_ram();
148f427d90bSFabiano Rosas } else {
1493205bebdSAvihai Horon return false;
1503205bebdSAvihai Horon }
151f427d90bSFabiano Rosas }
1523205bebdSAvihai Horon
migration_needs_seekable_channel(void)1538d9e0d41SFabiano Rosas static bool migration_needs_seekable_channel(void)
1548d9e0d41SFabiano Rosas {
1558d9e0d41SFabiano Rosas return migrate_mapped_ram();
1568d9e0d41SFabiano Rosas }
1578d9e0d41SFabiano Rosas
migration_needs_extra_fds(void)1589d70239eSFabiano Rosas static bool migration_needs_extra_fds(void)
1599d70239eSFabiano Rosas {
1609d70239eSFabiano Rosas /*
1619d70239eSFabiano Rosas * When doing direct-io, multifd requires two different,
1629d70239eSFabiano Rosas * non-duplicated file descriptors so we can use one of them for
1639d70239eSFabiano Rosas * unaligned IO.
1649d70239eSFabiano Rosas */
1659d70239eSFabiano Rosas return migrate_multifd() && migrate_direct_io();
1669d70239eSFabiano Rosas }
1679d70239eSFabiano Rosas
transport_supports_seeking(MigrationAddress * addr)1688d9e0d41SFabiano Rosas static bool transport_supports_seeking(MigrationAddress *addr)
1698d9e0d41SFabiano Rosas {
1708d9e0d41SFabiano Rosas if (addr->transport == MIGRATION_ADDRESS_TYPE_FILE) {
1718d9e0d41SFabiano Rosas return true;
1728d9e0d41SFabiano Rosas }
1738d9e0d41SFabiano Rosas
1748d9e0d41SFabiano Rosas return false;
1758d9e0d41SFabiano Rosas }
1768d9e0d41SFabiano Rosas
transport_supports_extra_fds(MigrationAddress * addr)1779d70239eSFabiano Rosas static bool transport_supports_extra_fds(MigrationAddress *addr)
1789d70239eSFabiano Rosas {
1799d70239eSFabiano Rosas /* file: works because QEMU can open it multiple times */
1809d70239eSFabiano Rosas return addr->transport == MIGRATION_ADDRESS_TYPE_FILE;
1819d70239eSFabiano Rosas }
1829d70239eSFabiano Rosas
183d6f74fd1SPeter Xu static bool
migration_channels_and_transport_compatible(MigrationAddress * addr,Error ** errp)184d95533e1SHet Gala migration_channels_and_transport_compatible(MigrationAddress *addr,
185d95533e1SHet Gala Error **errp)
186d6f74fd1SPeter Xu {
1878d9e0d41SFabiano Rosas if (migration_needs_seekable_channel() &&
1888d9e0d41SFabiano Rosas !transport_supports_seeking(addr)) {
1898d9e0d41SFabiano Rosas error_setg(errp, "Migration requires seekable transport (e.g. file)");
1908d9e0d41SFabiano Rosas return false;
1918d9e0d41SFabiano Rosas }
1928d9e0d41SFabiano Rosas
193d6f74fd1SPeter Xu if (migration_needs_multiple_sockets() &&
1943205bebdSAvihai Horon !transport_supports_multi_channels(addr)) {
195d6f74fd1SPeter Xu error_setg(errp, "Migration requires multi-channel URIs (e.g. tcp)");
196d6f74fd1SPeter Xu return false;
197d6f74fd1SPeter Xu }
198d6f74fd1SPeter Xu
1999d70239eSFabiano Rosas if (migration_needs_extra_fds() &&
2009d70239eSFabiano Rosas !transport_supports_extra_fds(addr)) {
2019d70239eSFabiano Rosas error_setg(errp,
2029d70239eSFabiano Rosas "Migration requires a transport that allows for extra fds (e.g. file)");
2039d70239eSFabiano Rosas return false;
2049d70239eSFabiano Rosas }
2059d70239eSFabiano Rosas
206d6f74fd1SPeter Xu return true;
207f444eedaSPeter Xu }
208f444eedaSPeter Xu
page_request_addr_cmp(gconstpointer ap,gconstpointer bp)2098f8bfffcSPeter Xu static gint page_request_addr_cmp(gconstpointer ap, gconstpointer bp)
2108f8bfffcSPeter Xu {
2118f8bfffcSPeter Xu uintptr_t a = (uintptr_t) ap, b = (uintptr_t) bp;
2128f8bfffcSPeter Xu
2138f8bfffcSPeter Xu return (a > b) - (a < b);
2148f8bfffcSPeter Xu }
2158f8bfffcSPeter Xu
migration_stop_vm(MigrationState * s,RunState state)2169867d4ddSSteve Sistare static int migration_stop_vm(MigrationState *s, RunState state)
21793bdf888SPeter Xu {
2189867d4ddSSteve Sistare int ret;
2199867d4ddSSteve Sistare
2209867d4ddSSteve Sistare migration_downtime_start(s);
2219867d4ddSSteve Sistare
2229867d4ddSSteve Sistare s->vm_old_state = runstate_get();
2239867d4ddSSteve Sistare global_state_store();
2249867d4ddSSteve Sistare
2259867d4ddSSteve Sistare ret = vm_stop_force_state(state);
2263e5f3bcdSPeter Xu
2273e5f3bcdSPeter Xu trace_vmstate_downtime_checkpoint("src-vm-stopped");
2289867d4ddSSteve Sistare trace_migration_completion_vm_stop(ret);
2293e5f3bcdSPeter Xu
2303e5f3bcdSPeter Xu return ret;
23193bdf888SPeter Xu }
23293bdf888SPeter Xu
migration_object_init(void)233e5cb7e76SPeter Xu void migration_object_init(void)
234e5cb7e76SPeter Xu {
235e5cb7e76SPeter Xu /* This can only be called once. */
236e5cb7e76SPeter Xu assert(!current_migration);
237e5cb7e76SPeter Xu current_migration = MIGRATION_OBJ(object_new(TYPE_MIGRATION));
2384ffdb337SPeter Xu
239e1b1b1bcSPeter Xu /*
240e1b1b1bcSPeter Xu * Init the migrate incoming object as well no matter whether
241e1b1b1bcSPeter Xu * we'll use it or not.
242e1b1b1bcSPeter Xu */
243e1b1b1bcSPeter Xu assert(!current_incoming);
244e1b1b1bcSPeter Xu current_incoming = g_new0(MigrationIncomingState, 1);
245e1b1b1bcSPeter Xu current_incoming->state = MIGRATION_STATUS_NONE;
246e1b1b1bcSPeter Xu current_incoming->postcopy_remote_fds =
247e1b1b1bcSPeter Xu g_array_new(FALSE, TRUE, sizeof(struct PostCopyFD));
248e1b1b1bcSPeter Xu qemu_mutex_init(¤t_incoming->rp_mutex);
24960bb3c58SPeter Xu qemu_mutex_init(¤t_incoming->postcopy_prio_thread_mutex);
250e1b1b1bcSPeter Xu qemu_event_init(¤t_incoming->main_thread_load_event, false);
251e1b1b1bcSPeter Xu qemu_sem_init(¤t_incoming->postcopy_pause_sem_dst, 0);
252e1b1b1bcSPeter Xu qemu_sem_init(¤t_incoming->postcopy_pause_sem_fault, 0);
25360bb3c58SPeter Xu qemu_sem_init(¤t_incoming->postcopy_pause_sem_fast_load, 0);
2545655aab0SPeter Xu qemu_sem_init(¤t_incoming->postcopy_qemufile_dst_done, 0);
2555655aab0SPeter Xu
2568f8bfffcSPeter Xu qemu_mutex_init(¤t_incoming->page_request_mutex);
257cf02f29eSPeter Xu qemu_cond_init(¤t_incoming->page_request_cond);
2588f8bfffcSPeter Xu current_incoming->page_requested = g_tree_new(page_request_addr_cmp);
259e1b1b1bcSPeter Xu
260dbea1c89SVladimir Sementsov-Ogievskiy current_incoming->exit_on_error = INMIGRATE_DEFAULT_EXIT_ON_ERROR;
261dbea1c89SVladimir Sementsov-Ogievskiy
262f9734d5dSMarkus Armbruster migration_object_check(current_migration, &error_fatal);
263e0d17dfdSPaolo Bonzini
264e0d17dfdSPaolo Bonzini ram_mig_init();
265e0d17dfdSPaolo Bonzini dirty_bitmap_mig_init();
266d481cec7SHyman Huang
267d481cec7SHyman Huang /* Initialize cpu throttle timers */
268d481cec7SHyman Huang cpu_throttle_init();
269e5cb7e76SPeter Xu }
270e5cb7e76SPeter Xu
27144d0d456SFabiano Rosas typedef struct {
27244d0d456SFabiano Rosas QEMUBH *bh;
27344d0d456SFabiano Rosas QEMUBHFunc *cb;
27444d0d456SFabiano Rosas void *opaque;
27544d0d456SFabiano Rosas } MigrationBH;
27644d0d456SFabiano Rosas
migration_bh_dispatch_bh(void * opaque)27744d0d456SFabiano Rosas static void migration_bh_dispatch_bh(void *opaque)
278699d9476SFabiano Rosas {
27944d0d456SFabiano Rosas MigrationState *s = migrate_get_current();
28044d0d456SFabiano Rosas MigrationBH *migbh = opaque;
28144d0d456SFabiano Rosas
28244d0d456SFabiano Rosas /* cleanup this BH */
28344d0d456SFabiano Rosas qemu_bh_delete(migbh->bh);
28444d0d456SFabiano Rosas migbh->bh = NULL;
28544d0d456SFabiano Rosas
28644d0d456SFabiano Rosas /* dispatch the other one */
28744d0d456SFabiano Rosas migbh->cb(migbh->opaque);
28844d0d456SFabiano Rosas object_unref(OBJECT(s));
28944d0d456SFabiano Rosas
29044d0d456SFabiano Rosas g_free(migbh);
29144d0d456SFabiano Rosas }
29244d0d456SFabiano Rosas
migration_bh_schedule(QEMUBHFunc * cb,void * opaque)29344d0d456SFabiano Rosas void migration_bh_schedule(QEMUBHFunc *cb, void *opaque)
29444d0d456SFabiano Rosas {
29544d0d456SFabiano Rosas MigrationState *s = migrate_get_current();
29644d0d456SFabiano Rosas MigrationBH *migbh = g_new0(MigrationBH, 1);
29744d0d456SFabiano Rosas QEMUBH *bh = qemu_bh_new(migration_bh_dispatch_bh, migbh);
29844d0d456SFabiano Rosas
29944d0d456SFabiano Rosas /* Store these to dispatch when the BH runs */
30044d0d456SFabiano Rosas migbh->bh = bh;
30144d0d456SFabiano Rosas migbh->cb = cb;
30244d0d456SFabiano Rosas migbh->opaque = opaque;
30344d0d456SFabiano Rosas
304699d9476SFabiano Rosas /*
305699d9476SFabiano Rosas * Ref the state for bh, because it may be called when
306699d9476SFabiano Rosas * there're already no other refs
307699d9476SFabiano Rosas */
308699d9476SFabiano Rosas object_ref(OBJECT(s));
309699d9476SFabiano Rosas qemu_bh_schedule(bh);
310699d9476SFabiano Rosas }
311699d9476SFabiano Rosas
migration_cancel(const Error * error)312458feccaSLaurent Vivier void migration_cancel(const Error *error)
313c7c0e724SDavid Hildenbrand {
314458feccaSLaurent Vivier if (error) {
315458feccaSLaurent Vivier migrate_set_error(current_migration, error);
316458feccaSLaurent Vivier }
317acac51baSHyman Huang(黄勇) if (migrate_dirty_limit()) {
318acac51baSHyman Huang(黄勇) qmp_cancel_vcpu_dirty_limit(false, -1, NULL);
319acac51baSHyman Huang(黄勇) }
320c7c0e724SDavid Hildenbrand migrate_fd_cancel(current_migration);
321c7c0e724SDavid Hildenbrand }
322c7c0e724SDavid Hildenbrand
migration_shutdown(void)323892ae715SDr. David Alan Gilbert void migration_shutdown(void)
3241f895604SVladimir Sementsov-Ogievskiy {
325892ae715SDr. David Alan Gilbert /*
326795969abSRao, Lei * When the QEMU main thread exit, the COLO thread
327795969abSRao, Lei * may wait a semaphore. So, we should wakeup the
328795969abSRao, Lei * COLO thread before migration shutdown.
329795969abSRao, Lei */
330795969abSRao, Lei colo_shutdown();
331795969abSRao, Lei /*
332892ae715SDr. David Alan Gilbert * Cancel the current migration - that will (eventually)
333892ae715SDr. David Alan Gilbert * stop the migration using this structure
334892ae715SDr. David Alan Gilbert */
335458feccaSLaurent Vivier migration_cancel(NULL);
3361f895604SVladimir Sementsov-Ogievskiy object_unref(OBJECT(current_migration));
3371499ab09SVladimir Sementsov-Ogievskiy
3381499ab09SVladimir Sementsov-Ogievskiy /*
3391499ab09SVladimir Sementsov-Ogievskiy * Cancel outgoing migration of dirty bitmaps. It should
3401499ab09SVladimir Sementsov-Ogievskiy * at least unref used block nodes.
3411499ab09SVladimir Sementsov-Ogievskiy */
3421499ab09SVladimir Sementsov-Ogievskiy dirty_bitmap_mig_cancel_outgoing();
3431499ab09SVladimir Sementsov-Ogievskiy
3441499ab09SVladimir Sementsov-Ogievskiy /*
3451499ab09SVladimir Sementsov-Ogievskiy * Cancel incoming migration of dirty bitmaps. Dirty bitmaps
3461499ab09SVladimir Sementsov-Ogievskiy * are non-critical data, and their loss never considered as
3471499ab09SVladimir Sementsov-Ogievskiy * something serious.
3481499ab09SVladimir Sementsov-Ogievskiy */
3491499ab09SVladimir Sementsov-Ogievskiy dirty_bitmap_mig_cancel_incoming();
3501f895604SVladimir Sementsov-Ogievskiy }
3511f895604SVladimir Sementsov-Ogievskiy
352bca7856aSDr. David Alan Gilbert /* For outgoing */
migrate_get_current(void)35360fe637bSDr. David Alan Gilbert MigrationState *migrate_get_current(void)
35460fe637bSDr. David Alan Gilbert {
355e5cb7e76SPeter Xu /* This can only be called after the object created. */
356e5cb7e76SPeter Xu assert(current_migration);
357e5cb7e76SPeter Xu return current_migration;
35860fe637bSDr. David Alan Gilbert }
35960fe637bSDr. David Alan Gilbert
migration_incoming_get_current(void)360bca7856aSDr. David Alan Gilbert MigrationIncomingState *migration_incoming_get_current(void)
361bca7856aSDr. David Alan Gilbert {
362e1b1b1bcSPeter Xu assert(current_incoming);
363e1b1b1bcSPeter Xu return current_incoming;
364bca7856aSDr. David Alan Gilbert }
365bca7856aSDr. David Alan Gilbert
migration_incoming_transport_cleanup(MigrationIncomingState * mis)366e031149cSPeter Xu void migration_incoming_transport_cleanup(MigrationIncomingState *mis)
367e031149cSPeter Xu {
368e031149cSPeter Xu if (mis->socket_address_list) {
369e031149cSPeter Xu qapi_free_SocketAddressList(mis->socket_address_list);
370e031149cSPeter Xu mis->socket_address_list = NULL;
371e031149cSPeter Xu }
372e031149cSPeter Xu
373e031149cSPeter Xu if (mis->transport_cleanup) {
374e031149cSPeter Xu mis->transport_cleanup(mis->transport_data);
375e031149cSPeter Xu mis->transport_data = mis->transport_cleanup = NULL;
376e031149cSPeter Xu }
377e031149cSPeter Xu }
378e031149cSPeter Xu
migration_incoming_state_destroy(void)379bca7856aSDr. David Alan Gilbert void migration_incoming_state_destroy(void)
380bca7856aSDr. David Alan Gilbert {
381b4b076daSJuan Quintela struct MigrationIncomingState *mis = migration_incoming_get_current();
382b4b076daSJuan Quintela
383cde85c37SPeter Xu multifd_recv_cleanup();
3844ce56229SFabiano Rosas /*
3854ce56229SFabiano Rosas * RAM state cleanup needs to happen after multifd cleanup, because
3864ce56229SFabiano Rosas * multifd threads can use some of its states (receivedmap).
3874ce56229SFabiano Rosas */
3884ce56229SFabiano Rosas qemu_loadvm_state_cleanup();
389cfc3bcf3SLeonardo Bras
3903482655bSPeter Xu if (mis->to_src_file) {
391660819b1SPeter Xu /* Tell source that we are done */
392660819b1SPeter Xu migrate_send_rp_shut(mis, qemu_file_get_error(mis->from_src_file) != 0);
3933482655bSPeter Xu qemu_fclose(mis->to_src_file);
3943482655bSPeter Xu mis->to_src_file = NULL;
3953482655bSPeter Xu }
3963482655bSPeter Xu
397660819b1SPeter Xu if (mis->from_src_file) {
39839675fffSPeter Xu migration_ioc_unregister_yank_from_file(mis->from_src_file);
399660819b1SPeter Xu qemu_fclose(mis->from_src_file);
400660819b1SPeter Xu mis->from_src_file = NULL;
401660819b1SPeter Xu }
40200fa4fc8SDr. David Alan Gilbert if (mis->postcopy_remote_fds) {
40300fa4fc8SDr. David Alan Gilbert g_array_free(mis->postcopy_remote_fds, TRUE);
40400fa4fc8SDr. David Alan Gilbert mis->postcopy_remote_fds = NULL;
40500fa4fc8SDr. David Alan Gilbert }
406660819b1SPeter Xu
407e031149cSPeter Xu migration_incoming_transport_cleanup(mis);
4081783c00fSDr. David Alan Gilbert qemu_event_reset(&mis->main_thread_load_event);
4091783c00fSDr. David Alan Gilbert
4108f8bfffcSPeter Xu if (mis->page_requested) {
4118f8bfffcSPeter Xu g_tree_destroy(mis->page_requested);
4128f8bfffcSPeter Xu mis->page_requested = NULL;
4138f8bfffcSPeter Xu }
4148f8bfffcSPeter Xu
41536f62f11SPeter Xu if (mis->postcopy_qemufile_dst) {
41636f62f11SPeter Xu migration_ioc_unregister_yank_from_file(mis->postcopy_qemufile_dst);
41736f62f11SPeter Xu qemu_fclose(mis->postcopy_qemufile_dst);
41836f62f11SPeter Xu mis->postcopy_qemufile_dst = NULL;
41936f62f11SPeter Xu }
42036f62f11SPeter Xu
421b5eea99eSLukas Straub yank_unregister_instance(MIGRATION_YANK_INSTANCE);
422bca7856aSDr. David Alan Gilbert }
423bca7856aSDr. David Alan Gilbert
migrate_generate_event(MigrationStatus new_state)424a5c24e13SPeter Xu static void migrate_generate_event(MigrationStatus new_state)
425b05dc723SJuan Quintela {
426b890902cSJuan Quintela if (migrate_events()) {
4273ab72385SPeter Xu qapi_event_send_migration(new_state);
428b05dc723SJuan Quintela }
429b05dc723SJuan Quintela }
430b05dc723SJuan Quintela
431adde220aSDr. David Alan Gilbert /*
432da6f1790SJuan Quintela * Send a message on the return channel back to the source
433da6f1790SJuan Quintela * of the migration.
434da6f1790SJuan Quintela */
migrate_send_rp_message(MigrationIncomingState * mis,enum mig_rp_message_type message_type,uint16_t len,void * data)435d6208e35SPeter Xu static int migrate_send_rp_message(MigrationIncomingState *mis,
436da6f1790SJuan Quintela enum mig_rp_message_type message_type,
437da6f1790SJuan Quintela uint16_t len, void *data)
438da6f1790SJuan Quintela {
439d6208e35SPeter Xu int ret = 0;
440d6208e35SPeter Xu
441da6f1790SJuan Quintela trace_migrate_send_rp_message((int)message_type, len);
44237396950SMahmoud Mandour QEMU_LOCK_GUARD(&mis->rp_mutex);
443d6208e35SPeter Xu
444d6208e35SPeter Xu /*
445d6208e35SPeter Xu * It's possible that the file handle got lost due to network
446d6208e35SPeter Xu * failures.
447d6208e35SPeter Xu */
448d6208e35SPeter Xu if (!mis->to_src_file) {
449d6208e35SPeter Xu ret = -EIO;
45037396950SMahmoud Mandour return ret;
451d6208e35SPeter Xu }
452d6208e35SPeter Xu
453da6f1790SJuan Quintela qemu_put_be16(mis->to_src_file, (unsigned int)message_type);
454da6f1790SJuan Quintela qemu_put_be16(mis->to_src_file, len);
455da6f1790SJuan Quintela qemu_put_buffer(mis->to_src_file, data, len);
456be07a0edSJuan Quintela return qemu_fflush(mis->to_src_file);
457da6f1790SJuan Quintela }
458da6f1790SJuan Quintela
4592e2bce16SPeter Xu /* Request one page from the source VM at the given start address.
4602e2bce16SPeter Xu * rb: the RAMBlock to request the page in
4611e2d90ebSDr. David Alan Gilbert * Start: Address offset within the RB
4621e2d90ebSDr. David Alan Gilbert * Len: Length in bytes required - must be a multiple of pagesize
4631e2d90ebSDr. David Alan Gilbert */
migrate_send_rp_message_req_pages(MigrationIncomingState * mis,RAMBlock * rb,ram_addr_t start)4647a267fc4SPeter Xu int migrate_send_rp_message_req_pages(MigrationIncomingState *mis,
4657a267fc4SPeter Xu RAMBlock *rb, ram_addr_t start)
4661e2d90ebSDr. David Alan Gilbert {
4671e2d90ebSDr. David Alan Gilbert uint8_t bufc[12 + 1 + 255]; /* start (8), len (4), rbname up to 256 */
4681e2d90ebSDr. David Alan Gilbert size_t msglen = 12; /* start + len */
4692e2bce16SPeter Xu size_t len = qemu_ram_pagesize(rb);
470d6208e35SPeter Xu enum mig_rp_message_type msg_type;
4712e2bce16SPeter Xu const char *rbname;
4722e2bce16SPeter Xu int rbname_len;
4731e2d90ebSDr. David Alan Gilbert
4741e2d90ebSDr. David Alan Gilbert *(uint64_t *)bufc = cpu_to_be64((uint64_t)start);
4751e2d90ebSDr. David Alan Gilbert *(uint32_t *)(bufc + 8) = cpu_to_be32((uint32_t)len);
4761e2d90ebSDr. David Alan Gilbert
4772e2bce16SPeter Xu /*
4782e2bce16SPeter Xu * We maintain the last ramblock that we requested for page. Note that we
4792e2bce16SPeter Xu * don't need locking because this function will only be called within the
4802e2bce16SPeter Xu * postcopy ram fault thread.
4812e2bce16SPeter Xu */
4822e2bce16SPeter Xu if (rb != mis->last_rb) {
4832e2bce16SPeter Xu mis->last_rb = rb;
4842e2bce16SPeter Xu
4852e2bce16SPeter Xu rbname = qemu_ram_get_idstr(rb);
4862e2bce16SPeter Xu rbname_len = strlen(rbname);
4872e2bce16SPeter Xu
4881e2d90ebSDr. David Alan Gilbert assert(rbname_len < 256);
4891e2d90ebSDr. David Alan Gilbert
4901e2d90ebSDr. David Alan Gilbert bufc[msglen++] = rbname_len;
4911e2d90ebSDr. David Alan Gilbert memcpy(bufc + msglen, rbname, rbname_len);
4921e2d90ebSDr. David Alan Gilbert msglen += rbname_len;
493d6208e35SPeter Xu msg_type = MIG_RP_MSG_REQ_PAGES_ID;
4941e2d90ebSDr. David Alan Gilbert } else {
495d6208e35SPeter Xu msg_type = MIG_RP_MSG_REQ_PAGES;
4961e2d90ebSDr. David Alan Gilbert }
497d6208e35SPeter Xu
498d6208e35SPeter Xu return migrate_send_rp_message(mis, msg_type, msglen, bufc);
4991e2d90ebSDr. David Alan Gilbert }
5001e2d90ebSDr. David Alan Gilbert
migrate_send_rp_req_pages(MigrationIncomingState * mis,RAMBlock * rb,ram_addr_t start,uint64_t haddr)5017a267fc4SPeter Xu int migrate_send_rp_req_pages(MigrationIncomingState *mis,
5028f8bfffcSPeter Xu RAMBlock *rb, ram_addr_t start, uint64_t haddr)
5037a267fc4SPeter Xu {
5047648297dSDavid Hildenbrand void *aligned = (void *)(uintptr_t)ROUND_DOWN(haddr, qemu_ram_pagesize(rb));
505a2429283SChen Qun bool received = false;
5068f8bfffcSPeter Xu
5078f8bfffcSPeter Xu WITH_QEMU_LOCK_GUARD(&mis->page_request_mutex) {
5088f8bfffcSPeter Xu received = ramblock_recv_bitmap_test_byte_offset(rb, start);
5098f8bfffcSPeter Xu if (!received && !g_tree_lookup(mis->page_requested, aligned)) {
5108f8bfffcSPeter Xu /*
5118f8bfffcSPeter Xu * The page has not been received, and it's not yet in the page
5128f8bfffcSPeter Xu * request list. Queue it. Set the value of element to 1, so that
5138f8bfffcSPeter Xu * things like g_tree_lookup() will return TRUE (1) when found.
5148f8bfffcSPeter Xu */
5158f8bfffcSPeter Xu g_tree_insert(mis->page_requested, aligned, (gpointer)1);
516cf02f29eSPeter Xu qatomic_inc(&mis->page_requested_count);
5178f8bfffcSPeter Xu trace_postcopy_page_req_add(aligned, mis->page_requested_count);
5188f8bfffcSPeter Xu }
5198f8bfffcSPeter Xu }
5208f8bfffcSPeter Xu
5218f8bfffcSPeter Xu /*
5228f8bfffcSPeter Xu * If the page is there, skip sending the message. We don't even need the
5238f8bfffcSPeter Xu * lock because as long as the page arrived, it'll be there forever.
5248f8bfffcSPeter Xu */
5258f8bfffcSPeter Xu if (received) {
5268f8bfffcSPeter Xu return 0;
5278f8bfffcSPeter Xu }
5288f8bfffcSPeter Xu
5297a267fc4SPeter Xu return migrate_send_rp_message_req_pages(mis, rb, start);
5307a267fc4SPeter Xu }
5317a267fc4SPeter Xu
532aad555c2SZhang Chen static bool migration_colo_enabled;
migration_incoming_colo_enabled(void)533aad555c2SZhang Chen bool migration_incoming_colo_enabled(void)
534aad555c2SZhang Chen {
535aad555c2SZhang Chen return migration_colo_enabled;
536aad555c2SZhang Chen }
537aad555c2SZhang Chen
migration_incoming_disable_colo(void)538aad555c2SZhang Chen void migration_incoming_disable_colo(void)
539aad555c2SZhang Chen {
54018b1d3c9SDavid Hildenbrand ram_block_discard_disable(false);
541aad555c2SZhang Chen migration_colo_enabled = false;
542aad555c2SZhang Chen }
543aad555c2SZhang Chen
migration_incoming_enable_colo(void)54418b1d3c9SDavid Hildenbrand int migration_incoming_enable_colo(void)
545aad555c2SZhang Chen {
54651e47cf8SVladimir Sementsov-Ogievskiy #ifndef CONFIG_REPLICATION
54755a33165SLi Zhijian error_report("ENABLE_COLO command come in migration stream, but the "
54855a33165SLi Zhijian "replication module is not built in");
54951e47cf8SVladimir Sementsov-Ogievskiy return -ENOTSUP;
55051e47cf8SVladimir Sementsov-Ogievskiy #endif
55151e47cf8SVladimir Sementsov-Ogievskiy
552121ccedcSVladimir Sementsov-Ogievskiy if (!migrate_colo()) {
55355a33165SLi Zhijian error_report("ENABLE_COLO command come in migration stream, but x-colo "
554121ccedcSVladimir Sementsov-Ogievskiy "capability is not set");
555121ccedcSVladimir Sementsov-Ogievskiy return -EINVAL;
556121ccedcSVladimir Sementsov-Ogievskiy }
557121ccedcSVladimir Sementsov-Ogievskiy
55818b1d3c9SDavid Hildenbrand if (ram_block_discard_disable(true)) {
55918b1d3c9SDavid Hildenbrand error_report("COLO: cannot disable RAM discard");
56018b1d3c9SDavid Hildenbrand return -EBUSY;
56118b1d3c9SDavid Hildenbrand }
562aad555c2SZhang Chen migration_colo_enabled = true;
56318b1d3c9SDavid Hildenbrand return 0;
564aad555c2SZhang Chen }
565aad555c2SZhang Chen
migrate_add_address(SocketAddress * address)5669aca82baSJuan Quintela void migrate_add_address(SocketAddress *address)
5679aca82baSJuan Quintela {
5689aca82baSJuan Quintela MigrationIncomingState *mis = migration_incoming_get_current();
5699aca82baSJuan Quintela
57054aa3de7SEric Blake QAPI_LIST_PREPEND(mis->socket_address_list,
57154aa3de7SEric Blake QAPI_CLONE(SocketAddress, address));
5729aca82baSJuan Quintela }
5739aca82baSJuan Quintela
migrate_uri_parse(const char * uri,MigrationChannel ** channel,Error ** errp)574967f2de5SHet Gala bool migrate_uri_parse(const char *uri, MigrationChannel **channel,
57572a8192eSHet Gala Error **errp)
57672a8192eSHet Gala {
5775994024fSHet Gala g_autoptr(MigrationChannel) val = g_new0(MigrationChannel, 1);
57872a8192eSHet Gala g_autoptr(MigrationAddress) addr = g_new0(MigrationAddress, 1);
57972a8192eSHet Gala InetSocketAddress *isock = &addr->u.rdma;
58072a8192eSHet Gala strList **tail = &addr->u.exec.args;
58172a8192eSHet Gala
58272a8192eSHet Gala if (strstart(uri, "exec:", NULL)) {
58372a8192eSHet Gala addr->transport = MIGRATION_ADDRESS_TYPE_EXEC;
58472a8192eSHet Gala #ifdef WIN32
58572a8192eSHet Gala QAPI_LIST_APPEND(tail, g_strdup(exec_get_cmd_path()));
58672a8192eSHet Gala QAPI_LIST_APPEND(tail, g_strdup("/c"));
58772a8192eSHet Gala #else
58872a8192eSHet Gala QAPI_LIST_APPEND(tail, g_strdup("/bin/sh"));
58972a8192eSHet Gala QAPI_LIST_APPEND(tail, g_strdup("-c"));
59072a8192eSHet Gala #endif
59172a8192eSHet Gala QAPI_LIST_APPEND(tail, g_strdup(uri + strlen("exec:")));
59272a8192eSHet Gala } else if (strstart(uri, "rdma:", NULL)) {
59372a8192eSHet Gala if (inet_parse(isock, uri + strlen("rdma:"), errp)) {
59472a8192eSHet Gala qapi_free_InetSocketAddress(isock);
59572a8192eSHet Gala return false;
59672a8192eSHet Gala }
59772a8192eSHet Gala addr->transport = MIGRATION_ADDRESS_TYPE_RDMA;
59872a8192eSHet Gala } else if (strstart(uri, "tcp:", NULL) ||
59972a8192eSHet Gala strstart(uri, "unix:", NULL) ||
60072a8192eSHet Gala strstart(uri, "vsock:", NULL) ||
60172a8192eSHet Gala strstart(uri, "fd:", NULL)) {
60272a8192eSHet Gala addr->transport = MIGRATION_ADDRESS_TYPE_SOCKET;
60341581265SZongmin Zhou SocketAddress *saddr = socket_parse(uri, errp);
60472a8192eSHet Gala if (!saddr) {
60572a8192eSHet Gala return false;
60672a8192eSHet Gala }
60772a8192eSHet Gala addr->u.socket.type = saddr->type;
60872a8192eSHet Gala addr->u.socket.u = saddr->u;
60941581265SZongmin Zhou /* Don't free the objects inside; their ownership moved to "addr" */
61041581265SZongmin Zhou g_free(saddr);
61172a8192eSHet Gala } else if (strstart(uri, "file:", NULL)) {
61272a8192eSHet Gala addr->transport = MIGRATION_ADDRESS_TYPE_FILE;
61372a8192eSHet Gala addr->u.file.filename = g_strdup(uri + strlen("file:"));
61472a8192eSHet Gala if (file_parse_offset(addr->u.file.filename, &addr->u.file.offset,
61572a8192eSHet Gala errp)) {
61672a8192eSHet Gala return false;
61772a8192eSHet Gala }
61872a8192eSHet Gala } else {
61972a8192eSHet Gala error_setg(errp, "unknown migration protocol: %s", uri);
62072a8192eSHet Gala return false;
62172a8192eSHet Gala }
62272a8192eSHet Gala
6235994024fSHet Gala val->channel_type = MIGRATION_CHANNEL_TYPE_MAIN;
6245994024fSHet Gala val->addr = g_steal_pointer(&addr);
6255994024fSHet Gala *channel = g_steal_pointer(&val);
62672a8192eSHet Gala return true;
62772a8192eSHet Gala }
62872a8192eSHet Gala
6294dd5f7b8SPeter Xu static bool
migration_incoming_state_setup(MigrationIncomingState * mis,Error ** errp)6304dd5f7b8SPeter Xu migration_incoming_state_setup(MigrationIncomingState *mis, Error **errp)
6314dd5f7b8SPeter Xu {
6324dd5f7b8SPeter Xu MigrationStatus current = mis->state;
6334dd5f7b8SPeter Xu
6344dd5f7b8SPeter Xu if (current == MIGRATION_STATUS_POSTCOPY_PAUSED) {
6354dd5f7b8SPeter Xu /*
6364dd5f7b8SPeter Xu * Incoming postcopy migration will stay in PAUSED state even if
6374dd5f7b8SPeter Xu * reconnection happened.
6384dd5f7b8SPeter Xu */
6394dd5f7b8SPeter Xu return true;
6404dd5f7b8SPeter Xu }
6414dd5f7b8SPeter Xu
6424dd5f7b8SPeter Xu if (current != MIGRATION_STATUS_NONE) {
6434dd5f7b8SPeter Xu error_setg(errp, "Illegal migration incoming state: %s",
6444dd5f7b8SPeter Xu MigrationStatus_str(current));
6454dd5f7b8SPeter Xu return false;
6464dd5f7b8SPeter Xu }
6474dd5f7b8SPeter Xu
6484dd5f7b8SPeter Xu migrate_set_state(&mis->state, current, MIGRATION_STATUS_SETUP);
6494dd5f7b8SPeter Xu return true;
6504dd5f7b8SPeter Xu }
6514dd5f7b8SPeter Xu
qemu_start_incoming_migration(const char * uri,bool has_channels,MigrationChannelList * channels,Error ** errp)652074dbce5SHet Gala static void qemu_start_incoming_migration(const char *uri, bool has_channels,
653074dbce5SHet Gala MigrationChannelList *channels,
654074dbce5SHet Gala Error **errp)
65560fe637bSDr. David Alan Gilbert {
656bc1d54eeSHet Gala g_autoptr(MigrationChannel) channel = NULL;
6575994024fSHet Gala MigrationAddress *addr = NULL;
6584111a732SFabiano Rosas MigrationIncomingState *mis = migration_incoming_get_current();
65960fe637bSDr. David Alan Gilbert
660074dbce5SHet Gala /*
661074dbce5SHet Gala * Having preliminary checks for uri and channel
662074dbce5SHet Gala */
6630770ad43SHet Gala if (!uri == !channels) {
6640770ad43SHet Gala error_setg(errp, "need either 'uri' or 'channels' argument");
665074dbce5SHet Gala return;
6660770ad43SHet Gala }
6670770ad43SHet Gala
6680770ad43SHet Gala if (channels) {
6695994024fSHet Gala /* To verify that Migrate channel list has only item */
6705994024fSHet Gala if (channels->next) {
6715994024fSHet Gala error_setg(errp, "Channel list has more than one entries");
6725994024fSHet Gala return;
673074dbce5SHet Gala }
674bc1d54eeSHet Gala addr = channels->value->addr;
6750770ad43SHet Gala }
6760770ad43SHet Gala
6770770ad43SHet Gala if (uri) {
6785994024fSHet Gala /* caller uses the old URI syntax */
6795994024fSHet Gala if (!migrate_uri_parse(uri, &channel, errp)) {
6805994024fSHet Gala return;
6815994024fSHet Gala }
682bc1d54eeSHet Gala addr = channel->addr;
683074dbce5SHet Gala }
684d6f74fd1SPeter Xu
685d95533e1SHet Gala /* transport mechanism not suitable for migration? */
6865994024fSHet Gala if (!migration_channels_and_transport_compatible(addr, errp)) {
68772a8192eSHet Gala return;
68872a8192eSHet Gala }
68972a8192eSHet Gala
6904dd5f7b8SPeter Xu if (!migration_incoming_state_setup(mis, errp)) {
6914dd5f7b8SPeter Xu return;
6924dd5f7b8SPeter Xu }
6934111a732SFabiano Rosas
6945994024fSHet Gala if (addr->transport == MIGRATION_ADDRESS_TYPE_SOCKET) {
6955994024fSHet Gala SocketAddress *saddr = &addr->u.socket;
69634dfc5e4SHet Gala if (saddr->type == SOCKET_ADDRESS_TYPE_INET ||
69734dfc5e4SHet Gala saddr->type == SOCKET_ADDRESS_TYPE_UNIX ||
69834dfc5e4SHet Gala saddr->type == SOCKET_ADDRESS_TYPE_VSOCK) {
69934dfc5e4SHet Gala socket_start_incoming_migration(saddr, errp);
70034dfc5e4SHet Gala } else if (saddr->type == SOCKET_ADDRESS_TYPE_FD) {
70134dfc5e4SHet Gala fd_start_incoming_migration(saddr->u.fd.str, errp);
70234dfc5e4SHet Gala }
70360fe637bSDr. David Alan Gilbert #ifdef CONFIG_RDMA
7045994024fSHet Gala } else if (addr->transport == MIGRATION_ADDRESS_TYPE_RDMA) {
705b88a3306SJuan Quintela if (migrate_xbzrle()) {
706b88a3306SJuan Quintela error_setg(errp, "RDMA and XBZRLE can't be used together");
707b88a3306SJuan Quintela return;
708b88a3306SJuan Quintela }
709b88a3306SJuan Quintela if (migrate_multifd()) {
710b88a3306SJuan Quintela error_setg(errp, "RDMA and multifd can't be used together");
711b88a3306SJuan Quintela return;
712b88a3306SJuan Quintela }
7135994024fSHet Gala rdma_start_incoming_migration(&addr->u.rdma, errp);
71460fe637bSDr. David Alan Gilbert #endif
7155994024fSHet Gala } else if (addr->transport == MIGRATION_ADDRESS_TYPE_EXEC) {
7165994024fSHet Gala exec_start_incoming_migration(addr->u.exec.args, errp);
7175994024fSHet Gala } else if (addr->transport == MIGRATION_ADDRESS_TYPE_FILE) {
7185994024fSHet Gala file_start_incoming_migration(&addr->u.file, errp);
719adde220aSDr. David Alan Gilbert } else {
72060fe637bSDr. David Alan Gilbert error_setg(errp, "unknown migration protocol: %s", uri);
72160fe637bSDr. David Alan Gilbert }
72260fe637bSDr. David Alan Gilbert }
72360fe637bSDr. David Alan Gilbert
process_incoming_migration_bh(void * opaque)7240aa6aefcSDenis V. Lunev static void process_incoming_migration_bh(void *opaque)
7250aa6aefcSDenis V. Lunev {
7260aa6aefcSDenis V. Lunev Error *local_err = NULL;
7270aa6aefcSDenis V. Lunev MigrationIncomingState *mis = opaque;
7280aa6aefcSDenis V. Lunev
7293e5f3bcdSPeter Xu trace_vmstate_downtime_checkpoint("dst-precopy-bh-enter");
7303e5f3bcdSPeter Xu
7310f073f44SDr. David Alan Gilbert /* If capability late_block_activate is set:
7320f073f44SDr. David Alan Gilbert * Only fire up the block code now if we're going to restart the
7330f073f44SDr. David Alan Gilbert * VM, else 'cont' will do it.
7340f073f44SDr. David Alan Gilbert * This causes file locking to happen; so we don't want it to happen
7350f073f44SDr. David Alan Gilbert * unless we really are starting the VM.
7360f073f44SDr. David Alan Gilbert */
7370f073f44SDr. David Alan Gilbert if (!migrate_late_block_activate() ||
7380f073f44SDr. David Alan Gilbert (autostart && (!global_state_received() ||
739b4e9ddccSSteve Sistare runstate_is_live(global_state_get_runstate())))) {
7403b717194SEmanuele Giuseppe Esposito /* Make sure all file formats throw away their mutable metadata.
741ace21a58SKevin Wolf * If we get an error here, just don't restart the VM yet. */
7423b717194SEmanuele Giuseppe Esposito bdrv_activate_all(&local_err);
743d35ff5e6SKevin Wolf if (local_err) {
744ace21a58SKevin Wolf error_report_err(local_err);
745d35ff5e6SKevin Wolf local_err = NULL;
746d35ff5e6SKevin Wolf autostart = false;
747d35ff5e6SKevin Wolf }
7480f073f44SDr. David Alan Gilbert }
749d35ff5e6SKevin Wolf
7500aa6aefcSDenis V. Lunev /*
7510aa6aefcSDenis V. Lunev * This must happen after all error conditions are dealt with and
7520aa6aefcSDenis V. Lunev * we're sure the VM is going to be running on this host.
7530aa6aefcSDenis V. Lunev */
7547659505cSDr. David Alan Gilbert qemu_announce_self(&mis->announce_timer, migrate_announce_params());
7550aa6aefcSDenis V. Lunev
7563e5f3bcdSPeter Xu trace_vmstate_downtime_checkpoint("dst-precopy-bh-announced");
7573e5f3bcdSPeter Xu
758cde85c37SPeter Xu multifd_recv_shutdown();
7590aa6aefcSDenis V. Lunev
760b35ebdf0SVladimir Sementsov-Ogievskiy dirty_bitmap_mig_before_vm_start();
761b35ebdf0SVladimir Sementsov-Ogievskiy
7620aa6aefcSDenis V. Lunev if (!global_state_received() ||
763b4e9ddccSSteve Sistare runstate_is_live(global_state_get_runstate())) {
7640aa6aefcSDenis V. Lunev if (autostart) {
7650aa6aefcSDenis V. Lunev vm_start();
7660aa6aefcSDenis V. Lunev } else {
7670aa6aefcSDenis V. Lunev runstate_set(RUN_STATE_PAUSED);
7680aa6aefcSDenis V. Lunev }
769db009729SZhang Chen } else if (migration_incoming_colo_enabled()) {
770db009729SZhang Chen migration_incoming_disable_colo();
771db009729SZhang Chen vm_start();
7720aa6aefcSDenis V. Lunev } else {
7730aa6aefcSDenis V. Lunev runstate_set(global_state_get_runstate());
7740aa6aefcSDenis V. Lunev }
7753e5f3bcdSPeter Xu trace_vmstate_downtime_checkpoint("dst-precopy-bh-vm-started");
7760aa6aefcSDenis V. Lunev /*
7770aa6aefcSDenis V. Lunev * This must happen after any state changes since as soon as an external
7780aa6aefcSDenis V. Lunev * observer sees this event they might start to prod at the VM assuming
7790aa6aefcSDenis V. Lunev * it's ready to use.
7800aa6aefcSDenis V. Lunev */
7810aa6aefcSDenis V. Lunev migrate_set_state(&mis->state, MIGRATION_STATUS_ACTIVE,
7820aa6aefcSDenis V. Lunev MIGRATION_STATUS_COMPLETED);
7830aa6aefcSDenis V. Lunev migration_incoming_state_destroy();
7840aa6aefcSDenis V. Lunev }
7850aa6aefcSDenis V. Lunev
78638e8f9afSMarc-André Lureau static void coroutine_fn
process_incoming_migration_co(void * opaque)78738e8f9afSMarc-André Lureau process_incoming_migration_co(void *opaque)
78860fe637bSDr. David Alan Gilbert {
789f84eaa9fSVladimir Sementsov-Ogievskiy MigrationState *s = migrate_get_current();
790b4b076daSJuan Quintela MigrationIncomingState *mis = migration_incoming_get_current();
791e9bef235SDr. David Alan Gilbert PostcopyState ps;
79260fe637bSDr. David Alan Gilbert int ret;
793f84eaa9fSVladimir Sementsov-Ogievskiy Error *local_err = NULL;
79460fe637bSDr. David Alan Gilbert
7954f0fae7fSJuan Quintela assert(mis->from_src_file);
796c323518aSLukas Straub
79767f11b5cSDr. David Alan Gilbert mis->largest_page_size = qemu_ram_pagesize_largest();
798093e3c42SDr. David Alan Gilbert postcopy_state_set(POSTCOPY_INCOMING_NONE);
7994111a732SFabiano Rosas migrate_set_state(&mis->state, MIGRATION_STATUS_SETUP,
80093d7af6fSzhanghailiang MIGRATION_STATUS_ACTIVE);
801dd42ce24SVladimir Sementsov-Ogievskiy
802dd42ce24SVladimir Sementsov-Ogievskiy mis->loadvm_co = qemu_coroutine_self();
8034f0fae7fSJuan Quintela ret = qemu_loadvm_state(mis->from_src_file);
804dd42ce24SVladimir Sementsov-Ogievskiy mis->loadvm_co = NULL;
805bca7856aSDr. David Alan Gilbert
8063e5f3bcdSPeter Xu trace_vmstate_downtime_checkpoint("dst-precopy-loadvm-completed");
8073e5f3bcdSPeter Xu
808e9bef235SDr. David Alan Gilbert ps = postcopy_state_get();
809e9bef235SDr. David Alan Gilbert trace_process_incoming_migration_co_end(ret, ps);
810e9bef235SDr. David Alan Gilbert if (ps != POSTCOPY_INCOMING_NONE) {
811e9bef235SDr. David Alan Gilbert if (ps == POSTCOPY_INCOMING_ADVISE) {
812e9bef235SDr. David Alan Gilbert /*
813e9bef235SDr. David Alan Gilbert * Where a migration had postcopy enabled (and thus went to advise)
814e9bef235SDr. David Alan Gilbert * but managed to complete within the precopy period, we can use
815e9bef235SDr. David Alan Gilbert * the normal exit.
816e9bef235SDr. David Alan Gilbert */
817e9bef235SDr. David Alan Gilbert postcopy_ram_incoming_cleanup(mis);
818e9bef235SDr. David Alan Gilbert } else if (ret >= 0) {
819e9bef235SDr. David Alan Gilbert /*
820e9bef235SDr. David Alan Gilbert * Postcopy was started, cleanup should happen at the end of the
821e9bef235SDr. David Alan Gilbert * postcopy thread.
822e9bef235SDr. David Alan Gilbert */
823e9bef235SDr. David Alan Gilbert trace_process_incoming_migration_co_postcopy_end_main();
824e9bef235SDr. David Alan Gilbert return;
825e9bef235SDr. David Alan Gilbert }
826e9bef235SDr. David Alan Gilbert /* Else if something went wrong then just fall out of the normal exit */
827e9bef235SDr. David Alan Gilbert }
828e9bef235SDr. David Alan Gilbert
829ecbfec6dSVladimir Sementsov-Ogievskiy if (ret < 0) {
830f84eaa9fSVladimir Sementsov-Ogievskiy error_setg(&local_err, "load of migration failed: %s", strerror(-ret));
831ecbfec6dSVladimir Sementsov-Ogievskiy goto fail;
832ecbfec6dSVladimir Sementsov-Ogievskiy }
833ecbfec6dSVladimir Sementsov-Ogievskiy
834787ea49eSLi Zhijian if (migration_incoming_colo_enabled()) {
835787ea49eSLi Zhijian /* yield until COLO exit */
836787ea49eSLi Zhijian colo_incoming_co();
8378e48ac95SZhang Chen }
8388e48ac95SZhang Chen
83944d0d456SFabiano Rosas migration_bh_schedule(process_incoming_migration_bh, mis);
8406d99c2d4SFei Li return;
8416d99c2d4SFei Li fail:
84293d7af6fSzhanghailiang migrate_set_state(&mis->state, MIGRATION_STATUS_ACTIVE,
84393d7af6fSzhanghailiang MIGRATION_STATUS_FAILED);
844f84eaa9fSVladimir Sementsov-Ogievskiy migrate_set_error(s, local_err);
845f84eaa9fSVladimir Sementsov-Ogievskiy error_free(local_err);
846f84eaa9fSVladimir Sementsov-Ogievskiy
847246f54e0SVladimir Sementsov-Ogievskiy migration_incoming_state_destroy();
848e5bac1f5SLeonardo Bras
849dbea1c89SVladimir Sementsov-Ogievskiy if (mis->exit_on_error) {
850f84eaa9fSVladimir Sementsov-Ogievskiy WITH_QEMU_LOCK_GUARD(&s->error_mutex) {
851f84eaa9fSVladimir Sementsov-Ogievskiy error_report_err(s->error);
852f84eaa9fSVladimir Sementsov-Ogievskiy s->error = NULL;
853f84eaa9fSVladimir Sementsov-Ogievskiy }
854f84eaa9fSVladimir Sementsov-Ogievskiy
85560fe637bSDr. David Alan Gilbert exit(EXIT_FAILURE);
85660fe637bSDr. David Alan Gilbert }
857dbea1c89SVladimir Sementsov-Ogievskiy }
85860fe637bSDr. David Alan Gilbert
859b673eab4SJuan Quintela /**
8607d6f6933SMarkus Armbruster * migration_incoming_setup: Setup incoming migration
861b673eab4SJuan Quintela * @f: file for main migration channel
862b673eab4SJuan Quintela */
migration_incoming_setup(QEMUFile * f)863c606f3baSAvihai Horon static void migration_incoming_setup(QEMUFile *f)
86460fe637bSDr. David Alan Gilbert {
8654f0fae7fSJuan Quintela MigrationIncomingState *mis = migration_incoming_get_current();
86660fe637bSDr. David Alan Gilbert
8674f0fae7fSJuan Quintela if (!mis->from_src_file) {
8684f0fae7fSJuan Quintela mis->from_src_file = f;
8694f0fae7fSJuan Quintela }
87006ad5135SDaniel P. Berrange qemu_file_set_blocking(f, false);
871e595a01aSJuan Quintela }
872e595a01aSJuan Quintela
migration_incoming_process(void)87336c2f8beSJuan Quintela void migration_incoming_process(void)
874e595a01aSJuan Quintela {
875e595a01aSJuan Quintela Coroutine *co = qemu_coroutine_create(process_incoming_migration_co, NULL);
8760b8b8753SPaolo Bonzini qemu_coroutine_enter(co);
87760fe637bSDr. David Alan Gilbert }
87860fe637bSDr. David Alan Gilbert
879884835faSPeter Xu /* Returns true if recovered from a paused migration, otherwise false */
postcopy_try_recover(void)880a39e9339SPeter Xu static bool postcopy_try_recover(void)
881e595a01aSJuan Quintela {
882d96c9e8dSPeter Xu MigrationIncomingState *mis = migration_incoming_get_current();
883d96c9e8dSPeter Xu
884d96c9e8dSPeter Xu if (mis->state == MIGRATION_STATUS_POSTCOPY_PAUSED) {
885d96c9e8dSPeter Xu /* Resumed from a paused postcopy migration */
886d96c9e8dSPeter Xu
887a39e9339SPeter Xu /* This should be set already in migration_incoming_setup() */
888a39e9339SPeter Xu assert(mis->from_src_file);
889d96c9e8dSPeter Xu /* Postcopy has standalone thread to do vm load */
890a39e9339SPeter Xu qemu_file_set_blocking(mis->from_src_file, true);
891d96c9e8dSPeter Xu
892d96c9e8dSPeter Xu /* Re-configure the return path */
893a39e9339SPeter Xu mis->to_src_file = qemu_file_get_return_path(mis->from_src_file);
894d96c9e8dSPeter Xu
895d96c9e8dSPeter Xu migrate_set_state(&mis->state, MIGRATION_STATUS_POSTCOPY_PAUSED,
896d96c9e8dSPeter Xu MIGRATION_STATUS_POSTCOPY_RECOVER);
897d96c9e8dSPeter Xu
898d96c9e8dSPeter Xu /*
899d96c9e8dSPeter Xu * Here, we only wake up the main loading thread (while the
90060bb3c58SPeter Xu * rest threads will still be waiting), so that we can receive
901d96c9e8dSPeter Xu * commands from source now, and answer it if needed. The
90260bb3c58SPeter Xu * rest threads will be woken up afterwards until we are sure
903d96c9e8dSPeter Xu * that source is ready to reply to page requests.
904d96c9e8dSPeter Xu */
905d96c9e8dSPeter Xu qemu_sem_post(&mis->postcopy_pause_sem_dst);
906884835faSPeter Xu return true;
907884835faSPeter Xu }
908884835faSPeter Xu
909884835faSPeter Xu return false;
910884835faSPeter Xu }
911884835faSPeter Xu
migration_fd_process_incoming(QEMUFile * f)912b0cf3bfcSAvihai Horon void migration_fd_process_incoming(QEMUFile *f)
913884835faSPeter Xu {
914c606f3baSAvihai Horon migration_incoming_setup(f);
915a39e9339SPeter Xu if (postcopy_try_recover()) {
916b673eab4SJuan Quintela return;
917b673eab4SJuan Quintela }
918e595a01aSJuan Quintela migration_incoming_process();
919e595a01aSJuan Quintela }
920e595a01aSJuan Quintela
9215655aab0SPeter Xu /*
9225655aab0SPeter Xu * Returns true when we want to start a new incoming migration process,
9235655aab0SPeter Xu * false otherwise.
9245655aab0SPeter Xu */
migration_should_start_incoming(bool main_channel)9255655aab0SPeter Xu static bool migration_should_start_incoming(bool main_channel)
9265655aab0SPeter Xu {
9275655aab0SPeter Xu /* Multifd doesn't start unless all channels are established */
92851b07548SJuan Quintela if (migrate_multifd()) {
9295655aab0SPeter Xu return migration_has_all_channels();
9305655aab0SPeter Xu }
9315655aab0SPeter Xu
9325655aab0SPeter Xu /* Preempt channel only starts when the main channel is created */
9335655aab0SPeter Xu if (migrate_postcopy_preempt()) {
9345655aab0SPeter Xu return main_channel;
9355655aab0SPeter Xu }
9365655aab0SPeter Xu
9375655aab0SPeter Xu /*
9385655aab0SPeter Xu * For all the rest types of migration, we should only reach here when
9395655aab0SPeter Xu * it's the main channel that's being created, and we should always
9405655aab0SPeter Xu * proceed with this channel.
9415655aab0SPeter Xu */
9425655aab0SPeter Xu assert(main_channel);
9435655aab0SPeter Xu return true;
9445655aab0SPeter Xu }
9455655aab0SPeter Xu
migration_ioc_process_incoming(QIOChannel * ioc,Error ** errp)94649ed0d24SFei Li void migration_ioc_process_incoming(QIOChannel *ioc, Error **errp)
9474f0fae7fSJuan Quintela {
9484f0fae7fSJuan Quintela MigrationIncomingState *mis = migration_incoming_get_current();
949b673eab4SJuan Quintela Error *local_err = NULL;
95036f62f11SPeter Xu QEMUFile *f;
9516720c2b3Smanish.mishra bool default_channel = true;
9526720c2b3Smanish.mishra uint32_t channel_magic = 0;
9536720c2b3Smanish.mishra int ret = 0;
9544f0fae7fSJuan Quintela
9552dd7ee7aSFabiano Rosas if (migrate_multifd() && !migrate_mapped_ram() &&
9562dd7ee7aSFabiano Rosas !migrate_postcopy_ram() &&
9576720c2b3Smanish.mishra qio_channel_has_feature(ioc, QIO_CHANNEL_FEATURE_READ_MSG_PEEK)) {
9586720c2b3Smanish.mishra /*
9596720c2b3Smanish.mishra * With multiple channels, it is possible that we receive channels
9606720c2b3Smanish.mishra * out of order on destination side, causing incorrect mapping of
9616720c2b3Smanish.mishra * source channels on destination side. Check channel MAGIC to
9626720c2b3Smanish.mishra * decide type of channel. Please note this is best effort, postcopy
9636720c2b3Smanish.mishra * preempt channel does not send any magic number so avoid it for
9646720c2b3Smanish.mishra * postcopy live migration. Also tls live migration already does
9656720c2b3Smanish.mishra * tls handshake while initializing main channel so with tls this
9666720c2b3Smanish.mishra * issue is not possible.
9676720c2b3Smanish.mishra */
9686720c2b3Smanish.mishra ret = migration_channel_read_peek(ioc, (void *)&channel_magic,
969b6f4c0c7SAvihai Horon sizeof(channel_magic), errp);
9706720c2b3Smanish.mishra
9716720c2b3Smanish.mishra if (ret != 0) {
9726720c2b3Smanish.mishra return;
9736720c2b3Smanish.mishra }
9746720c2b3Smanish.mishra
9756720c2b3Smanish.mishra default_channel = (channel_magic == cpu_to_be32(QEMU_VM_FILE_MAGIC));
9766720c2b3Smanish.mishra } else {
9776720c2b3Smanish.mishra default_channel = !mis->from_src_file;
9786720c2b3Smanish.mishra }
9796720c2b3Smanish.mishra
980cde85c37SPeter Xu if (multifd_recv_setup(errp) != 0) {
9816720c2b3Smanish.mishra return;
9826720c2b3Smanish.mishra }
9836720c2b3Smanish.mishra
9846720c2b3Smanish.mishra if (default_channel) {
98536f62f11SPeter Xu f = qemu_file_new_input(ioc);
986c606f3baSAvihai Horon migration_incoming_setup(f);
987a429e7f4SPeter Xu } else {
988a429e7f4SPeter Xu /* Multiple connections */
98936f62f11SPeter Xu assert(migration_needs_multiple_sockets());
99051b07548SJuan Quintela if (migrate_multifd()) {
9916720c2b3Smanish.mishra multifd_recv_new_channel(ioc, &local_err);
99236f62f11SPeter Xu } else {
99336f62f11SPeter Xu assert(migrate_postcopy_preempt());
99436f62f11SPeter Xu f = qemu_file_new_input(ioc);
9956720c2b3Smanish.mishra postcopy_preempt_new_channel(mis, f);
99636f62f11SPeter Xu }
99749ed0d24SFei Li if (local_err) {
99849ed0d24SFei Li error_propagate(errp, local_err);
99949ed0d24SFei Li return;
100049ed0d24SFei Li }
10014f0fae7fSJuan Quintela }
100281e62053SPeter Xu
10035655aab0SPeter Xu if (migration_should_start_incoming(default_channel)) {
1004a39e9339SPeter Xu /* If it's a recovery, we're done */
1005a39e9339SPeter Xu if (postcopy_try_recover()) {
1006a39e9339SPeter Xu return;
1007a39e9339SPeter Xu }
100881e62053SPeter Xu migration_incoming_process();
100981e62053SPeter Xu }
10104f0fae7fSJuan Quintela }
10114f0fae7fSJuan Quintela
1012428d8908SJuan Quintela /**
1013428d8908SJuan Quintela * @migration_has_all_channels: We have received all channels that we need
1014428d8908SJuan Quintela *
1015428d8908SJuan Quintela * Returns true when we have got connections to all the channels that
1016428d8908SJuan Quintela * we need for migration.
1017428d8908SJuan Quintela */
migration_has_all_channels(void)1018428d8908SJuan Quintela bool migration_has_all_channels(void)
1019428d8908SJuan Quintela {
1020ca273df3SDaniel P. Berrangé MigrationIncomingState *mis = migration_incoming_get_current();
102162c1e0caSJuan Quintela
102236f62f11SPeter Xu if (!mis->from_src_file) {
102336f62f11SPeter Xu return false;
102436f62f11SPeter Xu }
102562c1e0caSJuan Quintela
102651b07548SJuan Quintela if (migrate_multifd()) {
102736f62f11SPeter Xu return multifd_recv_all_channels_created();
102836f62f11SPeter Xu }
102936f62f11SPeter Xu
103036f62f11SPeter Xu if (migrate_postcopy_preempt()) {
103136f62f11SPeter Xu return mis->postcopy_qemufile_dst != NULL;
103236f62f11SPeter Xu }
103336f62f11SPeter Xu
103436f62f11SPeter Xu return true;
1035428d8908SJuan Quintela }
1036428d8908SJuan Quintela
migrate_send_rp_switchover_ack(MigrationIncomingState * mis)10371b4adb10SAvihai Horon int migrate_send_rp_switchover_ack(MigrationIncomingState *mis)
10381b4adb10SAvihai Horon {
10391b4adb10SAvihai Horon return migrate_send_rp_message(mis, MIG_RP_MSG_SWITCHOVER_ACK, 0, NULL);
10401b4adb10SAvihai Horon }
10411b4adb10SAvihai Horon
10426decec93SDr. David Alan Gilbert /*
10436decec93SDr. David Alan Gilbert * Send a 'SHUT' message on the return channel with the given value
10446decec93SDr. David Alan Gilbert * to indicate that we've finished with the RP. Non-0 value indicates
10456decec93SDr. David Alan Gilbert * error.
10466decec93SDr. David Alan Gilbert */
migrate_send_rp_shut(MigrationIncomingState * mis,uint32_t value)10476decec93SDr. David Alan Gilbert void migrate_send_rp_shut(MigrationIncomingState *mis,
10486decec93SDr. David Alan Gilbert uint32_t value)
10496decec93SDr. David Alan Gilbert {
10506decec93SDr. David Alan Gilbert uint32_t buf;
10516decec93SDr. David Alan Gilbert
10526decec93SDr. David Alan Gilbert buf = cpu_to_be32(value);
10536decec93SDr. David Alan Gilbert migrate_send_rp_message(mis, MIG_RP_MSG_SHUT, sizeof(buf), &buf);
10546decec93SDr. David Alan Gilbert }
10556decec93SDr. David Alan Gilbert
10566decec93SDr. David Alan Gilbert /*
10576decec93SDr. David Alan Gilbert * Send a 'PONG' message on the return channel with the given value
10586decec93SDr. David Alan Gilbert * (normally in response to a 'PING')
10596decec93SDr. David Alan Gilbert */
migrate_send_rp_pong(MigrationIncomingState * mis,uint32_t value)10606decec93SDr. David Alan Gilbert void migrate_send_rp_pong(MigrationIncomingState *mis,
10616decec93SDr. David Alan Gilbert uint32_t value)
10626decec93SDr. David Alan Gilbert {
10636decec93SDr. David Alan Gilbert uint32_t buf;
10646decec93SDr. David Alan Gilbert
10656decec93SDr. David Alan Gilbert buf = cpu_to_be32(value);
10666decec93SDr. David Alan Gilbert migrate_send_rp_message(mis, MIG_RP_MSG_PONG, sizeof(buf), &buf);
10676decec93SDr. David Alan Gilbert }
10686decec93SDr. David Alan Gilbert
migrate_send_rp_recv_bitmap(MigrationIncomingState * mis,char * block_name)1069a335debbSPeter Xu void migrate_send_rp_recv_bitmap(MigrationIncomingState *mis,
1070a335debbSPeter Xu char *block_name)
1071a335debbSPeter Xu {
1072a335debbSPeter Xu char buf[512];
1073a335debbSPeter Xu int len;
1074a335debbSPeter Xu int64_t res;
1075a335debbSPeter Xu
1076a335debbSPeter Xu /*
1077a335debbSPeter Xu * First, we send the header part. It contains only the len of
1078a335debbSPeter Xu * idstr, and the idstr itself.
1079a335debbSPeter Xu */
1080a335debbSPeter Xu len = strlen(block_name);
1081a335debbSPeter Xu buf[0] = len;
1082a335debbSPeter Xu memcpy(buf + 1, block_name, len);
1083a335debbSPeter Xu
1084a335debbSPeter Xu if (mis->state != MIGRATION_STATUS_POSTCOPY_RECOVER) {
1085a335debbSPeter Xu error_report("%s: MSG_RP_RECV_BITMAP only used for recovery",
1086a335debbSPeter Xu __func__);
1087a335debbSPeter Xu return;
1088a335debbSPeter Xu }
1089a335debbSPeter Xu
1090a335debbSPeter Xu migrate_send_rp_message(mis, MIG_RP_MSG_RECV_BITMAP, len + 1, buf);
1091a335debbSPeter Xu
1092a335debbSPeter Xu /*
1093a335debbSPeter Xu * Next, we dump the received bitmap to the stream.
1094a335debbSPeter Xu *
1095a335debbSPeter Xu * TODO: currently we are safe since we are the only one that is
1096a335debbSPeter Xu * using the to_src_file handle (fault thread is still paused),
1097a335debbSPeter Xu * and it's ok even not taking the mutex. However the best way is
1098a335debbSPeter Xu * to take the lock before sending the message header, and release
1099a335debbSPeter Xu * the lock after sending the bitmap.
1100a335debbSPeter Xu */
1101a335debbSPeter Xu qemu_mutex_lock(&mis->rp_mutex);
1102a335debbSPeter Xu res = ramblock_recv_bitmap_send(mis->to_src_file, block_name);
1103a335debbSPeter Xu qemu_mutex_unlock(&mis->rp_mutex);
1104a335debbSPeter Xu
1105a335debbSPeter Xu trace_migrate_send_rp_recv_bitmap(block_name, res);
1106a335debbSPeter Xu }
1107a335debbSPeter Xu
migrate_send_rp_resume_ack(MigrationIncomingState * mis,uint32_t value)110813955b89SPeter Xu void migrate_send_rp_resume_ack(MigrationIncomingState *mis, uint32_t value)
110913955b89SPeter Xu {
111013955b89SPeter Xu uint32_t buf;
111113955b89SPeter Xu
111213955b89SPeter Xu buf = cpu_to_be32(value);
111313955b89SPeter Xu migrate_send_rp_message(mis, MIG_RP_MSG_RESUME_ACK, sizeof(buf), &buf);
111413955b89SPeter Xu }
111513955b89SPeter Xu
migration_is_running(void)1116aeaafb1eSSteve Sistare bool migration_is_running(void)
1117392d87e2SJuan Quintela {
1118aeaafb1eSSteve Sistare MigrationState *s = current_migration;
1119aeaafb1eSSteve Sistare
1120*4daff81eSPeter Xu if (!s) {
1121*4daff81eSPeter Xu return false;
1122*4daff81eSPeter Xu }
1123*4daff81eSPeter Xu
1124aeaafb1eSSteve Sistare switch (s->state) {
1125392d87e2SJuan Quintela case MIGRATION_STATUS_ACTIVE:
1126392d87e2SJuan Quintela case MIGRATION_STATUS_POSTCOPY_ACTIVE:
1127392d87e2SJuan Quintela case MIGRATION_STATUS_POSTCOPY_PAUSED:
11284146b77eSPeter Xu case MIGRATION_STATUS_POSTCOPY_RECOVER_SETUP:
1129392d87e2SJuan Quintela case MIGRATION_STATUS_POSTCOPY_RECOVER:
1130392d87e2SJuan Quintela case MIGRATION_STATUS_SETUP:
1131392d87e2SJuan Quintela case MIGRATION_STATUS_PRE_SWITCHOVER:
1132392d87e2SJuan Quintela case MIGRATION_STATUS_DEVICE:
1133392d87e2SJuan Quintela case MIGRATION_STATUS_WAIT_UNPLUG:
1134392d87e2SJuan Quintela case MIGRATION_STATUS_CANCELLING:
1135f018eb62SPeter Xu case MIGRATION_STATUS_COLO:
1136392d87e2SJuan Quintela return true;
1137392d87e2SJuan Quintela default:
1138392d87e2SJuan Quintela return false;
1139392d87e2SJuan Quintela }
1140392d87e2SJuan Quintela }
1141392d87e2SJuan Quintela
migrate_show_downtime(MigrationState * s)1142db18dee7SPeter Xu static bool migrate_show_downtime(MigrationState *s)
1143db18dee7SPeter Xu {
1144db18dee7SPeter Xu return (s->state == MIGRATION_STATUS_COMPLETED) || migration_in_postcopy();
1145db18dee7SPeter Xu }
1146db18dee7SPeter Xu
populate_time_info(MigrationInfo * info,MigrationState * s)1147640dfb14SWei Yang static void populate_time_info(MigrationInfo *info, MigrationState *s)
1148640dfb14SWei Yang {
1149640dfb14SWei Yang info->has_status = true;
1150640dfb14SWei Yang info->has_setup_time = true;
1151640dfb14SWei Yang info->setup_time = s->setup_time;
1152db18dee7SPeter Xu
1153640dfb14SWei Yang if (s->state == MIGRATION_STATUS_COMPLETED) {
1154640dfb14SWei Yang info->has_total_time = true;
1155640dfb14SWei Yang info->total_time = s->total_time;
1156640dfb14SWei Yang } else {
1157640dfb14SWei Yang info->has_total_time = true;
1158640dfb14SWei Yang info->total_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME) -
1159640dfb14SWei Yang s->start_time;
1160db18dee7SPeter Xu }
1161db18dee7SPeter Xu
1162db18dee7SPeter Xu if (migrate_show_downtime(s)) {
1163db18dee7SPeter Xu info->has_downtime = true;
1164db18dee7SPeter Xu info->downtime = s->downtime;
1165db18dee7SPeter Xu } else {
1166640dfb14SWei Yang info->has_expected_downtime = true;
1167640dfb14SWei Yang info->expected_downtime = s->expected_downtime;
1168640dfb14SWei Yang }
1169640dfb14SWei Yang }
1170640dfb14SWei Yang
populate_ram_info(MigrationInfo * info,MigrationState * s)1171a22463a5SDr. David Alan Gilbert static void populate_ram_info(MigrationInfo *info, MigrationState *s)
1172a22463a5SDr. David Alan Gilbert {
1173144fa06bSJuan Quintela size_t page_size = qemu_target_page_size();
1174144fa06bSJuan Quintela
1175a22463a5SDr. David Alan Gilbert info->ram = g_malloc0(sizeof(*info->ram));
1176897fd8bdSJuan Quintela info->ram->transferred = migration_transferred_bytes();
1177a22463a5SDr. David Alan Gilbert info->ram->total = ram_bytes_total();
1178aff3f660SJuan Quintela info->ram->duplicate = stat64_get(&mig_stats.zero_pages);
1179aff3f660SJuan Quintela info->ram->normal = stat64_get(&mig_stats.normal_pages);
118023b7576dSPeter Xu info->ram->normal_bytes = info->ram->normal * page_size;
1181a22463a5SDr. David Alan Gilbert info->ram->mbps = s->mbps;
1182536b5a4eSJuan Quintela info->ram->dirty_sync_count =
1183aff3f660SJuan Quintela stat64_get(&mig_stats.dirty_sync_count);
1184cf20c897SLeonardo Bras info->ram->dirty_sync_missed_zero_copy =
1185aff3f660SJuan Quintela stat64_get(&mig_stats.dirty_sync_missed_zero_copy);
11863c764f9bSJuan Quintela info->ram->postcopy_requests =
1187aff3f660SJuan Quintela stat64_get(&mig_stats.postcopy_requests);
1188144fa06bSJuan Quintela info->ram->page_size = page_size;
1189aff3f660SJuan Quintela info->ram->multifd_bytes = stat64_get(&mig_stats.multifd_bytes);
1190aecbfe9cSXiao Guangrong info->ram->pages_per_second = s->pages_per_second;
1191aff3f660SJuan Quintela info->ram->precopy_bytes = stat64_get(&mig_stats.precopy_bytes);
1192aff3f660SJuan Quintela info->ram->downtime_bytes = stat64_get(&mig_stats.downtime_bytes);
1193aff3f660SJuan Quintela info->ram->postcopy_bytes = stat64_get(&mig_stats.postcopy_bytes);
1194a22463a5SDr. David Alan Gilbert
119587dca0c9SJuan Quintela if (migrate_xbzrle()) {
1196114f5aeeSJuan Quintela info->xbzrle_cache = g_malloc0(sizeof(*info->xbzrle_cache));
1197114f5aeeSJuan Quintela info->xbzrle_cache->cache_size = migrate_xbzrle_cache_size();
11989360447dSJuan Quintela info->xbzrle_cache->bytes = xbzrle_counters.bytes;
11999360447dSJuan Quintela info->xbzrle_cache->pages = xbzrle_counters.pages;
12009360447dSJuan Quintela info->xbzrle_cache->cache_miss = xbzrle_counters.cache_miss;
12019360447dSJuan Quintela info->xbzrle_cache->cache_miss_rate = xbzrle_counters.cache_miss_rate;
1202e460a4b1SWei Wang info->xbzrle_cache->encoding_rate = xbzrle_counters.encoding_rate;
12039360447dSJuan Quintela info->xbzrle_cache->overflow = xbzrle_counters.overflow;
1204114f5aeeSJuan Quintela }
1205114f5aeeSJuan Quintela
1206338182c8SJuan Quintela if (cpu_throttle_active()) {
1207338182c8SJuan Quintela info->has_cpu_throttle_percentage = true;
1208338182c8SJuan Quintela info->cpu_throttle_percentage = cpu_throttle_get_percentage();
1209338182c8SJuan Quintela }
1210338182c8SJuan Quintela
1211a22463a5SDr. David Alan Gilbert if (s->state != MIGRATION_STATUS_COMPLETED) {
1212a22463a5SDr. David Alan Gilbert info->ram->remaining = ram_bytes_remaining();
121372f8e587SJuan Quintela info->ram->dirty_pages_rate =
1214aff3f660SJuan Quintela stat64_get(&mig_stats.dirty_pages_rate);
1215a22463a5SDr. David Alan Gilbert }
121615699cf5SHyman Huang(黄勇)
121715699cf5SHyman Huang(黄勇) if (migrate_dirty_limit() && dirtylimit_in_service()) {
121815699cf5SHyman Huang(黄勇) info->has_dirty_limit_throttle_time_per_round = true;
121915699cf5SHyman Huang(黄勇) info->dirty_limit_throttle_time_per_round =
122015699cf5SHyman Huang(黄勇) dirtylimit_throttle_time_per_round();
122115699cf5SHyman Huang(黄勇)
122215699cf5SHyman Huang(黄勇) info->has_dirty_limit_ring_full_time = true;
122315699cf5SHyman Huang(黄勇) info->dirty_limit_ring_full_time = dirtylimit_ring_full_time();
122415699cf5SHyman Huang(黄勇) }
1225a22463a5SDr. David Alan Gilbert }
1226a22463a5SDr. David Alan Gilbert
fill_source_migration_info(MigrationInfo * info)122765ace060SAlexey Perevalov static void fill_source_migration_info(MigrationInfo *info)
122860fe637bSDr. David Alan Gilbert {
122960fe637bSDr. David Alan Gilbert MigrationState *s = migrate_get_current();
1230552de79bSDr. David Alan Gilbert int state = qatomic_read(&s->state);
1231fa3673e4SSteve Sistare GSList *cur_blocker = migration_blockers[migrate_mode()];
12323af8554bSDr. David Alan Gilbert
1233372043f3SMarkus Armbruster info->blocked_reasons = NULL;
1234372043f3SMarkus Armbruster
12353af8554bSDr. David Alan Gilbert /*
12363af8554bSDr. David Alan Gilbert * There are two types of reasons a migration might be blocked;
12373af8554bSDr. David Alan Gilbert * a) devices marked in VMState as non-migratable, and
12383af8554bSDr. David Alan Gilbert * b) Explicit migration blockers
12393af8554bSDr. David Alan Gilbert * We need to add both of them here.
12403af8554bSDr. David Alan Gilbert */
12413af8554bSDr. David Alan Gilbert qemu_savevm_non_migratable_list(&info->blocked_reasons);
12423af8554bSDr. David Alan Gilbert
12433af8554bSDr. David Alan Gilbert while (cur_blocker) {
12443af8554bSDr. David Alan Gilbert QAPI_LIST_PREPEND(info->blocked_reasons,
12453af8554bSDr. David Alan Gilbert g_strdup(error_get_pretty(cur_blocker->data)));
12463af8554bSDr. David Alan Gilbert cur_blocker = g_slist_next(cur_blocker);
12473af8554bSDr. David Alan Gilbert }
1248372043f3SMarkus Armbruster info->has_blocked_reasons = info->blocked_reasons != NULL;
12493af8554bSDr. David Alan Gilbert
1250552de79bSDr. David Alan Gilbert switch (state) {
125131194731Szhanghailiang case MIGRATION_STATUS_NONE:
125260fe637bSDr. David Alan Gilbert /* no migration has happened ever */
125365ace060SAlexey Perevalov /* do not overwrite destination migration status */
125465ace060SAlexey Perevalov return;
125531194731Szhanghailiang case MIGRATION_STATUS_SETUP:
125660fe637bSDr. David Alan Gilbert info->has_status = true;
125760fe637bSDr. David Alan Gilbert info->has_total_time = false;
125860fe637bSDr. David Alan Gilbert break;
125931194731Szhanghailiang case MIGRATION_STATUS_ACTIVE:
126031194731Szhanghailiang case MIGRATION_STATUS_CANCELLING:
12619ec055aeSDr. David Alan Gilbert case MIGRATION_STATUS_POSTCOPY_ACTIVE:
126231e06077SDr. David Alan Gilbert case MIGRATION_STATUS_PRE_SWITCHOVER:
126331e06077SDr. David Alan Gilbert case MIGRATION_STATUS_DEVICE:
1264a688d2c1SPeter Xu case MIGRATION_STATUS_POSTCOPY_PAUSED:
12654146b77eSPeter Xu case MIGRATION_STATUS_POSTCOPY_RECOVER_SETUP:
1266135b87b4SPeter Xu case MIGRATION_STATUS_POSTCOPY_RECOVER:
1267c8f9f4f4SJuan Quintela /* TODO add some postcopy stats */
1268640dfb14SWei Yang populate_time_info(info, s);
1269a22463a5SDr. David Alan Gilbert populate_ram_info(info, s);
127038c482b4SAvihai Horon migration_populate_vfio_info(info);
12719ec055aeSDr. David Alan Gilbert break;
12720b827d5eSzhanghailiang case MIGRATION_STATUS_COLO:
12730b827d5eSzhanghailiang info->has_status = true;
12740b827d5eSzhanghailiang /* TODO: display COLO specific information (checkpoint info etc.) */
12750b827d5eSzhanghailiang break;
127631194731Szhanghailiang case MIGRATION_STATUS_COMPLETED:
1277640dfb14SWei Yang populate_time_info(info, s);
1278a22463a5SDr. David Alan Gilbert populate_ram_info(info, s);
127938c482b4SAvihai Horon migration_populate_vfio_info(info);
128060fe637bSDr. David Alan Gilbert break;
128131194731Szhanghailiang case MIGRATION_STATUS_FAILED:
128260fe637bSDr. David Alan Gilbert info->has_status = true;
128360fe637bSDr. David Alan Gilbert break;
128431194731Szhanghailiang case MIGRATION_STATUS_CANCELLED:
128560fe637bSDr. David Alan Gilbert info->has_status = true;
128660fe637bSDr. David Alan Gilbert break;
1287c7e0acd5SJens Freimann case MIGRATION_STATUS_WAIT_UNPLUG:
1288c7e0acd5SJens Freimann info->has_status = true;
1289c7e0acd5SJens Freimann break;
129060fe637bSDr. David Alan Gilbert }
1291552de79bSDr. David Alan Gilbert info->status = state;
1292c94143e5SPeter Xu
1293c94143e5SPeter Xu QEMU_LOCK_GUARD(&s->error_mutex);
1294c94143e5SPeter Xu if (s->error) {
1295c94143e5SPeter Xu info->error_desc = g_strdup(error_get_pretty(s->error));
1296c94143e5SPeter Xu }
129760fe637bSDr. David Alan Gilbert }
129860fe637bSDr. David Alan Gilbert
fill_destination_migration_info(MigrationInfo * info)129965ace060SAlexey Perevalov static void fill_destination_migration_info(MigrationInfo *info)
130065ace060SAlexey Perevalov {
130165ace060SAlexey Perevalov MigrationIncomingState *mis = migration_incoming_get_current();
130265ace060SAlexey Perevalov
13039aca82baSJuan Quintela if (mis->socket_address_list) {
13049aca82baSJuan Quintela info->has_socket_address = true;
13059aca82baSJuan Quintela info->socket_address =
13069aca82baSJuan Quintela QAPI_CLONE(SocketAddressList, mis->socket_address_list);
13079aca82baSJuan Quintela }
13089aca82baSJuan Quintela
130965ace060SAlexey Perevalov switch (mis->state) {
131065ace060SAlexey Perevalov case MIGRATION_STATUS_SETUP:
131165ace060SAlexey Perevalov case MIGRATION_STATUS_CANCELLING:
131265ace060SAlexey Perevalov case MIGRATION_STATUS_CANCELLED:
131365ace060SAlexey Perevalov case MIGRATION_STATUS_ACTIVE:
131465ace060SAlexey Perevalov case MIGRATION_STATUS_POSTCOPY_ACTIVE:
13153c9928d9SPeter Xu case MIGRATION_STATUS_POSTCOPY_PAUSED:
13163c9928d9SPeter Xu case MIGRATION_STATUS_POSTCOPY_RECOVER:
131765ace060SAlexey Perevalov case MIGRATION_STATUS_FAILED:
131865ace060SAlexey Perevalov case MIGRATION_STATUS_COLO:
131965ace060SAlexey Perevalov info->has_status = true;
132065ace060SAlexey Perevalov break;
132165ace060SAlexey Perevalov case MIGRATION_STATUS_COMPLETED:
132265ace060SAlexey Perevalov info->has_status = true;
132365ace060SAlexey Perevalov fill_destination_postcopy_migration_info(info);
132465ace060SAlexey Perevalov break;
1325a5c24e13SPeter Xu default:
1326a5c24e13SPeter Xu return;
132765ace060SAlexey Perevalov }
132865ace060SAlexey Perevalov info->status = mis->state;
1329dbea1c89SVladimir Sementsov-Ogievskiy
1330dbea1c89SVladimir Sementsov-Ogievskiy if (!info->error_desc) {
1331dbea1c89SVladimir Sementsov-Ogievskiy MigrationState *s = migrate_get_current();
1332dbea1c89SVladimir Sementsov-Ogievskiy QEMU_LOCK_GUARD(&s->error_mutex);
1333dbea1c89SVladimir Sementsov-Ogievskiy
1334dbea1c89SVladimir Sementsov-Ogievskiy if (s->error) {
1335dbea1c89SVladimir Sementsov-Ogievskiy info->error_desc = g_strdup(error_get_pretty(s->error));
1336dbea1c89SVladimir Sementsov-Ogievskiy }
1337dbea1c89SVladimir Sementsov-Ogievskiy }
133865ace060SAlexey Perevalov }
133965ace060SAlexey Perevalov
qmp_query_migrate(Error ** errp)134065ace060SAlexey Perevalov MigrationInfo *qmp_query_migrate(Error **errp)
134165ace060SAlexey Perevalov {
134265ace060SAlexey Perevalov MigrationInfo *info = g_malloc0(sizeof(*info));
134365ace060SAlexey Perevalov
134465ace060SAlexey Perevalov fill_destination_migration_info(info);
134565ace060SAlexey Perevalov fill_source_migration_info(info);
134665ace060SAlexey Perevalov
134765ace060SAlexey Perevalov return info;
134865ace060SAlexey Perevalov }
134965ace060SAlexey Perevalov
qmp_migrate_start_postcopy(Error ** errp)13504886a1bcSDr. David Alan Gilbert void qmp_migrate_start_postcopy(Error **errp)
13514886a1bcSDr. David Alan Gilbert {
13524886a1bcSDr. David Alan Gilbert MigrationState *s = migrate_get_current();
13534886a1bcSDr. David Alan Gilbert
135416b0fd32SVladimir Sementsov-Ogievskiy if (!migrate_postcopy()) {
1355a54d340bSDr. David Alan Gilbert error_setg(errp, "Enable postcopy with migrate_set_capability before"
13564886a1bcSDr. David Alan Gilbert " the start of migration");
13574886a1bcSDr. David Alan Gilbert return;
13584886a1bcSDr. David Alan Gilbert }
13594886a1bcSDr. David Alan Gilbert
13604886a1bcSDr. David Alan Gilbert if (s->state == MIGRATION_STATUS_NONE) {
13614886a1bcSDr. David Alan Gilbert error_setg(errp, "Postcopy must be started after migration has been"
13624886a1bcSDr. David Alan Gilbert " started");
13634886a1bcSDr. David Alan Gilbert return;
13644886a1bcSDr. David Alan Gilbert }
13654886a1bcSDr. David Alan Gilbert /*
13664886a1bcSDr. David Alan Gilbert * we don't error if migration has finished since that would be racy
13674886a1bcSDr. David Alan Gilbert * with issuing this command.
13684886a1bcSDr. David Alan Gilbert */
1369d73415a3SStefan Hajnoczi qatomic_set(&s->start_postcopy, true);
13704886a1bcSDr. David Alan Gilbert }
13714886a1bcSDr. David Alan Gilbert
137260fe637bSDr. David Alan Gilbert /* shared migration helpers */
137360fe637bSDr. David Alan Gilbert
migrate_set_state(MigrationStatus * state,MigrationStatus old_state,MigrationStatus new_state)1374a5c24e13SPeter Xu void migrate_set_state(MigrationStatus *state, MigrationStatus old_state,
1375a5c24e13SPeter Xu MigrationStatus new_state)
137660fe637bSDr. David Alan Gilbert {
1377a31fedeeSPeter Xu assert(new_state < MIGRATION_STATUS__MAX);
1378d73415a3SStefan Hajnoczi if (qatomic_cmpxchg(state, old_state, new_state) == old_state) {
1379a31fedeeSPeter Xu trace_migrate_set_state(MigrationStatus_str(new_state));
1380b05dc723SJuan Quintela migrate_generate_event(new_state);
138160fe637bSDr. David Alan Gilbert }
138260fe637bSDr. David Alan Gilbert }
138360fe637bSDr. David Alan Gilbert
migrate_fd_cleanup(MigrationState * s)1384fd392cfaSYury Kotov static void migrate_fd_cleanup(MigrationState *s)
138560fe637bSDr. David Alan Gilbert {
13869d9babf7SSteve Sistare MigrationEventType type;
13876dd4f44cSPeter Xu QEMUFile *tmp = NULL;
13886dd4f44cSPeter Xu
13896dd4f44cSPeter Xu trace_migrate_fd_cleanup();
13909d9babf7SSteve Sistare
139183174765SPeter Xu g_free(s->hostname);
139283174765SPeter Xu s->hostname = NULL;
1393e3bf5e68SDavid Hildenbrand json_writer_free(s->vmdesc);
1394e3bf5e68SDavid Hildenbrand s->vmdesc = NULL;
139583174765SPeter Xu
13960ceccd85SPeter Xu qemu_savevm_state_cleanup();
13970ceccd85SPeter Xu
139822b04245SFabiano Rosas close_return_path_on_source(s);
139922b04245SFabiano Rosas
14001d34e4bfSDr. David Alan Gilbert if (s->migration_thread_running) {
14016dd4f44cSPeter Xu bql_unlock();
140260fe637bSDr. David Alan Gilbert qemu_thread_join(&s->thread);
14031d34e4bfSDr. David Alan Gilbert s->migration_thread_running = false;
1404195801d7SStefan Hajnoczi bql_lock();
14056dd4f44cSPeter Xu }
140660fe637bSDr. David Alan Gilbert
14076dd4f44cSPeter Xu WITH_QEMU_LOCK_GUARD(&s->qemu_file_lock) {
14086dd4f44cSPeter Xu /*
14096dd4f44cSPeter Xu * Close the file handle without the lock to make sure the critical
14106dd4f44cSPeter Xu * section won't block for long.
14116dd4f44cSPeter Xu */
141262df066fSPeter Xu tmp = s->to_dst_file;
141389a02a9fSzhanghailiang s->to_dst_file = NULL;
14146dd4f44cSPeter Xu }
14156dd4f44cSPeter Xu
14166dd4f44cSPeter Xu if (tmp) {
141762df066fSPeter Xu /*
14186dd4f44cSPeter Xu * We only need to shutdown multifd if tmp!=NULL, because if
14196dd4f44cSPeter Xu * tmp==NULL, it means the main channel isn't established, while
14206dd4f44cSPeter Xu * multifd is only setup after that (in migration_thread()).
142162df066fSPeter Xu */
14226dd4f44cSPeter Xu multifd_send_shutdown();
142339675fffSPeter Xu migration_ioc_unregister_yank_from_file(tmp);
142462df066fSPeter Xu qemu_fclose(tmp);
142560fe637bSDr. David Alan Gilbert }
142660fe637bSDr. David Alan Gilbert
14273a6813b6SSteve Sistare assert(!migration_is_active());
142860fe637bSDr. David Alan Gilbert
142931194731Szhanghailiang if (s->state == MIGRATION_STATUS_CANCELLING) {
143048781e5bSzhanghailiang migrate_set_state(&s->state, MIGRATION_STATUS_CANCELLING,
143131194731Szhanghailiang MIGRATION_STATUS_CANCELLED);
143260fe637bSDr. David Alan Gilbert }
143360fe637bSDr. David Alan Gilbert
143487db1a7dSJuan Quintela if (s->error) {
143587db1a7dSJuan Quintela /* It is used on info migrate. We can't free it */
143687db1a7dSJuan Quintela error_report_err(error_copy(s->error));
143787db1a7dSJuan Quintela }
14389d9babf7SSteve Sistare type = migration_has_failed(s) ? MIG_EVENT_PRECOPY_FAILED :
14399d9babf7SSteve Sistare MIG_EVENT_PRECOPY_DONE;
14404af667f8SSteve Sistare migration_call_notifiers(s, type, NULL);
1441b5eea99eSLukas Straub yank_unregister_instance(MIGRATION_YANK_INSTANCE);
144260fe637bSDr. David Alan Gilbert }
144360fe637bSDr. David Alan Gilbert
migrate_fd_cleanup_bh(void * opaque)1444fd392cfaSYury Kotov static void migrate_fd_cleanup_bh(void *opaque)
1445fd392cfaSYury Kotov {
144644d0d456SFabiano Rosas migrate_fd_cleanup(opaque);
1447fd392cfaSYury Kotov }
1448fd392cfaSYury Kotov
migrate_set_error(MigrationState * s,const Error * error)144987db1a7dSJuan Quintela void migrate_set_error(MigrationState *s, const Error *error)
145087db1a7dSJuan Quintela {
14516e8a355dSDaniel Brodsky QEMU_LOCK_GUARD(&s->error_mutex);
1452d4a17b8fSVladimir Sementsov-Ogievskiy
1453d4a17b8fSVladimir Sementsov-Ogievskiy trace_migrate_error(error_get_pretty(error));
1454d4a17b8fSVladimir Sementsov-Ogievskiy
145587db1a7dSJuan Quintela if (!s->error) {
145687db1a7dSJuan Quintela s->error = error_copy(error);
145787db1a7dSJuan Quintela }
145887db1a7dSJuan Quintela }
145987db1a7dSJuan Quintela
migrate_has_error(MigrationState * s)14602b2f6f41SPeter Xu bool migrate_has_error(MigrationState *s)
14612b2f6f41SPeter Xu {
14622b2f6f41SPeter Xu /* The lock is not helpful here, but still follow the rule */
14632b2f6f41SPeter Xu QEMU_LOCK_GUARD(&s->error_mutex);
14642b2f6f41SPeter Xu return qatomic_read(&s->error);
14652b2f6f41SPeter Xu }
14662b2f6f41SPeter Xu
migrate_error_free(MigrationState * s)1467ca7bd082SPeter Xu static void migrate_error_free(MigrationState *s)
1468ca7bd082SPeter Xu {
1469ca7bd082SPeter Xu QEMU_LOCK_GUARD(&s->error_mutex);
1470ca7bd082SPeter Xu if (s->error) {
1471ca7bd082SPeter Xu error_free(s->error);
1472ca7bd082SPeter Xu s->error = NULL;
1473ca7bd082SPeter Xu }
1474ca7bd082SPeter Xu }
1475ca7bd082SPeter Xu
migrate_fd_error(MigrationState * s,const Error * error)1476aaf26bd3SLaszlo Ersek static void migrate_fd_error(MigrationState *s, const Error *error)
147760fe637bSDr. David Alan Gilbert {
14784146b77eSPeter Xu MigrationStatus current = s->state;
14794146b77eSPeter Xu MigrationStatus next;
14804146b77eSPeter Xu
148189a02a9fSzhanghailiang assert(s->to_dst_file == NULL);
14824146b77eSPeter Xu
14834146b77eSPeter Xu switch (current) {
14844146b77eSPeter Xu case MIGRATION_STATUS_SETUP:
14854146b77eSPeter Xu next = MIGRATION_STATUS_FAILED;
14864146b77eSPeter Xu break;
14874146b77eSPeter Xu case MIGRATION_STATUS_POSTCOPY_RECOVER_SETUP:
14884146b77eSPeter Xu /* Never fail a postcopy migration; switch back to PAUSED instead */
14894146b77eSPeter Xu next = MIGRATION_STATUS_POSTCOPY_PAUSED;
14904146b77eSPeter Xu break;
14914146b77eSPeter Xu default:
14924146b77eSPeter Xu /*
14934146b77eSPeter Xu * This really shouldn't happen. Just be careful to not crash a VM
14944146b77eSPeter Xu * just for this. Instead, dump something.
14954146b77eSPeter Xu */
14964146b77eSPeter Xu error_report("%s: Illegal migration status (%s) detected",
14974146b77eSPeter Xu __func__, MigrationStatus_str(current));
14984146b77eSPeter Xu return;
14994146b77eSPeter Xu }
15004146b77eSPeter Xu
15014146b77eSPeter Xu migrate_set_state(&s->state, current, next);
150287db1a7dSJuan Quintela migrate_set_error(s, error);
150360fe637bSDr. David Alan Gilbert }
150460fe637bSDr. David Alan Gilbert
migrate_fd_cancel(MigrationState * s)150560fe637bSDr. David Alan Gilbert static void migrate_fd_cancel(MigrationState *s)
150660fe637bSDr. David Alan Gilbert {
150760fe637bSDr. David Alan Gilbert int old_state ;
15087478fb0dSFabiano Rosas
150960fe637bSDr. David Alan Gilbert trace_migrate_fd_cancel();
151060fe637bSDr. David Alan Gilbert
151143044ac0SPeter Xu WITH_QEMU_LOCK_GUARD(&s->qemu_file_lock) {
151270b20477SDr. David Alan Gilbert if (s->rp_state.from_dst_file) {
151370b20477SDr. David Alan Gilbert /* shutdown the rp socket, so causing the rp thread to shutdown */
151470b20477SDr. David Alan Gilbert qemu_file_shutdown(s->rp_state.from_dst_file);
151570b20477SDr. David Alan Gilbert }
151643044ac0SPeter Xu }
151770b20477SDr. David Alan Gilbert
151860fe637bSDr. David Alan Gilbert do {
151960fe637bSDr. David Alan Gilbert old_state = s->state;
1520aeaafb1eSSteve Sistare if (!migration_is_running()) {
152160fe637bSDr. David Alan Gilbert break;
152260fe637bSDr. David Alan Gilbert }
1523a7b36b48SDr. David Alan Gilbert /* If the migration is paused, kick it out of the pause */
1524a7b36b48SDr. David Alan Gilbert if (old_state == MIGRATION_STATUS_PRE_SWITCHOVER) {
1525a7b36b48SDr. David Alan Gilbert qemu_sem_post(&s->pause_sem);
1526a7b36b48SDr. David Alan Gilbert }
152748781e5bSzhanghailiang migrate_set_state(&s->state, old_state, MIGRATION_STATUS_CANCELLING);
152831194731Szhanghailiang } while (s->state != MIGRATION_STATUS_CANCELLING);
1529a26ba26eSDr. David Alan Gilbert
1530a26ba26eSDr. David Alan Gilbert /*
1531a26ba26eSDr. David Alan Gilbert * If we're unlucky the migration code might be stuck somewhere in a
1532a26ba26eSDr. David Alan Gilbert * send/write while the network has failed and is waiting to timeout;
1533a26ba26eSDr. David Alan Gilbert * if we've got shutdown(2) available then we can force it to quit.
1534a26ba26eSDr. David Alan Gilbert */
15357478fb0dSFabiano Rosas if (s->state == MIGRATION_STATUS_CANCELLING) {
15367478fb0dSFabiano Rosas WITH_QEMU_LOCK_GUARD(&s->qemu_file_lock) {
15377478fb0dSFabiano Rosas if (s->to_dst_file) {
15387478fb0dSFabiano Rosas qemu_file_shutdown(s->to_dst_file);
15397478fb0dSFabiano Rosas }
15407478fb0dSFabiano Rosas }
1541a26ba26eSDr. David Alan Gilbert }
15421d2acc31Szhanghailiang if (s->state == MIGRATION_STATUS_CANCELLING && s->block_inactive) {
15431d2acc31Szhanghailiang Error *local_err = NULL;
15441d2acc31Szhanghailiang
15453b717194SEmanuele Giuseppe Esposito bdrv_activate_all(&local_err);
15461d2acc31Szhanghailiang if (local_err) {
15471d2acc31Szhanghailiang error_report_err(local_err);
15481d2acc31Szhanghailiang } else {
15491d2acc31Szhanghailiang s->block_inactive = false;
15501d2acc31Szhanghailiang }
15511d2acc31Szhanghailiang }
155260fe637bSDr. David Alan Gilbert }
155360fe637bSDr. David Alan Gilbert
migration_add_notifier_mode(NotifierWithReturn * notify,MigrationNotifyFunc func,MigMode mode)15546835f5a1SSteve Sistare void migration_add_notifier_mode(NotifierWithReturn *notify,
15556835f5a1SSteve Sistare MigrationNotifyFunc func, MigMode mode)
15566835f5a1SSteve Sistare {
15576835f5a1SSteve Sistare notify->notify = (NotifierWithReturnFunc)func;
15586835f5a1SSteve Sistare notifier_with_return_list_add(&migration_state_notifiers[mode], notify);
15596835f5a1SSteve Sistare }
15606835f5a1SSteve Sistare
migration_add_notifier(NotifierWithReturn * notify,MigrationNotifyFunc func)15613e775730SSteve Sistare void migration_add_notifier(NotifierWithReturn *notify,
15625663dd3fSSteve Sistare MigrationNotifyFunc func)
156360fe637bSDr. David Alan Gilbert {
15646835f5a1SSteve Sistare migration_add_notifier_mode(notify, func, MIG_MODE_NORMAL);
156560fe637bSDr. David Alan Gilbert }
156660fe637bSDr. David Alan Gilbert
migration_remove_notifier(NotifierWithReturn * notify)15673e775730SSteve Sistare void migration_remove_notifier(NotifierWithReturn *notify)
156860fe637bSDr. David Alan Gilbert {
1569d9cda213SSteve Sistare if (notify->notify) {
15703e775730SSteve Sistare notifier_with_return_remove(notify);
1571d9cda213SSteve Sistare notify->notify = NULL;
1572d9cda213SSteve Sistare }
1573d9cda213SSteve Sistare }
1574d9cda213SSteve Sistare
migration_call_notifiers(MigrationState * s,MigrationEventType type,Error ** errp)15754af667f8SSteve Sistare int migration_call_notifiers(MigrationState *s, MigrationEventType type,
15764af667f8SSteve Sistare Error **errp)
1577d9cda213SSteve Sistare {
15786835f5a1SSteve Sistare MigMode mode = s->parameters.mode;
15799d9babf7SSteve Sistare MigrationEvent e;
15804af667f8SSteve Sistare int ret;
15819d9babf7SSteve Sistare
15829d9babf7SSteve Sistare e.type = type;
15834af667f8SSteve Sistare ret = notifier_with_return_list_notify(&migration_state_notifiers[mode],
15844af667f8SSteve Sistare &e, errp);
15854af667f8SSteve Sistare assert(!ret || type == MIG_EVENT_PRECOPY_SETUP);
15864af667f8SSteve Sistare return ret;
158760fe637bSDr. David Alan Gilbert }
158860fe637bSDr. David Alan Gilbert
migration_has_failed(MigrationState * s)158960fe637bSDr. David Alan Gilbert bool migration_has_failed(MigrationState *s)
159060fe637bSDr. David Alan Gilbert {
159131194731Szhanghailiang return (s->state == MIGRATION_STATUS_CANCELLED ||
159231194731Szhanghailiang s->state == MIGRATION_STATUS_FAILED);
159360fe637bSDr. David Alan Gilbert }
159460fe637bSDr. David Alan Gilbert
migration_in_postcopy(void)15955727309dSJuan Quintela bool migration_in_postcopy(void)
15969ec055aeSDr. David Alan Gilbert {
15975727309dSJuan Quintela MigrationState *s = migrate_get_current();
15985727309dSJuan Quintela
15993748fef9SDr. David Alan Gilbert switch (s->state) {
16003748fef9SDr. David Alan Gilbert case MIGRATION_STATUS_POSTCOPY_ACTIVE:
16013748fef9SDr. David Alan Gilbert case MIGRATION_STATUS_POSTCOPY_PAUSED:
16024146b77eSPeter Xu case MIGRATION_STATUS_POSTCOPY_RECOVER_SETUP:
16033748fef9SDr. David Alan Gilbert case MIGRATION_STATUS_POSTCOPY_RECOVER:
16043748fef9SDr. David Alan Gilbert return true;
16053748fef9SDr. David Alan Gilbert default:
16063748fef9SDr. David Alan Gilbert return false;
16073748fef9SDr. David Alan Gilbert }
16089ec055aeSDr. David Alan Gilbert }
16099ec055aeSDr. David Alan Gilbert
migration_postcopy_is_alive(MigrationStatus state)1610a5c24e13SPeter Xu bool migration_postcopy_is_alive(MigrationStatus state)
1611f8c543e8SPeter Xu {
1612f8c543e8SPeter Xu switch (state) {
1613f8c543e8SPeter Xu case MIGRATION_STATUS_POSTCOPY_ACTIVE:
1614f8c543e8SPeter Xu case MIGRATION_STATUS_POSTCOPY_RECOVER:
1615f8c543e8SPeter Xu return true;
1616f8c543e8SPeter Xu default:
1617f8c543e8SPeter Xu return false;
1618f8c543e8SPeter Xu }
1619f8c543e8SPeter Xu }
1620f8c543e8SPeter Xu
migration_in_incoming_postcopy(void)162106df2e69SDavid Hildenbrand bool migration_in_incoming_postcopy(void)
162206df2e69SDavid Hildenbrand {
162306df2e69SDavid Hildenbrand PostcopyState ps = postcopy_state_get();
162406df2e69SDavid Hildenbrand
162506df2e69SDavid Hildenbrand return ps >= POSTCOPY_INCOMING_DISCARD && ps < POSTCOPY_INCOMING_END;
162606df2e69SDavid Hildenbrand }
162706df2e69SDavid Hildenbrand
migration_incoming_postcopy_advised(void)162880fe315cSDavid Hildenbrand bool migration_incoming_postcopy_advised(void)
162980fe315cSDavid Hildenbrand {
163080fe315cSDavid Hildenbrand PostcopyState ps = postcopy_state_get();
163180fe315cSDavid Hildenbrand
163280fe315cSDavid Hildenbrand return ps >= POSTCOPY_INCOMING_ADVISE && ps < POSTCOPY_INCOMING_END;
163380fe315cSDavid Hildenbrand }
163480fe315cSDavid Hildenbrand
migration_in_bg_snapshot(void)16351a8e44a8SAndrey Gruzdev bool migration_in_bg_snapshot(void)
16361a8e44a8SAndrey Gruzdev {
1637f018eb62SPeter Xu return migrate_background_snapshot() && migration_is_running();
16381a8e44a8SAndrey Gruzdev }
16391a8e44a8SAndrey Gruzdev
migration_is_active(void)16403a6813b6SSteve Sistare bool migration_is_active(void)
16418f8d528eSWei Yang {
16423a6813b6SSteve Sistare MigrationState *s = current_migration;
16433a6813b6SSteve Sistare
16448f8d528eSWei Yang return (s->state == MIGRATION_STATUS_ACTIVE ||
16458f8d528eSWei Yang s->state == MIGRATION_STATUS_POSTCOPY_ACTIVE);
16468f8d528eSWei Yang }
16478f8d528eSWei Yang
migration_is_device(void)16489bb630c6SSteve Sistare bool migration_is_device(void)
16499bb630c6SSteve Sistare {
16509bb630c6SSteve Sistare MigrationState *s = current_migration;
16519bb630c6SSteve Sistare
16529bb630c6SSteve Sistare return s->state == MIGRATION_STATUS_DEVICE;
16539bb630c6SSteve Sistare }
16549bb630c6SSteve Sistare
migration_thread_is_self(void)16556e785639SSteve Sistare bool migration_thread_is_self(void)
16566e785639SSteve Sistare {
16576e785639SSteve Sistare MigrationState *s = current_migration;
16586e785639SSteve Sistare
16596e785639SSteve Sistare return qemu_thread_is_self(&s->thread);
16606e785639SSteve Sistare }
16616e785639SSteve Sistare
migrate_mode_is_cpr(MigrationState * s)16629867d4ddSSteve Sistare bool migrate_mode_is_cpr(MigrationState *s)
16639867d4ddSSteve Sistare {
16649867d4ddSSteve Sistare return s->parameters.mode == MIG_MODE_CPR_REBOOT;
16659867d4ddSSteve Sistare }
16669867d4ddSSteve Sistare
migrate_init(MigrationState * s,Error ** errp)166708fc4cb5SAvihai Horon int migrate_init(MigrationState *s, Error **errp)
166860fe637bSDr. David Alan Gilbert {
166908fc4cb5SAvihai Horon int ret;
167008fc4cb5SAvihai Horon
167108fc4cb5SAvihai Horon ret = qemu_savevm_state_prepare(errp);
167208fc4cb5SAvihai Horon if (ret) {
167308fc4cb5SAvihai Horon return ret;
167408fc4cb5SAvihai Horon }
167508fc4cb5SAvihai Horon
1676389775d1SDr. David Alan Gilbert /*
1677389775d1SDr. David Alan Gilbert * Reinitialise all migration state, except
1678389775d1SDr. David Alan Gilbert * parameters/capabilities that the user set, and
1679389775d1SDr. David Alan Gilbert * locks.
1680389775d1SDr. David Alan Gilbert */
168189a02a9fSzhanghailiang s->to_dst_file = NULL;
1682389775d1SDr. David Alan Gilbert s->state = MIGRATION_STATUS_NONE;
1683389775d1SDr. David Alan Gilbert s->rp_state.from_dst_file = NULL;
1684389775d1SDr. David Alan Gilbert s->mbps = 0.0;
1685aecbfe9cSXiao Guangrong s->pages_per_second = 0.0;
1686389775d1SDr. David Alan Gilbert s->downtime = 0;
1687389775d1SDr. David Alan Gilbert s->expected_downtime = 0;
1688389775d1SDr. David Alan Gilbert s->setup_time = 0;
1689389775d1SDr. David Alan Gilbert s->start_postcopy = false;
1690389775d1SDr. David Alan Gilbert s->migration_thread_running = false;
1691d59ce6f3SDaniel P. Berrange error_free(s->error);
1692d59ce6f3SDaniel P. Berrange s->error = NULL;
16932aae1eb8SNikolay Borisov s->vmdesc = NULL;
169460fe637bSDr. David Alan Gilbert
169548781e5bSzhanghailiang migrate_set_state(&s->state, MIGRATION_STATUS_NONE, MIGRATION_STATUS_SETUP);
169660fe637bSDr. David Alan Gilbert
16974af246a3SPeter Xu s->start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
16984af246a3SPeter Xu s->total_time = 0;
1699f4584076SVladimir Sementsov-Ogievskiy s->vm_old_state = -1;
1700b15df1aeSPeter Xu s->iteration_initial_bytes = 0;
1701b15df1aeSPeter Xu s->threshold_size = 0;
17021b4adb10SAvihai Horon s->switchover_acked = false;
170327fd25b0SJuan Quintela s->rdma_migration = false;
1704f543aa22SAvihai Horon /*
1705809f188aSJuan Quintela * set mig_stats memory to zero for a new migration
1706f543aa22SAvihai Horon */
1707f543aa22SAvihai Horon memset(&mig_stats, 0, sizeof(mig_stats));
1708f543aa22SAvihai Horon migration_reset_vfio_bytes_transferred();
170908fc4cb5SAvihai Horon
171008fc4cb5SAvihai Horon return 0;
171160fe637bSDr. David Alan Gilbert }
171260fe637bSDr. David Alan Gilbert
is_busy(Error ** reasonp,Error ** errp)1713fa3673e4SSteve Sistare static bool is_busy(Error **reasonp, Error **errp)
171460fe637bSDr. David Alan Gilbert {
1715fa3673e4SSteve Sistare ERRP_GUARD();
1716fa3673e4SSteve Sistare
17174c170330SPeter Xu /* Snapshots are similar to migrations, so check RUN_STATE_SAVE_VM too. */
171834a8892dSPeter Xu if (runstate_check(RUN_STATE_SAVE_VM) || migration_is_running()) {
1719c8a7fc51SSteve Sistare error_propagate_prepend(errp, *reasonp,
17204b576648SMarkus Armbruster "disallowing migration blocker "
17214c170330SPeter Xu "(migration/snapshot in progress) for: ");
1722c8a7fc51SSteve Sistare *reasonp = NULL;
1723fa3673e4SSteve Sistare return true;
1724fa3673e4SSteve Sistare }
1725fa3673e4SSteve Sistare return false;
172660fe637bSDr. David Alan Gilbert }
172760fe637bSDr. David Alan Gilbert
is_only_migratable(Error ** reasonp,Error ** errp,int modes)1728fa3673e4SSteve Sistare static bool is_only_migratable(Error **reasonp, Error **errp, int modes)
1729fa3673e4SSteve Sistare {
1730fa3673e4SSteve Sistare ERRP_GUARD();
1731fa3673e4SSteve Sistare
1732fa3673e4SSteve Sistare if (only_migratable && (modes & BIT(MIG_MODE_NORMAL))) {
1733fa3673e4SSteve Sistare error_propagate_prepend(errp, *reasonp,
1734fa3673e4SSteve Sistare "disallowing migration blocker "
1735fa3673e4SSteve Sistare "(--only-migratable) for: ");
1736fa3673e4SSteve Sistare *reasonp = NULL;
1737fa3673e4SSteve Sistare return true;
1738fa3673e4SSteve Sistare }
1739fa3673e4SSteve Sistare return false;
1740fa3673e4SSteve Sistare }
1741fa3673e4SSteve Sistare
get_modes(MigMode mode,va_list ap)1742fa3673e4SSteve Sistare static int get_modes(MigMode mode, va_list ap)
1743fa3673e4SSteve Sistare {
1744fa3673e4SSteve Sistare int modes = 0;
1745fa3673e4SSteve Sistare
1746fa3673e4SSteve Sistare while (mode != -1 && mode != MIG_MODE_ALL) {
1747fa3673e4SSteve Sistare assert(mode >= MIG_MODE_NORMAL && mode < MIG_MODE__MAX);
1748fa3673e4SSteve Sistare modes |= BIT(mode);
1749fa3673e4SSteve Sistare mode = va_arg(ap, MigMode);
1750fa3673e4SSteve Sistare }
1751fa3673e4SSteve Sistare if (mode == MIG_MODE_ALL) {
1752fa3673e4SSteve Sistare modes = BIT(MIG_MODE__MAX) - 1;
1753fa3673e4SSteve Sistare }
1754fa3673e4SSteve Sistare return modes;
1755fa3673e4SSteve Sistare }
1756fa3673e4SSteve Sistare
add_blockers(Error ** reasonp,Error ** errp,int modes)1757fa3673e4SSteve Sistare static int add_blockers(Error **reasonp, Error **errp, int modes)
1758fa3673e4SSteve Sistare {
1759fa3673e4SSteve Sistare for (MigMode mode = 0; mode < MIG_MODE__MAX; mode++) {
1760fa3673e4SSteve Sistare if (modes & BIT(mode)) {
1761fa3673e4SSteve Sistare migration_blockers[mode] = g_slist_prepend(migration_blockers[mode],
1762fa3673e4SSteve Sistare *reasonp);
1763fa3673e4SSteve Sistare }
1764fa3673e4SSteve Sistare }
17654c170330SPeter Xu return 0;
17664c170330SPeter Xu }
17674c170330SPeter Xu
migrate_add_blocker(Error ** reasonp,Error ** errp)1768c8a7fc51SSteve Sistare int migrate_add_blocker(Error **reasonp, Error **errp)
176960fd6801SPeter Xu {
1770fa3673e4SSteve Sistare return migrate_add_blocker_modes(reasonp, errp, MIG_MODE_ALL);
177160fd6801SPeter Xu }
177260fd6801SPeter Xu
migrate_add_blocker_normal(Error ** reasonp,Error ** errp)1773fa3673e4SSteve Sistare int migrate_add_blocker_normal(Error **reasonp, Error **errp)
1774fa3673e4SSteve Sistare {
1775fa3673e4SSteve Sistare return migrate_add_blocker_modes(reasonp, errp, MIG_MODE_NORMAL, -1);
1776fa3673e4SSteve Sistare }
1777fa3673e4SSteve Sistare
migrate_add_blocker_modes(Error ** reasonp,Error ** errp,MigMode mode,...)1778fa3673e4SSteve Sistare int migrate_add_blocker_modes(Error **reasonp, Error **errp, MigMode mode, ...)
1779fa3673e4SSteve Sistare {
1780fa3673e4SSteve Sistare int modes;
1781fa3673e4SSteve Sistare va_list ap;
1782fa3673e4SSteve Sistare
1783fa3673e4SSteve Sistare va_start(ap, mode);
1784fa3673e4SSteve Sistare modes = get_modes(mode, ap);
1785fa3673e4SSteve Sistare va_end(ap);
1786fa3673e4SSteve Sistare
1787fa3673e4SSteve Sistare if (is_only_migratable(reasonp, errp, modes)) {
1788fa3673e4SSteve Sistare return -EACCES;
1789fa3673e4SSteve Sistare } else if (is_busy(reasonp, errp)) {
1790fa3673e4SSteve Sistare return -EBUSY;
1791fa3673e4SSteve Sistare }
1792fa3673e4SSteve Sistare return add_blockers(reasonp, errp, modes);
1793fa3673e4SSteve Sistare }
1794fa3673e4SSteve Sistare
migrate_add_blocker_internal(Error ** reasonp,Error ** errp)1795fa3673e4SSteve Sistare int migrate_add_blocker_internal(Error **reasonp, Error **errp)
1796fa3673e4SSteve Sistare {
1797fa3673e4SSteve Sistare int modes = BIT(MIG_MODE__MAX) - 1;
1798fa3673e4SSteve Sistare
1799fa3673e4SSteve Sistare if (is_busy(reasonp, errp)) {
1800fa3673e4SSteve Sistare return -EBUSY;
1801fa3673e4SSteve Sistare }
1802fa3673e4SSteve Sistare return add_blockers(reasonp, errp, modes);
180360fd6801SPeter Xu }
180460fd6801SPeter Xu
migrate_del_blocker(Error ** reasonp)1805c8a7fc51SSteve Sistare void migrate_del_blocker(Error **reasonp)
180660fe637bSDr. David Alan Gilbert {
1807c8a7fc51SSteve Sistare if (*reasonp) {
1808fa3673e4SSteve Sistare for (MigMode mode = 0; mode < MIG_MODE__MAX; mode++) {
1809fa3673e4SSteve Sistare migration_blockers[mode] = g_slist_remove(migration_blockers[mode],
1810fa3673e4SSteve Sistare *reasonp);
1811fa3673e4SSteve Sistare }
1812c8a7fc51SSteve Sistare error_free(*reasonp);
1813c8a7fc51SSteve Sistare *reasonp = NULL;
1814c8a7fc51SSteve Sistare }
181560fe637bSDr. David Alan Gilbert }
181660fe637bSDr. David Alan Gilbert
qmp_migrate_incoming(const char * uri,bool has_channels,MigrationChannelList * channels,bool has_exit_on_error,bool exit_on_error,Error ** errp)1817074dbce5SHet Gala void qmp_migrate_incoming(const char *uri, bool has_channels,
1818dbea1c89SVladimir Sementsov-Ogievskiy MigrationChannelList *channels,
1819dbea1c89SVladimir Sementsov-Ogievskiy bool has_exit_on_error, bool exit_on_error,
1820dbea1c89SVladimir Sementsov-Ogievskiy Error **errp)
1821bf1ae1f4SDr. David Alan Gilbert {
1822bf1ae1f4SDr. David Alan Gilbert Error *local_err = NULL;
18234debb5f5SDr. David Alan Gilbert static bool once = true;
1824dbea1c89SVladimir Sementsov-Ogievskiy MigrationIncomingState *mis = migration_incoming_get_current();
1825bf1ae1f4SDr. David Alan Gilbert
18264debb5f5SDr. David Alan Gilbert if (!once) {
18274debb5f5SDr. David Alan Gilbert error_setg(errp, "The incoming migration has already been started");
1828603d5a42SYury Kotov return;
18294debb5f5SDr. David Alan Gilbert }
1830e69d50d6SPaolo Bonzini if (!runstate_check(RUN_STATE_INMIGRATE)) {
1831e69d50d6SPaolo Bonzini error_setg(errp, "'-incoming' was not specified on the command line");
1832e69d50d6SPaolo Bonzini return;
1833e69d50d6SPaolo Bonzini }
1834bf1ae1f4SDr. David Alan Gilbert
1835cc48c587SPeter Xu if (!yank_register_instance(MIGRATION_YANK_INSTANCE, errp)) {
1836cc48c587SPeter Xu return;
1837cc48c587SPeter Xu }
1838cc48c587SPeter Xu
1839dbea1c89SVladimir Sementsov-Ogievskiy mis->exit_on_error =
1840dbea1c89SVladimir Sementsov-Ogievskiy has_exit_on_error ? exit_on_error : INMIGRATE_DEFAULT_EXIT_ON_ERROR;
1841dbea1c89SVladimir Sementsov-Ogievskiy
1842074dbce5SHet Gala qemu_start_incoming_migration(uri, has_channels, channels, &local_err);
1843bf1ae1f4SDr. David Alan Gilbert
1844bf1ae1f4SDr. David Alan Gilbert if (local_err) {
1845cc48c587SPeter Xu yank_unregister_instance(MIGRATION_YANK_INSTANCE);
1846bf1ae1f4SDr. David Alan Gilbert error_propagate(errp, local_err);
1847bf1ae1f4SDr. David Alan Gilbert return;
1848bf1ae1f4SDr. David Alan Gilbert }
1849bf1ae1f4SDr. David Alan Gilbert
18504debb5f5SDr. David Alan Gilbert once = false;
1851bf1ae1f4SDr. David Alan Gilbert }
1852bf1ae1f4SDr. David Alan Gilbert
qmp_migrate_recover(const char * uri,Error ** errp)185302affd41SPeter Xu void qmp_migrate_recover(const char *uri, Error **errp)
185402affd41SPeter Xu {
185502affd41SPeter Xu MigrationIncomingState *mis = migration_incoming_get_current();
185602affd41SPeter Xu
1857b7f9afd4SPeter Xu /*
1858b7f9afd4SPeter Xu * Don't even bother to use ERRP_GUARD() as it _must_ always be set by
1859b7f9afd4SPeter Xu * callers (no one should ignore a recover failure); if there is, it's a
1860b7f9afd4SPeter Xu * programming error.
1861b7f9afd4SPeter Xu */
1862b7f9afd4SPeter Xu assert(errp);
1863b7f9afd4SPeter Xu
186402affd41SPeter Xu if (mis->state != MIGRATION_STATUS_POSTCOPY_PAUSED) {
186502affd41SPeter Xu error_setg(errp, "Migrate recover can only be run "
186602affd41SPeter Xu "when postcopy is paused.");
186702affd41SPeter Xu return;
186802affd41SPeter Xu }
186902affd41SPeter Xu
187008401c04SPeter Xu /* If there's an existing transport, release it */
187108401c04SPeter Xu migration_incoming_transport_cleanup(mis);
187202affd41SPeter Xu
187302affd41SPeter Xu /*
187402affd41SPeter Xu * Note that this call will never start a real migration; it will
187502affd41SPeter Xu * only re-setup the migration stream and poke existing migration
187602affd41SPeter Xu * to continue using that newly established channel.
187702affd41SPeter Xu */
1878074dbce5SHet Gala qemu_start_incoming_migration(uri, false, NULL, errp);
187902affd41SPeter Xu }
188002affd41SPeter Xu
qmp_migrate_pause(Error ** errp)1881bfbf89c2SPeter Xu void qmp_migrate_pause(Error **errp)
1882bfbf89c2SPeter Xu {
1883bfbf89c2SPeter Xu MigrationState *ms = migrate_get_current();
1884bfbf89c2SPeter Xu MigrationIncomingState *mis = migration_incoming_get_current();
18857478fb0dSFabiano Rosas int ret = 0;
1886bfbf89c2SPeter Xu
1887f8c543e8SPeter Xu if (migration_postcopy_is_alive(ms->state)) {
1888bfbf89c2SPeter Xu /* Source side, during postcopy */
1889f8c543e8SPeter Xu Error *error = NULL;
1890f8c543e8SPeter Xu
1891f8c543e8SPeter Xu /* Tell the core migration that we're pausing */
1892f8c543e8SPeter Xu error_setg(&error, "Postcopy migration is paused by the user");
1893f8c543e8SPeter Xu migrate_set_error(ms, error);
1894f8c543e8SPeter Xu error_free(error);
1895f8c543e8SPeter Xu
1896bfbf89c2SPeter Xu qemu_mutex_lock(&ms->qemu_file_lock);
18977478fb0dSFabiano Rosas if (ms->to_dst_file) {
1898bfbf89c2SPeter Xu ret = qemu_file_shutdown(ms->to_dst_file);
18997478fb0dSFabiano Rosas }
1900bfbf89c2SPeter Xu qemu_mutex_unlock(&ms->qemu_file_lock);
1901bfbf89c2SPeter Xu if (ret) {
1902bfbf89c2SPeter Xu error_setg(errp, "Failed to pause source migration");
1903bfbf89c2SPeter Xu }
1904f8c543e8SPeter Xu
1905f8c543e8SPeter Xu /*
1906f8c543e8SPeter Xu * Kick the migration thread out of any waiting windows (on behalf
1907f8c543e8SPeter Xu * of the rp thread).
1908f8c543e8SPeter Xu */
1909f8c543e8SPeter Xu migration_rp_kick(ms);
1910f8c543e8SPeter Xu
1911bfbf89c2SPeter Xu return;
1912bfbf89c2SPeter Xu }
1913bfbf89c2SPeter Xu
1914f8c543e8SPeter Xu if (migration_postcopy_is_alive(mis->state)) {
1915bfbf89c2SPeter Xu ret = qemu_file_shutdown(mis->from_src_file);
1916bfbf89c2SPeter Xu if (ret) {
1917bfbf89c2SPeter Xu error_setg(errp, "Failed to pause destination migration");
1918bfbf89c2SPeter Xu }
1919bfbf89c2SPeter Xu return;
1920bfbf89c2SPeter Xu }
1921bfbf89c2SPeter Xu
1922bfbf89c2SPeter Xu error_setg(errp, "migrate-pause is currently only supported "
1923f8c543e8SPeter Xu "during postcopy-active or postcopy-recover state");
1924bfbf89c2SPeter Xu }
1925bfbf89c2SPeter Xu
migration_is_blocked(Error ** errp)192624f3902bSGreg Kurz bool migration_is_blocked(Error **errp)
192724f3902bSGreg Kurz {
1928fa3673e4SSteve Sistare GSList *blockers = migration_blockers[migrate_mode()];
1929fa3673e4SSteve Sistare
193024f3902bSGreg Kurz if (qemu_savevm_state_blocked(errp)) {
193124f3902bSGreg Kurz return true;
193224f3902bSGreg Kurz }
193324f3902bSGreg Kurz
1934fa3673e4SSteve Sistare if (blockers) {
1935fa3673e4SSteve Sistare error_propagate(errp, error_copy(blockers->data));
193624f3902bSGreg Kurz return true;
193724f3902bSGreg Kurz }
193824f3902bSGreg Kurz
193924f3902bSGreg Kurz return false;
194024f3902bSGreg Kurz }
194124f3902bSGreg Kurz
1942d3e35b8fSPeter Xu /* Returns true if continue to migrate, or false if error detected */
migrate_prepare(MigrationState * s,bool resume,Error ** errp)194318d154f5SFabiano Rosas static bool migrate_prepare(MigrationState *s, bool resume, Error **errp)
1944d3e35b8fSPeter Xu {
1945d3e35b8fSPeter Xu if (resume) {
1946d3e35b8fSPeter Xu if (s->state != MIGRATION_STATUS_POSTCOPY_PAUSED) {
1947d3e35b8fSPeter Xu error_setg(errp, "Cannot resume if there is no "
1948d3e35b8fSPeter Xu "paused migration");
1949d3e35b8fSPeter Xu return false;
1950d3e35b8fSPeter Xu }
195197ca211cSPeter Xu
195297ca211cSPeter Xu /*
195397ca211cSPeter Xu * Postcopy recovery won't work well with release-ram
195497ca211cSPeter Xu * capability since release-ram will drop the page buffer as
195597ca211cSPeter Xu * long as the page is put into the send buffer. So if there
195697ca211cSPeter Xu * is a network failure happened, any page buffers that have
195797ca211cSPeter Xu * not yet reached the destination VM but have already been
195897ca211cSPeter Xu * sent from the source VM will be lost forever. Let's refuse
195997ca211cSPeter Xu * the client from resuming such a postcopy migration.
196097ca211cSPeter Xu * Luckily release-ram was designed to only be used when src
196197ca211cSPeter Xu * and destination VMs are on the same host, so it should be
196297ca211cSPeter Xu * fine.
196397ca211cSPeter Xu */
196497ca211cSPeter Xu if (migrate_release_ram()) {
196597ca211cSPeter Xu error_setg(errp, "Postcopy recovery cannot work "
196697ca211cSPeter Xu "when release-ram capability is set");
196797ca211cSPeter Xu return false;
196897ca211cSPeter Xu }
196997ca211cSPeter Xu
19704146b77eSPeter Xu migrate_set_state(&s->state, MIGRATION_STATUS_POSTCOPY_PAUSED,
19714146b77eSPeter Xu MIGRATION_STATUS_POSTCOPY_RECOVER_SETUP);
19724146b77eSPeter Xu
1973d3e35b8fSPeter Xu /* This is a resume, skip init status */
1974d3e35b8fSPeter Xu return true;
1975d3e35b8fSPeter Xu }
1976d3e35b8fSPeter Xu
1977aeaafb1eSSteve Sistare if (migration_is_running()) {
197800580786SPhilippe Mathieu-Daudé error_setg(errp, "There's a migration process in progress");
1979d3e35b8fSPeter Xu return false;
1980d3e35b8fSPeter Xu }
1981d3e35b8fSPeter Xu
1982d3e35b8fSPeter Xu if (runstate_check(RUN_STATE_INMIGRATE)) {
1983d3e35b8fSPeter Xu error_setg(errp, "Guest is waiting for an incoming migration");
1984d3e35b8fSPeter Xu return false;
1985d3e35b8fSPeter Xu }
1986d3e35b8fSPeter Xu
198736d0fe65STuguoyi if (runstate_check(RUN_STATE_POSTMIGRATE)) {
198836d0fe65STuguoyi error_setg(errp, "Can't migrate the vm that was paused due to "
198936d0fe65STuguoyi "previous migration");
199036d0fe65STuguoyi return false;
199136d0fe65STuguoyi }
199236d0fe65STuguoyi
199306152b89SWilliam Roche if (kvm_hwpoisoned_mem()) {
199406152b89SWilliam Roche error_setg(errp, "Can't migrate this vm with hardware poisoned memory, "
199506152b89SWilliam Roche "please reboot the vm and try again");
199606152b89SWilliam Roche return false;
199706152b89SWilliam Roche }
199806152b89SWilliam Roche
1999d3e35b8fSPeter Xu if (migration_is_blocked(errp)) {
2000d3e35b8fSPeter Xu return false;
2001d3e35b8fSPeter Xu }
2002d3e35b8fSPeter Xu
20034ed49febSFabiano Rosas if (migrate_mapped_ram()) {
20044ed49febSFabiano Rosas if (migrate_tls()) {
20054ed49febSFabiano Rosas error_setg(errp, "Cannot use TLS with mapped-ram");
20064ed49febSFabiano Rosas return false;
20074ed49febSFabiano Rosas }
2008f427d90bSFabiano Rosas
2009f427d90bSFabiano Rosas if (migrate_multifd_compression()) {
2010f427d90bSFabiano Rosas error_setg(errp, "Cannot use compression with mapped-ram");
2011f427d90bSFabiano Rosas return false;
2012f427d90bSFabiano Rosas }
20134ed49febSFabiano Rosas }
20144ed49febSFabiano Rosas
2015cbdafc1bSSteve Sistare if (migrate_mode_is_cpr(s)) {
2016cbdafc1bSSteve Sistare const char *conflict = NULL;
2017cbdafc1bSSteve Sistare
2018cbdafc1bSSteve Sistare if (migrate_postcopy()) {
2019cbdafc1bSSteve Sistare conflict = "postcopy";
2020cbdafc1bSSteve Sistare } else if (migrate_background_snapshot()) {
2021cbdafc1bSSteve Sistare conflict = "background snapshot";
2022cbdafc1bSSteve Sistare } else if (migrate_colo()) {
2023cbdafc1bSSteve Sistare conflict = "COLO";
2024cbdafc1bSSteve Sistare }
2025cbdafc1bSSteve Sistare
2026cbdafc1bSSteve Sistare if (conflict) {
2027cbdafc1bSSteve Sistare error_setg(errp, "Cannot use %s with CPR", conflict);
2028cbdafc1bSSteve Sistare return false;
2029cbdafc1bSSteve Sistare }
2030cbdafc1bSSteve Sistare }
2031cbdafc1bSSteve Sistare
203208fc4cb5SAvihai Horon if (migrate_init(s, errp)) {
203308fc4cb5SAvihai Horon return false;
203408fc4cb5SAvihai Horon }
2035d3e35b8fSPeter Xu
2036d3e35b8fSPeter Xu return true;
2037d3e35b8fSPeter Xu }
2038d3e35b8fSPeter Xu
qmp_migrate(const char * uri,bool has_channels,MigrationChannelList * channels,bool has_detach,bool detach,bool has_resume,bool resume,Error ** errp)2039074dbce5SHet Gala void qmp_migrate(const char *uri, bool has_channels,
204018d154f5SFabiano Rosas MigrationChannelList *channels, bool has_detach, bool detach,
204118d154f5SFabiano Rosas bool has_resume, bool resume, Error **errp)
204260fe637bSDr. David Alan Gilbert {
20438c69ae9eSLaszlo Ersek bool resume_requested;
204460fe637bSDr. David Alan Gilbert Error *local_err = NULL;
204560fe637bSDr. David Alan Gilbert MigrationState *s = migrate_get_current();
2046bc1d54eeSHet Gala g_autoptr(MigrationChannel) channel = NULL;
20475994024fSHet Gala MigrationAddress *addr = NULL;
204860fe637bSDr. David Alan Gilbert
2049074dbce5SHet Gala /*
2050074dbce5SHet Gala * Having preliminary checks for uri and channel
2051074dbce5SHet Gala */
20520770ad43SHet Gala if (!uri == !channels) {
20530770ad43SHet Gala error_setg(errp, "need either 'uri' or 'channels' argument");
2054074dbce5SHet Gala return;
20550770ad43SHet Gala }
20560770ad43SHet Gala
20570770ad43SHet Gala if (channels) {
20585994024fSHet Gala /* To verify that Migrate channel list has only item */
20595994024fSHet Gala if (channels->next) {
20605994024fSHet Gala error_setg(errp, "Channel list has more than one entries");
20615994024fSHet Gala return;
2062074dbce5SHet Gala }
2063bc1d54eeSHet Gala addr = channels->value->addr;
20640770ad43SHet Gala }
20650770ad43SHet Gala
20660770ad43SHet Gala if (uri) {
20675994024fSHet Gala /* caller uses the old URI syntax */
20685994024fSHet Gala if (!migrate_uri_parse(uri, &channel, errp)) {
20695994024fSHet Gala return;
20705994024fSHet Gala }
2071bc1d54eeSHet Gala addr = channel->addr;
2072074dbce5SHet Gala }
2073d6f74fd1SPeter Xu
2074d95533e1SHet Gala /* transport mechanism not suitable for migration? */
20755994024fSHet Gala if (!migration_channels_and_transport_compatible(addr, errp)) {
207672a8192eSHet Gala return;
207772a8192eSHet Gala }
207872a8192eSHet Gala
20798c69ae9eSLaszlo Ersek resume_requested = has_resume && resume;
208018d154f5SFabiano Rosas if (!migrate_prepare(s, resume_requested, errp)) {
2081d3e35b8fSPeter Xu /* Error detected, put into errp */
208260fe637bSDr. David Alan Gilbert return;
208360fe637bSDr. David Alan Gilbert }
208460fe637bSDr. David Alan Gilbert
20858c69ae9eSLaszlo Ersek if (!resume_requested) {
2086b5eea99eSLukas Straub if (!yank_register_instance(MIGRATION_YANK_INSTANCE, errp)) {
2087b5eea99eSLukas Straub return;
2088b5eea99eSLukas Straub }
2089b5eea99eSLukas Straub }
2090b5eea99eSLukas Straub
20915994024fSHet Gala if (addr->transport == MIGRATION_ADDRESS_TYPE_SOCKET) {
20925994024fSHet Gala SocketAddress *saddr = &addr->u.socket;
209334dfc5e4SHet Gala if (saddr->type == SOCKET_ADDRESS_TYPE_INET ||
209434dfc5e4SHet Gala saddr->type == SOCKET_ADDRESS_TYPE_UNIX ||
209534dfc5e4SHet Gala saddr->type == SOCKET_ADDRESS_TYPE_VSOCK) {
209634dfc5e4SHet Gala socket_start_outgoing_migration(s, saddr, &local_err);
209734dfc5e4SHet Gala } else if (saddr->type == SOCKET_ADDRESS_TYPE_FD) {
209834dfc5e4SHet Gala fd_start_outgoing_migration(s, saddr->u.fd.str, &local_err);
209934dfc5e4SHet Gala }
210060fe637bSDr. David Alan Gilbert #ifdef CONFIG_RDMA
21015994024fSHet Gala } else if (addr->transport == MIGRATION_ADDRESS_TYPE_RDMA) {
21025994024fSHet Gala rdma_start_outgoing_migration(s, &addr->u.rdma, &local_err);
210360fe637bSDr. David Alan Gilbert #endif
21045994024fSHet Gala } else if (addr->transport == MIGRATION_ADDRESS_TYPE_EXEC) {
21055994024fSHet Gala exec_start_outgoing_migration(s, addr->u.exec.args, &local_err);
21065994024fSHet Gala } else if (addr->transport == MIGRATION_ADDRESS_TYPE_FILE) {
21075994024fSHet Gala file_start_outgoing_migration(s, &addr->u.file, &local_err);
210860fe637bSDr. David Alan Gilbert } else {
2109908927dbSTejus GK error_setg(&local_err, QERR_INVALID_PARAMETER_VALUE, "uri",
2110c6bd8c70SMarkus Armbruster "a valid migration protocol");
211148781e5bSzhanghailiang migrate_set_state(&s->state, MIGRATION_STATUS_SETUP,
211248781e5bSzhanghailiang MIGRATION_STATUS_FAILED);
211360fe637bSDr. David Alan Gilbert }
211460fe637bSDr. David Alan Gilbert
211560fe637bSDr. David Alan Gilbert if (local_err) {
21168c69ae9eSLaszlo Ersek if (!resume_requested) {
2117b5eea99eSLukas Straub yank_unregister_instance(MIGRATION_YANK_INSTANCE);
2118b5eea99eSLukas Straub }
2119d59ce6f3SDaniel P. Berrange migrate_fd_error(s, local_err);
212060fe637bSDr. David Alan Gilbert error_propagate(errp, local_err);
212160fe637bSDr. David Alan Gilbert return;
212260fe637bSDr. David Alan Gilbert }
212360fe637bSDr. David Alan Gilbert }
212460fe637bSDr. David Alan Gilbert
qmp_migrate_cancel(Error ** errp)212560fe637bSDr. David Alan Gilbert void qmp_migrate_cancel(Error **errp)
212660fe637bSDr. David Alan Gilbert {
2127458feccaSLaurent Vivier migration_cancel(NULL);
212860fe637bSDr. David Alan Gilbert }
212960fe637bSDr. David Alan Gilbert
qmp_migrate_continue(MigrationStatus state,Error ** errp)213089cfc02cSDr. David Alan Gilbert void qmp_migrate_continue(MigrationStatus state, Error **errp)
213189cfc02cSDr. David Alan Gilbert {
213289cfc02cSDr. David Alan Gilbert MigrationState *s = migrate_get_current();
213389cfc02cSDr. David Alan Gilbert if (s->state != state) {
213489cfc02cSDr. David Alan Gilbert error_setg(errp, "Migration not in expected state: %s",
213589cfc02cSDr. David Alan Gilbert MigrationStatus_str(s->state));
213689cfc02cSDr. David Alan Gilbert return;
213789cfc02cSDr. David Alan Gilbert }
213889cfc02cSDr. David Alan Gilbert qemu_sem_post(&s->pause_sem);
213989cfc02cSDr. David Alan Gilbert }
214089cfc02cSDr. David Alan Gilbert
migration_rp_wait(MigrationState * s)2141f8c543e8SPeter Xu int migration_rp_wait(MigrationState *s)
21425e79a4bfSPeter Xu {
2143f8c543e8SPeter Xu /* If migration has failure already, ignore the wait */
2144f8c543e8SPeter Xu if (migrate_has_error(s)) {
2145f8c543e8SPeter Xu return -1;
2146f8c543e8SPeter Xu }
2147f8c543e8SPeter Xu
21485e79a4bfSPeter Xu qemu_sem_wait(&s->rp_state.rp_sem);
2149f8c543e8SPeter Xu
2150f8c543e8SPeter Xu /* After wait, double check that there's no failure */
2151f8c543e8SPeter Xu if (migrate_has_error(s)) {
2152f8c543e8SPeter Xu return -1;
2153f8c543e8SPeter Xu }
2154f8c543e8SPeter Xu
2155f8c543e8SPeter Xu return 0;
21565e79a4bfSPeter Xu }
21575e79a4bfSPeter Xu
migration_rp_kick(MigrationState * s)21585e79a4bfSPeter Xu void migration_rp_kick(MigrationState *s)
21595e79a4bfSPeter Xu {
21605e79a4bfSPeter Xu qemu_sem_post(&s->rp_state.rp_sem);
21615e79a4bfSPeter Xu }
21625e79a4bfSPeter Xu
216370b20477SDr. David Alan Gilbert static struct rp_cmd_args {
216470b20477SDr. David Alan Gilbert ssize_t len; /* -1 = variable */
216570b20477SDr. David Alan Gilbert const char *name;
216670b20477SDr. David Alan Gilbert } rp_cmd_args[] = {
216770b20477SDr. David Alan Gilbert [MIG_RP_MSG_INVALID] = { .len = -1, .name = "INVALID" },
216870b20477SDr. David Alan Gilbert [MIG_RP_MSG_SHUT] = { .len = 4, .name = "SHUT" },
216970b20477SDr. David Alan Gilbert [MIG_RP_MSG_PONG] = { .len = 4, .name = "PONG" },
21701e2d90ebSDr. David Alan Gilbert [MIG_RP_MSG_REQ_PAGES] = { .len = 12, .name = "REQ_PAGES" },
21711e2d90ebSDr. David Alan Gilbert [MIG_RP_MSG_REQ_PAGES_ID] = { .len = -1, .name = "REQ_PAGES_ID" },
2172a335debbSPeter Xu [MIG_RP_MSG_RECV_BITMAP] = { .len = -1, .name = "RECV_BITMAP" },
217313955b89SPeter Xu [MIG_RP_MSG_RESUME_ACK] = { .len = 4, .name = "RESUME_ACK" },
21741b4adb10SAvihai Horon [MIG_RP_MSG_SWITCHOVER_ACK] = { .len = 0, .name = "SWITCHOVER_ACK" },
217570b20477SDr. David Alan Gilbert [MIG_RP_MSG_MAX] = { .len = -1, .name = "MAX" },
217670b20477SDr. David Alan Gilbert };
217770b20477SDr. David Alan Gilbert
217870b20477SDr. David Alan Gilbert /*
21791e2d90ebSDr. David Alan Gilbert * Process a request for pages received on the return path,
21801e2d90ebSDr. David Alan Gilbert * We're allowed to send more than requested (e.g. to round to our page size)
21811e2d90ebSDr. David Alan Gilbert * and we don't need to send pages that have already been sent.
21821e2d90ebSDr. David Alan Gilbert */
21837aa6070dSPeter Xu static void
migrate_handle_rp_req_pages(MigrationState * ms,const char * rbname,ram_addr_t start,size_t len,Error ** errp)21847aa6070dSPeter Xu migrate_handle_rp_req_pages(MigrationState *ms, const char* rbname,
21857aa6070dSPeter Xu ram_addr_t start, size_t len, Error **errp)
21861e2d90ebSDr. David Alan Gilbert {
21878e3b0cbbSMarc-André Lureau long our_host_ps = qemu_real_host_page_size();
21886c595cdeSDr. David Alan Gilbert
21891e2d90ebSDr. David Alan Gilbert trace_migrate_handle_rp_req_pages(rbname, start, len);
21906c595cdeSDr. David Alan Gilbert
21916c595cdeSDr. David Alan Gilbert /*
21926c595cdeSDr. David Alan Gilbert * Since we currently insist on matching page sizes, just sanity check
21936c595cdeSDr. David Alan Gilbert * we're being asked for whole host pages.
21946c595cdeSDr. David Alan Gilbert */
21957648297dSDavid Hildenbrand if (!QEMU_IS_ALIGNED(start, our_host_ps) ||
21967648297dSDavid Hildenbrand !QEMU_IS_ALIGNED(len, our_host_ps)) {
21977aa6070dSPeter Xu error_setg(errp, "MIG_RP_MSG_REQ_PAGES: Misaligned page request, start:"
21987aa6070dSPeter Xu RAM_ADDR_FMT " len: %zd", start, len);
21996c595cdeSDr. David Alan Gilbert return;
22006c595cdeSDr. David Alan Gilbert }
22016c595cdeSDr. David Alan Gilbert
22027aa6070dSPeter Xu ram_save_queue_pages(rbname, start, len, errp);
22031e2d90ebSDr. David Alan Gilbert }
22041e2d90ebSDr. David Alan Gilbert
migrate_handle_rp_recv_bitmap(MigrationState * s,char * block_name,Error ** errp)220588577f32SPeter Xu static bool migrate_handle_rp_recv_bitmap(MigrationState *s, char *block_name,
22067aa6070dSPeter Xu Error **errp)
2207a335debbSPeter Xu {
2208a335debbSPeter Xu RAMBlock *block = qemu_ram_block_by_name(block_name);
2209a335debbSPeter Xu
2210a335debbSPeter Xu if (!block) {
22117aa6070dSPeter Xu error_setg(errp, "MIG_RP_MSG_RECV_BITMAP has invalid block name '%s'",
22127aa6070dSPeter Xu block_name);
221388577f32SPeter Xu return false;
2214a335debbSPeter Xu }
2215a335debbSPeter Xu
2216a335debbSPeter Xu /* Fetch the received bitmap and refresh the dirty bitmap */
22177aa6070dSPeter Xu return ram_dirty_bitmap_reload(s, block, errp);
2218a335debbSPeter Xu }
2219a335debbSPeter Xu
migrate_handle_rp_resume_ack(MigrationState * s,uint32_t value,Error ** errp)222088577f32SPeter Xu static bool migrate_handle_rp_resume_ack(MigrationState *s,
22217aa6070dSPeter Xu uint32_t value, Error **errp)
222213955b89SPeter Xu {
222313955b89SPeter Xu trace_source_return_path_thread_resume_ack(value);
222413955b89SPeter Xu
222513955b89SPeter Xu if (value != MIGRATION_RESUME_ACK_VALUE) {
22267aa6070dSPeter Xu error_setg(errp, "illegal resume_ack value %"PRIu32, value);
222788577f32SPeter Xu return false;
222813955b89SPeter Xu }
222913955b89SPeter Xu
223013955b89SPeter Xu /* Now both sides are active. */
223113955b89SPeter Xu migrate_set_state(&s->state, MIGRATION_STATUS_POSTCOPY_RECOVER,
223213955b89SPeter Xu MIGRATION_STATUS_POSTCOPY_ACTIVE);
223313955b89SPeter Xu
223494190696SPeter Xu /* Notify send thread that time to continue send pages */
22355e79a4bfSPeter Xu migration_rp_kick(s);
223613955b89SPeter Xu
223788577f32SPeter Xu return true;
223813955b89SPeter Xu }
223913955b89SPeter Xu
224093589827SPeter Xu /*
224193589827SPeter Xu * Release ms->rp_state.from_dst_file (and postcopy_qemufile_src if
224293589827SPeter Xu * existed) in a safe way.
224393589827SPeter Xu */
migration_release_dst_files(MigrationState * ms)224493589827SPeter Xu static void migration_release_dst_files(MigrationState *ms)
224543044ac0SPeter Xu {
22467cea8637SMarc-André Lureau QEMUFile *file = NULL;
224743044ac0SPeter Xu
224843044ac0SPeter Xu WITH_QEMU_LOCK_GUARD(&ms->qemu_file_lock) {
224943044ac0SPeter Xu /*
225043044ac0SPeter Xu * Reset the from_dst_file pointer first before releasing it, as we
225143044ac0SPeter Xu * can't block within lock section
225243044ac0SPeter Xu */
225343044ac0SPeter Xu file = ms->rp_state.from_dst_file;
225443044ac0SPeter Xu ms->rp_state.from_dst_file = NULL;
225543044ac0SPeter Xu }
225643044ac0SPeter Xu
225793589827SPeter Xu /*
225893589827SPeter Xu * Do the same to postcopy fast path socket too if there is. No
225993589827SPeter Xu * locking needed because this qemufile should only be managed by
226093589827SPeter Xu * return path thread.
226193589827SPeter Xu */
226293589827SPeter Xu if (ms->postcopy_qemufile_src) {
226393589827SPeter Xu migration_ioc_unregister_yank_from_file(ms->postcopy_qemufile_src);
226493589827SPeter Xu qemu_file_shutdown(ms->postcopy_qemufile_src);
226593589827SPeter Xu qemu_fclose(ms->postcopy_qemufile_src);
226693589827SPeter Xu ms->postcopy_qemufile_src = NULL;
226793589827SPeter Xu }
226893589827SPeter Xu
226943044ac0SPeter Xu qemu_fclose(file);
227043044ac0SPeter Xu }
227143044ac0SPeter Xu
22721e2d90ebSDr. David Alan Gilbert /*
227370b20477SDr. David Alan Gilbert * Handles messages sent on the return path towards the source VM
227470b20477SDr. David Alan Gilbert *
227570b20477SDr. David Alan Gilbert */
source_return_path_thread(void * opaque)227670b20477SDr. David Alan Gilbert static void *source_return_path_thread(void *opaque)
227770b20477SDr. David Alan Gilbert {
227870b20477SDr. David Alan Gilbert MigrationState *ms = opaque;
227970b20477SDr. David Alan Gilbert QEMUFile *rp = ms->rp_state.from_dst_file;
228070b20477SDr. David Alan Gilbert uint16_t header_len, header_type;
2281568b01caSPeter Xu uint8_t buf[512];
228270b20477SDr. David Alan Gilbert uint32_t tmp32, sibling_error;
22831e2d90ebSDr. David Alan Gilbert ram_addr_t start = 0; /* =0 to silence warning */
22841e2d90ebSDr. David Alan Gilbert size_t len = 0, expected_len;
22857aa6070dSPeter Xu Error *err = NULL;
228670b20477SDr. David Alan Gilbert int res;
228770b20477SDr. David Alan Gilbert
228870b20477SDr. David Alan Gilbert trace_source_return_path_thread_entry();
228974637e6fSLidong Chen rcu_register_thread();
229014b1742eSPeter Xu
2291f018eb62SPeter Xu while (migration_is_running()) {
229270b20477SDr. David Alan Gilbert trace_source_return_path_thread_loop_top();
22937aa6070dSPeter Xu
229470b20477SDr. David Alan Gilbert header_type = qemu_get_be16(rp);
229570b20477SDr. David Alan Gilbert header_len = qemu_get_be16(rp);
229670b20477SDr. David Alan Gilbert
22977a9ddfbfSPeter Xu if (qemu_file_get_error(rp)) {
22987aa6070dSPeter Xu qemu_file_get_error_obj(rp, &err);
22997a9ddfbfSPeter Xu goto out;
23007a9ddfbfSPeter Xu }
23017a9ddfbfSPeter Xu
230270b20477SDr. David Alan Gilbert if (header_type >= MIG_RP_MSG_MAX ||
230370b20477SDr. David Alan Gilbert header_type == MIG_RP_MSG_INVALID) {
23047aa6070dSPeter Xu error_setg(&err, "Received invalid message 0x%04x length 0x%04x",
230570b20477SDr. David Alan Gilbert header_type, header_len);
230670b20477SDr. David Alan Gilbert goto out;
230770b20477SDr. David Alan Gilbert }
230870b20477SDr. David Alan Gilbert
230970b20477SDr. David Alan Gilbert if ((rp_cmd_args[header_type].len != -1 &&
231070b20477SDr. David Alan Gilbert header_len != rp_cmd_args[header_type].len) ||
2311568b01caSPeter Xu header_len > sizeof(buf)) {
23127aa6070dSPeter Xu error_setg(&err, "Received '%s' message (0x%04x) with"
231370b20477SDr. David Alan Gilbert "incorrect length %d expecting %zu",
231470b20477SDr. David Alan Gilbert rp_cmd_args[header_type].name, header_type, header_len,
231570b20477SDr. David Alan Gilbert (size_t)rp_cmd_args[header_type].len);
231670b20477SDr. David Alan Gilbert goto out;
231770b20477SDr. David Alan Gilbert }
231870b20477SDr. David Alan Gilbert
231970b20477SDr. David Alan Gilbert /* We know we've got a valid header by this point */
232070b20477SDr. David Alan Gilbert res = qemu_get_buffer(rp, buf, header_len);
232170b20477SDr. David Alan Gilbert if (res != header_len) {
23227aa6070dSPeter Xu error_setg(&err, "Failed reading data for message 0x%04x"
232370b20477SDr. David Alan Gilbert " read %d expected %d",
232470b20477SDr. David Alan Gilbert header_type, res, header_len);
232570b20477SDr. David Alan Gilbert goto out;
232670b20477SDr. David Alan Gilbert }
232770b20477SDr. David Alan Gilbert
232870b20477SDr. David Alan Gilbert /* OK, we have the message and the data */
232970b20477SDr. David Alan Gilbert switch (header_type) {
233070b20477SDr. David Alan Gilbert case MIG_RP_MSG_SHUT:
23314d885131SPeter Maydell sibling_error = ldl_be_p(buf);
233270b20477SDr. David Alan Gilbert trace_source_return_path_thread_shut(sibling_error);
233370b20477SDr. David Alan Gilbert if (sibling_error) {
23347aa6070dSPeter Xu error_setg(&err, "Sibling indicated error %d", sibling_error);
233570b20477SDr. David Alan Gilbert }
233670b20477SDr. David Alan Gilbert /*
233770b20477SDr. David Alan Gilbert * We'll let the main thread deal with closing the RP
233870b20477SDr. David Alan Gilbert * we could do a shutdown(2) on it, but we're the only user
233970b20477SDr. David Alan Gilbert * anyway, so there's nothing gained.
234070b20477SDr. David Alan Gilbert */
234170b20477SDr. David Alan Gilbert goto out;
234270b20477SDr. David Alan Gilbert
234370b20477SDr. David Alan Gilbert case MIG_RP_MSG_PONG:
23444d885131SPeter Maydell tmp32 = ldl_be_p(buf);
234570b20477SDr. David Alan Gilbert trace_source_return_path_thread_pong(tmp32);
2346b28fb582SPeter Xu qemu_sem_post(&ms->rp_state.rp_pong_acks);
234770b20477SDr. David Alan Gilbert break;
234870b20477SDr. David Alan Gilbert
23491e2d90ebSDr. David Alan Gilbert case MIG_RP_MSG_REQ_PAGES:
23504d885131SPeter Maydell start = ldq_be_p(buf);
23514d885131SPeter Maydell len = ldl_be_p(buf + 8);
23527aa6070dSPeter Xu migrate_handle_rp_req_pages(ms, NULL, start, len, &err);
23537aa6070dSPeter Xu if (err) {
23547aa6070dSPeter Xu goto out;
23557aa6070dSPeter Xu }
23561e2d90ebSDr. David Alan Gilbert break;
23571e2d90ebSDr. David Alan Gilbert
23581e2d90ebSDr. David Alan Gilbert case MIG_RP_MSG_REQ_PAGES_ID:
23591e2d90ebSDr. David Alan Gilbert expected_len = 12 + 1; /* header + termination */
23601e2d90ebSDr. David Alan Gilbert
23611e2d90ebSDr. David Alan Gilbert if (header_len >= expected_len) {
23624d885131SPeter Maydell start = ldq_be_p(buf);
23634d885131SPeter Maydell len = ldl_be_p(buf + 8);
23641e2d90ebSDr. David Alan Gilbert /* Now we expect an idstr */
23651e2d90ebSDr. David Alan Gilbert tmp32 = buf[12]; /* Length of the following idstr */
23661e2d90ebSDr. David Alan Gilbert buf[13 + tmp32] = '\0';
23671e2d90ebSDr. David Alan Gilbert expected_len += tmp32;
23681e2d90ebSDr. David Alan Gilbert }
23691e2d90ebSDr. David Alan Gilbert if (header_len != expected_len) {
23707aa6070dSPeter Xu error_setg(&err, "Req_Page_id with length %d expecting %zd",
23711e2d90ebSDr. David Alan Gilbert header_len, expected_len);
23721e2d90ebSDr. David Alan Gilbert goto out;
23731e2d90ebSDr. David Alan Gilbert }
23747aa6070dSPeter Xu migrate_handle_rp_req_pages(ms, (char *)&buf[13], start, len,
23757aa6070dSPeter Xu &err);
23767aa6070dSPeter Xu if (err) {
23777aa6070dSPeter Xu goto out;
23787aa6070dSPeter Xu }
23791e2d90ebSDr. David Alan Gilbert break;
23801e2d90ebSDr. David Alan Gilbert
2381a335debbSPeter Xu case MIG_RP_MSG_RECV_BITMAP:
2382a335debbSPeter Xu if (header_len < 1) {
23837aa6070dSPeter Xu error_setg(&err, "MIG_RP_MSG_RECV_BITMAP missing block name");
2384a335debbSPeter Xu goto out;
2385a335debbSPeter Xu }
2386a335debbSPeter Xu /* Format: len (1B) + idstr (<255B). This ends the idstr. */
2387a335debbSPeter Xu buf[buf[0] + 1] = '\0';
238888577f32SPeter Xu if (!migrate_handle_rp_recv_bitmap(ms, (char *)(buf + 1), &err)) {
2389a335debbSPeter Xu goto out;
2390a335debbSPeter Xu }
2391a335debbSPeter Xu break;
2392a335debbSPeter Xu
239313955b89SPeter Xu case MIG_RP_MSG_RESUME_ACK:
239413955b89SPeter Xu tmp32 = ldl_be_p(buf);
239588577f32SPeter Xu if (!migrate_handle_rp_resume_ack(ms, tmp32, &err)) {
239613955b89SPeter Xu goto out;
239713955b89SPeter Xu }
239813955b89SPeter Xu break;
239913955b89SPeter Xu
24001b4adb10SAvihai Horon case MIG_RP_MSG_SWITCHOVER_ACK:
24011b4adb10SAvihai Horon ms->switchover_acked = true;
24021b4adb10SAvihai Horon trace_source_return_path_thread_switchover_acked();
24031b4adb10SAvihai Horon break;
24041b4adb10SAvihai Horon
240570b20477SDr. David Alan Gilbert default:
240670b20477SDr. David Alan Gilbert break;
240770b20477SDr. David Alan Gilbert }
240870b20477SDr. David Alan Gilbert }
240914b1742eSPeter Xu
241014b1742eSPeter Xu out:
24117aa6070dSPeter Xu if (err) {
24127aa6070dSPeter Xu migrate_set_error(ms, err);
24137aa6070dSPeter Xu error_free(err);
241470b20477SDr. David Alan Gilbert trace_source_return_path_thread_bad_end();
241570b20477SDr. David Alan Gilbert }
241670b20477SDr. David Alan Gilbert
2417f8c543e8SPeter Xu if (ms->state == MIGRATION_STATUS_POSTCOPY_RECOVER) {
2418f8c543e8SPeter Xu /*
2419f8c543e8SPeter Xu * this will be extremely unlikely: that we got yet another network
2420f8c543e8SPeter Xu * issue during recovering of the 1st network failure.. during this
2421f8c543e8SPeter Xu * period the main migration thread can be waiting on rp_sem for
2422f8c543e8SPeter Xu * this thread to sync with the other side.
2423f8c543e8SPeter Xu *
2424f8c543e8SPeter Xu * When this happens, explicitly kick the migration thread out of
2425f8c543e8SPeter Xu * RECOVER stage and back to PAUSED, so the admin can try
2426f8c543e8SPeter Xu * everything again.
2427f8c543e8SPeter Xu */
2428f8c543e8SPeter Xu migration_rp_kick(ms);
2429f8c543e8SPeter Xu }
2430f8c543e8SPeter Xu
243170b20477SDr. David Alan Gilbert trace_source_return_path_thread_end();
243274637e6fSLidong Chen rcu_unregister_thread();
24337aa6070dSPeter Xu
243470b20477SDr. David Alan Gilbert return NULL;
243570b20477SDr. David Alan Gilbert }
243670b20477SDr. David Alan Gilbert
open_return_path_on_source(MigrationState * ms)2437ef796ee9SFabiano Rosas static int open_return_path_on_source(MigrationState *ms)
243870b20477SDr. David Alan Gilbert {
243989a02a9fSzhanghailiang ms->rp_state.from_dst_file = qemu_file_get_return_path(ms->to_dst_file);
244070b20477SDr. David Alan Gilbert if (!ms->rp_state.from_dst_file) {
244170b20477SDr. David Alan Gilbert return -1;
244270b20477SDr. David Alan Gilbert }
244370b20477SDr. David Alan Gilbert
244470b20477SDr. David Alan Gilbert trace_open_return_path_on_source();
2445d3e35b8fSPeter Xu
2446e620b1e4SPeter Xu qemu_thread_create(&ms->rp_state.rp_thread, MIGRATION_THREAD_SRC_RETURN,
244770b20477SDr. David Alan Gilbert source_return_path_thread, ms, QEMU_THREAD_JOINABLE);
244853021ea1SPeter Xu ms->rp_state.rp_thread_created = true;
244970b20477SDr. David Alan Gilbert
245070b20477SDr. David Alan Gilbert trace_open_return_path_on_source_continue();
245170b20477SDr. David Alan Gilbert
245270b20477SDr. David Alan Gilbert return 0;
245370b20477SDr. David Alan Gilbert }
245470b20477SDr. David Alan Gilbert
24557aa6070dSPeter Xu /* Return true if error detected, or false otherwise */
close_return_path_on_source(MigrationState * ms)24567aa6070dSPeter Xu static bool close_return_path_on_source(MigrationState *ms)
245770b20477SDr. David Alan Gilbert {
2458d50f5dc0SFabiano Rosas if (!ms->rp_state.rp_thread_created) {
24597aa6070dSPeter Xu return false;
2460d50f5dc0SFabiano Rosas }
2461d50f5dc0SFabiano Rosas
2462d50f5dc0SFabiano Rosas trace_migration_return_path_end_before();
2463d50f5dc0SFabiano Rosas
246470b20477SDr. David Alan Gilbert /*
2465639decf5SFabiano Rosas * If this is a normal exit then the destination will send a SHUT
2466639decf5SFabiano Rosas * and the rp_thread will exit, however if there's an error we
2467639decf5SFabiano Rosas * need to cause it to exit. shutdown(2), if we have it, will
2468639decf5SFabiano Rosas * cause it to unblock if it's stuck waiting for the destination.
246970b20477SDr. David Alan Gilbert */
2470639decf5SFabiano Rosas WITH_QEMU_LOCK_GUARD(&ms->qemu_file_lock) {
24719425ef3fSCédric Le Goater if (migrate_has_error(ms) && ms->rp_state.from_dst_file) {
247270b20477SDr. David Alan Gilbert qemu_file_shutdown(ms->rp_state.from_dst_file);
247370b20477SDr. David Alan Gilbert }
2474639decf5SFabiano Rosas }
2475639decf5SFabiano Rosas
247670b20477SDr. David Alan Gilbert qemu_thread_join(&ms->rp_state.rp_thread);
247753021ea1SPeter Xu ms->rp_state.rp_thread_created = false;
247836e9aab3SFabiano Rosas migration_release_dst_files(ms);
24797aa6070dSPeter Xu trace_migration_return_path_end_after();
248036e9aab3SFabiano Rosas
24817aa6070dSPeter Xu /* Return path will persist the error in MigrationState when quit */
24827aa6070dSPeter Xu return migrate_has_error(ms);
248370b20477SDr. David Alan Gilbert }
248470b20477SDr. David Alan Gilbert
24855655aab0SPeter Xu static inline void
migration_wait_main_channel(MigrationState * ms)24865655aab0SPeter Xu migration_wait_main_channel(MigrationState *ms)
24875655aab0SPeter Xu {
24885655aab0SPeter Xu /* Wait until one PONG message received */
24895655aab0SPeter Xu qemu_sem_wait(&ms->rp_state.rp_pong_acks);
24905655aab0SPeter Xu }
24915655aab0SPeter Xu
24921d34e4bfSDr. David Alan Gilbert /*
24931d34e4bfSDr. David Alan Gilbert * Switch from normal iteration to postcopy
24941d34e4bfSDr. David Alan Gilbert * Returns non-0 on error
24951d34e4bfSDr. David Alan Gilbert */
postcopy_start(MigrationState * ms,Error ** errp)2496908927dbSTejus GK static int postcopy_start(MigrationState *ms, Error **errp)
24971d34e4bfSDr. David Alan Gilbert {
24981d34e4bfSDr. David Alan Gilbert int ret;
249961b67d47SDaniel P. Berrange QIOChannelBuffer *bioc;
250061b67d47SDaniel P. Berrange QEMUFile *fb;
250152033349SJuan Quintela uint64_t bandwidth = migrate_max_postcopy_bandwidth();
2502ef8d6488SDr. David Alan Gilbert bool restart_block = false;
25030331c8caSDr. David Alan Gilbert int cur_state = MIGRATION_STATUS_ACTIVE;
2504d0edb8a1SPeter Xu
25055655aab0SPeter Xu if (migrate_postcopy_preempt()) {
25065655aab0SPeter Xu migration_wait_main_channel(ms);
25075655aab0SPeter Xu if (postcopy_preempt_establish_channel(ms)) {
2508d0edb8a1SPeter Xu migrate_set_state(&ms->state, ms->state, MIGRATION_STATUS_FAILED);
2509d0ad271aSAvihai Horon error_setg(errp, "%s: Failed to establish preempt channel",
2510d0ad271aSAvihai Horon __func__);
2511d0edb8a1SPeter Xu return -1;
2512d0edb8a1SPeter Xu }
25135655aab0SPeter Xu }
2514d0edb8a1SPeter Xu
25150331c8caSDr. David Alan Gilbert if (!migrate_pause_before_switchover()) {
251648781e5bSzhanghailiang migrate_set_state(&ms->state, MIGRATION_STATUS_ACTIVE,
25171d34e4bfSDr. David Alan Gilbert MIGRATION_STATUS_POSTCOPY_ACTIVE);
25180331c8caSDr. David Alan Gilbert }
25191d34e4bfSDr. David Alan Gilbert
25201d34e4bfSDr. David Alan Gilbert trace_postcopy_start();
2521195801d7SStefan Hajnoczi bql_lock();
25221d34e4bfSDr. David Alan Gilbert trace_postcopy_start_set_run();
25231d34e4bfSDr. David Alan Gilbert
25249867d4ddSSteve Sistare ret = migration_stop_vm(ms, RUN_STATE_FINISH_MIGRATE);
252576b1c7feSKevin Wolf if (ret < 0) {
2526d0ad271aSAvihai Horon error_setg_errno(errp, -ret, "%s: Failed to stop the VM", __func__);
252776b1c7feSKevin Wolf goto fail;
252876b1c7feSKevin Wolf }
25291d34e4bfSDr. David Alan Gilbert
25300331c8caSDr. David Alan Gilbert ret = migration_maybe_pause(ms, &cur_state,
25310331c8caSDr. David Alan Gilbert MIGRATION_STATUS_POSTCOPY_ACTIVE);
25320331c8caSDr. David Alan Gilbert if (ret < 0) {
2533d0ad271aSAvihai Horon error_setg_errno(errp, -ret, "%s: Failed in migration_maybe_pause()",
2534d0ad271aSAvihai Horon __func__);
25350331c8caSDr. David Alan Gilbert goto fail;
25360331c8caSDr. David Alan Gilbert }
25370331c8caSDr. David Alan Gilbert
253876b1c7feSKevin Wolf ret = bdrv_inactivate_all();
25391d34e4bfSDr. David Alan Gilbert if (ret < 0) {
2540d0ad271aSAvihai Horon error_setg_errno(errp, -ret, "%s: Failed in bdrv_inactivate_all()",
2541d0ad271aSAvihai Horon __func__);
25421d34e4bfSDr. David Alan Gilbert goto fail;
25431d34e4bfSDr. David Alan Gilbert }
2544ef8d6488SDr. David Alan Gilbert restart_block = true;
25451d34e4bfSDr. David Alan Gilbert
25461d34e4bfSDr. David Alan Gilbert /*
25471c0d249dSDr. David Alan Gilbert * Cause any non-postcopiable, but iterative devices to
25481c0d249dSDr. David Alan Gilbert * send out their final data.
25491c0d249dSDr. David Alan Gilbert */
2550a1fbe750SFam Zheng qemu_savevm_state_complete_precopy(ms->to_dst_file, true, false);
25511c0d249dSDr. David Alan Gilbert
25521c0d249dSDr. David Alan Gilbert /*
25531d34e4bfSDr. David Alan Gilbert * in Finish migrate and with the io-lock held everything should
25541d34e4bfSDr. David Alan Gilbert * be quiet, but we've potentially still got dirty pages and we
25551d34e4bfSDr. David Alan Gilbert * need to tell the destination to throw any pages it's already received
25561d34e4bfSDr. David Alan Gilbert * that are dirty
25571d34e4bfSDr. David Alan Gilbert */
255858110f0aSVladimir Sementsov-Ogievskiy if (migrate_postcopy_ram()) {
2559739fcc1bSPeter Xu ram_postcopy_send_discard_bitmap(ms);
256058110f0aSVladimir Sementsov-Ogievskiy }
25611d34e4bfSDr. David Alan Gilbert
25621d34e4bfSDr. David Alan Gilbert /*
25631d34e4bfSDr. David Alan Gilbert * send rest of state - note things that are doing postcopy
25641d34e4bfSDr. David Alan Gilbert * will notice we're in POSTCOPY_ACTIVE and not actually
25651d34e4bfSDr. David Alan Gilbert * wrap their state up here
25661d34e4bfSDr. David Alan Gilbert */
2567e1fde0e0SJuan Quintela migration_rate_set(bandwidth);
256858110f0aSVladimir Sementsov-Ogievskiy if (migrate_postcopy_ram()) {
25691d34e4bfSDr. David Alan Gilbert /* Ping just for debugging, helps line traces up */
257089a02a9fSzhanghailiang qemu_savevm_send_ping(ms->to_dst_file, 2);
257158110f0aSVladimir Sementsov-Ogievskiy }
25721d34e4bfSDr. David Alan Gilbert
25731d34e4bfSDr. David Alan Gilbert /*
25741d34e4bfSDr. David Alan Gilbert * While loading the device state we may trigger page transfer
25751d34e4bfSDr. David Alan Gilbert * requests and the fd must be free to process those, and thus
25761d34e4bfSDr. David Alan Gilbert * the destination must read the whole device state off the fd before
25771d34e4bfSDr. David Alan Gilbert * it starts processing it. Unfortunately the ad-hoc migration format
25781d34e4bfSDr. David Alan Gilbert * doesn't allow the destination to know the size to read without fully
25791d34e4bfSDr. David Alan Gilbert * parsing it through each devices load-state code (especially the open
25801d34e4bfSDr. David Alan Gilbert * coded devices that use get/put).
25811d34e4bfSDr. David Alan Gilbert * So we wrap the device state up in a package with a length at the start;
25821d34e4bfSDr. David Alan Gilbert * to do this we use a qemu_buf to hold the whole of the device state.
25831d34e4bfSDr. David Alan Gilbert */
258461b67d47SDaniel P. Berrange bioc = qio_channel_buffer_new(4096);
25856f01f136SDaniel P. Berrange qio_channel_set_name(QIO_CHANNEL(bioc), "migration-postcopy-buffer");
258677ef2dc1SDaniel P. Berrangé fb = qemu_file_new_output(QIO_CHANNEL(bioc));
258761b67d47SDaniel P. Berrange object_unref(OBJECT(bioc));
25881d34e4bfSDr. David Alan Gilbert
2589c76201abSDr. David Alan Gilbert /*
2590c76201abSDr. David Alan Gilbert * Make sure the receiver can get incoming pages before we send the rest
2591c76201abSDr. David Alan Gilbert * of the state
2592c76201abSDr. David Alan Gilbert */
2593c76201abSDr. David Alan Gilbert qemu_savevm_send_postcopy_listen(fb);
2594c76201abSDr. David Alan Gilbert
2595a1fbe750SFam Zheng qemu_savevm_state_complete_precopy(fb, false, false);
259658110f0aSVladimir Sementsov-Ogievskiy if (migrate_postcopy_ram()) {
25971d34e4bfSDr. David Alan Gilbert qemu_savevm_send_ping(fb, 3);
259858110f0aSVladimir Sementsov-Ogievskiy }
25991d34e4bfSDr. David Alan Gilbert
26001d34e4bfSDr. David Alan Gilbert qemu_savevm_send_postcopy_run(fb);
26011d34e4bfSDr. David Alan Gilbert
26021d34e4bfSDr. David Alan Gilbert /* <><> end of stuff going into the package */
26031d34e4bfSDr. David Alan Gilbert
2604ef8d6488SDr. David Alan Gilbert /* Last point of recovery; as soon as we send the package the destination
2605ef8d6488SDr. David Alan Gilbert * can open devices and potentially start running.
2606ef8d6488SDr. David Alan Gilbert * Lets just check again we've not got any errors.
2607ef8d6488SDr. David Alan Gilbert */
2608ef8d6488SDr. David Alan Gilbert ret = qemu_file_get_error(ms->to_dst_file);
2609ef8d6488SDr. David Alan Gilbert if (ret) {
2610908927dbSTejus GK error_setg(errp, "postcopy_start: Migration stream errored (pre package)");
2611ef8d6488SDr. David Alan Gilbert goto fail_closefb;
2612ef8d6488SDr. David Alan Gilbert }
2613ef8d6488SDr. David Alan Gilbert
2614ef8d6488SDr. David Alan Gilbert restart_block = false;
2615ef8d6488SDr. David Alan Gilbert
26161d34e4bfSDr. David Alan Gilbert /* Now send that blob */
261761b67d47SDaniel P. Berrange if (qemu_savevm_send_packaged(ms->to_dst_file, bioc->data, bioc->usage)) {
2618d0ad271aSAvihai Horon error_setg(errp, "%s: Failed to send packaged data", __func__);
26191d34e4bfSDr. David Alan Gilbert goto fail_closefb;
26201d34e4bfSDr. David Alan Gilbert }
26211d34e4bfSDr. David Alan Gilbert qemu_fclose(fb);
2622b82fc321SDr. David Alan Gilbert
2623b82fc321SDr. David Alan Gilbert /* Send a notify to give a chance for anything that needs to happen
2624b82fc321SDr. David Alan Gilbert * at the transition to postcopy and after the device state; in particular
2625b82fc321SDr. David Alan Gilbert * spice needs to trigger a transition now
2626b82fc321SDr. David Alan Gilbert */
26274af667f8SSteve Sistare migration_call_notifiers(ms, MIG_EVENT_PRECOPY_DONE, NULL);
2628b82fc321SDr. David Alan Gilbert
2629e22ffad0SPeter Xu migration_downtime_end(ms);
26301d34e4bfSDr. David Alan Gilbert
2631195801d7SStefan Hajnoczi bql_unlock();
26321d34e4bfSDr. David Alan Gilbert
263358110f0aSVladimir Sementsov-Ogievskiy if (migrate_postcopy_ram()) {
26341d34e4bfSDr. David Alan Gilbert /*
26351d34e4bfSDr. David Alan Gilbert * Although this ping is just for debug, it could potentially be
26361d34e4bfSDr. David Alan Gilbert * used for getting a better measurement of downtime at the source.
26371d34e4bfSDr. David Alan Gilbert */
263889a02a9fSzhanghailiang qemu_savevm_send_ping(ms->to_dst_file, 4);
263958110f0aSVladimir Sementsov-Ogievskiy }
26401d34e4bfSDr. David Alan Gilbert
2641ced1c616SPavel Butsykin if (migrate_release_ram()) {
2642ced1c616SPavel Butsykin ram_postcopy_migrated_memory_release(ms);
2643ced1c616SPavel Butsykin }
2644ced1c616SPavel Butsykin
264589a02a9fSzhanghailiang ret = qemu_file_get_error(ms->to_dst_file);
26461d34e4bfSDr. David Alan Gilbert if (ret) {
26474af667f8SSteve Sistare error_setg_errno(errp, -ret, "postcopy_start: Migration stream error");
26484af667f8SSteve Sistare bql_lock();
26494af667f8SSteve Sistare goto fail;
26501d34e4bfSDr. David Alan Gilbert }
2651c01b16edSPeter Xu trace_postcopy_preempt_enabled(migrate_postcopy_preempt());
2652c01b16edSPeter Xu
26531d34e4bfSDr. David Alan Gilbert return ret;
26541d34e4bfSDr. David Alan Gilbert
26551d34e4bfSDr. David Alan Gilbert fail_closefb:
26561d34e4bfSDr. David Alan Gilbert qemu_fclose(fb);
26571d34e4bfSDr. David Alan Gilbert fail:
265848781e5bSzhanghailiang migrate_set_state(&ms->state, MIGRATION_STATUS_POSTCOPY_ACTIVE,
26591d34e4bfSDr. David Alan Gilbert MIGRATION_STATUS_FAILED);
2660ef8d6488SDr. David Alan Gilbert if (restart_block) {
2661ef8d6488SDr. David Alan Gilbert /* A failure happened early enough that we know the destination hasn't
2662ef8d6488SDr. David Alan Gilbert * accessed block devices, so we're safe to recover.
2663ef8d6488SDr. David Alan Gilbert */
2664ef8d6488SDr. David Alan Gilbert Error *local_err = NULL;
2665ef8d6488SDr. David Alan Gilbert
26663b717194SEmanuele Giuseppe Esposito bdrv_activate_all(&local_err);
2667ef8d6488SDr. David Alan Gilbert if (local_err) {
2668ef8d6488SDr. David Alan Gilbert error_report_err(local_err);
2669ef8d6488SDr. David Alan Gilbert }
2670ef8d6488SDr. David Alan Gilbert }
26714af667f8SSteve Sistare migration_call_notifiers(ms, MIG_EVENT_PRECOPY_FAILED, NULL);
2672195801d7SStefan Hajnoczi bql_unlock();
26731d34e4bfSDr. David Alan Gilbert return -1;
26741d34e4bfSDr. David Alan Gilbert }
26751d34e4bfSDr. David Alan Gilbert
267609f6c85eSDr. David Alan Gilbert /**
2677e91d8951SDr. David Alan Gilbert * migration_maybe_pause: Pause if required to by
2678a4a411fbSStefan Hajnoczi * migrate_pause_before_switchover called with the BQL locked
2679e91d8951SDr. David Alan Gilbert * Returns: 0 on success
2680e91d8951SDr. David Alan Gilbert */
migration_maybe_pause(MigrationState * s,int * current_active_state,int new_state)26810331c8caSDr. David Alan Gilbert static int migration_maybe_pause(MigrationState *s,
26820331c8caSDr. David Alan Gilbert int *current_active_state,
26830331c8caSDr. David Alan Gilbert int new_state)
2684e91d8951SDr. David Alan Gilbert {
2685e91d8951SDr. David Alan Gilbert if (!migrate_pause_before_switchover()) {
2686e91d8951SDr. David Alan Gilbert return 0;
2687e91d8951SDr. David Alan Gilbert }
2688e91d8951SDr. David Alan Gilbert
2689e91d8951SDr. David Alan Gilbert /* Since leaving this state is not atomic with posting the semaphore
2690e91d8951SDr. David Alan Gilbert * it's possible that someone could have issued multiple migrate_continue
2691e91d8951SDr. David Alan Gilbert * and the semaphore is incorrectly positive at this point;
2692e91d8951SDr. David Alan Gilbert * the docs say it's undefined to reinit a semaphore that's already
2693e91d8951SDr. David Alan Gilbert * init'd, so use timedwait to eat up any existing posts.
2694e91d8951SDr. David Alan Gilbert */
2695e91d8951SDr. David Alan Gilbert while (qemu_sem_timedwait(&s->pause_sem, 1) == 0) {
2696e91d8951SDr. David Alan Gilbert /* This block intentionally left blank */
2697e91d8951SDr. David Alan Gilbert }
2698e91d8951SDr. David Alan Gilbert
26998958338bSZhimin Feng /*
27008958338bSZhimin Feng * If the migration is cancelled when it is in the completion phase,
27018958338bSZhimin Feng * the migration state is set to MIGRATION_STATUS_CANCELLING.
27028958338bSZhimin Feng * So we don't need to wait a semaphore, otherwise we would always
27038958338bSZhimin Feng * wait for the 'pause_sem' semaphore.
27048958338bSZhimin Feng */
27058958338bSZhimin Feng if (s->state != MIGRATION_STATUS_CANCELLING) {
2706195801d7SStefan Hajnoczi bql_unlock();
2707e91d8951SDr. David Alan Gilbert migrate_set_state(&s->state, *current_active_state,
2708e91d8951SDr. David Alan Gilbert MIGRATION_STATUS_PRE_SWITCHOVER);
2709e91d8951SDr. David Alan Gilbert qemu_sem_wait(&s->pause_sem);
2710e91d8951SDr. David Alan Gilbert migrate_set_state(&s->state, MIGRATION_STATUS_PRE_SWITCHOVER,
27110331c8caSDr. David Alan Gilbert new_state);
27120331c8caSDr. David Alan Gilbert *current_active_state = new_state;
2713195801d7SStefan Hajnoczi bql_lock();
27148958338bSZhimin Feng }
2715e91d8951SDr. David Alan Gilbert
27160331c8caSDr. David Alan Gilbert return s->state == new_state ? 0 : -EINVAL;
2717e91d8951SDr. David Alan Gilbert }
2718e91d8951SDr. David Alan Gilbert
migration_completion_precopy(MigrationState * s,int * current_active_state)2719d7f5a043SWei Wang static int migration_completion_precopy(MigrationState *s,
2720d7f5a043SWei Wang int *current_active_state)
272109f6c85eSDr. David Alan Gilbert {
272209f6c85eSDr. David Alan Gilbert int ret;
272309f6c85eSDr. David Alan Gilbert
2724195801d7SStefan Hajnoczi bql_lock();
2725f4584076SVladimir Sementsov-Ogievskiy
27269867d4ddSSteve Sistare if (!migrate_mode_is_cpr(s)) {
27279867d4ddSSteve Sistare ret = migration_stop_vm(s, RUN_STATE_FINISH_MIGRATE);
2728d7f5a043SWei Wang if (ret < 0) {
2729d7f5a043SWei Wang goto out_unlock;
2730e91d8951SDr. David Alan Gilbert }
27319867d4ddSSteve Sistare }
2732d7f5a043SWei Wang
2733d7f5a043SWei Wang ret = migration_maybe_pause(s, current_active_state,
2734d7f5a043SWei Wang MIGRATION_STATUS_DEVICE);
2735d7f5a043SWei Wang if (ret < 0) {
2736d7f5a043SWei Wang goto out_unlock;
2737d7f5a043SWei Wang }
2738d7f5a043SWei Wang
27396dab4c93SEric Blake /*
2740d7f5a043SWei Wang * Inactivate disks except in COLO, and track that we have done so in order
2741d7f5a043SWei Wang * to remember to reactivate them if migration fails or is cancelled.
27426dab4c93SEric Blake */
27435e804644SJuan Quintela s->block_inactive = !migrate_colo();
2744e1fde0e0SJuan Quintela migration_rate_set(RATE_LIMIT_DISABLED);
2745a1fbe750SFam Zheng ret = qemu_savevm_state_complete_precopy(s->to_dst_file, false,
27465d39f44dSEric Blake s->block_inactive);
2747d7f5a043SWei Wang out_unlock:
2748195801d7SStefan Hajnoczi bql_unlock();
2749d7f5a043SWei Wang return ret;
275009f6c85eSDr. David Alan Gilbert }
2751d7f5a043SWei Wang
migration_completion_postcopy(MigrationState * s)2752d7f5a043SWei Wang static void migration_completion_postcopy(MigrationState *s)
2753d7f5a043SWei Wang {
2754b10ac0c4SDr. David Alan Gilbert trace_migration_completion_postcopy_end();
2755b10ac0c4SDr. David Alan Gilbert
2756195801d7SStefan Hajnoczi bql_lock();
275789a02a9fSzhanghailiang qemu_savevm_state_complete_postcopy(s->to_dst_file);
2758195801d7SStefan Hajnoczi bql_unlock();
275968b88468SEmanuele Giuseppe Esposito
27606621883fSPeter Xu /*
2761d7f5a043SWei Wang * Shutdown the postcopy fast path thread. This is only needed when dest
2762d7f5a043SWei Wang * QEMU binary is old (7.1/7.2). QEMU 8.0+ doesn't need this.
27636621883fSPeter Xu */
27646621883fSPeter Xu if (migrate_postcopy_preempt() && s->preempt_pre_7_2) {
276536f62f11SPeter Xu postcopy_preempt_shutdown_file(s);
276636f62f11SPeter Xu }
276736f62f11SPeter Xu
2768b10ac0c4SDr. David Alan Gilbert trace_migration_completion_postcopy_end_after_complete();
2769b10ac0c4SDr. David Alan Gilbert }
2770b10ac0c4SDr. David Alan Gilbert
migration_completion_failed(MigrationState * s,int current_active_state)2771d7f5a043SWei Wang static void migration_completion_failed(MigrationState *s,
2772d7f5a043SWei Wang int current_active_state)
2773d7f5a043SWei Wang {
27746dab4c93SEric Blake if (s->block_inactive && (s->state == MIGRATION_STATUS_ACTIVE ||
27756dab4c93SEric Blake s->state == MIGRATION_STATUS_DEVICE)) {
27766dab4c93SEric Blake /*
27776dab4c93SEric Blake * If not doing postcopy, vm_start() will be called: let's
27786dab4c93SEric Blake * regain control on images.
2779fe904ea8SGreg Kurz */
2780fe904ea8SGreg Kurz Error *local_err = NULL;
2781fe904ea8SGreg Kurz
2782195801d7SStefan Hajnoczi bql_lock();
27833b717194SEmanuele Giuseppe Esposito bdrv_activate_all(&local_err);
2784fe904ea8SGreg Kurz if (local_err) {
2785fe904ea8SGreg Kurz error_report_err(local_err);
27861d2acc31Szhanghailiang } else {
27871d2acc31Szhanghailiang s->block_inactive = false;
2788fe904ea8SGreg Kurz }
2789195801d7SStefan Hajnoczi bql_unlock();
2790fe904ea8SGreg Kurz }
2791fe904ea8SGreg Kurz
279248781e5bSzhanghailiang migrate_set_state(&s->state, current_active_state,
279348781e5bSzhanghailiang MIGRATION_STATUS_FAILED);
279409f6c85eSDr. David Alan Gilbert }
279509f6c85eSDr. David Alan Gilbert
27968518278aSAndrey Gruzdev /**
2797d7f5a043SWei Wang * migration_completion: Used by migration_thread when there's not much left.
2798d7f5a043SWei Wang * The caller 'breaks' the loop when this returns.
2799d7f5a043SWei Wang *
2800d7f5a043SWei Wang * @s: Current migration state
2801d7f5a043SWei Wang */
migration_completion(MigrationState * s)2802d7f5a043SWei Wang static void migration_completion(MigrationState *s)
2803d7f5a043SWei Wang {
2804d7f5a043SWei Wang int ret = 0;
2805d7f5a043SWei Wang int current_active_state = s->state;
280630158d88SAvihai Horon Error *local_err = NULL;
2807d7f5a043SWei Wang
2808d7f5a043SWei Wang if (s->state == MIGRATION_STATUS_ACTIVE) {
2809d7f5a043SWei Wang ret = migration_completion_precopy(s, ¤t_active_state);
2810d7f5a043SWei Wang } else if (s->state == MIGRATION_STATUS_POSTCOPY_ACTIVE) {
2811d7f5a043SWei Wang migration_completion_postcopy(s);
2812d7f5a043SWei Wang } else {
2813d7f5a043SWei Wang ret = -1;
2814d7f5a043SWei Wang }
2815d7f5a043SWei Wang
2816d7f5a043SWei Wang if (ret < 0) {
2817d7f5a043SWei Wang goto fail;
2818d7f5a043SWei Wang }
2819d7f5a043SWei Wang
2820d7f5a043SWei Wang if (close_return_path_on_source(s)) {
2821d7f5a043SWei Wang goto fail;
2822d7f5a043SWei Wang }
2823d7f5a043SWei Wang
2824d7f5a043SWei Wang if (qemu_file_get_error(s->to_dst_file)) {
2825d7f5a043SWei Wang trace_migration_completion_file_err();
2826d7f5a043SWei Wang goto fail;
2827d7f5a043SWei Wang }
2828d7f5a043SWei Wang
2829d7f5a043SWei Wang if (migrate_colo() && s->state == MIGRATION_STATUS_ACTIVE) {
2830d7f5a043SWei Wang /* COLO does not support postcopy */
2831d7f5a043SWei Wang migrate_set_state(&s->state, MIGRATION_STATUS_ACTIVE,
2832d7f5a043SWei Wang MIGRATION_STATUS_COLO);
2833d7f5a043SWei Wang } else {
283463f64d77SFabiano Rosas migration_completion_end(s);
2835d7f5a043SWei Wang }
2836d7f5a043SWei Wang
2837d7f5a043SWei Wang return;
2838d7f5a043SWei Wang
2839d7f5a043SWei Wang fail:
284030158d88SAvihai Horon if (qemu_file_get_error_obj(s->to_dst_file, &local_err)) {
284130158d88SAvihai Horon migrate_set_error(s, local_err);
284230158d88SAvihai Horon error_free(local_err);
284330158d88SAvihai Horon } else if (ret) {
284430158d88SAvihai Horon error_setg_errno(&local_err, -ret, "Error in migration completion");
284530158d88SAvihai Horon migrate_set_error(s, local_err);
284630158d88SAvihai Horon error_free(local_err);
284730158d88SAvihai Horon }
284830158d88SAvihai Horon
2849d7f5a043SWei Wang migration_completion_failed(s, current_active_state);
2850d7f5a043SWei Wang }
2851d7f5a043SWei Wang
2852d7f5a043SWei Wang /**
28538518278aSAndrey Gruzdev * bg_migration_completion: Used by bg_migration_thread when after all the
28548518278aSAndrey Gruzdev * RAM has been saved. The caller 'breaks' the loop when this returns.
28558518278aSAndrey Gruzdev *
28568518278aSAndrey Gruzdev * @s: Current migration state
28578518278aSAndrey Gruzdev */
bg_migration_completion(MigrationState * s)28588518278aSAndrey Gruzdev static void bg_migration_completion(MigrationState *s)
28598518278aSAndrey Gruzdev {
28608518278aSAndrey Gruzdev int current_active_state = s->state;
28618518278aSAndrey Gruzdev
28628518278aSAndrey Gruzdev if (s->state == MIGRATION_STATUS_ACTIVE) {
28638518278aSAndrey Gruzdev /*
28648518278aSAndrey Gruzdev * By this moment we have RAM content saved into the migration stream.
28658518278aSAndrey Gruzdev * The next step is to flush the non-RAM content (device state)
28668518278aSAndrey Gruzdev * right after the ram content. The device state has been stored into
28678518278aSAndrey Gruzdev * the temporary buffer before RAM saving started.
28688518278aSAndrey Gruzdev */
28698518278aSAndrey Gruzdev qemu_put_buffer(s->to_dst_file, s->bioc->data, s->bioc->usage);
28708518278aSAndrey Gruzdev qemu_fflush(s->to_dst_file);
28718518278aSAndrey Gruzdev } else if (s->state == MIGRATION_STATUS_CANCELLING) {
28728518278aSAndrey Gruzdev goto fail;
28738518278aSAndrey Gruzdev }
28748518278aSAndrey Gruzdev
28758518278aSAndrey Gruzdev if (qemu_file_get_error(s->to_dst_file)) {
28768518278aSAndrey Gruzdev trace_migration_completion_file_err();
28778518278aSAndrey Gruzdev goto fail;
28788518278aSAndrey Gruzdev }
28798518278aSAndrey Gruzdev
288063f64d77SFabiano Rosas migration_completion_end(s);
28818518278aSAndrey Gruzdev return;
28828518278aSAndrey Gruzdev
28838518278aSAndrey Gruzdev fail:
28848518278aSAndrey Gruzdev migrate_set_state(&s->state, current_active_state,
28858518278aSAndrey Gruzdev MIGRATION_STATUS_FAILED);
28868518278aSAndrey Gruzdev }
28878518278aSAndrey Gruzdev
2888b23c2adeSPeter Xu typedef enum MigThrError {
2889b23c2adeSPeter Xu /* No error detected */
2890b23c2adeSPeter Xu MIG_THR_ERR_NONE = 0,
2891b23c2adeSPeter Xu /* Detected error, but resumed successfully */
2892b23c2adeSPeter Xu MIG_THR_ERR_RECOVERED = 1,
2893b23c2adeSPeter Xu /* Detected fatal error, need to exit */
2894b23c2adeSPeter Xu MIG_THR_ERR_FATAL = 2,
2895b23c2adeSPeter Xu } MigThrError;
2896b23c2adeSPeter Xu
postcopy_resume_handshake(MigrationState * s)289794190696SPeter Xu static int postcopy_resume_handshake(MigrationState *s)
289894190696SPeter Xu {
289994190696SPeter Xu qemu_savevm_send_postcopy_resume(s->to_dst_file);
290094190696SPeter Xu
290194190696SPeter Xu while (s->state == MIGRATION_STATUS_POSTCOPY_RECOVER) {
2902f8c543e8SPeter Xu if (migration_rp_wait(s)) {
2903f8c543e8SPeter Xu return -1;
2904f8c543e8SPeter Xu }
290594190696SPeter Xu }
290694190696SPeter Xu
290794190696SPeter Xu if (s->state == MIGRATION_STATUS_POSTCOPY_ACTIVE) {
290894190696SPeter Xu return 0;
290994190696SPeter Xu }
291094190696SPeter Xu
291194190696SPeter Xu return -1;
291294190696SPeter Xu }
291394190696SPeter Xu
2914135b87b4SPeter Xu /* Return zero if success, or <0 for error */
postcopy_do_resume(MigrationState * s)2915135b87b4SPeter Xu static int postcopy_do_resume(MigrationState *s)
2916135b87b4SPeter Xu {
2917d1b8eadbSPeter Xu int ret;
2918d1b8eadbSPeter Xu
2919d1b8eadbSPeter Xu /*
2920d1b8eadbSPeter Xu * Call all the resume_prepare() hooks, so that modules can be
2921d1b8eadbSPeter Xu * ready for the migration resume.
2922d1b8eadbSPeter Xu */
2923d1b8eadbSPeter Xu ret = qemu_savevm_state_resume_prepare(s);
2924d1b8eadbSPeter Xu if (ret) {
2925d1b8eadbSPeter Xu error_report("%s: resume_prepare() failure detected: %d",
2926d1b8eadbSPeter Xu __func__, ret);
2927d1b8eadbSPeter Xu return ret;
2928d1b8eadbSPeter Xu }
2929d1b8eadbSPeter Xu
2930d1b8eadbSPeter Xu /*
29315655aab0SPeter Xu * If preempt is enabled, re-establish the preempt channel. Note that
29325655aab0SPeter Xu * we do it after resume prepare to make sure the main channel will be
29335655aab0SPeter Xu * created before the preempt channel. E.g. with weak network, the
29345655aab0SPeter Xu * dest QEMU may get messed up with the preempt and main channels on
29355655aab0SPeter Xu * the order of connection setup. This guarantees the correct order.
29365655aab0SPeter Xu */
29375655aab0SPeter Xu ret = postcopy_preempt_establish_channel(s);
29385655aab0SPeter Xu if (ret) {
29395655aab0SPeter Xu error_report("%s: postcopy_preempt_establish_channel(): %d",
29405655aab0SPeter Xu __func__, ret);
29415655aab0SPeter Xu return ret;
29425655aab0SPeter Xu }
29435655aab0SPeter Xu
29445655aab0SPeter Xu /*
294594190696SPeter Xu * Last handshake with destination on the resume (destination will
294694190696SPeter Xu * switch to postcopy-active afterwards)
2947d1b8eadbSPeter Xu */
294894190696SPeter Xu ret = postcopy_resume_handshake(s);
294994190696SPeter Xu if (ret) {
295094190696SPeter Xu error_report("%s: handshake failed: %d", __func__, ret);
295194190696SPeter Xu return ret;
295294190696SPeter Xu }
2953d1b8eadbSPeter Xu
2954135b87b4SPeter Xu return 0;
2955135b87b4SPeter Xu }
2956135b87b4SPeter Xu
2957b23c2adeSPeter Xu /*
2958b23c2adeSPeter Xu * We don't return until we are in a safe state to continue current
2959b23c2adeSPeter Xu * postcopy migration. Returns MIG_THR_ERR_RECOVERED if recovered, or
2960b23c2adeSPeter Xu * MIG_THR_ERR_FATAL if unrecovery failure happened.
2961b23c2adeSPeter Xu */
postcopy_pause(MigrationState * s)2962b23c2adeSPeter Xu static MigThrError postcopy_pause(MigrationState *s)
2963b23c2adeSPeter Xu {
2964b23c2adeSPeter Xu assert(s->state == MIGRATION_STATUS_POSTCOPY_ACTIVE);
2965135b87b4SPeter Xu
2966135b87b4SPeter Xu while (true) {
296762df066fSPeter Xu QEMUFile *file;
296862df066fSPeter Xu
296939675fffSPeter Xu /*
297022b04245SFabiano Rosas * We're already pausing, so ignore any errors on the return
297122b04245SFabiano Rosas * path and just wait for the thread to finish. It will be
297222b04245SFabiano Rosas * re-created when we resume.
297322b04245SFabiano Rosas */
297422b04245SFabiano Rosas close_return_path_on_source(s);
297522b04245SFabiano Rosas
297622b04245SFabiano Rosas /*
297739675fffSPeter Xu * Current channel is possibly broken. Release it. Note that this is
297839675fffSPeter Xu * guaranteed even without lock because to_dst_file should only be
297939675fffSPeter Xu * modified by the migration thread. That also guarantees that the
298039675fffSPeter Xu * unregister of yank is safe too without the lock. It should be safe
298139675fffSPeter Xu * even to be within the qemu_file_lock, but we didn't do that to avoid
298239675fffSPeter Xu * taking more mutex (yank_lock) within qemu_file_lock. TL;DR: we make
298339675fffSPeter Xu * the qemu_file_lock critical section as small as possible.
298439675fffSPeter Xu */
2985b23c2adeSPeter Xu assert(s->to_dst_file);
298639675fffSPeter Xu migration_ioc_unregister_yank_from_file(s->to_dst_file);
298762df066fSPeter Xu qemu_mutex_lock(&s->qemu_file_lock);
298862df066fSPeter Xu file = s->to_dst_file;
2989b23c2adeSPeter Xu s->to_dst_file = NULL;
299062df066fSPeter Xu qemu_mutex_unlock(&s->qemu_file_lock);
299162df066fSPeter Xu
299262df066fSPeter Xu qemu_file_shutdown(file);
299362df066fSPeter Xu qemu_fclose(file);
2994b23c2adeSPeter Xu
2995d246ea50SPeter Xu migrate_set_state(&s->state, s->state,
2996d246ea50SPeter Xu MIGRATION_STATUS_POSTCOPY_PAUSED);
2997d246ea50SPeter Xu
2998b23c2adeSPeter Xu error_report("Detected IO failure for postcopy. "
2999b23c2adeSPeter Xu "Migration paused.");
3000b23c2adeSPeter Xu
3001b23c2adeSPeter Xu /*
3002b23c2adeSPeter Xu * We wait until things fixed up. Then someone will setup the
3003b23c2adeSPeter Xu * status back for us.
3004b23c2adeSPeter Xu */
30054146b77eSPeter Xu do {
3006b23c2adeSPeter Xu qemu_sem_wait(&s->postcopy_pause_sem);
30074146b77eSPeter Xu } while (postcopy_is_paused(s->state));
3008b23c2adeSPeter Xu
3009135b87b4SPeter Xu if (s->state == MIGRATION_STATUS_POSTCOPY_RECOVER) {
3010135b87b4SPeter Xu /* Woken up by a recover procedure. Give it a shot */
3011b23c2adeSPeter Xu
3012135b87b4SPeter Xu /* Do the resume logic */
3013135b87b4SPeter Xu if (postcopy_do_resume(s) == 0) {
3014135b87b4SPeter Xu /* Let's continue! */
3015135b87b4SPeter Xu trace_postcopy_pause_continued();
3016b23c2adeSPeter Xu return MIG_THR_ERR_RECOVERED;
3017135b87b4SPeter Xu } else {
3018135b87b4SPeter Xu /*
3019135b87b4SPeter Xu * Something wrong happened during the recovery, let's
3020135b87b4SPeter Xu * pause again. Pause is always better than throwing
3021135b87b4SPeter Xu * data away.
3022135b87b4SPeter Xu */
3023135b87b4SPeter Xu continue;
3024135b87b4SPeter Xu }
3025135b87b4SPeter Xu } else {
3026135b87b4SPeter Xu /* This is not right... Time to quit. */
3027135b87b4SPeter Xu return MIG_THR_ERR_FATAL;
3028135b87b4SPeter Xu }
3029135b87b4SPeter Xu }
3030b23c2adeSPeter Xu }
3031b23c2adeSPeter Xu
migration_file_set_error(int ret,Error * err)3032019d9e6cSCédric Le Goater void migration_file_set_error(int ret, Error *err)
303320c64c8aSSteve Sistare {
303420c64c8aSSteve Sistare MigrationState *s = current_migration;
303520c64c8aSSteve Sistare
303620c64c8aSSteve Sistare WITH_QEMU_LOCK_GUARD(&s->qemu_file_lock) {
303720c64c8aSSteve Sistare if (s->to_dst_file) {
3038019d9e6cSCédric Le Goater qemu_file_set_error_obj(s->to_dst_file, ret, err);
3039019d9e6cSCédric Le Goater } else if (err) {
3040019d9e6cSCédric Le Goater error_report_err(err);
304120c64c8aSSteve Sistare }
304220c64c8aSSteve Sistare }
304320c64c8aSSteve Sistare }
304420c64c8aSSteve Sistare
migration_detect_error(MigrationState * s)3045b23c2adeSPeter Xu static MigThrError migration_detect_error(MigrationState *s)
3046b23c2adeSPeter Xu {
3047b23c2adeSPeter Xu int ret;
3048c3c5eae6SDr. David Alan Gilbert int state = s->state;
30493d661c8aSYury Kotov Error *local_error = NULL;
3050c3c5eae6SDr. David Alan Gilbert
3051c3c5eae6SDr. David Alan Gilbert if (state == MIGRATION_STATUS_CANCELLING ||
3052c3c5eae6SDr. David Alan Gilbert state == MIGRATION_STATUS_CANCELLED) {
3053c3c5eae6SDr. David Alan Gilbert /* End the migration, but don't set the state to failed */
3054c3c5eae6SDr. David Alan Gilbert return MIG_THR_ERR_FATAL;
3055c3c5eae6SDr. David Alan Gilbert }
3056b23c2adeSPeter Xu
305760bb3c58SPeter Xu /*
305860bb3c58SPeter Xu * Try to detect any file errors. Note that postcopy_qemufile_src will
305960bb3c58SPeter Xu * be NULL when postcopy preempt is not enabled.
306060bb3c58SPeter Xu */
306160bb3c58SPeter Xu ret = qemu_file_get_error_obj_any(s->to_dst_file,
306260bb3c58SPeter Xu s->postcopy_qemufile_src,
306360bb3c58SPeter Xu &local_error);
3064b23c2adeSPeter Xu if (!ret) {
3065b23c2adeSPeter Xu /* Everything is fine */
30663d661c8aSYury Kotov assert(!local_error);
3067b23c2adeSPeter Xu return MIG_THR_ERR_NONE;
3068b23c2adeSPeter Xu }
3069b23c2adeSPeter Xu
30703d661c8aSYury Kotov if (local_error) {
30713d661c8aSYury Kotov migrate_set_error(s, local_error);
30723d661c8aSYury Kotov error_free(local_error);
30733d661c8aSYury Kotov }
30743d661c8aSYury Kotov
3075d5c8f2afSPeter Xu if (state == MIGRATION_STATUS_POSTCOPY_ACTIVE && ret) {
3076b23c2adeSPeter Xu /*
3077b23c2adeSPeter Xu * For postcopy, we allow the network to be down for a
3078b23c2adeSPeter Xu * while. After that, it can be continued by a
3079b23c2adeSPeter Xu * recovery phase.
3080b23c2adeSPeter Xu */
3081b23c2adeSPeter Xu return postcopy_pause(s);
3082b23c2adeSPeter Xu } else {
3083b23c2adeSPeter Xu /*
3084b23c2adeSPeter Xu * For precopy (or postcopy with error outside IO), we fail
3085b23c2adeSPeter Xu * with no time.
3086b23c2adeSPeter Xu */
3087c3c5eae6SDr. David Alan Gilbert migrate_set_state(&s->state, state, MIGRATION_STATUS_FAILED);
3088b23c2adeSPeter Xu trace_migration_thread_file_err();
3089b23c2adeSPeter Xu
3090b23c2adeSPeter Xu /* Time to stop the migration, now. */
3091b23c2adeSPeter Xu return MIG_THR_ERR_FATAL;
3092b23c2adeSPeter Xu }
3093b23c2adeSPeter Xu }
3094b23c2adeSPeter Xu
migration_completion_end(MigrationState * s)309563f64d77SFabiano Rosas static void migration_completion_end(MigrationState *s)
3096cf011f08SPeter Xu {
3097f57e5a6cSJuan Quintela uint64_t bytes = migration_transferred_bytes();
3098cf011f08SPeter Xu int64_t end_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
30996cde6fbeSJuan Quintela int64_t transfer_time;
3100cf011f08SPeter Xu
310163f64d77SFabiano Rosas /*
310263f64d77SFabiano Rosas * Take the BQL here so that query-migrate on the QMP thread sees:
310363f64d77SFabiano Rosas * - atomic update of s->total_time and s->mbps;
310463f64d77SFabiano Rosas * - correct ordering of s->mbps update vs. s->state;
310563f64d77SFabiano Rosas */
310663f64d77SFabiano Rosas bql_lock();
3107e22ffad0SPeter Xu migration_downtime_end(s);
3108cf011f08SPeter Xu s->total_time = end_time - s->start_time;
31096cde6fbeSJuan Quintela transfer_time = s->total_time - s->setup_time;
31106cde6fbeSJuan Quintela if (transfer_time) {
31116cde6fbeSJuan Quintela s->mbps = ((double) bytes * 8.0) / transfer_time / 1000;
3112cf011f08SPeter Xu }
311363f64d77SFabiano Rosas
311463f64d77SFabiano Rosas migrate_set_state(&s->state, s->state,
311563f64d77SFabiano Rosas MIGRATION_STATUS_COMPLETED);
311663f64d77SFabiano Rosas bql_unlock();
3117cf011f08SPeter Xu }
3118cf011f08SPeter Xu
update_iteration_initial_status(MigrationState * s)311987f3bd87SIvan Ren static void update_iteration_initial_status(MigrationState *s)
312087f3bd87SIvan Ren {
312187f3bd87SIvan Ren /*
312287f3bd87SIvan Ren * Update these three fields at the same time to avoid mismatch info lead
312387f3bd87SIvan Ren * wrong speed calculation.
312487f3bd87SIvan Ren */
312587f3bd87SIvan Ren s->iteration_start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
3126f57e5a6cSJuan Quintela s->iteration_initial_bytes = migration_transferred_bytes();
312787f3bd87SIvan Ren s->iteration_initial_pages = ram_get_total_transferred_pages();
312887f3bd87SIvan Ren }
312987f3bd87SIvan Ren
migration_update_counters(MigrationState * s,int64_t current_time)3130b15df1aeSPeter Xu static void migration_update_counters(MigrationState *s,
3131b15df1aeSPeter Xu int64_t current_time)
3132b15df1aeSPeter Xu {
3133aecbfe9cSXiao Guangrong uint64_t transferred, transferred_pages, time_spent;
31340c8f0efdSJuan Quintela uint64_t current_bytes; /* bytes transferred since the beginning */
31358b239597SPeter Xu uint64_t switchover_bw;
31368b239597SPeter Xu /* Expected bandwidth when switching over to destination QEMU */
31378b239597SPeter Xu double expected_bw_per_ms;
3138b15df1aeSPeter Xu double bandwidth;
3139b15df1aeSPeter Xu
3140b15df1aeSPeter Xu if (current_time < s->iteration_start_time + BUFFER_DELAY) {
3141b15df1aeSPeter Xu return;
3142b15df1aeSPeter Xu }
3143b15df1aeSPeter Xu
31448b239597SPeter Xu switchover_bw = migrate_avail_switchover_bandwidth();
3145f57e5a6cSJuan Quintela current_bytes = migration_transferred_bytes();
31460c8f0efdSJuan Quintela transferred = current_bytes - s->iteration_initial_bytes;
3147b15df1aeSPeter Xu time_spent = current_time - s->iteration_start_time;
3148b15df1aeSPeter Xu bandwidth = (double)transferred / time_spent;
31498b239597SPeter Xu
31508b239597SPeter Xu if (switchover_bw) {
31518b239597SPeter Xu /*
31528b239597SPeter Xu * If the user specified a switchover bandwidth, let's trust the
31538b239597SPeter Xu * user so that can be more accurate than what we estimated.
31548b239597SPeter Xu */
31558b239597SPeter Xu expected_bw_per_ms = switchover_bw / 1000;
31568b239597SPeter Xu } else {
31578b239597SPeter Xu /* If the user doesn't specify bandwidth, we use the estimated */
31588b239597SPeter Xu expected_bw_per_ms = bandwidth;
31598b239597SPeter Xu }
31608b239597SPeter Xu
31618b239597SPeter Xu s->threshold_size = expected_bw_per_ms * migrate_downtime_limit();
3162b15df1aeSPeter Xu
3163b15df1aeSPeter Xu s->mbps = (((double) transferred * 8.0) /
3164b15df1aeSPeter Xu ((double) time_spent / 1000.0)) / 1000.0 / 1000.0;
3165b15df1aeSPeter Xu
3166aecbfe9cSXiao Guangrong transferred_pages = ram_get_total_transferred_pages() -
3167aecbfe9cSXiao Guangrong s->iteration_initial_pages;
3168aecbfe9cSXiao Guangrong s->pages_per_second = (double) transferred_pages /
3169aecbfe9cSXiao Guangrong (((double) time_spent / 1000.0));
3170aecbfe9cSXiao Guangrong
3171b15df1aeSPeter Xu /*
3172b15df1aeSPeter Xu * if we haven't sent anything, we don't want to
3173b15df1aeSPeter Xu * recalculate. 10000 is a small enough number for our purposes
3174b15df1aeSPeter Xu */
3175aff3f660SJuan Quintela if (stat64_get(&mig_stats.dirty_pages_rate) &&
317672f8e587SJuan Quintela transferred > 10000) {
317773208a33SJuan Quintela s->expected_downtime =
31788b239597SPeter Xu stat64_get(&mig_stats.dirty_bytes_last_sync) / expected_bw_per_ms;
3179b15df1aeSPeter Xu }
3180b15df1aeSPeter Xu
31810743f41fSJuan Quintela migration_rate_reset();
3182b15df1aeSPeter Xu
318387f3bd87SIvan Ren update_iteration_initial_status(s);
3184b15df1aeSPeter Xu
3185b15df1aeSPeter Xu trace_migrate_transferred(transferred, time_spent,
31868b239597SPeter Xu /* Both in unit bytes/ms */
31878b239597SPeter Xu bandwidth, switchover_bw / 1000,
31888b239597SPeter Xu s->threshold_size);
3189b15df1aeSPeter Xu }
3190b15df1aeSPeter Xu
migration_can_switchover(MigrationState * s)31911b4adb10SAvihai Horon static bool migration_can_switchover(MigrationState *s)
31921b4adb10SAvihai Horon {
31931b4adb10SAvihai Horon if (!migrate_switchover_ack()) {
31941b4adb10SAvihai Horon return true;
31951b4adb10SAvihai Horon }
31961b4adb10SAvihai Horon
31971b4adb10SAvihai Horon /* No reason to wait for switchover ACK if VM is stopped */
31981b4adb10SAvihai Horon if (!runstate_is_running()) {
31991b4adb10SAvihai Horon return true;
32001b4adb10SAvihai Horon }
32011b4adb10SAvihai Horon
32021b4adb10SAvihai Horon return s->switchover_acked;
32031b4adb10SAvihai Horon }
32041b4adb10SAvihai Horon
32052ad87305SPeter Xu /* Migration thread iteration status */
32062ad87305SPeter Xu typedef enum {
32072ad87305SPeter Xu MIG_ITERATE_RESUME, /* Resume current iteration */
32082ad87305SPeter Xu MIG_ITERATE_SKIP, /* Skip current iteration */
32092ad87305SPeter Xu MIG_ITERATE_BREAK, /* Break the loop */
32102ad87305SPeter Xu } MigIterateState;
32112ad87305SPeter Xu
32122ad87305SPeter Xu /*
32132ad87305SPeter Xu * Return true if continue to the next iteration directly, false
32142ad87305SPeter Xu * otherwise.
32152ad87305SPeter Xu */
migration_iteration_run(MigrationState * s)32162ad87305SPeter Xu static MigIterateState migration_iteration_run(MigrationState *s)
32172ad87305SPeter Xu {
3218910c1647SPeter Xu uint64_t must_precopy, can_postcopy, pending_size;
3219908927dbSTejus GK Error *local_err = NULL;
32202ad87305SPeter Xu bool in_postcopy = s->state == MIGRATION_STATUS_POSTCOPY_ACTIVE;
32211b4adb10SAvihai Horon bool can_switchover = migration_can_switchover(s);
32222ad87305SPeter Xu
322324beea4eSJuan Quintela qemu_savevm_state_pending_estimate(&must_precopy, &can_postcopy);
3224910c1647SPeter Xu pending_size = must_precopy + can_postcopy;
322524beea4eSJuan Quintela trace_migrate_pending_estimate(pending_size, must_precopy, can_postcopy);
3226c8df4a7aSJuan Quintela
3227910c1647SPeter Xu if (pending_size < s->threshold_size) {
322824beea4eSJuan Quintela qemu_savevm_state_pending_exact(&must_precopy, &can_postcopy);
322924beea4eSJuan Quintela pending_size = must_precopy + can_postcopy;
323024beea4eSJuan Quintela trace_migrate_pending_exact(pending_size, must_precopy, can_postcopy);
3231c8df4a7aSJuan Quintela }
32322ad87305SPeter Xu
32331b4adb10SAvihai Horon if ((!pending_size || pending_size < s->threshold_size) && can_switchover) {
3234d9df9292SJuan Quintela trace_migration_thread_low_pending(pending_size);
3235d9df9292SJuan Quintela migration_completion(s);
3236d9df9292SJuan Quintela return MIG_ITERATE_BREAK;
3237d9df9292SJuan Quintela }
3238d9df9292SJuan Quintela
32392ad87305SPeter Xu /* Still a significant amount to transfer */
32401b4adb10SAvihai Horon if (!in_postcopy && must_precopy <= s->threshold_size && can_switchover &&
3241d73415a3SStefan Hajnoczi qatomic_read(&s->start_postcopy)) {
3242908927dbSTejus GK if (postcopy_start(s, &local_err)) {
3243908927dbSTejus GK migrate_set_error(s, local_err);
3244908927dbSTejus GK error_report_err(local_err);
32452ad87305SPeter Xu }
32462ad87305SPeter Xu return MIG_ITERATE_SKIP;
32472ad87305SPeter Xu }
3248d9df9292SJuan Quintela
32492ad87305SPeter Xu /* Just another iteration step */
325017d9351bSWei Yang qemu_savevm_state_iterate(s->to_dst_file, in_postcopy);
32512ad87305SPeter Xu return MIG_ITERATE_RESUME;
32522ad87305SPeter Xu }
32532ad87305SPeter Xu
migration_iteration_finish(MigrationState * s)3254199aa6d4SPeter Xu static void migration_iteration_finish(MigrationState *s)
3255199aa6d4SPeter Xu {
325652ac968aSHyman Huang bql_lock();
325752ac968aSHyman Huang
325852ac968aSHyman Huang /*
325952ac968aSHyman Huang * If we enabled cpu throttling for auto-converge, turn it off.
326052ac968aSHyman Huang * Stopping CPU throttle should be serialized by BQL to avoid
326152ac968aSHyman Huang * racing for the throttle_dirty_sync_timer.
326252ac968aSHyman Huang */
3263054e5d66SHyman Huang if (migrate_auto_converge()) {
3264199aa6d4SPeter Xu cpu_throttle_stop();
3265054e5d66SHyman Huang }
3266199aa6d4SPeter Xu
3267199aa6d4SPeter Xu switch (s->state) {
3268199aa6d4SPeter Xu case MIGRATION_STATUS_COMPLETED:
3269199aa6d4SPeter Xu runstate_set(RUN_STATE_POSTMIGRATE);
3270199aa6d4SPeter Xu break;
3271751fe4c6SZhang Chen case MIGRATION_STATUS_COLO:
3272d70178a8SVladimir Sementsov-Ogievskiy assert(migrate_colo());
3273199aa6d4SPeter Xu migrate_start_colo_process(s);
3274f4584076SVladimir Sementsov-Ogievskiy s->vm_old_state = RUN_STATE_RUNNING;
3275199aa6d4SPeter Xu /* Fallthrough */
3276199aa6d4SPeter Xu case MIGRATION_STATUS_FAILED:
3277199aa6d4SPeter Xu case MIGRATION_STATUS_CANCELLED:
327857225e5fSDr. David Alan Gilbert case MIGRATION_STATUS_CANCELLING:
3279b4e9ddccSSteve Sistare if (runstate_is_live(s->vm_old_state)) {
3280aa505f8eSRao, Lei if (!runstate_check(RUN_STATE_SHUTDOWN)) {
3281199aa6d4SPeter Xu vm_start();
3282aa505f8eSRao, Lei }
3283199aa6d4SPeter Xu } else {
3284199aa6d4SPeter Xu if (runstate_check(RUN_STATE_FINISH_MIGRATE)) {
3285a4c6275aSVladimir Sementsov-Ogievskiy runstate_set(s->vm_old_state);
3286199aa6d4SPeter Xu }
3287199aa6d4SPeter Xu }
3288199aa6d4SPeter Xu break;
3289199aa6d4SPeter Xu
3290199aa6d4SPeter Xu default:
3291199aa6d4SPeter Xu /* Should not reach here, but if so, forgive the VM. */
3292199aa6d4SPeter Xu error_report("%s: Unknown ending state %d", __func__, s->state);
3293199aa6d4SPeter Xu break;
3294199aa6d4SPeter Xu }
329544d0d456SFabiano Rosas
329644d0d456SFabiano Rosas migration_bh_schedule(migrate_fd_cleanup_bh, s);
3297195801d7SStefan Hajnoczi bql_unlock();
3298199aa6d4SPeter Xu }
3299199aa6d4SPeter Xu
bg_migration_iteration_finish(MigrationState * s)33008518278aSAndrey Gruzdev static void bg_migration_iteration_finish(MigrationState *s)
33018518278aSAndrey Gruzdev {
33023a8b81f2SFiona Ebner /*
33033a8b81f2SFiona Ebner * Stop tracking RAM writes - un-protect memory, un-register UFFD
33043a8b81f2SFiona Ebner * memory ranges, flush kernel wait queues and wake up threads
33053a8b81f2SFiona Ebner * waiting for write fault to be resolved.
33063a8b81f2SFiona Ebner */
33073a8b81f2SFiona Ebner ram_write_tracking_stop();
33083a8b81f2SFiona Ebner
3309195801d7SStefan Hajnoczi bql_lock();
33108518278aSAndrey Gruzdev switch (s->state) {
33118518278aSAndrey Gruzdev case MIGRATION_STATUS_COMPLETED:
33128518278aSAndrey Gruzdev case MIGRATION_STATUS_ACTIVE:
33138518278aSAndrey Gruzdev case MIGRATION_STATUS_FAILED:
33148518278aSAndrey Gruzdev case MIGRATION_STATUS_CANCELLED:
33158518278aSAndrey Gruzdev case MIGRATION_STATUS_CANCELLING:
33168518278aSAndrey Gruzdev break;
33178518278aSAndrey Gruzdev
33188518278aSAndrey Gruzdev default:
33198518278aSAndrey Gruzdev /* Should not reach here, but if so, forgive the VM. */
33208518278aSAndrey Gruzdev error_report("%s: Unknown ending state %d", __func__, s->state);
33218518278aSAndrey Gruzdev break;
33228518278aSAndrey Gruzdev }
33238518278aSAndrey Gruzdev
332444d0d456SFabiano Rosas migration_bh_schedule(migrate_fd_cleanup_bh, s);
3325195801d7SStefan Hajnoczi bql_unlock();
33268518278aSAndrey Gruzdev }
33278518278aSAndrey Gruzdev
33288518278aSAndrey Gruzdev /*
33298518278aSAndrey Gruzdev * Return true if continue to the next iteration directly, false
33308518278aSAndrey Gruzdev * otherwise.
33318518278aSAndrey Gruzdev */
bg_migration_iteration_run(MigrationState * s)33328518278aSAndrey Gruzdev static MigIterateState bg_migration_iteration_run(MigrationState *s)
33338518278aSAndrey Gruzdev {
33348518278aSAndrey Gruzdev int res;
33358518278aSAndrey Gruzdev
33368518278aSAndrey Gruzdev res = qemu_savevm_state_iterate(s->to_dst_file, false);
33378518278aSAndrey Gruzdev if (res > 0) {
33388518278aSAndrey Gruzdev bg_migration_completion(s);
33398518278aSAndrey Gruzdev return MIG_ITERATE_BREAK;
33408518278aSAndrey Gruzdev }
33418518278aSAndrey Gruzdev
33428518278aSAndrey Gruzdev return MIG_ITERATE_RESUME;
33438518278aSAndrey Gruzdev }
33448518278aSAndrey Gruzdev
migration_make_urgent_request(void)3345ad767bedSDr. David Alan Gilbert void migration_make_urgent_request(void)
3346ad767bedSDr. David Alan Gilbert {
3347ad767bedSDr. David Alan Gilbert qemu_sem_post(&migrate_get_current()->rate_limit_sem);
3348ad767bedSDr. David Alan Gilbert }
3349ad767bedSDr. David Alan Gilbert
migration_consume_urgent_request(void)3350ad767bedSDr. David Alan Gilbert void migration_consume_urgent_request(void)
3351ad767bedSDr. David Alan Gilbert {
3352ad767bedSDr. David Alan Gilbert qemu_sem_wait(&migrate_get_current()->rate_limit_sem);
3353ad767bedSDr. David Alan Gilbert }
3354ad767bedSDr. David Alan Gilbert
335597e1e067SDr. David Alan Gilbert /* Returns true if the rate limiting was broken by an urgent request */
migration_rate_limit(void)335697e1e067SDr. David Alan Gilbert bool migration_rate_limit(void)
335797e1e067SDr. David Alan Gilbert {
335897e1e067SDr. David Alan Gilbert int64_t now = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
335997e1e067SDr. David Alan Gilbert MigrationState *s = migrate_get_current();
336097e1e067SDr. David Alan Gilbert
336197e1e067SDr. David Alan Gilbert bool urgent = false;
336297e1e067SDr. David Alan Gilbert migration_update_counters(s, now);
3363e1fde0e0SJuan Quintela if (migration_rate_exceeded(s->to_dst_file)) {
336477386127SLukas Straub
336577386127SLukas Straub if (qemu_file_get_error(s->to_dst_file)) {
336677386127SLukas Straub return false;
336777386127SLukas Straub }
336897e1e067SDr. David Alan Gilbert /*
336997e1e067SDr. David Alan Gilbert * Wait for a delay to do rate limiting OR
337097e1e067SDr. David Alan Gilbert * something urgent to post the semaphore.
337197e1e067SDr. David Alan Gilbert */
337297e1e067SDr. David Alan Gilbert int ms = s->iteration_start_time + BUFFER_DELAY - now;
337397e1e067SDr. David Alan Gilbert trace_migration_rate_limit_pre(ms);
337497e1e067SDr. David Alan Gilbert if (qemu_sem_timedwait(&s->rate_limit_sem, ms) == 0) {
337597e1e067SDr. David Alan Gilbert /*
337697e1e067SDr. David Alan Gilbert * We were woken by one or more urgent things but
337797e1e067SDr. David Alan Gilbert * the timedwait will have consumed one of them.
337897e1e067SDr. David Alan Gilbert * The service routine for the urgent wake will dec
337997e1e067SDr. David Alan Gilbert * the semaphore itself for each item it consumes,
338097e1e067SDr. David Alan Gilbert * so add this one we just eat back.
338197e1e067SDr. David Alan Gilbert */
338297e1e067SDr. David Alan Gilbert qemu_sem_post(&s->rate_limit_sem);
338397e1e067SDr. David Alan Gilbert urgent = true;
338497e1e067SDr. David Alan Gilbert }
338597e1e067SDr. David Alan Gilbert trace_migration_rate_limit_post(urgent);
338697e1e067SDr. David Alan Gilbert }
338797e1e067SDr. David Alan Gilbert return urgent;
338897e1e067SDr. David Alan Gilbert }
338997e1e067SDr. David Alan Gilbert
339070b20477SDr. David Alan Gilbert /*
3391fde93d99SLaurent Vivier * if failover devices are present, wait they are completely
3392fde93d99SLaurent Vivier * unplugged
3393fde93d99SLaurent Vivier */
3394fde93d99SLaurent Vivier
qemu_savevm_wait_unplug(MigrationState * s,int old_state,int new_state)3395fde93d99SLaurent Vivier static void qemu_savevm_wait_unplug(MigrationState *s, int old_state,
3396fde93d99SLaurent Vivier int new_state)
3397fde93d99SLaurent Vivier {
3398fde93d99SLaurent Vivier if (qemu_savevm_state_guest_unplug_pending()) {
3399fde93d99SLaurent Vivier migrate_set_state(&s->state, old_state, MIGRATION_STATUS_WAIT_UNPLUG);
3400fde93d99SLaurent Vivier
3401fde93d99SLaurent Vivier while (s->state == MIGRATION_STATUS_WAIT_UNPLUG &&
3402fde93d99SLaurent Vivier qemu_savevm_state_guest_unplug_pending()) {
3403fde93d99SLaurent Vivier qemu_sem_timedwait(&s->wait_unplug_sem, 250);
3404fde93d99SLaurent Vivier }
3405944bc528SLaurent Vivier if (s->state != MIGRATION_STATUS_WAIT_UNPLUG) {
3406944bc528SLaurent Vivier int timeout = 120; /* 30 seconds */
3407944bc528SLaurent Vivier /*
3408944bc528SLaurent Vivier * migration has been canceled
3409944bc528SLaurent Vivier * but as we have started an unplug we must wait the end
3410944bc528SLaurent Vivier * to be able to plug back the card
3411944bc528SLaurent Vivier */
3412944bc528SLaurent Vivier while (timeout-- && qemu_savevm_state_guest_unplug_pending()) {
3413944bc528SLaurent Vivier qemu_sem_timedwait(&s->wait_unplug_sem, 250);
3414944bc528SLaurent Vivier }
34151b529d90SLaurent Vivier if (qemu_savevm_state_guest_unplug_pending() &&
34161b529d90SLaurent Vivier !qtest_enabled()) {
3417a51dcef0SLaurent Vivier warn_report("migration: partially unplugged device on "
3418a51dcef0SLaurent Vivier "failure");
3419a51dcef0SLaurent Vivier }
3420944bc528SLaurent Vivier }
3421fde93d99SLaurent Vivier
3422fde93d99SLaurent Vivier migrate_set_state(&s->state, MIGRATION_STATUS_WAIT_UNPLUG, new_state);
3423fde93d99SLaurent Vivier } else {
3424fde93d99SLaurent Vivier migrate_set_state(&s->state, old_state, new_state);
3425fde93d99SLaurent Vivier }
3426fde93d99SLaurent Vivier }
3427fde93d99SLaurent Vivier
3428fde93d99SLaurent Vivier /*
342970b20477SDr. David Alan Gilbert * Master migration thread on the source VM.
343070b20477SDr. David Alan Gilbert * It drives the migration and pumps the data down the outgoing channel.
343170b20477SDr. David Alan Gilbert */
migration_thread(void * opaque)343260fe637bSDr. David Alan Gilbert static void *migration_thread(void *opaque)
343360fe637bSDr. David Alan Gilbert {
343460fe637bSDr. David Alan Gilbert MigrationState *s = opaque;
34351b1f4ab6SJiang Jiacheng MigrationThread *thread = NULL;
343660fe637bSDr. David Alan Gilbert int64_t setup_start = qemu_clock_get_ms(QEMU_CLOCK_HOST);
3437b23c2adeSPeter Xu MigThrError thr_error;
3438ad767bedSDr. David Alan Gilbert bool urgent = false;
3439057a2009SCédric Le Goater Error *local_err = NULL;
3440057a2009SCédric Le Goater int ret;
344160fe637bSDr. David Alan Gilbert
3442e620b1e4SPeter Xu thread = migration_threads_add(MIGRATION_THREAD_SRC_MAIN,
3443e620b1e4SPeter Xu qemu_get_thread_id());
34441b1f4ab6SJiang Jiacheng
3445ab28bd23SPaolo Bonzini rcu_register_thread();
3446ab28bd23SPaolo Bonzini
344787f3bd87SIvan Ren update_iteration_initial_status(s);
3448b15df1aeSPeter Xu
3449dd904bc1SFabiano Rosas if (!multifd_send_setup()) {
3450dd904bc1SFabiano Rosas goto out;
3451dd904bc1SFabiano Rosas }
3452dd904bc1SFabiano Rosas
3453195801d7SStefan Hajnoczi bql_lock();
345489a02a9fSzhanghailiang qemu_savevm_state_header(s->to_dst_file);
3455195801d7SStefan Hajnoczi bql_unlock();
34561d34e4bfSDr. David Alan Gilbert
345762a02658SPeter Xu /*
345862a02658SPeter Xu * If we opened the return path, we need to make sure dst has it
345962a02658SPeter Xu * opened as well.
346062a02658SPeter Xu */
346143044ac0SPeter Xu if (s->rp_state.rp_thread_created) {
34621d34e4bfSDr. David Alan Gilbert /* Now tell the dest that it should open its end so it can reply */
346389a02a9fSzhanghailiang qemu_savevm_send_open_return_path(s->to_dst_file);
34641d34e4bfSDr. David Alan Gilbert
34651d34e4bfSDr. David Alan Gilbert /* And do a ping that will make stuff easier to debug */
346689a02a9fSzhanghailiang qemu_savevm_send_ping(s->to_dst_file, 1);
34670425dc97SPeter Xu }
34681d34e4bfSDr. David Alan Gilbert
346958110f0aSVladimir Sementsov-Ogievskiy if (migrate_postcopy()) {
34701d34e4bfSDr. David Alan Gilbert /*
34711d34e4bfSDr. David Alan Gilbert * Tell the destination that we *might* want to do postcopy later;
34721d34e4bfSDr. David Alan Gilbert * if the other end can't do postcopy it should fail now, nice and
34731d34e4bfSDr. David Alan Gilbert * early.
34741d34e4bfSDr. David Alan Gilbert */
347589a02a9fSzhanghailiang qemu_savevm_send_postcopy_advise(s->to_dst_file);
34761d34e4bfSDr. David Alan Gilbert }
34771d34e4bfSDr. David Alan Gilbert
34785e804644SJuan Quintela if (migrate_colo()) {
3479aad555c2SZhang Chen /* Notify migration destination that we enable COLO */
3480aad555c2SZhang Chen qemu_savevm_send_colo_enable(s->to_dst_file);
3481aad555c2SZhang Chen }
3482aad555c2SZhang Chen
348352ac968aSHyman Huang if (migrate_auto_converge()) {
348452ac968aSHyman Huang /* Start RAMBlock dirty bitmap sync timer */
348552ac968aSHyman Huang cpu_throttle_dirty_sync_timer(true);
348652ac968aSHyman Huang }
348752ac968aSHyman Huang
3488195801d7SStefan Hajnoczi bql_lock();
3489057a2009SCédric Le Goater ret = qemu_savevm_state_setup(s->to_dst_file, &local_err);
3490195801d7SStefan Hajnoczi bql_unlock();
349160fe637bSDr. David Alan Gilbert
3492fde93d99SLaurent Vivier qemu_savevm_wait_unplug(s, MIGRATION_STATUS_SETUP,
3493c7e0acd5SJens Freimann MIGRATION_STATUS_ACTIVE);
3494c7e0acd5SJens Freimann
3495057a2009SCédric Le Goater /*
3496057a2009SCédric Le Goater * Handle SETUP failures after waiting for virtio-net-failover
3497057a2009SCédric Le Goater * devices to unplug. This to preserve migration state transitions.
3498057a2009SCédric Le Goater */
3499057a2009SCédric Le Goater if (ret) {
3500057a2009SCédric Le Goater migrate_set_error(s, local_err);
3501057a2009SCédric Le Goater error_free(local_err);
3502057a2009SCédric Le Goater migrate_set_state(&s->state, MIGRATION_STATUS_ACTIVE,
3503057a2009SCédric Le Goater MIGRATION_STATUS_FAILED);
3504057a2009SCédric Le Goater goto out;
3505057a2009SCédric Le Goater }
3506057a2009SCédric Le Goater
350760fe637bSDr. David Alan Gilbert s->setup_time = qemu_clock_get_ms(QEMU_CLOCK_HOST) - setup_start;
350860fe637bSDr. David Alan Gilbert
35099ec055aeSDr. David Alan Gilbert trace_migration_thread_setup_complete();
35109ec055aeSDr. David Alan Gilbert
35113a6813b6SSteve Sistare while (migration_is_active()) {
3512e1fde0e0SJuan Quintela if (urgent || !migration_rate_exceeded(s->to_dst_file)) {
35132ad87305SPeter Xu MigIterateState iter_state = migration_iteration_run(s);
35142ad87305SPeter Xu if (iter_state == MIG_ITERATE_SKIP) {
35151d34e4bfSDr. David Alan Gilbert continue;
35162ad87305SPeter Xu } else if (iter_state == MIG_ITERATE_BREAK) {
351760fe637bSDr. David Alan Gilbert break;
351860fe637bSDr. David Alan Gilbert }
351960fe637bSDr. David Alan Gilbert }
352060fe637bSDr. David Alan Gilbert
3521b23c2adeSPeter Xu /*
3522b23c2adeSPeter Xu * Try to detect any kind of failures, and see whether we
3523b23c2adeSPeter Xu * should stop the migration now.
3524b23c2adeSPeter Xu */
3525b23c2adeSPeter Xu thr_error = migration_detect_error(s);
3526b23c2adeSPeter Xu if (thr_error == MIG_THR_ERR_FATAL) {
3527b23c2adeSPeter Xu /* Stop migration */
352860fe637bSDr. David Alan Gilbert break;
3529b23c2adeSPeter Xu } else if (thr_error == MIG_THR_ERR_RECOVERED) {
3530b23c2adeSPeter Xu /*
3531b23c2adeSPeter Xu * Just recovered from a e.g. network failure, reset all
3532b23c2adeSPeter Xu * the local variables. This is important to avoid
3533b23c2adeSPeter Xu * breaking transferred_bytes and bandwidth calculation
3534b23c2adeSPeter Xu */
353587f3bd87SIvan Ren update_iteration_initial_status(s);
353660fe637bSDr. David Alan Gilbert }
3537b15df1aeSPeter Xu
353897e1e067SDr. David Alan Gilbert urgent = migration_rate_limit();
353960fe637bSDr. David Alan Gilbert }
354060fe637bSDr. David Alan Gilbert
3541dd904bc1SFabiano Rosas out:
35421d34e4bfSDr. David Alan Gilbert trace_migration_thread_after_loop();
3543199aa6d4SPeter Xu migration_iteration_finish(s);
3544892ae715SDr. David Alan Gilbert object_unref(OBJECT(s));
3545ab28bd23SPaolo Bonzini rcu_unregister_thread();
3546788fa680SFabiano Rosas migration_threads_remove(thread);
354760fe637bSDr. David Alan Gilbert return NULL;
354860fe637bSDr. David Alan Gilbert }
354960fe637bSDr. David Alan Gilbert
bg_migration_vm_start_bh(void * opaque)35508518278aSAndrey Gruzdev static void bg_migration_vm_start_bh(void *opaque)
35518518278aSAndrey Gruzdev {
35528518278aSAndrey Gruzdev MigrationState *s = opaque;
35538518278aSAndrey Gruzdev
355449a50206SSteve Sistare vm_resume(s->vm_old_state);
3555e22ffad0SPeter Xu migration_downtime_end(s);
35568518278aSAndrey Gruzdev }
35578518278aSAndrey Gruzdev
35588518278aSAndrey Gruzdev /**
35598518278aSAndrey Gruzdev * Background snapshot thread, based on live migration code.
35608518278aSAndrey Gruzdev * This is an alternative implementation of live migration mechanism
35618518278aSAndrey Gruzdev * introduced specifically to support background snapshots.
35628518278aSAndrey Gruzdev *
35638518278aSAndrey Gruzdev * It takes advantage of userfault_fd write protection mechanism introduced
35648518278aSAndrey Gruzdev * in v5.7 kernel. Compared to existing dirty page logging migration much
35658518278aSAndrey Gruzdev * lesser stream traffic is produced resulting in smaller snapshot images,
35668518278aSAndrey Gruzdev * simply cause of no page duplicates can get into the stream.
35678518278aSAndrey Gruzdev *
35688518278aSAndrey Gruzdev * Another key point is that generated vmstate stream reflects machine state
35698518278aSAndrey Gruzdev * 'frozen' at the beginning of snapshot creation compared to dirty page logging
35708518278aSAndrey Gruzdev * mechanism, which effectively results in that saved snapshot is the state of VM
35718518278aSAndrey Gruzdev * at the end of the process.
35728518278aSAndrey Gruzdev */
bg_migration_thread(void * opaque)35738518278aSAndrey Gruzdev static void *bg_migration_thread(void *opaque)
35748518278aSAndrey Gruzdev {
35758518278aSAndrey Gruzdev MigrationState *s = opaque;
35768518278aSAndrey Gruzdev int64_t setup_start;
35778518278aSAndrey Gruzdev MigThrError thr_error;
35788518278aSAndrey Gruzdev QEMUFile *fb;
35798518278aSAndrey Gruzdev bool early_fail = true;
3580057a2009SCédric Le Goater Error *local_err = NULL;
3581057a2009SCédric Le Goater int ret;
35828518278aSAndrey Gruzdev
35838518278aSAndrey Gruzdev rcu_register_thread();
35848518278aSAndrey Gruzdev
3585e1fde0e0SJuan Quintela migration_rate_set(RATE_LIMIT_DISABLED);
35868518278aSAndrey Gruzdev
35878518278aSAndrey Gruzdev setup_start = qemu_clock_get_ms(QEMU_CLOCK_HOST);
35888518278aSAndrey Gruzdev /*
35898518278aSAndrey Gruzdev * We want to save vmstate for the moment when migration has been
35908518278aSAndrey Gruzdev * initiated but also we want to save RAM content while VM is running.
35918518278aSAndrey Gruzdev * The RAM content should appear first in the vmstate. So, we first
35928518278aSAndrey Gruzdev * stash the non-RAM part of the vmstate to the temporary buffer,
35938518278aSAndrey Gruzdev * then write RAM part of the vmstate to the migration stream
35948518278aSAndrey Gruzdev * with vCPUs running and, finally, write stashed non-RAM part of
35958518278aSAndrey Gruzdev * the vmstate from the buffer to the migration stream.
35968518278aSAndrey Gruzdev */
3597ecb23efeSAndrey Gruzdev s->bioc = qio_channel_buffer_new(512 * 1024);
35988518278aSAndrey Gruzdev qio_channel_set_name(QIO_CHANNEL(s->bioc), "vmstate-buffer");
359977ef2dc1SDaniel P. Berrangé fb = qemu_file_new_output(QIO_CHANNEL(s->bioc));
36008518278aSAndrey Gruzdev object_unref(OBJECT(s->bioc));
36018518278aSAndrey Gruzdev
36028518278aSAndrey Gruzdev update_iteration_initial_status(s);
36038518278aSAndrey Gruzdev
3604eeccb99cSAndrey Gruzdev /*
3605eeccb99cSAndrey Gruzdev * Prepare for tracking memory writes with UFFD-WP - populate
3606eeccb99cSAndrey Gruzdev * RAM pages before protecting.
3607eeccb99cSAndrey Gruzdev */
3608eeccb99cSAndrey Gruzdev #ifdef __linux__
3609eeccb99cSAndrey Gruzdev ram_write_tracking_prepare();
3610eeccb99cSAndrey Gruzdev #endif
3611eeccb99cSAndrey Gruzdev
3612195801d7SStefan Hajnoczi bql_lock();
36138518278aSAndrey Gruzdev qemu_savevm_state_header(s->to_dst_file);
3614057a2009SCédric Le Goater ret = qemu_savevm_state_setup(s->to_dst_file, &local_err);
3615195801d7SStefan Hajnoczi bql_unlock();
36168518278aSAndrey Gruzdev
3617fde93d99SLaurent Vivier qemu_savevm_wait_unplug(s, MIGRATION_STATUS_SETUP,
36188518278aSAndrey Gruzdev MIGRATION_STATUS_ACTIVE);
3619fde93d99SLaurent Vivier
3620057a2009SCédric Le Goater /*
3621057a2009SCédric Le Goater * Handle SETUP failures after waiting for virtio-net-failover
3622057a2009SCédric Le Goater * devices to unplug. This to preserve migration state transitions.
3623057a2009SCédric Le Goater */
3624057a2009SCédric Le Goater if (ret) {
3625057a2009SCédric Le Goater migrate_set_error(s, local_err);
3626057a2009SCédric Le Goater error_free(local_err);
3627057a2009SCédric Le Goater migrate_set_state(&s->state, MIGRATION_STATUS_ACTIVE,
3628057a2009SCédric Le Goater MIGRATION_STATUS_FAILED);
3629057a2009SCédric Le Goater goto fail_setup;
3630057a2009SCédric Le Goater }
3631057a2009SCédric Le Goater
36328518278aSAndrey Gruzdev s->setup_time = qemu_clock_get_ms(QEMU_CLOCK_HOST) - setup_start;
36338518278aSAndrey Gruzdev
36348518278aSAndrey Gruzdev trace_migration_thread_setup_complete();
36358518278aSAndrey Gruzdev
3636195801d7SStefan Hajnoczi bql_lock();
36378518278aSAndrey Gruzdev
36389867d4ddSSteve Sistare if (migration_stop_vm(s, RUN_STATE_PAUSED)) {
36398518278aSAndrey Gruzdev goto fail;
36408518278aSAndrey Gruzdev }
36418518278aSAndrey Gruzdev /*
36428518278aSAndrey Gruzdev * Put vCPUs in sync with shadow context structures, then
36438518278aSAndrey Gruzdev * save their state to channel-buffer along with devices.
36448518278aSAndrey Gruzdev */
36458518278aSAndrey Gruzdev cpu_synchronize_all_states();
36468518278aSAndrey Gruzdev if (qemu_savevm_state_complete_precopy_non_iterable(fb, false, false)) {
36478518278aSAndrey Gruzdev goto fail;
36488518278aSAndrey Gruzdev }
3649ecb23efeSAndrey Gruzdev /*
3650ecb23efeSAndrey Gruzdev * Since we are going to get non-iterable state data directly
3651ecb23efeSAndrey Gruzdev * from s->bioc->data, explicit flush is needed here.
3652ecb23efeSAndrey Gruzdev */
3653ecb23efeSAndrey Gruzdev qemu_fflush(fb);
3654ecb23efeSAndrey Gruzdev
36558518278aSAndrey Gruzdev /* Now initialize UFFD context and start tracking RAM writes */
36568518278aSAndrey Gruzdev if (ram_write_tracking_start()) {
36578518278aSAndrey Gruzdev goto fail;
36588518278aSAndrey Gruzdev }
36598518278aSAndrey Gruzdev early_fail = false;
36608518278aSAndrey Gruzdev
36618518278aSAndrey Gruzdev /*
36628518278aSAndrey Gruzdev * Start VM from BH handler to avoid write-fault lock here.
36638518278aSAndrey Gruzdev * UFFD-WP protection for the whole RAM is already enabled so
36648518278aSAndrey Gruzdev * calling VM state change notifiers from vm_start() would initiate
36658518278aSAndrey Gruzdev * writes to virtio VQs memory which is in write-protected region.
36668518278aSAndrey Gruzdev */
366744d0d456SFabiano Rosas migration_bh_schedule(bg_migration_vm_start_bh, s);
3668195801d7SStefan Hajnoczi bql_unlock();
36698518278aSAndrey Gruzdev
36703a6813b6SSteve Sistare while (migration_is_active()) {
36718518278aSAndrey Gruzdev MigIterateState iter_state = bg_migration_iteration_run(s);
36728518278aSAndrey Gruzdev if (iter_state == MIG_ITERATE_SKIP) {
36738518278aSAndrey Gruzdev continue;
36748518278aSAndrey Gruzdev } else if (iter_state == MIG_ITERATE_BREAK) {
36758518278aSAndrey Gruzdev break;
36768518278aSAndrey Gruzdev }
36778518278aSAndrey Gruzdev
36788518278aSAndrey Gruzdev /*
36798518278aSAndrey Gruzdev * Try to detect any kind of failures, and see whether we
36808518278aSAndrey Gruzdev * should stop the migration now.
36818518278aSAndrey Gruzdev */
36828518278aSAndrey Gruzdev thr_error = migration_detect_error(s);
36838518278aSAndrey Gruzdev if (thr_error == MIG_THR_ERR_FATAL) {
36848518278aSAndrey Gruzdev /* Stop migration */
36858518278aSAndrey Gruzdev break;
36868518278aSAndrey Gruzdev }
36878518278aSAndrey Gruzdev
36888518278aSAndrey Gruzdev migration_update_counters(s, qemu_clock_get_ms(QEMU_CLOCK_REALTIME));
36898518278aSAndrey Gruzdev }
36908518278aSAndrey Gruzdev
36918518278aSAndrey Gruzdev trace_migration_thread_after_loop();
36928518278aSAndrey Gruzdev
36938518278aSAndrey Gruzdev fail:
36948518278aSAndrey Gruzdev if (early_fail) {
36958518278aSAndrey Gruzdev migrate_set_state(&s->state, MIGRATION_STATUS_ACTIVE,
36968518278aSAndrey Gruzdev MIGRATION_STATUS_FAILED);
3697195801d7SStefan Hajnoczi bql_unlock();
36988518278aSAndrey Gruzdev }
36998518278aSAndrey Gruzdev
3700057a2009SCédric Le Goater fail_setup:
37018518278aSAndrey Gruzdev bg_migration_iteration_finish(s);
37028518278aSAndrey Gruzdev
37038518278aSAndrey Gruzdev qemu_fclose(fb);
37048518278aSAndrey Gruzdev object_unref(OBJECT(s));
37058518278aSAndrey Gruzdev rcu_unregister_thread();
37068518278aSAndrey Gruzdev
37078518278aSAndrey Gruzdev return NULL;
37088518278aSAndrey Gruzdev }
37098518278aSAndrey Gruzdev
migrate_fd_connect(MigrationState * s,Error * error_in)3710cce8040bSDr. David Alan Gilbert void migrate_fd_connect(MigrationState *s, Error *error_in)
371160fe637bSDr. David Alan Gilbert {
371200f4b572SJuan Quintela Error *local_err = NULL;
371352033349SJuan Quintela uint64_t rate_limit;
37144146b77eSPeter Xu bool resume = (s->state == MIGRATION_STATUS_POSTCOPY_RECOVER_SETUP);
37159867d4ddSSteve Sistare int ret;
3716d3e35b8fSPeter Xu
3717ca7bd082SPeter Xu /*
3718ca7bd082SPeter Xu * If there's a previous error, free it and prepare for another one.
3719ca7bd082SPeter Xu * Meanwhile if migration completes successfully, there won't have an error
3720ca7bd082SPeter Xu * dumped when calling migrate_fd_cleanup().
3721ca7bd082SPeter Xu */
3722ca7bd082SPeter Xu migrate_error_free(s);
3723ca7bd082SPeter Xu
3724f5da8ba4SJuan Quintela s->expected_downtime = migrate_downtime_limit();
3725cce8040bSDr. David Alan Gilbert if (error_in) {
3726cce8040bSDr. David Alan Gilbert migrate_fd_error(s, error_in);
3727ca30f24dSPeter Xu if (resume) {
3728ca30f24dSPeter Xu /*
3729ca30f24dSPeter Xu * Don't do cleanup for resume if channel is invalid, but only dump
3730ca30f24dSPeter Xu * the error. We wait for another channel connect from the user.
3731ca30f24dSPeter Xu * The error_report still gives HMP user a hint on what failed.
3732ca30f24dSPeter Xu * It's normally done in migrate_fd_cleanup(), but call it here
3733ca30f24dSPeter Xu * explicitly.
3734ca30f24dSPeter Xu */
3735ca30f24dSPeter Xu error_report_err(error_copy(s->error));
3736ca30f24dSPeter Xu } else {
3737cce8040bSDr. David Alan Gilbert migrate_fd_cleanup(s);
3738ca30f24dSPeter Xu }
3739cce8040bSDr. David Alan Gilbert return;
3740cce8040bSDr. David Alan Gilbert }
374160fe637bSDr. David Alan Gilbert
3742d3e35b8fSPeter Xu if (resume) {
3743d3e35b8fSPeter Xu /* This is a resumed migration */
37449d3ebbe2SJuan Quintela rate_limit = migrate_max_postcopy_bandwidth();
3745d3e35b8fSPeter Xu } else {
3746d3e35b8fSPeter Xu /* This is a fresh new migration */
37479d3ebbe2SJuan Quintela rate_limit = migrate_max_bandwidth();
374860fe637bSDr. David Alan Gilbert
374960fe637bSDr. David Alan Gilbert /* Notify before starting migration thread */
37504af667f8SSteve Sistare if (migration_call_notifiers(s, MIG_EVENT_PRECOPY_SETUP, &local_err)) {
37514af667f8SSteve Sistare goto fail;
37524af667f8SSteve Sistare }
3753d3e35b8fSPeter Xu }
3754d3e35b8fSPeter Xu
3755e1fde0e0SJuan Quintela migration_rate_set(rate_limit);
3756d3e35b8fSPeter Xu qemu_file_set_blocking(s->to_dst_file, true);
375760fe637bSDr. David Alan Gilbert
37581d34e4bfSDr. David Alan Gilbert /*
3759c788ada8SPeter Xu * Open the return path. For postcopy, it is used exclusively. For
3760c788ada8SPeter Xu * precopy, only if user specified "return-path" capability would
3761c788ada8SPeter Xu * QEMU uses the return path.
37621d34e4bfSDr. David Alan Gilbert */
376338ad1110SJuan Quintela if (migrate_postcopy_ram() || migrate_return_path()) {
3764ef796ee9SFabiano Rosas if (open_return_path_on_source(s)) {
3765908927dbSTejus GK error_setg(&local_err, "Unable to open return-path for postcopy");
3766bf78a046SSteve Sistare goto fail;
37671d34e4bfSDr. David Alan Gilbert }
37681d34e4bfSDr. David Alan Gilbert }
37691d34e4bfSDr. David Alan Gilbert
377006064a67SPeter Xu /*
377106064a67SPeter Xu * This needs to be done before resuming a postcopy. Note: for newer
377206064a67SPeter Xu * QEMUs we will delay the channel creation until postcopy_start(), to
377306064a67SPeter Xu * avoid disorder of channel creations.
377406064a67SPeter Xu */
377506064a67SPeter Xu if (migrate_postcopy_preempt() && s->preempt_pre_7_2) {
377606064a67SPeter Xu postcopy_preempt_setup(s);
377706064a67SPeter Xu }
377806064a67SPeter Xu
3779d3e35b8fSPeter Xu if (resume) {
3780135b87b4SPeter Xu /* Wakeup the main migration thread to do the recovery */
37814146b77eSPeter Xu migrate_set_state(&s->state, MIGRATION_STATUS_POSTCOPY_RECOVER_SETUP,
3782135b87b4SPeter Xu MIGRATION_STATUS_POSTCOPY_RECOVER);
3783135b87b4SPeter Xu qemu_sem_post(&s->postcopy_pause_sem);
3784d3e35b8fSPeter Xu return;
3785d3e35b8fSPeter Xu }
3786d3e35b8fSPeter Xu
37879867d4ddSSteve Sistare if (migrate_mode_is_cpr(s)) {
37889867d4ddSSteve Sistare ret = migration_stop_vm(s, RUN_STATE_FINISH_MIGRATE);
37899867d4ddSSteve Sistare if (ret < 0) {
37909867d4ddSSteve Sistare error_setg(&local_err, "migration_stop_vm failed, error %d", -ret);
37919867d4ddSSteve Sistare goto fail;
37929867d4ddSSteve Sistare }
37939867d4ddSSteve Sistare }
37949867d4ddSSteve Sistare
37957fc8beb1SPeter Xu /*
37967fc8beb1SPeter Xu * Take a refcount to make sure the migration object won't get freed by
37977fc8beb1SPeter Xu * the main thread already in migration_shutdown().
37987fc8beb1SPeter Xu *
37997fc8beb1SPeter Xu * The refcount will be released at the end of the thread function.
38007fc8beb1SPeter Xu */
38017fc8beb1SPeter Xu object_ref(OBJECT(s));
38027fc8beb1SPeter Xu
38038518278aSAndrey Gruzdev if (migrate_background_snapshot()) {
3804e620b1e4SPeter Xu qemu_thread_create(&s->thread, MIGRATION_THREAD_SNAPSHOT,
38058518278aSAndrey Gruzdev bg_migration_thread, s, QEMU_THREAD_JOINABLE);
38068518278aSAndrey Gruzdev } else {
3807e620b1e4SPeter Xu qemu_thread_create(&s->thread, MIGRATION_THREAD_SRC_MAIN,
38088518278aSAndrey Gruzdev migration_thread, s, QEMU_THREAD_JOINABLE);
38098518278aSAndrey Gruzdev }
38101d34e4bfSDr. David Alan Gilbert s->migration_thread_running = true;
3811bf78a046SSteve Sistare return;
3812bf78a046SSteve Sistare
3813bf78a046SSteve Sistare fail:
3814bf78a046SSteve Sistare migrate_set_error(s, local_err);
3815bf78a046SSteve Sistare migrate_set_state(&s->state, s->state, MIGRATION_STATUS_FAILED);
3816bf78a046SSteve Sistare error_report_err(local_err);
3817bf78a046SSteve Sistare migrate_fd_cleanup(s);
381860fe637bSDr. David Alan Gilbert }
3819093e3c42SDr. David Alan Gilbert
migration_class_init(ObjectClass * klass,void * data)3820e5cb7e76SPeter Xu static void migration_class_init(ObjectClass *klass, void *data)
3821e5cb7e76SPeter Xu {
3822e5cb7e76SPeter Xu DeviceClass *dc = DEVICE_CLASS(klass);
3823e5cb7e76SPeter Xu
3824e5cb7e76SPeter Xu dc->user_creatable = false;
38254f67d30bSMarc-André Lureau device_class_set_props(dc, migration_properties);
3826e5cb7e76SPeter Xu }
3827e5cb7e76SPeter Xu
migration_instance_finalize(Object * obj)3828b91bf5e4SMarc-André Lureau static void migration_instance_finalize(Object *obj)
3829b91bf5e4SMarc-André Lureau {
3830b91bf5e4SMarc-André Lureau MigrationState *ms = MIGRATION_OBJ(obj);
3831b91bf5e4SMarc-André Lureau
383287db1a7dSJuan Quintela qemu_mutex_destroy(&ms->error_mutex);
383362df066fSPeter Xu qemu_mutex_destroy(&ms->qemu_file_lock);
3834c7e0acd5SJens Freimann qemu_sem_destroy(&ms->wait_unplug_sem);
3835ad767bedSDr. David Alan Gilbert qemu_sem_destroy(&ms->rate_limit_sem);
3836e91d8951SDr. David Alan Gilbert qemu_sem_destroy(&ms->pause_sem);
3837b23c2adeSPeter Xu qemu_sem_destroy(&ms->postcopy_pause_sem);
3838edd090c7SPeter Xu qemu_sem_destroy(&ms->rp_state.rp_sem);
3839b28fb582SPeter Xu qemu_sem_destroy(&ms->rp_state.rp_pong_acks);
3840d0edb8a1SPeter Xu qemu_sem_destroy(&ms->postcopy_qemufile_src_sem);
3841ab105cc1SMarc-André Lureau error_free(ms->error);
3842b91bf5e4SMarc-André Lureau }
3843b91bf5e4SMarc-André Lureau
migration_instance_init(Object * obj)3844e5cb7e76SPeter Xu static void migration_instance_init(Object *obj)
3845e5cb7e76SPeter Xu {
3846e5cb7e76SPeter Xu MigrationState *ms = MIGRATION_OBJ(obj);
3847e5cb7e76SPeter Xu
3848e5cb7e76SPeter Xu ms->state = MIGRATION_STATUS_NONE;
3849e5cb7e76SPeter Xu ms->mbps = -1;
3850aecbfe9cSXiao Guangrong ms->pages_per_second = -1;
3851e91d8951SDr. David Alan Gilbert qemu_sem_init(&ms->pause_sem, 0);
385287db1a7dSJuan Quintela qemu_mutex_init(&ms->error_mutex);
38538b0b29dcSPeter Xu
385461a174e2SJuan Quintela migrate_params_init(&ms->parameters);
3855b23c2adeSPeter Xu
3856b23c2adeSPeter Xu qemu_sem_init(&ms->postcopy_pause_sem, 0);
3857edd090c7SPeter Xu qemu_sem_init(&ms->rp_state.rp_sem, 0);
3858b28fb582SPeter Xu qemu_sem_init(&ms->rp_state.rp_pong_acks, 0);
3859ad767bedSDr. David Alan Gilbert qemu_sem_init(&ms->rate_limit_sem, 0);
3860c7e0acd5SJens Freimann qemu_sem_init(&ms->wait_unplug_sem, 0);
3861d0edb8a1SPeter Xu qemu_sem_init(&ms->postcopy_qemufile_src_sem, 0);
386262df066fSPeter Xu qemu_mutex_init(&ms->qemu_file_lock);
38638b0b29dcSPeter Xu }
38648b0b29dcSPeter Xu
38658b0b29dcSPeter Xu /*
38668b0b29dcSPeter Xu * Return true if check pass, false otherwise. Error will be put
38678b0b29dcSPeter Xu * inside errp if provided.
38688b0b29dcSPeter Xu */
migration_object_check(MigrationState * ms,Error ** errp)38698b0b29dcSPeter Xu static bool migration_object_check(MigrationState *ms, Error **errp)
38708b0b29dcSPeter Xu {
38716b19a7d9SPeter Xu /* Assuming all off */
3872b02c7fc9SJuan Quintela bool old_caps[MIGRATION_CAPABILITY__MAX] = { 0 };
38736b19a7d9SPeter Xu
38748b0b29dcSPeter Xu if (!migrate_params_check(&ms->parameters, errp)) {
38758b0b29dcSPeter Xu return false;
38768b0b29dcSPeter Xu }
38778b0b29dcSPeter Xu
3878b02c7fc9SJuan Quintela return migrate_caps_check(old_caps, ms->capabilities, errp);
3879e5cb7e76SPeter Xu }
3880e5cb7e76SPeter Xu
3881e5cb7e76SPeter Xu static const TypeInfo migration_type = {
3882e5cb7e76SPeter Xu .name = TYPE_MIGRATION,
388301f6e14cSPeter Xu /*
3884c8d3ff38SPeter Xu * NOTE: TYPE_MIGRATION is not really a device, as the object is
38852194abd6SMarkus Armbruster * not created using qdev_new(), it is not attached to the qdev
3886c8d3ff38SPeter Xu * device tree, and it is never realized.
3887c8d3ff38SPeter Xu *
3888c8d3ff38SPeter Xu * TODO: Make this TYPE_OBJECT once QOM provides something like
3889c8d3ff38SPeter Xu * TYPE_DEVICE's "-global" properties.
389001f6e14cSPeter Xu */
3891e5cb7e76SPeter Xu .parent = TYPE_DEVICE,
3892e5cb7e76SPeter Xu .class_init = migration_class_init,
3893e5cb7e76SPeter Xu .class_size = sizeof(MigrationClass),
3894e5cb7e76SPeter Xu .instance_size = sizeof(MigrationState),
3895e5cb7e76SPeter Xu .instance_init = migration_instance_init,
3896b91bf5e4SMarc-André Lureau .instance_finalize = migration_instance_finalize,
3897e5cb7e76SPeter Xu };
3898e5cb7e76SPeter Xu
register_migration_types(void)3899e5cb7e76SPeter Xu static void register_migration_types(void)
3900e5cb7e76SPeter Xu {
3901e5cb7e76SPeter Xu type_register_static(&migration_type);
3902e5cb7e76SPeter Xu }
3903e5cb7e76SPeter Xu
3904e5cb7e76SPeter Xu type_init(register_migration_types);
3905