X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=migration.c;h=af3a1f27027c83cb482595f8bf641dfabd9443d0;hb=021a1318604e0898cee3800d5b13033e68191f4e;hp=468d51749f4cc190662e2741ebfaf27b3aab4719;hpb=e447b1a603091cbaa5eed36c0a3c9ed3f2224535;p=qemu.git diff --git a/migration.c b/migration.c index 468d51749..af3a1f270 100644 --- a/migration.c +++ b/migration.c @@ -32,10 +32,13 @@ #endif /* Migration speed throttling */ -static uint32_t max_throttle = (32 << 20); +static int64_t max_throttle = (32 << 20); static MigrationState *current_migration; +static NotifierList migration_state_notifiers = + NOTIFIER_LIST_INITIALIZER(migration_state_notifiers); + int qemu_start_incoming_migration(const char *uri) { const char *p; @@ -88,6 +91,10 @@ int do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data) return -1; } + if (qemu_savevm_state_blocked(mon)) { + return -1; + } + if (strstart(uri, "tcp:", &p)) { s = tcp_start_outgoing_migration(mon, p, max_throttle, detach, blk, inc); @@ -117,6 +124,7 @@ int do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data) } current_migration = s; + notifier_list_notify(&migration_state_notifiers); return 0; } @@ -132,11 +140,13 @@ int do_migrate_cancel(Monitor *mon, const QDict *qdict, QObject **ret_data) int do_migrate_set_speed(Monitor *mon, const QDict *qdict, QObject **ret_data) { - double d; + int64_t d; FdMigrationState *s; - d = qdict_get_double(qdict, "value"); - d = MAX(0, MIN(UINT32_MAX, d)); + d = qdict_get_int(qdict, "value"); + if (d < 0) { + d = 0; + } max_throttle = d; s = migrate_to_fms(current_migration); @@ -266,6 +276,7 @@ void migrate_fd_error(FdMigrationState *s) { DPRINTF("setting error state\n"); s->state = MIG_STATE_ERROR; + notifier_list_notify(&migration_state_notifiers); migrate_fd_cleanup(s); } @@ -323,6 +334,7 @@ ssize_t migrate_fd_put_buffer(void *opaque, const void *data, size_t size) monitor_resume(s->mon); } s->state = MIG_STATE_ERROR; + notifier_list_notify(&migration_state_notifiers); } return ret; @@ -366,10 +378,8 @@ void migrate_fd_put_ready(void *opaque) int old_vm_running = vm_running; DPRINTF("done iterating\n"); - vm_stop(0); + vm_stop(VMSTOP_MIGRATE); - qemu_aio_flush(); - bdrv_flush_all(); if ((qemu_savevm_state_complete(s->mon, s->file)) < 0) { if (old_vm_running) { vm_start(); @@ -385,6 +395,7 @@ void migrate_fd_put_ready(void *opaque) state = MIG_STATE_ERROR; } s->state = state; + notifier_list_notify(&migration_state_notifiers); } } @@ -404,6 +415,7 @@ void migrate_fd_cancel(MigrationState *mig_state) DPRINTF("cancelling migration\n"); s->state = MIG_STATE_CANCELLED; + notifier_list_notify(&migration_state_notifiers); qemu_savevm_state_cancel(s->mon, s->file); migrate_fd_cleanup(s); @@ -417,6 +429,7 @@ void migrate_fd_release(MigrationState *mig_state) if (s->state == MIG_STATE_ACTIVE) { s->state = MIG_STATE_CANCELLED; + notifier_list_notify(&migration_state_notifiers); migrate_fd_cleanup(s); } qemu_free(s); @@ -448,3 +461,22 @@ int migrate_fd_close(void *opaque) qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL); return s->close(s); } + +void add_migration_state_change_notifier(Notifier *notify) +{ + notifier_list_add(&migration_state_notifiers, notify); +} + +void remove_migration_state_change_notifier(Notifier *notify) +{ + notifier_list_remove(&migration_state_notifiers, notify); +} + +int get_migration_state(void) +{ + if (current_migration) { + return migrate_fd_get_status(current_migration); + } else { + return MIG_STATE_ERROR; + } +}