void migrate_fd_put_ready(void *opaque) { FdMigrationState *s = opaque; if (s->state != MIG_STATE_ACTIVE) { DPRINTF("put_ready returning because of non-active state\n"); return; } DPRINTF("iterate\n"); if (qemu_savevm_state_iterate(s->mon, s->file) == 1) { int state; int old_vm_running = vm_running; DPRINTF("done iterating\n"); vm_stop(VMSTOP_MIGRATE); if ((qemu_savevm_state_complete(s->mon, s->file)) < 0) { if (old_vm_running) { vm_start(); } state = MIG_STATE_ERROR; } else { state = MIG_STATE_COMPLETED; } if (migrate_fd_cleanup(s) < 0) { if (old_vm_running) { vm_start(); } state = MIG_STATE_ERROR; } s->state = state; notifier_list_notify(&migration_state_notifiers); } }
static void migrate_fd_cleanup(void *opaque) { MigrationState *s = opaque; qemu_bh_delete(s->cleanup_bh); s->cleanup_bh = NULL; if (s->file) { DPRINTF("closing file\n"); qemu_mutex_unlock_iothread(); qemu_thread_join(&s->thread); qemu_mutex_lock_iothread(); qemu_fclose(s->file); s->file = NULL; } assert(s->state != MIG_STATE_ACTIVE); if (s->state != MIG_STATE_COMPLETED) { qemu_savevm_state_cancel(); if (s->state == MIG_STATE_CANCELLING) { migrate_set_state(s, MIG_STATE_CANCELLING, MIG_STATE_CANCELLED); } } notifier_list_notify(&migration_state_notifiers, s); }
void migrate_fd_error(FdMigrationState *s) { DPRINTF("setting error state\n"); s->state = MIG_STATE_ERROR; notifier_list_notify(&migration_state_notifiers, NULL); migrate_fd_cleanup(s); }
void migrate_fd_cancel(MigrationState *mig_state) { FdMigrationState *s = migrate_to_fms(mig_state); if (s->state == MIG_STATE_CANCELLED) { return; } DPRINTF("cancelling migration\n"); s->state = MIG_STATE_CANCELLED; notifier_list_notify(&migration_state_notifiers); if (ft_mode) { if (s->file) { qemu_ft_trans_cancel(s->file); } ft_mode = FT_OFF; event_tap_unregister(); } if (s->file) { qemu_savevm_state_cancel(s->mon, s->file); migrate_fd_cleanup(s); } }
void migrate_fd_error(MigrationState *s) { trace_migrate_fd_error(); assert(s->file == NULL); s->state = MIGRATION_STATUS_FAILED; trace_migrate_set_state(MIGRATION_STATUS_FAILED); notifier_list_notify(&migration_state_notifiers, s); }
void migrate_fd_error(MigrationState *s) { DPRINTF("setting error state\n"); assert(s->file == NULL); s->state = MIG_STATE_ERROR; trace_migrate_set_state(MIG_STATE_ERROR); notifier_list_notify(&migration_state_notifiers, s); }
int do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data) { MigrationState *s = NULL; const char *p; int detach = qdict_get_try_bool(qdict, "detach", 0); int blk = qdict_get_try_bool(qdict, "blk", 0); int inc = qdict_get_try_bool(qdict, "inc", 0); const char *uri = qdict_get_str(qdict, "uri"); if (current_migration && current_migration->get_status(current_migration) == MIG_STATE_ACTIVE) { monitor_printf(mon, "migration already in progress\n"); return -1; } if (qemu_savevm_state_blocked(mon)) { return -1; } /* check ft_mode (Kemari protocol) */ if (strstart(uri, "kemari:", &p)) { ft_mode = FT_INIT; uri = p; } if (strstart(uri, "tcp:", &p)) { s = tcp_start_outgoing_migration(mon, p, max_throttle, detach, blk, inc); #if !defined(WIN32) } else if (strstart(uri, "exec:", &p)) { s = exec_start_outgoing_migration(mon, p, max_throttle, detach, blk, inc); } else if (strstart(uri, "unix:", &p)) { s = unix_start_outgoing_migration(mon, p, max_throttle, detach, blk, inc); } else if (strstart(uri, "fd:", &p)) { s = fd_start_outgoing_migration(mon, p, max_throttle, detach, blk, inc); #endif } else { monitor_printf(mon, "unknown migration protocol: %s\n", uri); return -1; } if (s == NULL) { monitor_printf(mon, "migration failed\n"); return -1; } if (current_migration) { current_migration->release(current_migration); } current_migration = s; notifier_list_notify(&migration_state_notifiers); return 0; }
int do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data) { MigrationState *s = migrate_get_current(); const char *p; int detach = qdict_get_try_bool(qdict, "detach", 0); int blk = qdict_get_try_bool(qdict, "blk", 0); int inc = qdict_get_try_bool(qdict, "inc", 0); const char *uri = qdict_get_str(qdict, "uri"); int ret; if (s->state == MIG_STATE_ACTIVE) { monitor_printf(mon, "migration already in progress\n"); return -1; } if (qemu_savevm_state_blocked(mon)) { return -1; } if (migration_blockers) { Error *err = migration_blockers->data; qerror_report_err(err); return -1; } s = migrate_init(mon, detach, blk, inc); if (strstart(uri, "tcp:", &p)) { ret = tcp_start_outgoing_migration(s, p); #if !defined(WIN32) } else if (strstart(uri, "exec:", &p)) { ret = exec_start_outgoing_migration(s, p); } else if (strstart(uri, "unix:", &p)) { ret = unix_start_outgoing_migration(s, p); } else if (strstart(uri, "fd:", &p)) { ret = fd_start_outgoing_migration(s, p); #endif } else { monitor_printf(mon, "unknown migration protocol: %s\n", uri); ret = -EINVAL; } if (ret < 0) { monitor_printf(mon, "migration failed: %s\n", strerror(-ret)); return ret; } if (detach) { s->mon = NULL; } notifier_list_notify(&migration_state_notifiers, s); return 0; }
static void migrate_fd_completed(MigrationState *s) { DPRINTF("setting completed state\n"); if (migrate_fd_cleanup(s) < 0) { s->state = MIG_STATE_ERROR; } else { s->state = MIG_STATE_COMPLETED; runstate_set(RUN_STATE_POSTMIGRATE); } notifier_list_notify(&migration_state_notifiers, s); }
void migrate_fd_release(MigrationState *mig_state) { FdMigrationState *s = migrate_to_fms(mig_state); DPRINTF("releasing state\n"); if (s->state == MIG_STATE_ACTIVE) { s->state = MIG_STATE_CANCELLED; notifier_list_notify(&migration_state_notifiers, NULL); migrate_fd_cleanup(s); } g_free(s); }
static void migrate_fd_cancel(MigrationState *s) { if (s->state != MIG_STATE_ACTIVE) return; DPRINTF("cancelling migration\n"); s->state = MIG_STATE_CANCELLED; notifier_list_notify(&migration_state_notifiers, s); qemu_savevm_state_cancel(); migrate_fd_cleanup(s); }
void qmp_migrate(const char *uri, bool has_blk, bool blk, bool has_inc, bool inc, bool has_detach, bool detach, Error **errp) { Error *local_err = NULL; MigrationState *s = migrate_get_current(); MigrationParams params; const char *p; params.blk = blk; params.shared = inc; if (s->state == MIG_STATE_ACTIVE) { error_set(errp, QERR_MIGRATION_ACTIVE); return; } if (qemu_savevm_state_blocked(errp)) { return; } if (migration_blockers) { *errp = error_copy(migration_blockers->data); return; } s = migrate_init(¶ms); if (strstart(uri, "tcp:", &p)) { tcp_start_outgoing_migration(s, p, &local_err); #if !defined(WIN32) } else if (strstart(uri, "exec:", &p)) { exec_start_outgoing_migration(s, p, &local_err); } else if (strstart(uri, "unix:", &p)) { unix_start_outgoing_migration(s, p, &local_err); } else if (strstart(uri, "fd:", &p)) { fd_start_outgoing_migration(s, p, &local_err); #endif } else { error_set(errp, QERR_INVALID_PARAMETER_VALUE, "uri", "a valid migration protocol"); return; } if (local_err) { migrate_fd_error(s); error_propagate(errp, local_err); return; } notifier_list_notify(&migration_state_notifiers, s); }
void migrate_fd_cancel(MigrationState *mig_state) { FdMigrationState *s = migrate_to_fms(mig_state); if (s->state != MIG_STATE_ACTIVE) return; DPRINTF("cancelling migration\n"); s->state = MIG_STATE_CANCELLED; notifier_list_notify(&migration_state_notifiers, NULL); qemu_savevm_state_cancel(s->mon, s->file); migrate_fd_cleanup(s); }
void qemu_thread_exit(void *arg) { QemuThreadData *data = qemu_thread_data; notifier_list_notify(&data->exit, NULL); if (data->mode == QEMU_THREAD_JOINABLE) { data->ret = arg; EnterCriticalSection(&data->cs); data->exited = true; LeaveCriticalSection(&data->cs); } else { g_free(data); } _endthreadex(0); }
void migrate_fd_connect(MigrationState *s) { s->state = MIG_STATE_ACTIVE; trace_migrate_set_state(MIG_STATE_ACTIVE); /* This is a best 1st approximation. ns to ms */ s->expected_downtime = max_downtime/1000000; s->cleanup_bh = qemu_bh_new(migrate_fd_cleanup, s); qemu_file_set_rate_limit(s->file, s->bandwidth_limit / XFER_LIMIT_RATIO); qemu_thread_create(&s->thread, migration_thread, s, QEMU_THREAD_JOINABLE); notifier_list_notify(&migration_state_notifiers, s); }
void migrate_fd_connect(MigrationState *s) { s->state = MIG_STATE_ACTIVE; s->bytes_xfer = 0; s->buffer = NULL; s->buffer_size = 0; s->buffer_capacity = 0; s->xfer_limit = s->bandwidth_limit / XFER_LIMIT_RATIO; s->complete = false; s->file = qemu_fopen_ops(s, &buffered_file_ops); qemu_thread_create(&s->thread, buffered_file_thread, s, QEMU_THREAD_DETACHED); notifier_list_notify(&migration_state_notifiers, s); }
void migrate_fd_connect(MigrationState *s) { s->state = MIGRATION_STATUS_SETUP; trace_migrate_set_state(MIGRATION_STATUS_SETUP); /* This is a best 1st approximation. ns to ms */ s->expected_downtime = max_downtime/1000000; s->cleanup_bh = qemu_bh_new(migrate_fd_cleanup, s); qemu_file_set_rate_limit(s->file, s->bandwidth_limit / XFER_LIMIT_RATIO); /* Notify before starting migration thread */ notifier_list_notify(&migration_state_notifiers, s); migrate_compress_threads_create(); qemu_thread_create(&s->thread, "migration", migration_thread, s, QEMU_THREAD_JOINABLE); }
ssize_t migrate_fd_put_buffer(void *opaque, const void *data, size_t size) { FdMigrationState *s = opaque; ssize_t ret; do { ret = s->write(s, data, size); } while (ret == -1 && ((s->get_error(s)) == EINTR)); if (ret == -1) ret = -(s->get_error(s)); if (ret == -EAGAIN) { qemu_set_fd_handler2(s->fd, NULL, NULL, migrate_fd_put_notify, s); } else if (ret < 0) { s->state = MIG_STATE_ERROR; notifier_list_notify(&migration_state_notifiers, NULL); } return ret; }
int64_t qemu_get_clock_ns(QEMUClock *clock) { int64_t now, last; switch(clock->type) { case QEMU_CLOCK_REALTIME: return get_clock(); default: case QEMU_CLOCK_VIRTUAL: if (use_icount) { return cpu_get_icount(); } else { return cpu_get_clock(); } case QEMU_CLOCK_HOST: now = get_clock_realtime(); last = clock->last; clock->last = now; if (now < last) { notifier_list_notify(&clock->reset_notifiers, &now); } return now; } }
static void run_main_thread_exit(void) { notifier_list_notify(&main_thread_exit, NULL); }
static void qemu_thread_atexit_run(void *arg) { union NotifierThreadData ntd = { .ptr = arg }; notifier_list_notify(&ntd.list, NULL); }