migration.c 12.7 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
    g_free(current_migration);
127
    current_migration = s;
128
    notifier_list_notify(&migration_state_notifiers, NULL);
129
    return 0;
130 131 132
free_migrate_state:
    g_free(s);
    return -1;
A
aliguori 已提交
133 134
}

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

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

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

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

156
    s = current_migration;
157
    if (s && s->file) {
158 159
        qemu_file_set_rate_limit(s->file, max_throttle);
    }
160 161

    return 0;
A
aliguori 已提交
162 163
}

164 165 166 167 168 169 170 171 172 173 174
/* 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;
}

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

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

    return 0;
G
Glauber Costa 已提交
185 186
}

187 188
static void migrate_print_status(Monitor *mon, const char *name,
                                 const QDict *status_dict)
A
aliguori 已提交
189
{
190 191 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
    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 已提交
234

235
    if (current_migration) {
236
        MigrationState *s = current_migration;
237 238

        switch (s->get_status(current_migration)) {
239 240 241
        case MIG_STATE_SETUP:
            /* no migration has happened ever */
            break;
A
aliguori 已提交
242
        case MIG_STATE_ACTIVE:
243 244 245 246 247 248
            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());

249
            if (blk_mig_active()) {
250 251 252
                migrate_put_status(qdict, "disk", blk_mig_bytes_transferred(),
                                   blk_mig_bytes_remaining(),
                                   blk_mig_bytes_total());
253
            }
254 255

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

270 271
/* shared migration helpers */

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

283
static int migrate_fd_cleanup(MigrationState *s)
284
{
285 286
    int ret = 0;

287 288 289
    qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);

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

301
    if (s->fd != -1) {
302
        close(s->fd);
303
        s->fd = -1;
304
    }
305

306
    return ret;
307 308
}

309 310 311 312 313 314 315 316
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);
}

317 318 319 320 321 322 323 324 325 326 327 328
static void migrate_fd_completed(MigrationState *s)
{
    DPRINTF("setting completed state\n");
    if (migrate_fd_cleanup(s) < 0) {
        s->state = MIG_STATE_ERROR;
    } else {
        s->state = MIG_STATE_COMPLETED;
        runstate_set(RUN_STATE_POSTMIGRATE);
    }
    notifier_list_notify(&migration_state_notifiers, NULL);
}

329
static void migrate_fd_put_notify(void *opaque)
330
{
331
    MigrationState *s = opaque;
332 333 334

    qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
    qemu_file_put_notify(s->file);
335
    if (qemu_file_get_error(s->file)) {
336 337
        migrate_fd_error(s);
    }
338 339
}

340 341
static ssize_t migrate_fd_put_buffer(void *opaque, const void *data,
                                     size_t size)
342
{
343
    MigrationState *s = opaque;
344 345
    ssize_t ret;

346 347 348 349
    if (s->state != MIG_STATE_ACTIVE) {
        return -EIO;
    }

350 351
    do {
        ret = s->write(s, data, size);
352
    } while (ret == -1 && ((s->get_error(s)) == EINTR));
353 354 355 356

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

357
    if (ret == -EAGAIN) {
358
        qemu_set_fd_handler2(s->fd, NULL, NULL, migrate_fd_put_notify, s);
359
    }
360 361 362 363

    return ret;
}

364
static void migrate_fd_put_ready(void *opaque)
365
{
366
    MigrationState *s = opaque;
J
Juan Quintela 已提交
367
    int ret;
368 369

    if (s->state != MIG_STATE_ACTIVE) {
M
malc 已提交
370
        DPRINTF("put_ready returning because of non-active state\n");
371 372 373
        return;
    }

M
malc 已提交
374
    DPRINTF("iterate\n");
J
Juan Quintela 已提交
375 376 377 378
    ret = qemu_savevm_state_iterate(s->mon, s->file);
    if (ret < 0) {
        migrate_fd_error(s);
    } else if (ret == 1) {
379
        int old_vm_running = runstate_is_running();
380

M
malc 已提交
381
        DPRINTF("done iterating\n");
382
        vm_stop(RUN_STATE_FINISH_MIGRATE);
383

384 385 386
        if (qemu_savevm_state_complete(s->mon, s->file) < 0) {
            migrate_fd_error(s);
        } else {
387
            migrate_fd_completed(s);
388
        }
389
        if (s->get_status(s) != MIG_STATE_COMPLETED) {
390 391 392 393
            if (old_vm_running) {
                vm_start();
            }
        }
394 395 396
    }
}

397
static int migrate_fd_get_status(MigrationState *s)
398 399 400 401
{
    return s->state;
}

402
static void migrate_fd_cancel(MigrationState *s)
403 404 405 406
{
    if (s->state != MIG_STATE_ACTIVE)
        return;

M
malc 已提交
407
    DPRINTF("cancelling migration\n");
408 409

    s->state = MIG_STATE_CANCELLED;
410
    notifier_list_notify(&migration_state_notifiers, NULL);
411
    qemu_savevm_state_cancel(s->mon, s->file);
412 413 414 415

    migrate_fd_cleanup(s);
}

416
static void migrate_fd_wait_for_unfreeze(void *opaque)
417
{
418
    MigrationState *s = opaque;
419 420
    int ret;

M
malc 已提交
421
    DPRINTF("wait for unfreeze\n");
422 423 424 425 426 427 428 429 430 431 432
    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);
433 434

    if (ret == -1) {
435
        qemu_file_set_error(s->file, -s->get_error(s));
436
    }
437 438
}

439
static int migrate_fd_close(void *opaque)
440
{
441
    MigrationState *s = opaque;
442

443 444 445
    if (s->mon) {
        monitor_resume(s->mon);
    }
446
    qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
447 448
    return s->close(s);
}
449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467

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;
    }
}
468

469 470 471 472
void migrate_fd_connect(MigrationState *s)
{
    int ret;

473
    s->state = MIG_STATE_ACTIVE;
474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490
    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);
}

491 492
static MigrationState *migrate_new(Monitor *mon, int64_t bandwidth_limit,
                                   int detach, int blk, int inc)
493 494 495 496 497 498 499 500 501
{
    MigrationState *s = g_malloc0(sizeof(*s));

    s->cancel = migrate_fd_cancel;
    s->get_status = migrate_fd_get_status;
    s->blk = blk;
    s->shared = inc;
    s->mon = NULL;
    s->bandwidth_limit = bandwidth_limit;
502
    s->state = MIG_STATE_SETUP;
503 504 505 506 507 508 509

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

    return s;
}