Statistics
| Branch: | Revision:

root / migration.c @ 7267c094

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, NULL);
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, NULL);
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
    } else {
296
        if (s->mon) {
297
            monitor_resume(s->mon);
298
        }
299
    }
300

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

    
306
    return ret;
307
}
308

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

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

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

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

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

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

    
336
    return ret;
337
}
338

    
339
void migrate_fd_connect(FdMigrationState *s)
340
{
341
    int ret;
342

    
343
    s->file = qemu_fopen_ops_buffered(s,
344
                                      s->bandwidth_limit,
345
                                      migrate_fd_put_buffer,
346
                                      migrate_fd_put_ready,
347
                                      migrate_fd_wait_for_unfreeze,
348
                                      migrate_fd_close);
349

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

    
362
void migrate_fd_put_ready(void *opaque)
363
{
364
    FdMigrationState *s = opaque;
365

    
366
    if (s->state != MIG_STATE_ACTIVE) {
367
        DPRINTF("put_ready returning because of non-active state\n");
368
        return;
369
    }
370

    
371
    DPRINTF("iterate\n");
372
    if (qemu_savevm_state_iterate(s->mon, s->file) == 1) {
373
        int state;
374
        int old_vm_running = vm_running;
375

    
376
        DPRINTF("done iterating\n");
377
        vm_stop(VMSTOP_MIGRATE);
378

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

    
398
int migrate_fd_get_status(MigrationState *mig_state)
399
{
400
    FdMigrationState *s = migrate_to_fms(mig_state);
401
    return s->state;
402
}
403

    
404
void migrate_fd_cancel(MigrationState *mig_state)
405
{
406
    FdMigrationState *s = migrate_to_fms(mig_state);
407

    
408
    if (s->state != MIG_STATE_ACTIVE)
409
        return;
410

    
411
    DPRINTF("cancelling migration\n");
412

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

    
417
    migrate_fd_cleanup(s);
418
}
419

    
420
void migrate_fd_release(MigrationState *mig_state)
421
{
422
    FdMigrationState *s = migrate_to_fms(mig_state);
423

    
424
    DPRINTF("releasing state\n");
425
   
426
    if (s->state == MIG_STATE_ACTIVE) {
427
        s->state = MIG_STATE_CANCELLED;
428
        notifier_list_notify(&migration_state_notifiers, NULL);
429
        migrate_fd_cleanup(s);
430
    }
431
    g_free(s);
432
}
433

    
434
void migrate_fd_wait_for_unfreeze(void *opaque)
435
{
436
    FdMigrationState *s = opaque;
437
    int ret;
438

    
439
    DPRINTF("wait for unfreeze\n");
440
    if (s->state != MIG_STATE_ACTIVE)
441
        return;
442

    
443
    do {
444
        fd_set wfds;
445

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

    
449
        ret = select(s->fd + 1, NULL, &wfds, NULL, NULL);
450
    } while (ret == -1 && (s->get_error(s)) == EINTR);
451
}
452

    
453
int migrate_fd_close(void *opaque)
454
{
455
    FdMigrationState *s = opaque;
456

    
457
    if (s->mon) {
458
        monitor_resume(s->mon);
459
    }
460
    qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
461
    return s->close(s);
462
}
463

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

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

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