Statistics
| Branch: | Revision:

root / migration.c @ dcd1d224

History | View | Annotate | Download (12.4 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
    if (autostart) {
74
        vm_start();
75
    } else {
76
        runstate_set(RUN_STATE_PRELAUNCH);
77
    }
78
}
79

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

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

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

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

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

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

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

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

    
136
    if (s && s->get_status(s) == MIG_STATE_ACTIVE) {
137
        s->cancel(s);
138
    }
139
    return 0;
140
}
141

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

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

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

    
158
    return 0;
159
}
160

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

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

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

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

    
181
    return 0;
182
}
183

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

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

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

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

    
203
    qdict = qobject_to_qdict(data);
204

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

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

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

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

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

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

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

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

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

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

    
263
/* shared migration helpers */
264

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

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

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

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

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

    
302
    if (s->fd != -1) {
303
        close(s->fd);
304
        s->fd = -1;
305
    }
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
    if (qemu_file_has_error(s->file)) {
317
        migrate_fd_error(s);
318
    }
319
}
320

    
321
ssize_t migrate_fd_put_buffer(void *opaque, const void *data, size_t size)
322
{
323
    FdMigrationState *s = opaque;
324
    ssize_t ret;
325

    
326
    if (s->state != MIG_STATE_ACTIVE) {
327
        return -EIO;
328
    }
329

    
330
    do {
331
        ret = s->write(s, data, size);
332
    } while (ret == -1 && ((s->get_error(s)) == EINTR));
333

    
334
    if (ret == -1)
335
        ret = -(s->get_error(s));
336

    
337
    if (ret == -EAGAIN) {
338
        qemu_set_fd_handler2(s->fd, NULL, NULL, migrate_fd_put_notify, s);
339
    }
340

    
341
    return ret;
342
}
343

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

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

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

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

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

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

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

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

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

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

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

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

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

    
422
    migrate_fd_cleanup(s);
423
}
424

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

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

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

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

    
448
    do {
449
        fd_set wfds;
450

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

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

    
457
    if (ret == -1) {
458
        qemu_file_set_error(s->file, -s->get_error(s));
459
    }
460
}
461

    
462
int migrate_fd_close(void *opaque)
463
{
464
    FdMigrationState *s = opaque;
465

    
466
    if (s->mon) {
467
        monitor_resume(s->mon);
468
    }
469
    qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
470
    return s->close(s);
471
}
472

    
473
void add_migration_state_change_notifier(Notifier *notify)
474
{
475
    notifier_list_add(&migration_state_notifiers, notify);
476
}
477

    
478
void remove_migration_state_change_notifier(Notifier *notify)
479
{
480
    notifier_list_remove(&migration_state_notifiers, notify);
481
}
482

    
483
int get_migration_state(void)
484
{
485
    if (current_migration) {
486
        return migrate_fd_get_status(current_migration);
487
    } else {
488
        return MIG_STATE_ERROR;
489
    }
490
}