migration.c 12.9 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)) {
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 317
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)
318
{
319
    MigrationState *s = opaque;
320 321 322

    qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
    qemu_file_put_notify(s->file);
323
    if (qemu_file_get_error(s->file)) {
324 325
        migrate_fd_error(s);
    }
326 327
}

328 329
static ssize_t migrate_fd_put_buffer(void *opaque, const void *data,
                                     size_t size)
330
{
331
    MigrationState *s = opaque;
332 333
    ssize_t ret;

334 335 336 337
    if (s->state != MIG_STATE_ACTIVE) {
        return -EIO;
    }

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

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

345
    if (ret == -EAGAIN) {
346
        qemu_set_fd_handler2(s->fd, NULL, NULL, migrate_fd_put_notify, s);
347
    }
348 349 350 351

    return ret;
}

352
static void migrate_fd_put_ready(void *opaque)
353
{
354
    MigrationState *s = opaque;
J
Juan Quintela 已提交
355
    int ret;
356 357

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

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

M
malc 已提交
369
        DPRINTF("done iterating\n");
370
        vm_stop(RUN_STATE_FINISH_MIGRATE);
371

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

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

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

M
malc 已提交
402
    DPRINTF("cancelling migration\n");
403 404

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

    migrate_fd_cleanup(s);
}

411
static void migrate_fd_release(MigrationState *s)
412 413
{

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

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

M
malc 已提交
429
    DPRINTF("wait for unfreeze\n");
430 431 432 433 434 435 436 437 438 439 440
    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);
441 442

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

447
static int migrate_fd_close(void *opaque)
448
{
449
    MigrationState *s = opaque;
450

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

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

477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497
void migrate_fd_connect(MigrationState *s)
{
    int ret;

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

498 499
static MigrationState *migrate_new(Monitor *mon, int64_t bandwidth_limit,
                                   int detach, int blk, int inc)
500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517
{
    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;
    s->state = MIG_STATE_ACTIVE;

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

    return s;
}