~fboudra/qemu-linaro/new-upstream-release-1.2.0-2012.09-0ubuntu1

« back to all changes in this revision

Viewing changes to migration.c

  • Committer: Fathi Boudra
  • Author(s): Fathi Boudra
  • Date: 2012-08-21 06:47:11 UTC
  • mfrom: (0.1.16)
  • Revision ID: fathi.boudra@linaro.org-20120821064711-7yxmubp2v8a44xce
Tags: 1.1.50-2012.08-0ubuntu1
* New upstream release.
  - support emulated systems with more than 2G of memory. (LP: #1030588)
* Drop powerpc-missing-include.patch - merged upstream.
* Update debian/control: 
  - drop perl build dependency.
  - add libfdt-dev build dependency.
* Update debian/qemu-keymaps.install file.
* Update debian/rules:
  - update QEMU_CPU for ARM architecture: armv4l -> armv7l.
  - update conf_audio_drv: default to PulseAudio since PA is the default on
    Ubuntu.
  - enable KVM on ARM architecture.
  - enable flat device tree support (--enable-fdt). (LP: #1030594)

Show diffs side-by-side

added added

removed removed

Lines of Context:
60
60
    return &current_migration;
61
61
}
62
62
 
63
 
int qemu_start_incoming_migration(const char *uri)
 
63
int qemu_start_incoming_migration(const char *uri, Error **errp)
64
64
{
65
65
    const char *p;
66
66
    int ret;
67
67
 
68
68
    if (strstart(uri, "tcp:", &p))
69
 
        ret = tcp_start_incoming_migration(p);
 
69
        ret = tcp_start_incoming_migration(p, errp);
70
70
#if !defined(WIN32)
71
71
    else if (strstart(uri, "exec:", &p))
72
72
        ret =  exec_start_incoming_migration(p);
91
91
    qemu_announce_self();
92
92
    DPRINTF("successfully loaded vm state\n");
93
93
 
 
94
    bdrv_clear_incoming_migration_all();
94
95
    /* Make sure all file formats flush their mutable metadata */
95
96
    bdrv_invalidate_cache_all();
96
97
 
130
131
        info->ram->transferred = ram_bytes_transferred();
131
132
        info->ram->remaining = ram_bytes_remaining();
132
133
        info->ram->total = ram_bytes_total();
 
134
        info->ram->total_time = qemu_get_clock_ms(rt_clock)
 
135
            - s->total_time;
133
136
 
134
137
        if (blk_mig_active()) {
135
138
            info->has_disk = true;
142
145
    case MIG_STATE_COMPLETED:
143
146
        info->has_status = true;
144
147
        info->status = g_strdup("completed");
 
148
 
 
149
        info->has_ram = true;
 
150
        info->ram = g_malloc0(sizeof(*info->ram));
 
151
        info->ram->transferred = ram_bytes_transferred();
 
152
        info->ram->remaining = 0;
 
153
        info->ram->total = ram_bytes_total();
 
154
        info->ram->total_time = s->total_time;
145
155
        break;
146
156
    case MIG_STATE_ERROR:
147
157
        info->has_status = true;
158
168
 
159
169
/* shared migration helpers */
160
170
 
161
 
static void migrate_fd_monitor_suspend(MigrationState *s, Monitor *mon)
162
 
{
163
 
    if (monitor_suspend(mon) == 0) {
164
 
        DPRINTF("suspending monitor\n");
165
 
    } else {
166
 
        monitor_printf(mon, "terminal does not allow synchronous "
167
 
                       "migration, continuing detached\n");
168
 
    }
169
 
}
170
 
 
171
171
static int migrate_fd_cleanup(MigrationState *s)
172
172
{
173
173
    int ret = 0;
178
178
        DPRINTF("closing file\n");
179
179
        ret = qemu_fclose(s->file);
180
180
        s->file = NULL;
181
 
    } else {
182
 
        if (s->mon) {
183
 
            monitor_resume(s->mon);
184
 
        }
185
181
    }
186
182
 
187
183
    if (s->fd != -1) {
258
254
    }
259
255
 
260
256
    DPRINTF("iterate\n");
261
 
    ret = qemu_savevm_state_iterate(s->mon, s->file);
 
257
    ret = qemu_savevm_state_iterate(s->file);
262
258
    if (ret < 0) {
263
259
        migrate_fd_error(s);
264
260
    } else if (ret == 1) {
265
261
        int old_vm_running = runstate_is_running();
266
262
 
267
263
        DPRINTF("done iterating\n");
 
264
        qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
268
265
        vm_stop_force_state(RUN_STATE_FINISH_MIGRATE);
269
266
 
270
 
        if (qemu_savevm_state_complete(s->mon, s->file) < 0) {
 
267
        if (qemu_savevm_state_complete(s->file) < 0) {
271
268
            migrate_fd_error(s);
272
269
        } else {
273
270
            migrate_fd_completed(s);
274
271
        }
 
272
        s->total_time = qemu_get_clock_ms(rt_clock) - s->total_time;
275
273
        if (s->state != MIG_STATE_COMPLETED) {
276
274
            if (old_vm_running) {
277
275
                vm_start();
289
287
 
290
288
    s->state = MIG_STATE_CANCELLED;
291
289
    notifier_list_notify(&migration_state_notifiers, s);
292
 
    qemu_savevm_state_cancel(s->mon, s->file);
 
290
    qemu_savevm_state_cancel(s->file);
293
291
 
294
292
    migrate_fd_cleanup(s);
295
293
}
321
319
{
322
320
    MigrationState *s = opaque;
323
321
 
324
 
    if (s->mon) {
325
 
        monitor_resume(s->mon);
326
 
    }
327
322
    qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
328
323
    return s->close(s);
329
324
}
367
362
                                      migrate_fd_close);
368
363
 
369
364
    DPRINTF("beginning savevm\n");
370
 
    ret = qemu_savevm_state_begin(s->mon, s->file, s->blk, s->shared);
 
365
    ret = qemu_savevm_state_begin(s->file, &s->params);
371
366
    if (ret < 0) {
372
367
        DPRINTF("failed, %d\n", ret);
373
368
        migrate_fd_error(s);
376
371
    migrate_fd_put_ready(s);
377
372
}
378
373
 
379
 
static MigrationState *migrate_init(Monitor *mon, int detach, int blk, int inc)
 
374
static MigrationState *migrate_init(const MigrationParams *params)
380
375
{
381
376
    MigrationState *s = migrate_get_current();
382
377
    int64_t bandwidth_limit = s->bandwidth_limit;
383
378
 
384
379
    memset(s, 0, sizeof(*s));
385
380
    s->bandwidth_limit = bandwidth_limit;
386
 
    s->blk = blk;
387
 
    s->shared = inc;
 
381
    s->params = *params;
388
382
 
389
 
    /* s->mon is used for two things:
390
 
       - pass fd in fd migration
391
 
       - suspend/resume monitor for not detached migration
392
 
    */
393
 
    s->mon = mon;
394
383
    s->bandwidth_limit = bandwidth_limit;
395
384
    s->state = MIG_STATE_SETUP;
396
 
 
397
 
    if (!detach) {
398
 
        migrate_fd_monitor_suspend(s, mon);
399
 
    }
 
385
    s->total_time = qemu_get_clock_ms(rt_clock);
400
386
 
401
387
    return s;
402
388
}
413
399
    migration_blockers = g_slist_remove(migration_blockers, reason);
414
400
}
415
401
 
416
 
int do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data)
 
402
void qmp_migrate(const char *uri, bool has_blk, bool blk,
 
403
                 bool has_inc, bool inc, bool has_detach, bool detach,
 
404
                 Error **errp)
417
405
{
418
406
    MigrationState *s = migrate_get_current();
 
407
    MigrationParams params;
419
408
    const char *p;
420
 
    int detach = qdict_get_try_bool(qdict, "detach", 0);
421
 
    int blk = qdict_get_try_bool(qdict, "blk", 0);
422
 
    int inc = qdict_get_try_bool(qdict, "inc", 0);
423
 
    const char *uri = qdict_get_str(qdict, "uri");
424
409
    int ret;
425
410
 
 
411
    params.blk = blk;
 
412
    params.shared = inc;
 
413
 
426
414
    if (s->state == MIG_STATE_ACTIVE) {
427
 
        monitor_printf(mon, "migration already in progress\n");
428
 
        return -1;
 
415
        error_set(errp, QERR_MIGRATION_ACTIVE);
 
416
        return;
429
417
    }
430
418
 
431
 
    if (qemu_savevm_state_blocked(mon)) {
432
 
        return -1;
 
419
    if (qemu_savevm_state_blocked(errp)) {
 
420
        return;
433
421
    }
434
422
 
435
423
    if (migration_blockers) {
436
 
        Error *err = migration_blockers->data;
437
 
        qerror_report_err(err);
438
 
        return -1;
 
424
        *errp = error_copy(migration_blockers->data);
 
425
        return;
439
426
    }
440
427
 
441
 
    s = migrate_init(mon, detach, blk, inc);
 
428
    s = migrate_init(&params);
442
429
 
443
430
    if (strstart(uri, "tcp:", &p)) {
444
 
        ret = tcp_start_outgoing_migration(s, p);
 
431
        ret = tcp_start_outgoing_migration(s, p, errp);
445
432
#if !defined(WIN32)
446
433
    } else if (strstart(uri, "exec:", &p)) {
447
434
        ret = exec_start_outgoing_migration(s, p);
451
438
        ret = fd_start_outgoing_migration(s, p);
452
439
#endif
453
440
    } else {
454
 
        monitor_printf(mon, "unknown migration protocol: %s\n", uri);
455
 
        ret  = -EINVAL;
 
441
        error_set(errp, QERR_INVALID_PARAMETER_VALUE, "uri", "a valid migration protocol");
 
442
        return;
456
443
    }
457
444
 
458
445
    if (ret < 0) {
459
 
        monitor_printf(mon, "migration failed: %s\n", strerror(-ret));
460
 
        return ret;
461
 
    }
462
 
 
463
 
    if (detach) {
464
 
        s->mon = NULL;
 
446
        if (!error_is_set(errp)) {
 
447
            DPRINTF("migration failed: %s\n", strerror(-ret));
 
448
            /* FIXME: we should return meaningful errors */
 
449
            error_set(errp, QERR_UNDEFINED_ERROR);
 
450
        }
 
451
        return;
465
452
    }
466
453
 
467
454
    notifier_list_notify(&migration_state_notifiers, s);
468
 
    return 0;
469
455
}
470
456
 
471
457
void qmp_migrate_cancel(Error **errp)