X-Git-Url: http://git.maemo.org/git/?a=blobdiff_plain;f=migration.c;h=7f93e3fcdd52367a39f44ec427eee95fd880e3c2;hb=dea21e97f433093bd93b0fb55ec1e1eec3171158;hp=15639c177f0a5989a27a83c075d6e96b974364c9;hpb=731b03642d0ac0365294c7b39713fede769a3f39;p=qemu diff --git a/migration.c b/migration.c index 15639c1..7f93e3f 100644 --- a/migration.c +++ b/migration.c @@ -43,21 +43,31 @@ void qemu_start_incoming_migration(const char *uri) #if !defined(WIN32) else if (strstart(uri, "exec:", &p)) exec_start_incoming_migration(p); + else if (strstart(uri, "unix:", &p)) + unix_start_incoming_migration(p); + else if (strstart(uri, "fd:", &p)) + fd_start_incoming_migration(p); #endif else fprintf(stderr, "unknown migration protocol: %s\n", uri); } -void do_migrate(Monitor *mon, int detach, const char *uri) +void do_migrate(Monitor *mon, const QDict *qdict) { MigrationState *s = NULL; const char *p; + int detach = qdict_get_int(qdict, "detach"); + const char *uri = qdict_get_str(qdict, "uri"); if (strstart(uri, "tcp:", &p)) s = tcp_start_outgoing_migration(p, max_throttle, detach); #if !defined(WIN32) else if (strstart(uri, "exec:", &p)) s = exec_start_outgoing_migration(p, max_throttle, detach); + else if (strstart(uri, "unix:", &p)) + s = unix_start_outgoing_migration(p, max_throttle, detach); + else if (strstart(uri, "fd:", &p)) + s = fd_start_outgoing_migration(mon, p, max_throttle, detach); #endif else monitor_printf(mon, "unknown migration protocol: %s\n", uri); @@ -72,7 +82,7 @@ void do_migrate(Monitor *mon, int detach, const char *uri) } } -void do_migrate_cancel(Monitor *mon) +void do_migrate_cancel(Monitor *mon, const QDict *qdict) { MigrationState *s = current_migration; @@ -80,10 +90,12 @@ void do_migrate_cancel(Monitor *mon) s->cancel(s); } -void do_migrate_set_speed(Monitor *mon, const char *value) +void do_migrate_set_speed(Monitor *mon, const QDict *qdict) { double d; char *ptr; + FdMigrationState *s; + const char *value = qdict_get_str(qdict, "value"); d = strtod(value, &ptr); switch (*ptr) { @@ -98,6 +110,43 @@ void do_migrate_set_speed(Monitor *mon, const char *value) } max_throttle = (uint32_t)d; + s = migrate_to_fms(current_migration); + + if (s) { + qemu_file_set_rate_limit(s->file, max_throttle); + } + +} + +/* amount of nanoseconds we are willing to wait for migration to be down. + * the choice of nanoseconds is because it is the maximum resolution that + * get_clock() can achieve. It is an internal measure. All user-visible + * units must be in seconds */ +static uint64_t max_downtime = 30000000; + +uint64_t migrate_max_downtime(void) +{ + return max_downtime; +} + +void do_migrate_set_downtime(Monitor *mon, const QDict *qdict) +{ + char *ptr; + double d; + const char *value = qdict_get_str(qdict, "value"); + + d = strtod(value, &ptr); + if (!strcmp(ptr,"ms")) { + d *= 1000000; + } else if (!strcmp(ptr,"us")) { + d *= 1000; + } else if (!strcmp(ptr,"ns")) { + } else { + /* all else considered to be seconds */ + d *= 1000000000; + } + + max_downtime = (uint64_t)d; } void do_info_migrate(Monitor *mon) @@ -109,6 +158,9 @@ void do_info_migrate(Monitor *mon) switch (s->get_status(s)) { case MIG_STATE_ACTIVE: monitor_printf(mon, "active\n"); + monitor_printf(mon, "transferred ram: %" PRIu64 " kbytes\n", ram_bytes_transferred() >> 10); + monitor_printf(mon, "remaining ram: %" PRIu64 " kbytes\n", ram_bytes_remaining() >> 10); + monitor_printf(mon, "total ram: %" PRIu64 " kbytes\n", ram_bytes_total() >> 10); break; case MIG_STATE_COMPLETED: monitor_printf(mon, "completed\n"); @@ -128,8 +180,11 @@ void do_info_migrate(Monitor *mon) void migrate_fd_monitor_suspend(FdMigrationState *s) { s->mon_resume = cur_mon; - monitor_suspend(cur_mon); - dprintf("suspending monitor\n"); + if (monitor_suspend(cur_mon) == 0) + dprintf("suspending monitor\n"); + else + monitor_printf(cur_mon, "terminal does not allow synchronous " + "migration, continuing detached\n"); } void migrate_fd_error(FdMigrationState *s) @@ -173,7 +228,7 @@ ssize_t migrate_fd_put_buffer(void *opaque, const void *data, size_t size) do { ret = s->write(s, data, size); - } while (ret == -1 && ((s->get_error(s)) == EINTR || (s->get_error(s)) == EWOULDBLOCK)); + } while (ret == -1 && ((s->get_error(s)) == EINTR)); if (ret == -1) ret = -(s->get_error(s)); @@ -217,13 +272,24 @@ void migrate_fd_put_ready(void *opaque) dprintf("iterate\n"); if (qemu_savevm_state_iterate(s->file) == 1) { + int state; + int old_vm_running = vm_running; + dprintf("done iterating\n"); vm_stop(0); + qemu_aio_flush(); bdrv_flush_all(); - qemu_savevm_state_complete(s->file); - s->state = MIG_STATE_COMPLETED; + if ((qemu_savevm_state_complete(s->file)) < 0) { + if (old_vm_running) { + vm_start(); + } + state = MIG_STATE_ERROR; + } else { + state = MIG_STATE_COMPLETED; + } migrate_fd_cleanup(s); + s->state = state; } } @@ -282,5 +348,7 @@ void migrate_fd_wait_for_unfreeze(void *opaque) int migrate_fd_close(void *opaque) { FdMigrationState *s = opaque; + + qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL); return s->close(s); }