示例#1
0
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);
    }
}
示例#2
0
文件: migration.c 项目: Annovae/qemu
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);
}
示例#3
0
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);
}
示例#4
0
文件: migration.c 项目: daisu-mi/qemu
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);
    }
}
示例#5
0
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);
}
示例#6
0
文件: migration.c 项目: Annovae/qemu
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);
}
示例#7
0
文件: migration.c 项目: daisu-mi/qemu
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;
}
示例#8
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;
}
示例#9
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);
}
示例#10
0
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);
}
示例#11
0
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);
}
示例#12
0
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(&params);

    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);
}
示例#13
0
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);
}
示例#14
0
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);
}
示例#15
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);
}
示例#16
0
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);
}
示例#17
0
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);
}
示例#18
0
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;
}
示例#19
0
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;
    }
}
示例#20
0
static void run_main_thread_exit(void)
{
    notifier_list_notify(&main_thread_exit, NULL);
}
示例#21
0
static void qemu_thread_atexit_run(void *arg)
{
    union NotifierThreadData ntd = { .ptr = arg };
    notifier_list_notify(&ntd.list, NULL);
}