Example #1
0
void do_migrate_set_speed(Monitor *mon, const QDict *qdict, QObject **ret_data)
{
    double d;
    char *ptr;
    FdMigrationState *s;
    const char *value = qdict_get_str(qdict, "value");

    d = strtod(value, &ptr);
    switch (*ptr) {
    case 'G': case 'g':
        d *= 1024;
    case 'M': case 'm':
        d *= 1024;
    case 'K': case 'k':
        d *= 1024;
    default:
        break;
    }

    max_throttle = (uint32_t)d;
    s = migrate_to_fms(current_migration);

    if (s) {
        qemu_file_set_rate_limit(s->file, max_throttle);
    }
    
}
Example #2
0
void qmp_migrate_set_speed(int64_t value, Error **errp)
{
    MigrationState *s;

    if (value < 0) {
        value = 0;
    }

    s = migrate_get_current();
    s->bandwidth_limit = value;
    qemu_file_set_rate_limit(s->file, s->bandwidth_limit);
}
Example #3
0
int do_migrate_set_speed(Monitor *mon, const QDict *qdict, QObject **ret_data)
{
    double d;
    FdMigrationState *s;

    d = qdict_get_double(qdict, "value");
    d = MAX(0, MIN(UINT32_MAX, d));
    max_throttle = d;

    s = migrate_to_fms(current_migration);
    if (s && s->file) {
        qemu_file_set_rate_limit(s->file, max_throttle);
    }

    return 0;
}
Example #4
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);
}
Example #5
0
int do_migrate_set_speed(Monitor *mon, const QDict *qdict, QObject **ret_data)
{
    int64_t d;
    MigrationState *s;

    d = qdict_get_int(qdict, "value");
    if (d < 0) {
        d = 0;
    }

    s = migrate_get_current();
    s->bandwidth_limit = d;
    qemu_file_set_rate_limit(s->file, s->bandwidth_limit);

    return 0;
}
Example #6
0
void qmp_migrate_set_speed(int64_t value, Error **errp)
{
    MigrationState *s;

    if (value < 0) {
        value = 0;
    }
    if (value > SIZE_MAX) {
        value = SIZE_MAX;
    }

    s = migrate_get_current();
    s->bandwidth_limit = value;
    if (s->file) {
        qemu_file_set_rate_limit(s->file, s->bandwidth_limit / XFER_LIMIT_RATIO);
    }
}
Example #7
0
int do_migrate_set_speed(Monitor *mon, const QDict *qdict, QObject **ret_data)
{
    int64_t d;
    FdMigrationState *s;

    d = qdict_get_int(qdict, "value");
    if (d < 0) {
        d = 0;
    }
    max_throttle = d;

    s = migrate_to_fms(current_migration);
    if (s && s->file) {
        qemu_file_set_rate_limit(s->file, max_throttle);
    }

    return 0;
}
Example #8
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);
}
Example #9
0
static int migrate_ft_trans_put_ready(void)
{
    FdMigrationState *s = migrate_to_fms(current_migration);
    int ret = -1, init = 0, timeout;
    static int64_t start, now;

    switch (ft_mode) {
    case FT_INIT:
        init = 1;
        ft_mode = FT_TRANSACTION_BEGIN;
    case FT_TRANSACTION_BEGIN:
        now = start = qemu_get_clock_ns(vm_clock);
        /* start transatcion at best effort */
        qemu_file_set_rate_limit(s->file, 1);

        if (qemu_ft_trans_begin(s->file) < 0) {
            fprintf(stderr, "qemu_transaction_begin failed\n");
            goto error_out;
        }

        vm_stop(0);

        ret = qemu_savevm_trans_begin(s->mon, s->file, init);
        if (ret < 0) {
            fprintf(stderr, "qemu_savevm_trans_begin\n");
            goto error_out;
        }

        if (ret) {
            ft_mode = FT_TRANSACTION_ITER;
            vm_start();
        } else {
            ft_mode = FT_TRANSACTION_COMMIT;
            if (migrate_ft_trans_commit(s) < 0) {
                goto error_out;
            }
        }
        break;

    case FT_TRANSACTION_ITER:
        now = qemu_get_clock_ns(vm_clock);
        timeout = ((now - start) >= max_downtime);
        if (timeout || qemu_savevm_state_iterate(s->mon, s->file) == 1) {
            DPRINTF("ft trans iter timeout %d\n", timeout);

            ft_mode = FT_TRANSACTION_COMMIT;
            if (migrate_ft_trans_commit(s) < 0) {
                goto error_out;
            }
            return 1;
        }

        ft_mode = FT_TRANSACTION_ITER;
        break;

    case FT_TRANSACTION_ATOMIC:
    case FT_TRANSACTION_COMMIT:
        if (migrate_ft_trans_commit(s) < 0) {
            goto error_out;
        }
        break;

    default:
        fprintf(stderr,
                "migrate_ft_trans_put_ready: invalid ft_mode %d", ft_mode);
        goto error_out;
    }

    ret = 0;
    goto out;

error_out:
    migrate_ft_trans_error(s);

out:
    return ret;
}
Example #10
0
static int migrate_ft_trans_commit(void *opaque)
{
    FdMigrationState *s = opaque;
    int ret = -1;

    if (ft_mode != FT_TRANSACTION_COMMIT && ft_mode != FT_TRANSACTION_ATOMIC) {
        fprintf(stderr,
                "migrate_ft_trans_commit: invalid ft_mode %d\n", ft_mode);
        goto out;
    }

    do {
        if (ft_mode == FT_TRANSACTION_ATOMIC) {
            if (qemu_ft_trans_begin(s->file) < 0) {
                fprintf(stderr, "qemu_ft_trans_begin failed\n");
                goto out;
            }

            ret = qemu_savevm_trans_begin(s->mon, s->file, 0);
            if (ret < 0) {
                fprintf(stderr, "qemu_savevm_trans_begin failed\n");
                goto out;
            }

            ft_mode = FT_TRANSACTION_COMMIT;
            if (ret) {
                /* don't proceed until if fd isn't ready */
                goto out;
            }
        }

        /* make the VM state consistent by flushing outstanding events */
        vm_stop(0);

        /* send at full speed */
        qemu_file_set_rate_limit(s->file, 0);

        ret = qemu_savevm_trans_complete(s->mon, s->file);
        if (ret < 0) {
            fprintf(stderr, "qemu_savevm_trans_complete failed\n");
            goto out;
        }

        ret = qemu_ft_trans_commit(s->file);
        if (ret < 0) {
            fprintf(stderr, "qemu_ft_trans_commit failed\n");
            goto out;
        }

        if (ret) {
            ft_mode = FT_TRANSACTION_RECV;
            ret = 1;
            goto out;
        }

        /* flush and check if events are remaining */
        vm_start();
        ret = event_tap_flush_one();
        if (ret < 0) {
            fprintf(stderr, "event_tap_flush_one failed\n");
            goto out;
        }

        ft_mode =  ret ? FT_TRANSACTION_BEGIN : FT_TRANSACTION_ATOMIC;
    } while (ft_mode != FT_TRANSACTION_BEGIN);

    vm_start();
    ret = 0;

out:
    return ret;
}
Example #11
0
static void *migration_thread(void *opaque)
{
    MigrationState *s = opaque;
    int64_t initial_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
    int64_t setup_start = qemu_clock_get_ms(QEMU_CLOCK_HOST);
    int64_t initial_bytes = 0;
    int64_t max_size = 0;
    int64_t start_time = initial_time;
    bool old_vm_running = false;

    DPRINTF("beginning savevm\n");
    qemu_savevm_state_begin(s->file, &s->params);

    s->setup_time = qemu_clock_get_ms(QEMU_CLOCK_HOST) - setup_start;
    migrate_set_state(s, MIG_STATE_SETUP, MIG_STATE_ACTIVE);

    DPRINTF("setup complete\n");

    while (s->state == MIG_STATE_ACTIVE) {
        int64_t current_time;
        uint64_t pending_size;

        if (!qemu_file_rate_limit(s->file)) {
            DPRINTF("iterate\n");
            pending_size = qemu_savevm_state_pending(s->file, max_size);
            DPRINTF("pending size %" PRIu64 " max %" PRIu64 "\n",
                    pending_size, max_size);
            if (pending_size && pending_size >= max_size) {
                qemu_savevm_state_iterate(s->file);
            } else {
                int ret;

                DPRINTF("done iterating\n");
                qemu_mutex_lock_iothread();
                start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
                qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
                old_vm_running = runstate_is_running();

                ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE);
                if (ret >= 0) {
                    qemu_file_set_rate_limit(s->file, INT64_MAX);
                    qemu_savevm_state_complete(s->file);
                }
                qemu_mutex_unlock_iothread();

                if (ret < 0) {
                    migrate_set_state(s, MIG_STATE_ACTIVE, MIG_STATE_ERROR);
                    break;
                }

                if (!qemu_file_get_error(s->file)) {
                    migrate_set_state(s, MIG_STATE_ACTIVE, MIG_STATE_COMPLETED);
                    break;
                }
            }
        }

        if (qemu_file_get_error(s->file)) {
            migrate_set_state(s, MIG_STATE_ACTIVE, MIG_STATE_ERROR);
            break;
        }
        current_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
        if (current_time >= initial_time + BUFFER_DELAY) {
            uint64_t transferred_bytes = qemu_ftell(s->file) - initial_bytes;
            uint64_t time_spent = current_time - initial_time;
            double bandwidth = transferred_bytes / time_spent;
            max_size = bandwidth * migrate_max_downtime() / 1000000;

            s->mbps = time_spent ? (((double) transferred_bytes * 8.0) /
                    ((double) time_spent / 1000.0)) / 1000.0 / 1000.0 : -1;

            DPRINTF("transferred %" PRIu64 " time_spent %" PRIu64
                    " bandwidth %g max_size %" PRId64 "\n",
                    transferred_bytes, time_spent, bandwidth, max_size);
            /* if we haven't sent anything, we don't want to recalculate
               10000 is a small enough number for our purposes */
            if (s->dirty_bytes_rate && transferred_bytes > 10000) {
                s->expected_downtime = s->dirty_bytes_rate / bandwidth;
            }

            qemu_file_reset_rate_limit(s->file);
            initial_time = current_time;
            initial_bytes = qemu_ftell(s->file);
        }
        if (qemu_file_rate_limit(s->file)) {
            /* usleep expects microseconds */
            g_usleep((initial_time + BUFFER_DELAY - current_time)*1000);
        }
    }

    qemu_mutex_lock_iothread();
    if (s->state == MIG_STATE_COMPLETED) {
        int64_t end_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
        s->total_time = end_time - s->total_time;
        s->downtime = end_time - start_time;
        runstate_set(RUN_STATE_POSTMIGRATE);
    } else {
        if (old_vm_running) {
            vm_start();
        }
    }
    qemu_bh_schedule(s->cleanup_bh);
    qemu_mutex_unlock_iothread();

    return NULL;
}