static void qtest_event(void *opaque, int event) { int i; switch (event) { case CHR_EVENT_OPENED: qemu_system_reset(false); for (i = 0; i < ARRAY_SIZE(irq_levels); i++) { irq_levels[i] = 0; } qemu_gettimeofday(&start_time); qtest_opened = true; if (qtest_log_fp) { fprintf(qtest_log_fp, "[I " FMT_timeval "] OPENED\n", start_time.tv_sec, (long) start_time.tv_usec); } break; case CHR_EVENT_CLOSED: qtest_opened = false; if (qtest_log_fp) { qemu_timeval tv; qtest_get_time(&tv); fprintf(qtest_log_fp, "[I +" FMT_timeval "] CLOSED\n", tv.tv_sec, (long) tv.tv_usec); } break; default: break; } }
void main_loop(void) { int r; #ifdef CONFIG_HAX if (hax_enabled()) hax_sync_vcpus(); #endif for (;;) { do { #ifdef CONFIG_PROFILER int64_t ti; #endif tcg_cpu_exec(); #ifdef CONFIG_PROFILER ti = profile_getclock(); #endif main_loop_wait(qemu_calculate_timeout()); #ifdef CONFIG_PROFILER dev_time += profile_getclock() - ti; #endif qemu_log_rotation_poll(); } while (vm_can_run()); if (qemu_debug_requested()) vm_stop(EXCP_DEBUG); if (qemu_shutdown_requested()) { if (no_shutdown) { vm_stop(0); no_shutdown = 0; } else { if (savevm_on_exit != NULL) { /* Prior to saving VM to the snapshot file, save HW config * settings for that VM, so we can match them when VM gets * loaded from the snapshot. */ snaphost_save_config(savevm_on_exit); do_savevm(cur_mon, savevm_on_exit); } break; } } if (qemu_reset_requested()) { pause_all_vcpus(); qemu_system_reset(); resume_all_vcpus(); } if (qemu_powerdown_requested()) qemu_system_powerdown(); if ((r = qemu_vmstop_requested())) vm_stop(r); } pause_all_vcpus(); }
void *colo_process_incoming_thread(void *opaque) { MigrationIncomingState *mis = opaque; QEMUFile *fb = NULL; QIOChannelBuffer *bioc = NULL; /* Cache incoming device state */ uint64_t total_size; uint64_t value; Error *local_err = NULL; qemu_sem_init(&mis->colo_incoming_sem, 0); migrate_set_state(&mis->state, MIGRATION_STATUS_ACTIVE, MIGRATION_STATUS_COLO); failover_init_state(); mis->to_src_file = qemu_file_get_return_path(mis->from_src_file); if (!mis->to_src_file) { error_report("COLO incoming thread: Open QEMUFile to_src_file failed"); goto out; } /* * Note: the communication between Primary side and Secondary side * should be sequential, we set the fd to unblocked in migration incoming * coroutine, and here we are in the COLO incoming thread, so it is ok to * set the fd back to blocked. */ qemu_file_set_blocking(mis->from_src_file, true); bioc = qio_channel_buffer_new(COLO_BUFFER_BASE_SIZE); fb = qemu_fopen_channel_input(QIO_CHANNEL(bioc)); object_unref(OBJECT(bioc)); colo_send_message(mis->to_src_file, COLO_MESSAGE_CHECKPOINT_READY, &local_err); if (local_err) { goto out; } while (mis->state == MIGRATION_STATUS_COLO) { int request = 0; colo_wait_handle_message(mis->from_src_file, &request, &local_err); if (local_err) { goto out; } assert(request); if (failover_get_state() != FAILOVER_STATUS_NONE) { error_report("failover request"); goto out; } /* FIXME: This is unnecessary for periodic checkpoint mode */ colo_send_message(mis->to_src_file, COLO_MESSAGE_CHECKPOINT_REPLY, &local_err); if (local_err) { goto out; } colo_receive_check_message(mis->from_src_file, COLO_MESSAGE_VMSTATE_SEND, &local_err); if (local_err) { goto out; } value = colo_receive_message_value(mis->from_src_file, COLO_MESSAGE_VMSTATE_SIZE, &local_err); if (local_err) { goto out; } /* * Read VM device state data into channel buffer, * It's better to re-use the memory allocated. * Here we need to handle the channel buffer directly. */ if (value > bioc->capacity) { bioc->capacity = value; bioc->data = g_realloc(bioc->data, bioc->capacity); } total_size = qemu_get_buffer(mis->from_src_file, bioc->data, value); if (total_size != value) { error_report("Got %" PRIu64 " VMState data, less than expected" " %" PRIu64, total_size, value); goto out; } bioc->usage = total_size; qio_channel_io_seek(QIO_CHANNEL(bioc), 0, 0, NULL); colo_send_message(mis->to_src_file, COLO_MESSAGE_VMSTATE_RECEIVED, &local_err); if (local_err) { goto out; } qemu_mutex_lock_iothread(); qemu_system_reset(VMRESET_SILENT); vmstate_loading = true; if (qemu_loadvm_state(fb) < 0) { error_report("COLO: loadvm failed"); qemu_mutex_unlock_iothread(); goto out; } vmstate_loading = false; qemu_mutex_unlock_iothread(); if (failover_get_state() == FAILOVER_STATUS_RELAUNCH) { failover_set_state(FAILOVER_STATUS_RELAUNCH, FAILOVER_STATUS_NONE); failover_request_active(NULL); goto out; } colo_send_message(mis->to_src_file, COLO_MESSAGE_VMSTATE_LOADED, &local_err); if (local_err) { goto out; } } out: vmstate_loading = false; /* Throw the unreported error message after exited from loop */ if (local_err) { error_report_err(local_err); } if (fb) { qemu_fclose(fb); } /* Hope this not to be too long to loop here */ qemu_sem_wait(&mis->colo_incoming_sem); qemu_sem_destroy(&mis->colo_incoming_sem); /* Must be called after failover BH is completed */ if (mis->to_src_file) { qemu_fclose(mis->to_src_file); } migration_incoming_exit_colo(); return NULL; }