xref: /openbmc/qemu/migration/migration.c (revision 43f2def68476697deb0d119cbae51b20019c6c86)
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(&current_incoming->rp_mutex);
24960bb3c58SPeter Xu     qemu_mutex_init(&current_incoming->postcopy_prio_thread_mutex);
250e1b1b1bcSPeter Xu     qemu_event_init(&current_incoming->main_thread_load_event, false);
251e1b1b1bcSPeter Xu     qemu_sem_init(&current_incoming->postcopy_pause_sem_dst, 0);
252e1b1b1bcSPeter Xu     qemu_sem_init(&current_incoming->postcopy_pause_sem_fault, 0);
25360bb3c58SPeter Xu     qemu_sem_init(&current_incoming->postcopy_pause_sem_fast_load, 0);
2545655aab0SPeter Xu     qemu_sem_init(&current_incoming->postcopy_qemufile_dst_done, 0);
2555655aab0SPeter Xu 
2568f8bfffcSPeter Xu     qemu_mutex_init(&current_incoming->page_request_mutex);
257cf02f29eSPeter Xu     qemu_cond_init(&current_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, &current_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