migration.c 13.0 KB
Newer Older
A
aliguori 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*
 * QEMU live migration
 *
 * Copyright IBM, Corp. 2008
 *
 * Authors:
 *  Anthony Liguori   <aliguori@us.ibm.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2.  See
 * the COPYING file in the top-level directory.
 *
 */

#include "qemu-common.h"
#include "migration.h"
A
aliguori 已提交
16
#include "monitor.h"
17 18 19 20
#include "buffered_file.h"
#include "sysemu.h"
#include "block.h"
#include "qemu_socket.h"
21
#include "block-migration.h"
22
#include "qemu-objects.h"
23 24 25 26

//#define DEBUG_MIGRATION

#ifdef DEBUG_MIGRATION
M
malc 已提交
27
#define DPRINTF(fmt, ...) \
28 29
    do { printf("migration: " fmt, ## __VA_ARGS__); } while (0)
#else
M
malc 已提交
30
#define DPRINTF(fmt, ...) \
31 32
    do { } while (0)
#endif
A
aliguori 已提交
33 34

/* Migration speed throttling */
M
Michael S. Tsirkin 已提交
35
static int64_t max_throttle = (32 << 20);
A
aliguori 已提交
36

37
static MigrationState *current_migration;
A
aliguori 已提交
38

39 40 41
static NotifierList migration_state_notifiers =
    NOTIFIER_LIST_INITIALIZER(migration_state_notifiers);

J
Juan Quintela 已提交
42
int qemu_start_incoming_migration(const char *uri)
A
aliguori 已提交
43
{
A
aliguori 已提交
44
    const char *p;
J
Juan Quintela 已提交
45
    int ret;
A
aliguori 已提交
46 47

    if (strstart(uri, "tcp:", &p))
J
Juan Quintela 已提交
48
        ret = tcp_start_incoming_migration(p);
49 50
#if !defined(WIN32)
    else if (strstart(uri, "exec:", &p))
J
Juan Quintela 已提交
51
        ret =  exec_start_incoming_migration(p);
C
Chris Lalancette 已提交
52
    else if (strstart(uri, "unix:", &p))
J
Juan Quintela 已提交
53
        ret = unix_start_incoming_migration(p);
P
Paolo Bonzini 已提交
54
    else if (strstart(uri, "fd:", &p))
J
Juan Quintela 已提交
55
        ret = fd_start_incoming_migration(p);
56
#endif
J
Juan Quintela 已提交
57
    else {
A
aliguori 已提交
58
        fprintf(stderr, "unknown migration protocol: %s\n", uri);
J
Juan Quintela 已提交
59 60 61
        ret = -EPROTONOSUPPORT;
    }
    return ret;
A
aliguori 已提交
62 63
}

64 65 66 67 68 69 70 71 72
void process_incoming_migration(QEMUFile *f)
{
    if (qemu_loadvm_state(f) < 0) {
        fprintf(stderr, "load of migration failed\n");
        exit(0);
    }
    qemu_announce_self();
    DPRINTF("successfully loaded vm state\n");

73
    if (autostart) {
74
        vm_start();
75
    } else {
76
        runstate_set(RUN_STATE_PRELAUNCH);
77
    }
78 79
}

80 81 82
static MigrationState *migrate_new(Monitor *mon, int64_t bandwidth_limit,
                                   int detach, int blk, int inc);

83
int do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data)
A
aliguori 已提交
84
{
85
    MigrationState *s = NULL;
A
aliguori 已提交
86
    const char *p;
87 88 89
    int detach = qdict_get_try_bool(qdict, "detach", 0);
    int blk = qdict_get_try_bool(qdict, "blk", 0);
    int inc = qdict_get_try_bool(qdict, "inc", 0);
90
    const char *uri = qdict_get_str(qdict, "uri");
91
    int ret;
92 93

    if (current_migration &&
94
        current_migration->get_status(current_migration) == MIG_STATE_ACTIVE) {
95
        monitor_printf(mon, "migration already in progress\n");
96
        return -1;
97 98
    }

A
Alex Williamson 已提交
99 100 101 102
    if (qemu_savevm_state_blocked(mon)) {
        return -1;
    }

103 104
    s = migrate_new(mon, max_throttle, detach, blk, inc);

105
    if (strstart(uri, "tcp:", &p)) {
106
        ret = tcp_start_outgoing_migration(s, p);
107
#if !defined(WIN32)
108
    } else if (strstart(uri, "exec:", &p)) {
109
        ret = exec_start_outgoing_migration(s, p);
110
    } else if (strstart(uri, "unix:", &p)) {
111
        ret = unix_start_outgoing_migration(s, p);
112
    } else if (strstart(uri, "fd:", &p)) {
113
        ret = fd_start_outgoing_migration(s, p);
114
#endif
115
    } else {
A
aliguori 已提交
116
        monitor_printf(mon, "unknown migration protocol: %s\n", uri);
117 118
        ret  = -EINVAL;
        goto free_migrate_state;
119
    }
A
aliguori 已提交
120

121
    if (ret < 0) {
A
aliguori 已提交
122
        monitor_printf(mon, "migration failed\n");
123
        goto free_migrate_state;
124
    }
A
aliguori 已提交
125

126
    if (current_migration) {
127
        current_migration->release(current_migration);
A
aliguori 已提交
128
    }
129

130
    current_migration = s;
131
    notifier_list_notify(&migration_state_notifiers, NULL);
132
    return 0;
133 134 135
free_migrate_state:
    g_free(s);
    return -1;
A
aliguori 已提交
136 137
}

138
int do_migrate_cancel(Monitor *mon, const QDict *qdict, QObject **ret_data)
A
aliguori 已提交
139
{
140
    MigrationState *s = current_migration;
A
aliguori 已提交
141

142 143
    if (s && s->get_status(s) == MIG_STATE_ACTIVE) {
        s->cancel(s);
144
    }
145
    return 0;
A
aliguori 已提交
146 147
}

148
int do_migrate_set_speed(Monitor *mon, const QDict *qdict, QObject **ret_data)
A
aliguori 已提交
149
{
150
    int64_t d;
151
    MigrationState *s;
A
aliguori 已提交
152

153
    d = qdict_get_int(qdict, "value");
M
Michael S. Tsirkin 已提交
154 155 156
    if (d < 0) {
        d = 0;
    }
157
    max_throttle = d;
158

159
    s = current_migration;
160
    if (s && s->file) {
161 162
        qemu_file_set_rate_limit(s->file, max_throttle);
    }
163 164

    return 0;
A
aliguori 已提交
165 166
}

167 168 169 170 171 172 173 174 175 176 177
/* amount of nanoseconds we are willing to wait for migration to be down.
 * the choice of nanoseconds is because it is the maximum resolution that
 * get_clock() can achieve. It is an internal measure. All user-visible
 * units must be in seconds */
static uint64_t max_downtime = 30000000;

uint64_t migrate_max_downtime(void)
{
    return max_downtime;
}

178 179
int do_migrate_set_downtime(Monitor *mon, const QDict *qdict,
                            QObject **ret_data)
G
Glauber Costa 已提交
180 181 182
{
    double d;

183 184
    d = qdict_get_double(qdict, "value") * 1e9;
    d = MAX(0, MIN(UINT64_MAX, d));
G
Glauber Costa 已提交
185
    max_downtime = (uint64_t)d;
186 187

    return 0;
G
Glauber Costa 已提交
188 189
}

190 191
static void migrate_print_status(Monitor *mon, const char *name,
                                 const QDict *status_dict)
A
aliguori 已提交
192
{
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236
    QDict *qdict;

    qdict = qobject_to_qdict(qdict_get(status_dict, name));

    monitor_printf(mon, "transferred %s: %" PRIu64 " kbytes\n", name,
                        qdict_get_int(qdict, "transferred") >> 10);
    monitor_printf(mon, "remaining %s: %" PRIu64 " kbytes\n", name,
                        qdict_get_int(qdict, "remaining") >> 10);
    monitor_printf(mon, "total %s: %" PRIu64 " kbytes\n", name,
                        qdict_get_int(qdict, "total") >> 10);
}

void do_info_migrate_print(Monitor *mon, const QObject *data)
{
    QDict *qdict;

    qdict = qobject_to_qdict(data);

    monitor_printf(mon, "Migration status: %s\n",
                   qdict_get_str(qdict, "status"));

    if (qdict_haskey(qdict, "ram")) {
        migrate_print_status(mon, "ram", qdict);
    }

    if (qdict_haskey(qdict, "disk")) {
        migrate_print_status(mon, "disk", qdict);
    }
}

static void migrate_put_status(QDict *qdict, const char *name,
                               uint64_t trans, uint64_t rem, uint64_t total)
{
    QObject *obj;

    obj = qobject_from_jsonf("{ 'transferred': %" PRId64 ", "
                               "'remaining': %" PRId64 ", "
                               "'total': %" PRId64 " }", trans, rem, total);
    qdict_put_obj(qdict, name, obj);
}

void do_info_migrate(Monitor *mon, QObject **ret_data)
{
    QDict *qdict;
A
aliguori 已提交
237

238
    if (current_migration) {
239
        MigrationState *s = current_migration;
240 241

        switch (s->get_status(current_migration)) {
242 243 244
        case MIG_STATE_SETUP:
            /* no migration has happened ever */
            break;
A
aliguori 已提交
245
        case MIG_STATE_ACTIVE:
246 247 248 249 250 251
            qdict = qdict_new();
            qdict_put(qdict, "status", qstring_from_str("active"));

            migrate_put_status(qdict, "ram", ram_bytes_transferred(),
                               ram_bytes_remaining(), ram_bytes_total());

252
            if (blk_mig_active()) {
253 254 255
                migrate_put_status(qdict, "disk", blk_mig_bytes_transferred(),
                                   blk_mig_bytes_remaining(),
                                   blk_mig_bytes_total());
256
            }
257 258

            *ret_data = QOBJECT(qdict);
A
aliguori 已提交
259 260
            break;
        case MIG_STATE_COMPLETED:
261
            *ret_data = qobject_from_jsonf("{ 'status': 'completed' }");
A
aliguori 已提交
262 263
            break;
        case MIG_STATE_ERROR:
264
            *ret_data = qobject_from_jsonf("{ 'status': 'failed' }");
A
aliguori 已提交
265 266
            break;
        case MIG_STATE_CANCELLED:
267
            *ret_data = qobject_from_jsonf("{ 'status': 'cancelled' }");
A
aliguori 已提交
268 269
            break;
        }
A
aliguori 已提交
270 271 272
    }
}

273 274
/* shared migration helpers */

275
static void migrate_fd_monitor_suspend(MigrationState *s, Monitor *mon)
276
{
277 278
    s->mon = mon;
    if (monitor_suspend(mon) == 0) {
M
malc 已提交
279
        DPRINTF("suspending monitor\n");
280 281
    } else {
        monitor_printf(mon, "terminal does not allow synchronous "
282
                       "migration, continuing detached\n");
283
    }
284 285
}

286
static int migrate_fd_cleanup(MigrationState *s)
287
{
288 289
    int ret = 0;

290 291 292
    qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);

    if (s->file) {
M
malc 已提交
293
        DPRINTF("closing file\n");
294 295 296
        if (qemu_fclose(s->file) != 0) {
            ret = -1;
        }
297
        s->file = NULL;
298 299 300 301
    } else {
        if (s->mon) {
            monitor_resume(s->mon);
        }
302 303
    }

304
    if (s->fd != -1) {
305
        close(s->fd);
306
        s->fd = -1;
307
    }
308

309
    return ret;
310 311
}

312 313 314 315 316 317 318 319 320
void migrate_fd_error(MigrationState *s)
{
    DPRINTF("setting error state\n");
    s->state = MIG_STATE_ERROR;
    notifier_list_notify(&migration_state_notifiers, NULL);
    migrate_fd_cleanup(s);
}

static void migrate_fd_put_notify(void *opaque)
321
{
322
    MigrationState *s = opaque;
323 324 325

    qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
    qemu_file_put_notify(s->file);
326
    if (qemu_file_get_error(s->file)) {
327 328
        migrate_fd_error(s);
    }
329 330
}

331 332
static ssize_t migrate_fd_put_buffer(void *opaque, const void *data,
                                     size_t size)
333
{
334
    MigrationState *s = opaque;
335 336
    ssize_t ret;

337 338 339 340
    if (s->state != MIG_STATE_ACTIVE) {
        return -EIO;
    }

341 342
    do {
        ret = s->write(s, data, size);
343
    } while (ret == -1 && ((s->get_error(s)) == EINTR));
344 345 346 347

    if (ret == -1)
        ret = -(s->get_error(s));

348
    if (ret == -EAGAIN) {
349
        qemu_set_fd_handler2(s->fd, NULL, NULL, migrate_fd_put_notify, s);
350
    }
351 352 353 354

    return ret;
}

355
static void migrate_fd_put_ready(void *opaque)
356
{
357
    MigrationState *s = opaque;
J
Juan Quintela 已提交
358
    int ret;
359 360

    if (s->state != MIG_STATE_ACTIVE) {
M
malc 已提交
361
        DPRINTF("put_ready returning because of non-active state\n");
362 363 364
        return;
    }

M
malc 已提交
365
    DPRINTF("iterate\n");
J
Juan Quintela 已提交
366 367 368 369
    ret = qemu_savevm_state_iterate(s->mon, s->file);
    if (ret < 0) {
        migrate_fd_error(s);
    } else if (ret == 1) {
370
        int old_vm_running = runstate_is_running();
371

M
malc 已提交
372
        DPRINTF("done iterating\n");
373
        vm_stop(RUN_STATE_FINISH_MIGRATE);
374

375 376 377 378 379 380 381 382 383
        if (qemu_savevm_state_complete(s->mon, s->file) < 0) {
            migrate_fd_error(s);
        } else {
            if (migrate_fd_cleanup(s) < 0) {
                migrate_fd_error(s);
            } else {
                s->state = MIG_STATE_COMPLETED;
                runstate_set(RUN_STATE_POSTMIGRATE);
                notifier_list_notify(&migration_state_notifiers, NULL);
384
            }
385
        }
386
        if (s->get_status(s) != MIG_STATE_COMPLETED) {
387 388 389 390
            if (old_vm_running) {
                vm_start();
            }
        }
391 392 393
    }
}

394
static int migrate_fd_get_status(MigrationState *s)
395 396 397 398
{
    return s->state;
}

399
static void migrate_fd_cancel(MigrationState *s)
400 401 402 403
{
    if (s->state != MIG_STATE_ACTIVE)
        return;

M
malc 已提交
404
    DPRINTF("cancelling migration\n");
405 406

    s->state = MIG_STATE_CANCELLED;
407
    notifier_list_notify(&migration_state_notifiers, NULL);
408
    qemu_savevm_state_cancel(s->mon, s->file);
409 410 411 412

    migrate_fd_cleanup(s);
}

413
static void migrate_fd_release(MigrationState *s)
414 415
{

M
malc 已提交
416
    DPRINTF("releasing state\n");
417 418 419
   
    if (s->state == MIG_STATE_ACTIVE) {
        s->state = MIG_STATE_CANCELLED;
420
        notifier_list_notify(&migration_state_notifiers, NULL);
421 422
        migrate_fd_cleanup(s);
    }
423
    g_free(s);
424 425
}

426
static void migrate_fd_wait_for_unfreeze(void *opaque)
427
{
428
    MigrationState *s = opaque;
429 430
    int ret;

M
malc 已提交
431
    DPRINTF("wait for unfreeze\n");
432 433 434 435 436 437 438 439 440 441 442
    if (s->state != MIG_STATE_ACTIVE)
        return;

    do {
        fd_set wfds;

        FD_ZERO(&wfds);
        FD_SET(s->fd, &wfds);

        ret = select(s->fd + 1, NULL, &wfds, NULL, NULL);
    } while (ret == -1 && (s->get_error(s)) == EINTR);
443 444

    if (ret == -1) {
445
        qemu_file_set_error(s->file, -s->get_error(s));
446
    }
447 448
}

449
static int migrate_fd_close(void *opaque)
450
{
451
    MigrationState *s = opaque;
452

453 454 455
    if (s->mon) {
        monitor_resume(s->mon);
    }
456
    qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
457 458
    return s->close(s);
}
459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477

void add_migration_state_change_notifier(Notifier *notify)
{
    notifier_list_add(&migration_state_notifiers, notify);
}

void remove_migration_state_change_notifier(Notifier *notify)
{
    notifier_list_remove(&migration_state_notifiers, notify);
}

int get_migration_state(void)
{
    if (current_migration) {
        return migrate_fd_get_status(current_migration);
    } else {
        return MIG_STATE_ERROR;
    }
}
478

479 480 481 482
void migrate_fd_connect(MigrationState *s)
{
    int ret;

483
    s->state = MIG_STATE_ACTIVE;
484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500
    s->file = qemu_fopen_ops_buffered(s,
                                      s->bandwidth_limit,
                                      migrate_fd_put_buffer,
                                      migrate_fd_put_ready,
                                      migrate_fd_wait_for_unfreeze,
                                      migrate_fd_close);

    DPRINTF("beginning savevm\n");
    ret = qemu_savevm_state_begin(s->mon, s->file, s->blk, s->shared);
    if (ret < 0) {
        DPRINTF("failed, %d\n", ret);
        migrate_fd_error(s);
        return;
    }
    migrate_fd_put_ready(s);
}

501 502
static MigrationState *migrate_new(Monitor *mon, int64_t bandwidth_limit,
                                   int detach, int blk, int inc)
503 504 505 506 507 508 509 510 511 512
{
    MigrationState *s = g_malloc0(sizeof(*s));

    s->cancel = migrate_fd_cancel;
    s->get_status = migrate_fd_get_status;
    s->release = migrate_fd_release;
    s->blk = blk;
    s->shared = inc;
    s->mon = NULL;
    s->bandwidth_limit = bandwidth_limit;
513
    s->state = MIG_STATE_SETUP;
514 515 516 517 518 519 520

    if (!detach) {
        migrate_fd_monitor_suspend(s, mon);
    }

    return s;
}