MigrationState *migrate_get_current(void) { static MigrationState current_migration = { .state = MIG_STATE_NONE, .bandwidth_limit = MAX_THROTTLE, .xbzrle_cache_size = DEFAULT_MIGRATE_CACHE_SIZE, .mbps = -1, }; return ¤t_migration; } void qemu_start_incoming_migration(const char *uri, Error **errp) { const char *p; if (strstart(uri, "tcp:", &p)) tcp_start_incoming_migration(p, errp); #ifdef CONFIG_RDMA else if (strstart(uri, "rdma:", &p)) rdma_start_incoming_migration(p, errp); #endif #if !defined(WIN32) else if (strstart(uri, "exec:", &p)) exec_start_incoming_migration(p, errp); else if (strstart(uri, "unix:", &p)) unix_start_incoming_migration(p, errp); else if (strstart(uri, "fd:", &p)) fd_start_incoming_migration(p, errp); #endif else { error_setg(errp, "unknown migration protocol: %s", uri); } } static void process_incoming_migration_co(void *opaque) { QEMUFile *f = opaque; int ret; ret = qemu_loadvm_state(f); qemu_fclose(f); free_xbzrle_decoded_buf(); if (ret < 0) { fprintf(stderr, "load of migration failed\n"); exit(EXIT_FAILURE); } qemu_announce_self(); DPRINTF("successfully loaded vm state\n"); bdrv_clear_incoming_migration_all(); /* Make sure all file formats flush their mutable metadata */ bdrv_invalidate_cache_all(); if (autostart) { vm_start(); } else { runstate_set(RUN_STATE_PAUSED); } }
int exec_start_incoming_migration(const char *command) { int ret; QEMUFile *f; dprintf("Attempting to start an incoming migration\n"); f = qemu_popen_cmd(command, "r"); if(f == NULL) { dprintf("Unable to apply qemu wrapper to popen file\n"); return -errno; } vm_stop(0); /* just in case */ ret = qemu_loadvm_state(f); if (ret < 0) { fprintf(stderr, "load of migration failed\n"); goto err; } qemu_announce_self(); dprintf("successfully loaded vm state\n"); vm_start(); qemu_fclose(f); return 0; err: qemu_fclose(f); return -errno; }
static void process_incoming_migration_co(void *opaque) { QEMUFile *f = opaque; int ret; ret = qemu_loadvm_state(f); qemu_set_fd_handler(qemu_get_fd(f), NULL, NULL, NULL); qemu_fclose(f); if (ret < 0) { fprintf(stderr, "load of migration failed\n"); exit(0); } qemu_announce_self(); DPRINTF("successfully loaded vm state\n"); bdrv_clear_incoming_migration_all(); /* Make sure all file formats flush their mutable metadata */ bdrv_invalidate_cache_all(); if (autostart) { vm_start(); } else { runstate_set(RUN_STATE_PAUSED); } }
void process_incoming_migration(QEMUFile *f) { if (qemu_loadvm_state(f) < 0) { fprintf(stderr, "load of migration failed\n"); exit(0); } qemu_announce_self(); DPRINTF("successfully loaded vm state\n"); if (autostart) vm_start(); }
static void tcp_accept_incoming_migration(void *opaque) { struct sockaddr_in addr; socklen_t addrlen = sizeof(addr); int s = (unsigned long)opaque; QEMUFile *f; int c, ret; do { c = accept(s, (struct sockaddr *)&addr, &addrlen); } while (c == -1 && socket_error() == EINTR); dprintf("accepted migration\n"); if (c == -1) { fprintf(stderr, "could not accept migration connection\n"); return; } f = qemu_fopen_socket(c); if (f == NULL) { fprintf(stderr, "could not qemu_fopen socket\n"); goto out; } vm_stop(0); /* just in case */ ret = qemu_loadvm_state(f); if (ret < 0) { fprintf(stderr, "load of migration failed\n"); goto out_fopen; } qemu_announce_self(); dprintf("successfully loaded vm state\n"); /* we've successfully migrated, close the server socket */ qemu_set_fd_handler2(s, NULL, NULL, NULL, NULL); close(s); vm_start(); out_fopen: qemu_fclose(f); out: close(c); }
void process_incoming_migration(QEMUFile *f) { if (qemu_loadvm_state(f) < 0) { fprintf(stderr, "load of migration failed\n"); exit(0); } qemu_announce_self(); DPRINTF("successfully loaded vm state\n"); /* Make sure all file formats flush their mutable metadata */ bdrv_invalidate_cache_all(); if (autostart) { vm_start(); } else { runstate_set(RUN_STATE_PRELAUNCH); } }
static void exec_accept_incoming_migration(void *opaque) { QEMUFile *f = opaque; int ret; ret = qemu_loadvm_state(f); if (ret < 0) { fprintf(stderr, "load of migration failed\n"); goto err; } qemu_announce_self(); dprintf("successfully loaded vm state\n"); /* we've successfully migrated, close the fd */ qemu_set_fd_handler2(qemu_stdio_fd(f), NULL, NULL, NULL, NULL); if (autostart) vm_start(); err: qemu_fclose(f); }
static void tcp_accept_incoming_migration(void *opaque) { SockAddress addr; int s = (unsigned long)opaque; QEMUFile *f; int c, ret; c = socket_accept(s, &addr); dprintf("accepted migration\n"); if (c == -1) { fprintf(stderr, "could not accept migration connection\n"); return; } f = qemu_fopen_socket(c); if (f == NULL) { fprintf(stderr, "could not qemu_fopen socket\n"); goto out; } vm_stop(0); /* just in case */ ret = qemu_loadvm_state(f); if (ret < 0) { fprintf(stderr, "load of migration failed\n"); goto out_fopen; } qemu_announce_self(); dprintf("successfully loaded vm state\n"); /* we've successfully migrated, close the server socket */ qemu_set_fd_handler2(s, NULL, NULL, NULL, NULL); socket_close(s); vm_start(); out_fopen: qemu_fclose(f); out: socket_close(c); }
void do_loadvm(const char *name) { QEMUFile *f; int saved_vm_running, ret; /* Flush all IO requests so they don't interfere with the new state. */ qemu_aio_flush(); saved_vm_running = vm_running; vm_stop(0); /* restore the VM state */ f = qemu_fopen(name, "rb"); if (!f) { fprintf(logfile, "Could not open VM state file\n"); goto the_end; } ret = qemu_loadvm_state(f); qemu_fclose(f); if (ret < 0) { fprintf(logfile, "Error %d while loading savevm file '%s'\n", ret, name); goto the_end; } #if 0 /* del tmp file */ if (unlink(name) == -1) fprintf(stderr, "delete tmp qemu state file failed.\n"); #endif the_end: if (saved_vm_running) vm_start(); }
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; }
MigrationState *migrate_get_current(void) { static MigrationState current_migration = { .state = MIGRATION_STATUS_NONE, .bandwidth_limit = MAX_THROTTLE, .xbzrle_cache_size = DEFAULT_MIGRATE_CACHE_SIZE, .mbps = -1, .parameters[MIGRATION_PARAMETER_COMPRESS_LEVEL] = DEFAULT_MIGRATE_COMPRESS_LEVEL, .parameters[MIGRATION_PARAMETER_COMPRESS_THREADS] = DEFAULT_MIGRATE_COMPRESS_THREAD_COUNT, .parameters[MIGRATION_PARAMETER_DECOMPRESS_THREADS] = DEFAULT_MIGRATE_DECOMPRESS_THREAD_COUNT, }; return ¤t_migration; } /* * Called on -incoming with a defer: uri. * The migration can be started later after any parameters have been * changed. */ static void deferred_incoming_migration(Error **errp) { if (deferred_incoming) { error_setg(errp, "Incoming migration already deferred"); } deferred_incoming = true; } void qemu_start_incoming_migration(const char *uri, Error **errp) { const char *p; if (!strcmp(uri, "defer")) { deferred_incoming_migration(errp); } else if (strstart(uri, "tcp:", &p)) { tcp_start_incoming_migration(p, errp); #ifdef CONFIG_RDMA } else if (strstart(uri, "rdma:", &p)) { rdma_start_incoming_migration(p, errp); #endif #if !defined(WIN32) } else if (strstart(uri, "exec:", &p)) { exec_start_incoming_migration(p, errp); } else if (strstart(uri, "unix:", &p)) { unix_start_incoming_migration(p, errp); } else if (strstart(uri, "fd:", &p)) { fd_start_incoming_migration(p, errp); #endif } else { error_setg(errp, "unknown migration protocol: %s", uri); } } static void process_incoming_migration_co(void *opaque) { QEMUFile *f = opaque; Error *local_err = NULL; int ret; ret = qemu_loadvm_state(f); qemu_fclose(f); free_xbzrle_decoded_buf(); if (ret < 0) { error_report("load of migration failed: %s", strerror(-ret)); migrate_decompress_threads_join(); exit(EXIT_FAILURE); } qemu_announce_self(); /* Make sure all file formats flush their mutable metadata */ bdrv_invalidate_cache_all(&local_err); if (local_err) { error_report_err(local_err); migrate_decompress_threads_join(); exit(EXIT_FAILURE); } if (autostart) { vm_start(); } else { runstate_set(RUN_STATE_PAUSED); } migrate_decompress_threads_join(); }