Statistics
| Branch: | Revision:

root / migration.c @ f58ae59c

History | View | Annotate | Download (11.1 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 uint32_t max_throttle = (32 << 20);
36

    
37
static MigrationState *current_migration;
38

    
39
int qemu_start_incoming_migration(const char *uri)
40
{
41
    const char *p;
42
    int ret;
43

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

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

    
70
    if (autostart)
71
        vm_start();
72
}
73

    
74
int do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data)
75
{
76
    MigrationState *s = NULL;
77
    const char *p;
78
    int detach = qdict_get_try_bool(qdict, "detach", 0);
79
    int blk = qdict_get_try_bool(qdict, "blk", 0);
80
    int inc = qdict_get_try_bool(qdict, "inc", 0);
81
    const char *uri = qdict_get_str(qdict, "uri");
82

    
83
    if (current_migration &&
84
        current_migration->get_status(current_migration) == MIG_STATE_ACTIVE) {
85
        monitor_printf(mon, "migration already in progress\n");
86
        return -1;
87
    }
88

    
89
    if (strstart(uri, "tcp:", &p)) {
90
        s = tcp_start_outgoing_migration(mon, p, max_throttle, detach,
91
                                         blk, inc);
92
#if !defined(WIN32)
93
    } else if (strstart(uri, "exec:", &p)) {
94
        s = exec_start_outgoing_migration(mon, p, max_throttle, detach,
95
                                          blk, inc);
96
    } else if (strstart(uri, "unix:", &p)) {
97
        s = unix_start_outgoing_migration(mon, p, max_throttle, detach,
98
                                          blk, inc);
99
    } else if (strstart(uri, "fd:", &p)) {
100
        s = fd_start_outgoing_migration(mon, p, max_throttle, detach, 
101
                                        blk, inc);
102
#endif
103
    } else {
104
        monitor_printf(mon, "unknown migration protocol: %s\n", uri);
105
        return -1;
106
    }
107

    
108
    if (s == NULL) {
109
        monitor_printf(mon, "migration failed\n");
110
        return -1;
111
    }
112

    
113
    if (current_migration) {
114
        current_migration->release(current_migration);
115
    }
116

    
117
    current_migration = s;
118
    return 0;
119
}
120

    
121
int do_migrate_cancel(Monitor *mon, const QDict *qdict, QObject **ret_data)
122
{
123
    MigrationState *s = current_migration;
124

    
125
    if (s)
126
        s->cancel(s);
127

    
128
    return 0;
129
}
130

    
131
int do_migrate_set_speed(Monitor *mon, const QDict *qdict, QObject **ret_data)
132
{
133
    double d;
134
    FdMigrationState *s;
135

    
136
    d = qdict_get_double(qdict, "value");
137
    d = MAX(0, MIN(UINT32_MAX, d));
138
    max_throttle = d;
139

    
140
    s = migrate_to_fms(current_migration);
141
    if (s && s->file) {
142
        qemu_file_set_rate_limit(s->file, max_throttle);
143
    }
144

    
145
    return 0;
146
}
147

    
148
/* amount of nanoseconds we are willing to wait for migration to be down.
149
 * the choice of nanoseconds is because it is the maximum resolution that
150
 * get_clock() can achieve. It is an internal measure. All user-visible
151
 * units must be in seconds */
152
static uint64_t max_downtime = 30000000;
153

    
154
uint64_t migrate_max_downtime(void)
155
{
156
    return max_downtime;
157
}
158

    
159
int do_migrate_set_downtime(Monitor *mon, const QDict *qdict,
160
                            QObject **ret_data)
161
{
162
    double d;
163

    
164
    d = qdict_get_double(qdict, "value") * 1e9;
165
    d = MAX(0, MIN(UINT64_MAX, d));
166
    max_downtime = (uint64_t)d;
167

    
168
    return 0;
169
}
170

    
171
static void migrate_print_status(Monitor *mon, const char *name,
172
                                 const QDict *status_dict)
173
{
174
    QDict *qdict;
175

    
176
    qdict = qobject_to_qdict(qdict_get(status_dict, name));
177

    
178
    monitor_printf(mon, "transferred %s: %" PRIu64 " kbytes\n", name,
179
                        qdict_get_int(qdict, "transferred") >> 10);
180
    monitor_printf(mon, "remaining %s: %" PRIu64 " kbytes\n", name,
181
                        qdict_get_int(qdict, "remaining") >> 10);
182
    monitor_printf(mon, "total %s: %" PRIu64 " kbytes\n", name,
183
                        qdict_get_int(qdict, "total") >> 10);
184
}
185

    
186
void do_info_migrate_print(Monitor *mon, const QObject *data)
187
{
188
    QDict *qdict;
189

    
190
    qdict = qobject_to_qdict(data);
191

    
192
    monitor_printf(mon, "Migration status: %s\n",
193
                   qdict_get_str(qdict, "status"));
194

    
195
    if (qdict_haskey(qdict, "ram")) {
196
        migrate_print_status(mon, "ram", qdict);
197
    }
198

    
199
    if (qdict_haskey(qdict, "disk")) {
200
        migrate_print_status(mon, "disk", qdict);
201
    }
202
}
203

    
204
static void migrate_put_status(QDict *qdict, const char *name,
205
                               uint64_t trans, uint64_t rem, uint64_t total)
206
{
207
    QObject *obj;
208

    
209
    obj = qobject_from_jsonf("{ 'transferred': %" PRId64 ", "
210
                               "'remaining': %" PRId64 ", "
211
                               "'total': %" PRId64 " }", trans, rem, total);
212
    qdict_put_obj(qdict, name, obj);
213
}
214

    
215
void do_info_migrate(Monitor *mon, QObject **ret_data)
216
{
217
    QDict *qdict;
218
    MigrationState *s = current_migration;
219

    
220
    if (s) {
221
        switch (s->get_status(s)) {
222
        case MIG_STATE_ACTIVE:
223
            qdict = qdict_new();
224
            qdict_put(qdict, "status", qstring_from_str("active"));
225

    
226
            migrate_put_status(qdict, "ram", ram_bytes_transferred(),
227
                               ram_bytes_remaining(), ram_bytes_total());
228

    
229
            if (blk_mig_active()) {
230
                migrate_put_status(qdict, "disk", blk_mig_bytes_transferred(),
231
                                   blk_mig_bytes_remaining(),
232
                                   blk_mig_bytes_total());
233
            }
234

    
235
            *ret_data = QOBJECT(qdict);
236
            break;
237
        case MIG_STATE_COMPLETED:
238
            *ret_data = qobject_from_jsonf("{ 'status': 'completed' }");
239
            break;
240
        case MIG_STATE_ERROR:
241
            *ret_data = qobject_from_jsonf("{ 'status': 'failed' }");
242
            break;
243
        case MIG_STATE_CANCELLED:
244
            *ret_data = qobject_from_jsonf("{ 'status': 'cancelled' }");
245
            break;
246
        }
247
    }
248
}
249

    
250
/* shared migration helpers */
251

    
252
void migrate_fd_monitor_suspend(FdMigrationState *s, Monitor *mon)
253
{
254
    s->mon = mon;
255
    if (monitor_suspend(mon) == 0) {
256
        DPRINTF("suspending monitor\n");
257
    } else {
258
        monitor_printf(mon, "terminal does not allow synchronous "
259
                       "migration, continuing detached\n");
260
    }
261
}
262

    
263
void migrate_fd_error(FdMigrationState *s)
264
{
265
    DPRINTF("setting error state\n");
266
    s->state = MIG_STATE_ERROR;
267
    migrate_fd_cleanup(s);
268
}
269

    
270
int migrate_fd_cleanup(FdMigrationState *s)
271
{
272
    int ret = 0;
273

    
274
    qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
275

    
276
    if (s->file) {
277
        DPRINTF("closing file\n");
278
        if (qemu_fclose(s->file) != 0) {
279
            ret = -1;
280
        }
281
        s->file = NULL;
282
    }
283

    
284
    if (s->fd != -1)
285
        close(s->fd);
286

    
287
    /* Don't resume monitor until we've flushed all of the buffers */
288
    if (s->mon) {
289
        monitor_resume(s->mon);
290
    }
291

    
292
    s->fd = -1;
293

    
294
    return ret;
295
}
296

    
297
void migrate_fd_put_notify(void *opaque)
298
{
299
    FdMigrationState *s = opaque;
300

    
301
    qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
302
    qemu_file_put_notify(s->file);
303
}
304

    
305
ssize_t migrate_fd_put_buffer(void *opaque, const void *data, size_t size)
306
{
307
    FdMigrationState *s = opaque;
308
    ssize_t ret;
309

    
310
    do {
311
        ret = s->write(s, data, size);
312
    } while (ret == -1 && ((s->get_error(s)) == EINTR));
313

    
314
    if (ret == -1)
315
        ret = -(s->get_error(s));
316

    
317
    if (ret == -EAGAIN)
318
        qemu_set_fd_handler2(s->fd, NULL, NULL, migrate_fd_put_notify, s);
319

    
320
    return ret;
321
}
322

    
323
void migrate_fd_connect(FdMigrationState *s)
324
{
325
    int ret;
326

    
327
    s->file = qemu_fopen_ops_buffered(s,
328
                                      s->bandwidth_limit,
329
                                      migrate_fd_put_buffer,
330
                                      migrate_fd_put_ready,
331
                                      migrate_fd_wait_for_unfreeze,
332
                                      migrate_fd_close);
333

    
334
    DPRINTF("beginning savevm\n");
335
    ret = qemu_savevm_state_begin(s->mon, s->file, s->mig_state.blk,
336
                                  s->mig_state.shared);
337
    if (ret < 0) {
338
        DPRINTF("failed, %d\n", ret);
339
        migrate_fd_error(s);
340
        return;
341
    }
342
    
343
    migrate_fd_put_ready(s);
344
}
345

    
346
void migrate_fd_put_ready(void *opaque)
347
{
348
    FdMigrationState *s = opaque;
349

    
350
    if (s->state != MIG_STATE_ACTIVE) {
351
        DPRINTF("put_ready returning because of non-active state\n");
352
        return;
353
    }
354

    
355
    DPRINTF("iterate\n");
356
    if (qemu_savevm_state_iterate(s->mon, s->file) == 1) {
357
        int state;
358
        int old_vm_running = vm_running;
359

    
360
        DPRINTF("done iterating\n");
361
        vm_stop(0);
362

    
363
        qemu_aio_flush();
364
        bdrv_flush_all();
365
        if ((qemu_savevm_state_complete(s->mon, s->file)) < 0) {
366
            if (old_vm_running) {
367
                vm_start();
368
            }
369
            state = MIG_STATE_ERROR;
370
        } else {
371
            state = MIG_STATE_COMPLETED;
372
        }
373
        if (migrate_fd_cleanup(s) < 0) {
374
            if (old_vm_running) {
375
                vm_start();
376
            }
377
            state = MIG_STATE_ERROR;
378
        }
379
        s->state = state;
380
    }
381
}
382

    
383
int migrate_fd_get_status(MigrationState *mig_state)
384
{
385
    FdMigrationState *s = migrate_to_fms(mig_state);
386
    return s->state;
387
}
388

    
389
void migrate_fd_cancel(MigrationState *mig_state)
390
{
391
    FdMigrationState *s = migrate_to_fms(mig_state);
392

    
393
    if (s->state != MIG_STATE_ACTIVE)
394
        return;
395

    
396
    DPRINTF("cancelling migration\n");
397

    
398
    s->state = MIG_STATE_CANCELLED;
399
    qemu_savevm_state_cancel(s->mon, s->file);
400

    
401
    migrate_fd_cleanup(s);
402
}
403

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

    
408
    DPRINTF("releasing state\n");
409
   
410
    if (s->state == MIG_STATE_ACTIVE) {
411
        s->state = MIG_STATE_CANCELLED;
412
        migrate_fd_cleanup(s);
413
    }
414
    qemu_free(s);
415
}
416

    
417
void migrate_fd_wait_for_unfreeze(void *opaque)
418
{
419
    FdMigrationState *s = opaque;
420
    int ret;
421

    
422
    DPRINTF("wait for unfreeze\n");
423
    if (s->state != MIG_STATE_ACTIVE)
424
        return;
425

    
426
    do {
427
        fd_set wfds;
428

    
429
        FD_ZERO(&wfds);
430
        FD_SET(s->fd, &wfds);
431

    
432
        ret = select(s->fd + 1, NULL, &wfds, NULL, NULL);
433
    } while (ret == -1 && (s->get_error(s)) == EINTR);
434
}
435

    
436
int migrate_fd_close(void *opaque)
437
{
438
    FdMigrationState *s = opaque;
439

    
440
    qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
441
    return s->close(s);
442
}