X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=migration.c;h=af3a1f27027c83cb482595f8bf641dfabd9443d0;hb=fd2a9d2fc719d53caeb37c28440a0e9d34c1b563;hp=622a9d2d95a45ffbecd49f4ffa83f28470305f1a;hpb=3d002df33eb034757d98e1ae529318f57df78f91;p=qemu.git diff --git a/migration.c b/migration.c index 622a9d2d9..af3a1f270 100644 --- a/migration.c +++ b/migration.c @@ -36,6 +36,9 @@ 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; } @@ -268,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); } @@ -325,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; @@ -368,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(); @@ -387,6 +395,7 @@ void migrate_fd_put_ready(void *opaque) state = MIG_STATE_ERROR; } s->state = state; + notifier_list_notify(&migration_state_notifiers); } } @@ -406,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); @@ -419,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); @@ -450,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; + } +}