Commit c369f40d authored by Juan Quintela's avatar Juan Quintela
Browse files

migration: unfold rest of migrate_fd_put_ready() into thread



This will allow us finer control in next patches.

Signed-off-by: default avatarJuan Quintela <quintela@redhat.com>

Reviewed-by: default avatarReviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 7de6a690
Loading
Loading
Loading
Loading
+41 −54
Original line number Diff line number Diff line
@@ -662,20 +662,47 @@ static int64_t buffered_get_rate_limit(void *opaque)
    return s->xfer_limit;
}

static bool migrate_fd_put_ready(MigrationState *s, uint64_t max_size)
static void *buffered_file_thread(void *opaque)
{
    MigrationState *s = opaque;
    int64_t initial_time = qemu_get_clock_ms(rt_clock);
    int64_t max_size = 0;
    bool last_round = false;
    int ret;

    qemu_mutex_lock_iothread();
    DPRINTF("beginning savevm\n");
    ret = qemu_savevm_state_begin(s->file, &s->params);
    if (ret < 0) {
        DPRINTF("failed, %d\n", ret);
        qemu_mutex_unlock_iothread();
        goto out;
    }
    qemu_mutex_unlock_iothread();

    while (true) {
        int64_t current_time = qemu_get_clock_ms(rt_clock);
        uint64_t pending_size;
    bool last_round = false;

        qemu_mutex_lock_iothread();
        if (s->state != MIG_STATE_ACTIVE) {
            DPRINTF("put_ready returning because of non-active state\n");
            qemu_mutex_unlock_iothread();
            break;
        }
        if (s->complete) {
            qemu_mutex_unlock_iothread();
            break;
        }
        if (s->bytes_xfer < s->xfer_limit) {
            DPRINTF("iterate\n");
            pending_size = qemu_savevm_state_pending(s->file, max_size);
            DPRINTF("pending size %lu max %lu\n", pending_size, max_size);
            if (pending_size >= max_size) {
                ret = qemu_savevm_state_iterate(s->file);
                if (ret < 0) {
            migrate_fd_error(s);
                    qemu_mutex_unlock_iothread();
                    break;
                }
            } else {
                int old_vm_running = runstate_is_running();
@@ -689,9 +716,10 @@ static bool migrate_fd_put_ready(MigrationState *s, uint64_t max_size)
                } else {
                    vm_stop_force_state(RUN_STATE_FINISH_MIGRATE);
                }

        if (qemu_savevm_state_complete(s->file) < 0) {
            migrate_fd_error(s);
                ret = qemu_savevm_state_complete(s->file);
                if (ret < 0) {
                    qemu_mutex_unlock_iothread();
                    break;
                } else {
                    migrate_fd_completed(s);
                }
@@ -705,41 +733,6 @@ static bool migrate_fd_put_ready(MigrationState *s, uint64_t max_size)
                }
                last_round = true;
            }
    qemu_mutex_unlock_iothread();

    return last_round;
}

static void *buffered_file_thread(void *opaque)
{
    MigrationState *s = opaque;
    int64_t initial_time = qemu_get_clock_ms(rt_clock);
    int64_t max_size = 0;
    bool last_round = false;
    int ret;

    qemu_mutex_lock_iothread();
    DPRINTF("beginning savevm\n");
    ret = qemu_savevm_state_begin(s->file, &s->params);
    if (ret < 0) {
        DPRINTF("failed, %d\n", ret);
        qemu_mutex_unlock_iothread();
        goto out;
    }
    qemu_mutex_unlock_iothread();

    while (true) {
        int64_t current_time = qemu_get_clock_ms(rt_clock);

        qemu_mutex_lock_iothread();
        if (s->state != MIG_STATE_ACTIVE) {
            DPRINTF("put_ready returning because of non-active state\n");
            qemu_mutex_unlock_iothread();
            break;
        }
        if (s->complete) {
            qemu_mutex_unlock_iothread();
            break;
        }
        qemu_mutex_unlock_iothread();
        if (current_time >= initial_time + BUFFER_DELAY) {
@@ -763,12 +756,6 @@ static void *buffered_file_thread(void *opaque)
        if (ret < 0) {
            break;
        }

        DPRINTF("file is ready\n");
        if (s->bytes_xfer < s->xfer_limit) {
            DPRINTF("notifying client\n");
            last_round = migrate_fd_put_ready(s, max_size);
        }
    }

out: