Statistics
| Branch: | Revision:

root / migration.c @ 148954fa

History | View | Annotate | Download (12.2 kB)

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

    
14
#include "qemu-common.h"
15
#include "migration.h"
16
#include "monitor.h"
17
#include "buffered_file.h"
18
#include "sysemu.h"
19
#include "block.h"
20
#include "qemu_socket.h"
21
#include "block-migration.h"
22
#include "qemu-objects.h"
23

    
24
//#define DEBUG_MIGRATION
25

    
26
#ifdef DEBUG_MIGRATION
27
#define DPRINTF(fmt, ...) \
28
    do { printf("migration: " fmt, ## __VA_ARGS__); } while (0)
29
#else
30
#define DPRINTF(fmt, ...) \
31
    do { } while (0)
32
#endif
33

    
34
/* Migration speed throttling */
35
static int64_t max_throttle = (32 << 20);
36

    
37
static MigrationState *current_migration;
38

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

    
42
int qemu_start_incoming_migration(const char *uri)
43
{
44
    const char *p;
45
    int ret;
46

    
47
    if (strstart(uri, "tcp:", &p))
48
        ret = tcp_start_incoming_migration(p);
49
#if !defined(WIN32)
50
    else if (strstart(uri, "exec:", &p))
51
        ret =  exec_start_incoming_migration(p);
52
    else if (strstart(uri, "unix:", &p))
53
        ret = unix_start_incoming_migration(p);
54
    else if (strstart(uri, "fd:", &p))
55
        ret = fd_start_incoming_migration(p);
56
#endif
57
    else {
58
        fprintf(stderr, "unknown migration protocol: %s\n", uri);
59
        ret = -EPROTONOSUPPORT;
60
    }
61
    return ret;
62
}
63

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

    
73
    incoming_expected = false;
74

    
75
    if (autostart)
76
        vm_start();
77
}
78

    
79
int do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data)
80
{
81
    MigrationState *s = NULL;
82
    const char *p;
83
    int detach = qdict_get_try_bool(qdict, "detach", 0);
84
    int blk = qdict_get_try_bool(qdict, "blk", 0);
85
    int inc = qdict_get_try_bool(qdict, "inc", 0);
86
    const char *uri = qdict_get_str(qdict, "uri");
87

    
88
    if (current_migration &&
89
        current_migration->get_status(current_migration) == MIG_STATE_ACTIVE) {
90
        monitor_printf(mon, "migration already in progress\n");
91
        return -1;
92
    }
93

    
94
    if (qemu_savevm_state_blocked(mon)) {
95
        return -1;
96
    }
97

    
98
    if (strstart(uri, "tcp:", &p)) {
99
        s = tcp_start_outgoing_migration(mon, p, max_throttle, detach,
100
                                         blk, inc);
101
#if !defined(WIN32)
102
    } else if (strstart(uri, "exec:", &p)) {
103
        s = exec_start_outgoing_migration(mon, p, max_throttle, detach,
104
                                          blk, inc);
105
    } else if (strstart(uri, "unix:", &p)) {
106
        s = unix_start_outgoing_migration(mon, p, max_throttle, detach,
107
                                          blk, inc);
108
    } else if (strstart(uri, "fd:", &p)) {
109
        s = fd_start_outgoing_migration(mon, p, max_throttle, detach, 
110
                                        blk, inc);
111
#endif
112
    } else {
113
        monitor_printf(mon, "unknown migration protocol: %s\n", uri);
114
        return -1;
115
    }
116

    
117
    if (s == NULL) {
118
        monitor_printf(mon, "migration failed\n");
119
        return -1;
120
    }
121

    
122
    if (current_migration) {
123
        current_migration->release(current_migration);
124
    }
125

    
126
    current_migration = s;
127
    notifier_list_notify(&migration_state_notifiers);
128
    return 0;
129
}
130

    
131
int do_migrate_cancel(Monitor *mon, const QDict *qdict, QObject **ret_data)
132
{
133
    MigrationState *s = current_migration;
134

    
135
    if (s)
136
        s->cancel(s);
137

    
138
    return 0;
139
}
140

    
141
int do_migrate_set_speed(Monitor *mon, const QDict *qdict, QObject **ret_data)
142
{
143
    int64_t d;
144
    FdMigrationState *s;
145

    
146
    d = qdict_get_int(qdict, "value");
147
    if (d < 0) {
148
        d = 0;
149
    }
150
    max_throttle = d;
151

    
152
    s = migrate_to_fms(current_migration);
153
    if (s && s->file) {
154
        qemu_file_set_rate_limit(s->file, max_throttle);
155
    }
156

    
157
    return 0;
158
}
159

    
160
/* amount of nanoseconds we are willing to wait for migration to be down.
161
 * the choice of nanoseconds is because it is the maximum resolution that
162
 * get_clock() can achieve. It is an internal measure. All user-visible
163
 * units must be in seconds */
164
static uint64_t max_downtime = 30000000;
165

    
166
uint64_t migrate_max_downtime(void)
167
{
168
    return max_downtime;
169
}
170

    
171
int do_migrate_set_downtime(Monitor *mon, const QDict *qdict,
172
                            QObject **ret_data)
173
{
174
    double d;
175

    
176
    d = qdict_get_double(qdict, "value") * 1e9;
177
    d = MAX(0, MIN(UINT64_MAX, d));
178
    max_downtime = (uint64_t)d;
179

    
180
    return 0;
181
}
182

    
183
static void migrate_print_status(Monitor *mon, const char *name,
184
                                 const QDict *status_dict)
185
{
186
    QDict *qdict;
187

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

    
190
    monitor_printf(mon, "transferred %s: %" PRIu64 " kbytes\n", name,
191
                        qdict_get_int(qdict, "transferred") >> 10);
192
    monitor_printf(mon, "remaining %s: %" PRIu64 " kbytes\n", name,
193
                        qdict_get_int(qdict, "remaining") >> 10);
194
    monitor_printf(mon, "total %s: %" PRIu64 " kbytes\n", name,
195
                        qdict_get_int(qdict, "total") >> 10);
196
}
197

    
198
void do_info_migrate_print(Monitor *mon, const QObject *data)
199
{
200
    QDict *qdict;
201

    
202
    qdict = qobject_to_qdict(data);
203

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

    
207
    if (qdict_haskey(qdict, "ram")) {
208
        migrate_print_status(mon, "ram", qdict);
209
    }
210

    
211
    if (qdict_haskey(qdict, "disk")) {
212
        migrate_print_status(mon, "disk", qdict);
213
    }
214
}
215

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

    
221
    obj = qobject_from_jsonf("{ 'transferred': %" PRId64 ", "
222
                               "'remaining': %" PRId64 ", "
223
                               "'total': %" PRId64 " }", trans, rem, total);
224
    qdict_put_obj(qdict, name, obj);
225
}
226

    
227
void do_info_migrate(Monitor *mon, QObject **ret_data)
228
{
229
    QDict *qdict;
230
    MigrationState *s = current_migration;
231

    
232
    if (s) {
233
        switch (s->get_status(s)) {
234
        case MIG_STATE_ACTIVE:
235
            qdict = qdict_new();
236
            qdict_put(qdict, "status", qstring_from_str("active"));
237

    
238
            migrate_put_status(qdict, "ram", ram_bytes_transferred(),
239
                               ram_bytes_remaining(), ram_bytes_total());
240

    
241
            if (blk_mig_active()) {
242
                migrate_put_status(qdict, "disk", blk_mig_bytes_transferred(),
243
                                   blk_mig_bytes_remaining(),
244
                                   blk_mig_bytes_total());
245
            }
246

    
247
            *ret_data = QOBJECT(qdict);
248
            break;
249
        case MIG_STATE_COMPLETED:
250
            *ret_data = qobject_from_jsonf("{ 'status': 'completed' }");
251
            break;
252
        case MIG_STATE_ERROR:
253
            *ret_data = qobject_from_jsonf("{ 'status': 'failed' }");
254
            break;
255
        case MIG_STATE_CANCELLED:
256
            *ret_data = qobject_from_jsonf("{ 'status': 'cancelled' }");
257
            break;
258
        }
259
    }
260
}
261

    
262
/* shared migration helpers */
263

    
264
void migrate_fd_monitor_suspend(FdMigrationState *s, Monitor *mon)
265
{
266
    s->mon = mon;
267
    if (monitor_suspend(mon) == 0) {
268
        DPRINTF("suspending monitor\n");
269
    } else {
270
        monitor_printf(mon, "terminal does not allow synchronous "
271
                       "migration, continuing detached\n");
272
    }
273
}
274

    
275
void migrate_fd_error(FdMigrationState *s)
276
{
277
    DPRINTF("setting error state\n");
278
    s->state = MIG_STATE_ERROR;
279
    notifier_list_notify(&migration_state_notifiers);
280
    migrate_fd_cleanup(s);
281
}
282

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

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

    
289
    if (s->file) {
290
        DPRINTF("closing file\n");
291
        if (qemu_fclose(s->file) != 0) {
292
            ret = -1;
293
        }
294
        s->file = NULL;
295
    }
296

    
297
    if (s->fd != -1)
298
        close(s->fd);
299

    
300
    /* Don't resume monitor until we've flushed all of the buffers */
301
    if (s->mon) {
302
        monitor_resume(s->mon);
303
    }
304

    
305
    s->fd = -1;
306

    
307
    return ret;
308
}
309

    
310
void migrate_fd_put_notify(void *opaque)
311
{
312
    FdMigrationState *s = opaque;
313

    
314
    qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
315
    qemu_file_put_notify(s->file);
316
}
317

    
318
ssize_t migrate_fd_put_buffer(void *opaque, const void *data, size_t size)
319
{
320
    FdMigrationState *s = opaque;
321
    ssize_t ret;
322

    
323
    do {
324
        ret = s->write(s, data, size);
325
    } while (ret == -1 && ((s->get_error(s)) == EINTR));
326

    
327
    if (ret == -1)
328
        ret = -(s->get_error(s));
329

    
330
    if (ret == -EAGAIN) {
331
        qemu_set_fd_handler2(s->fd, NULL, NULL, migrate_fd_put_notify, s);
332
    } else if (ret < 0) {
333
        if (s->mon) {
334
            monitor_resume(s->mon);
335
        }
336
        s->state = MIG_STATE_ERROR;
337
        notifier_list_notify(&migration_state_notifiers);
338
    }
339

    
340
    return ret;
341
}
342

    
343
void migrate_fd_connect(FdMigrationState *s)
344
{
345
    int ret;
346

    
347
    s->file = qemu_fopen_ops_buffered(s,
348
                                      s->bandwidth_limit,
349
                                      migrate_fd_put_buffer,
350
                                      migrate_fd_put_ready,
351
                                      migrate_fd_wait_for_unfreeze,
352
                                      migrate_fd_close);
353

    
354
    DPRINTF("beginning savevm\n");
355
    ret = qemu_savevm_state_begin(s->mon, s->file, s->mig_state.blk,
356
                                  s->mig_state.shared);
357
    if (ret < 0) {
358
        DPRINTF("failed, %d\n", ret);
359
        migrate_fd_error(s);
360
        return;
361
    }
362
    
363
    migrate_fd_put_ready(s);
364
}
365

    
366
void migrate_fd_put_ready(void *opaque)
367
{
368
    FdMigrationState *s = opaque;
369

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

    
375
    DPRINTF("iterate\n");
376
    if (qemu_savevm_state_iterate(s->mon, s->file) == 1) {
377
        int state;
378
        int old_vm_running = vm_running;
379

    
380
        DPRINTF("done iterating\n");
381
        vm_stop(VMSTOP_MIGRATE);
382

    
383
        if ((qemu_savevm_state_complete(s->mon, s->file)) < 0) {
384
            if (old_vm_running) {
385
                vm_start();
386
            }
387
            state = MIG_STATE_ERROR;
388
        } else {
389
            state = MIG_STATE_COMPLETED;
390
        }
391
        if (migrate_fd_cleanup(s) < 0) {
392
            if (old_vm_running) {
393
                vm_start();
394
            }
395
            state = MIG_STATE_ERROR;
396
        }
397
        s->state = state;
398
        notifier_list_notify(&migration_state_notifiers);
399
    }
400
}
401

    
402
int migrate_fd_get_status(MigrationState *mig_state)
403
{
404
    FdMigrationState *s = migrate_to_fms(mig_state);
405
    return s->state;
406
}
407

    
408
void migrate_fd_cancel(MigrationState *mig_state)
409
{
410
    FdMigrationState *s = migrate_to_fms(mig_state);
411

    
412
    if (s->state != MIG_STATE_ACTIVE)
413
        return;
414

    
415
    DPRINTF("cancelling migration\n");
416

    
417
    s->state = MIG_STATE_CANCELLED;
418
    notifier_list_notify(&migration_state_notifiers);
419
    qemu_savevm_state_cancel(s->mon, s->file);
420

    
421
    migrate_fd_cleanup(s);
422
}
423

    
424
void migrate_fd_release(MigrationState *mig_state)
425
{
426
    FdMigrationState *s = migrate_to_fms(mig_state);
427

    
428
    DPRINTF("releasing state\n");
429
   
430
    if (s->state == MIG_STATE_ACTIVE) {
431
        s->state = MIG_STATE_CANCELLED;
432
        notifier_list_notify(&migration_state_notifiers);
433
        migrate_fd_cleanup(s);
434
    }
435
    qemu_free(s);
436
}
437

    
438
void migrate_fd_wait_for_unfreeze(void *opaque)
439
{
440
    FdMigrationState *s = opaque;
441
    int ret;
442

    
443
    DPRINTF("wait for unfreeze\n");
444
    if (s->state != MIG_STATE_ACTIVE)
445
        return;
446

    
447
    do {
448
        fd_set wfds;
449

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

    
453
        ret = select(s->fd + 1, NULL, &wfds, NULL, NULL);
454
    } while (ret == -1 && (s->get_error(s)) == EINTR);
455
}
456

    
457
int migrate_fd_close(void *opaque)
458
{
459
    FdMigrationState *s = opaque;
460

    
461
    qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
462
    return s->close(s);
463
}
464

    
465
void add_migration_state_change_notifier(Notifier *notify)
466
{
467
    notifier_list_add(&migration_state_notifiers, notify);
468
}
469

    
470
void remove_migration_state_change_notifier(Notifier *notify)
471
{
472
    notifier_list_remove(&migration_state_notifiers, notify);
473
}
474

    
475
int get_migration_state(void)
476
{
477
    if (current_migration) {
478
        return migrate_fd_get_status(current_migration);
479
    } else {
480
        return MIG_STATE_ERROR;
481
    }
482
}