15d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/*
25d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * QEMU live migration
35d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *
45d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Copyright IBM, Corp. 2008
55d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *
65d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Authors:
75d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *  Anthony Liguori   <aliguori@us.ibm.com>
85d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *
95d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * This work is licensed under the terms of the GNU GPL, version 2.  See
105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * the COPYING file in the top-level directory.
115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *
125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */
135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "qemu-common.h"
155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "migration.h"
165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "monitor.h"
175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "buffered_file.h"
185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "sysemu.h"
195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "block.h"
205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "qemu_socket.h"
215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner//#define DEBUG_MIGRATION
235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef DEBUG_MIGRATION
255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define dprintf(fmt, ...) \
265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    do { printf("migration: " fmt, ## __VA_ARGS__); } while (0)
275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define dprintf(fmt, ...) \
295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    do { } while (0)
305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* Migration speed throttling */
335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic uint32_t max_throttle = (32 << 20);
345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic MigrationState *current_migration;
365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid qemu_start_incoming_migration(const char *uri)
385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *p;
405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (strstart(uri, "tcp:", &p))
425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        tcp_start_incoming_migration(p);
435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if !defined(WIN32)
445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else if (strstart(uri, "exec:", &p))
455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        exec_start_incoming_migration(p);
465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else
485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fprintf(stderr, "unknown migration protocol: %s\n", uri);
495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid do_migrate(Monitor *mon, int detach, const char *uri)
525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    MigrationState *s = NULL;
545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *p;
555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (strstart(uri, "tcp:", &p))
575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        s = tcp_start_outgoing_migration(p, max_throttle, detach);
585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if !defined(WIN32)
595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else if (strstart(uri, "exec:", &p))
605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        s = exec_start_outgoing_migration(p, max_throttle, detach);
615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else
635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        monitor_printf(mon, "unknown migration protocol: %s\n", uri);
645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (s == NULL)
665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        monitor_printf(mon, "migration failed\n");
675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else {
685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (current_migration)
695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            current_migration->release(current_migration);
705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        current_migration = s;
725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid do_migrate_cancel(Monitor *mon)
765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    MigrationState *s = current_migration;
785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (s)
805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        s->cancel(s);
815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid do_migrate_set_speed(Monitor *mon, const char *value)
845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    double d;
865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char *ptr;
875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    FdMigrationState *s;
885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    d = strtod(value, &ptr);
905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    switch (*ptr) {
915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 'G': case 'g':
925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        d *= 1024;
935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 'M': case 'm':
945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        d *= 1024;
955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 'K': case 'k':
965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        d *= 1024;
975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    default:
985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
1005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    max_throttle = (uint32_t)d;
1025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s = migrate_to_fms(current_migration);
1035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (s) {
1055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_file_set_rate_limit(s->file, max_throttle);
1065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
1075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
1095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* amount of nanoseconds we are willing to wait for migration to be down.
1115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * the choice of nanoseconds is because it is the maximum resolution that
1125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * get_clock() can achieve. It is an internal measure. All user-visible
1135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * units must be in seconds */
1145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic uint64_t max_downtime = 30000000;
1155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turneruint64_t migrate_max_downtime(void)
1175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
1185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return max_downtime;
1195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
1205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid do_migrate_set_downtime(Monitor *mon, const char *value)
1225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
1235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char *ptr;
1245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    double d;
1255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    d = strtod(value, &ptr);
1275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!strcmp(ptr,"ms")) {
1285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        d *= 1000000;
1295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (!strcmp(ptr,"us")) {
1305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        d *= 1000;
1315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (!strcmp(ptr,"ns")) {
1325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else {
1335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* all else considered to be seconds */
1345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        d *= 1000000000;
1355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
1365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    max_downtime = (uint64_t)d;
1385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
1395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid do_info_migrate(Monitor *mon)
1415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
1425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    MigrationState *s = current_migration;
1435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (s) {
1455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        monitor_printf(mon, "Migration status: ");
1465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        switch (s->get_status(s)) {
1475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case MIG_STATE_ACTIVE:
1485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            monitor_printf(mon, "active\n");
1495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            monitor_printf(mon, "transferred ram: %" PRIu64 " kbytes\n", ram_bytes_transferred() >> 10);
1505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            monitor_printf(mon, "remaining ram: %" PRIu64 " kbytes\n", ram_bytes_remaining() >> 10);
1515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            monitor_printf(mon, "total ram: %" PRIu64 " kbytes\n", ram_bytes_total() >> 10);
1525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
1535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case MIG_STATE_COMPLETED:
1545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            monitor_printf(mon, "completed\n");
1555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
1565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case MIG_STATE_ERROR:
1575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            monitor_printf(mon, "failed\n");
1585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
1595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case MIG_STATE_CANCELLED:
1605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            monitor_printf(mon, "cancelled\n");
1615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
1625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
1635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
1645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
1655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* shared migration helpers */
1675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid migrate_fd_monitor_suspend(FdMigrationState *s)
1695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
1705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->mon_resume = cur_mon;
1715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (monitor_suspend(cur_mon) == 0)
1725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dprintf("suspending monitor\n");
1735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else
1745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        monitor_printf(cur_mon, "terminal does not allow synchronous "
1755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                       "migration, continuing detached\n");
1765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
1775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid migrate_fd_error(FdMigrationState *s)
1795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
1805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    dprintf("setting error state\n");
1815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->state = MIG_STATE_ERROR;
1825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    migrate_fd_cleanup(s);
1835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
1845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid migrate_fd_cleanup(FdMigrationState *s)
1865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
1875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
1885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (s->file) {
1905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dprintf("closing file\n");
1915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_fclose(s->file);
1925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
1935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (s->fd != -1)
1955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        close(s->fd);
1965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* Don't resume monitor until we've flushed all of the buffers */
1985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (s->mon_resume)
1995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        monitor_resume(s->mon_resume);
2005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->fd = -1;
2025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
2035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid migrate_fd_put_notify(void *opaque)
2055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
2065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    FdMigrationState *s = opaque;
2075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
2095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_file_put_notify(s->file);
2105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
2115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerssize_t migrate_fd_put_buffer(void *opaque, const void *data, size_t size)
2135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
2145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    FdMigrationState *s = opaque;
2155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ssize_t ret;
2165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    do {
2185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ret = s->write(s, data, size);
2195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } while (ret == -1 && ((s->get_error(s)) == EINTR));
2205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (ret == -1)
2225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ret = -(s->get_error(s));
2235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (ret == -EAGAIN)
2255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_set_fd_handler2(s->fd, NULL, NULL, migrate_fd_put_notify, s);
2265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return ret;
2285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
2295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid migrate_fd_connect(FdMigrationState *s)
2315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
2325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int ret;
2335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->file = qemu_fopen_ops_buffered(s,
2355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                      s->bandwidth_limit,
2365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                      migrate_fd_put_buffer,
2375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                      migrate_fd_put_ready,
2385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                      migrate_fd_wait_for_unfreeze,
2395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                      migrate_fd_close);
2405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    dprintf("beginning savevm\n");
2425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ret = qemu_savevm_state_begin(s->file);
2435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (ret < 0) {
2445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dprintf("failed, %d\n", ret);
2455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        migrate_fd_error(s);
2465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return;
2475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
2485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    migrate_fd_put_ready(s);
2505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
2515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid migrate_fd_put_ready(void *opaque)
2535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
2545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    FdMigrationState *s = opaque;
2555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (s->state != MIG_STATE_ACTIVE) {
2575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dprintf("put_ready returning because of non-active state\n");
2585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return;
2595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
2605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    dprintf("iterate\n");
2625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (qemu_savevm_state_iterate(s->file) == 1) {
2635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        int state;
2645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        dprintf("done iterating\n");
2655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        vm_stop(0);
2665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        bdrv_flush_all();
2685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if ((qemu_savevm_state_complete(s->file)) < 0) {
2695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            vm_start();
2705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            state = MIG_STATE_ERROR;
2715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else {
2725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            state = MIG_STATE_COMPLETED;
2735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
2745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        migrate_fd_cleanup(s);
2755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        s->state = state;
2765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
2775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
2785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint migrate_fd_get_status(MigrationState *mig_state)
2805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
2815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    FdMigrationState *s = migrate_to_fms(mig_state);
2825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return s->state;
2835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
2845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid migrate_fd_cancel(MigrationState *mig_state)
2865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
2875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    FdMigrationState *s = migrate_to_fms(mig_state);
2885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (s->state != MIG_STATE_ACTIVE)
2905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return;
2915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    dprintf("cancelling migration\n");
2935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->state = MIG_STATE_CANCELLED;
2955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    migrate_fd_cleanup(s);
2975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
2985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid migrate_fd_release(MigrationState *mig_state)
3005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
3015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    FdMigrationState *s = migrate_to_fms(mig_state);
3025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    dprintf("releasing state\n");
3045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (s->state == MIG_STATE_ACTIVE) {
3065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        s->state = MIG_STATE_CANCELLED;
3075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        migrate_fd_cleanup(s);
3085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
3095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    free(s);
3105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
3115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid migrate_fd_wait_for_unfreeze(void *opaque)
3135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
3145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    FdMigrationState *s = opaque;
3155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int ret;
3165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    dprintf("wait for unfreeze\n");
3185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (s->state != MIG_STATE_ACTIVE)
3195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return;
3205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    do {
3225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fd_set wfds;
3235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        FD_ZERO(&wfds);
3255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        FD_SET(s->fd, &wfds);
3265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ret = select(s->fd + 1, NULL, &wfds, NULL, NULL);
3285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } while (ret == -1 && (s->get_error(s)) == EINTR);
3295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
3305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint migrate_fd_close(void *opaque)
3325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
3335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    FdMigrationState *s = opaque;
3345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
3365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return s->close(s);
3375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
338