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); } }
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); }
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; }
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); }
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; }
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); } }
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; }
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); }
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; }
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; }
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; }