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; }
int migrate_fd_cleanup(FdMigrationState *s) { int ret = 0; qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL); if (s->file) { DPRINTF("closing file\n"); if (qemu_fclose(s->file) != 0) { ret = -1; } s->file = NULL; } if (s->fd != -1) close(s->fd); /* Don't resume monitor until we've flushed all of the buffers */ if (s->mon) { monitor_resume(s->mon); } s->fd = -1; return ret; }
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; do { c = qemu_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; } process_incoming_migration(f); qemu_fclose(f); out: qemu_set_fd_handler2(s, NULL, NULL, NULL, NULL); close(s); close(c); }
void do_savevm(const char *name) { QEMUFile *f; int saved_vm_running, ret; f = qemu_fopen(name, "wb"); /* ??? Should this occur after vm_stop? */ qemu_aio_flush(); saved_vm_running = vm_running; vm_stop(0); if (!f) { fprintf(logfile, "Failed to open savevm file '%s'\n", name); goto the_end; } ret = qemu_savevm_state(f); qemu_fclose(f); if (ret < 0) fprintf(logfile, "Error %d while writing VM to savevm file '%s'\n", ret, name); the_end: if (saved_vm_running) vm_start(); return; }
/* Initialisation routine */ void *ds1225y_init(target_phys_addr_t mem_base, const char *filename) { ds1225y_t *s; int mem_indexRW, mem_indexRP; QEMUFile *file; s = qemu_mallocz(sizeof(ds1225y_t)); s->chip_size = 0x2000; /* Fixed for ds1225y chip: 8 KiB */ s->contents = qemu_mallocz(s->chip_size); s->protection = 7; /* Read current file */ file = qemu_fopen(filename, "rb"); if (file) { /* Read nvram contents */ qemu_get_buffer(file, s->contents, s->chip_size); qemu_fclose(file); } s->file = qemu_fopen(filename, "wb"); if (s->file) { /* Write back contents, as 'wb' mode cleaned the file */ qemu_put_buffer(s->file, s->contents, s->chip_size); qemu_fflush(s->file); } /* Read/write memory */ mem_indexRW = cpu_register_io_memory(nvram_read, nvram_write, s); cpu_register_physical_memory(mem_base, s->chip_size, mem_indexRW); /* Read/write protected memory */ mem_indexRP = cpu_register_io_memory(nvram_read, nvram_write_protected, s); cpu_register_physical_memory(mem_base + s->chip_size, s->chip_size, mem_indexRP); return s; }
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); } }
static void migrate_ft_trans_connect(FdMigrationState *s, int old_vm_running) { /* close buffered_file and open ft_trans_file * NB: fd won't get closed, and reused by ft_trans_file */ qemu_fclose(s->file); s->file = qemu_fopen_ops_ft_trans(s, migrate_fd_put_buffer, migrate_fd_get_buffer, migrate_ft_trans_put_ready, migrate_ft_trans_get_ready, migrate_fd_wait_for_unfreeze, migrate_fd_close, 1); socket_set_nodelay(s->fd); /* events are tapped from now */ if (event_tap_register(migrate_ft_trans_put_ready) < 0) { migrate_ft_trans_error(s); } event_tap_schedule_suspend(); if (old_vm_running) { vm_start(); } }
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); } }
static void migrate_fd_cleanup(void *opaque) { MigrationState *s = opaque; qemu_bh_delete(s->cleanup_bh); s->cleanup_bh = NULL; if (s->file) { DPRINTF("closing file\n"); qemu_mutex_unlock_iothread(); qemu_thread_join(&s->thread); qemu_mutex_lock_iothread(); qemu_fclose(s->file); s->file = NULL; } assert(s->state != MIG_STATE_ACTIVE); if (s->state != MIG_STATE_COMPLETED) { qemu_savevm_state_cancel(); if (s->state == MIG_STATE_CANCELLING) { migrate_set_state(s, MIG_STATE_CANCELLING, MIG_STATE_CANCELLED); } } notifier_list_notify(&migration_state_notifiers, s); }
int migrate_fd_cleanup(FdMigrationState *s) { int ret = 0; qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL); if (s->file) { DPRINTF("closing file\n"); if (qemu_fclose(s->file) != 0) { ret = -1; } s->file = NULL; } else { if (s->mon) { monitor_resume(s->mon); } } if (s->fd != -1) { close(s->fd); s->fd = -1; } return ret; }
static void exec_accept_incoming_migration(void *opaque) { QEMUFile *f = opaque; process_incoming_migration(f); qemu_set_fd_handler2(qemu_stdio_fd(f), NULL, NULL, NULL, NULL); qemu_fclose(f); }
int before_block_exec(CPUState *env, TranslationBlock *tb) { uint64_t count = rr_get_guest_instr_count(); if (!snipping && count+tb->icount > start_count) { sassert((oldlog = fopen(rr_nondet_log->name, "r")), 8); sassert(fread(&orig_last_prog_point, sizeof(RR_prog_point), 1, oldlog) == 1, 9); printf("Original ending prog point: "); rr_spit_prog_point(orig_last_prog_point); actual_start_count = count; printf("Saving snapshot at instr count %lu...\n", count); // Force running state global_state_store_running(); printf("writing snapshot:\t%s\n", snp_name); QIOChannelFile* ioc = qio_channel_file_new_path(snp_name, O_WRONLY | O_CREAT, 0660, NULL); QEMUFile* snp = qemu_fopen_channel_output(QIO_CHANNEL(ioc)); qemu_savevm_state(snp, NULL); qemu_fclose(snp); printf("Beginning cut-and-paste process at prog point:\n"); rr_spit_prog_point(rr_prog_point()); printf("Writing entries to %s...\n", nondet_name); newlog = fopen(nondet_name, "w"); sassert(newlog, 10); // We'll fix this up later. RR_prog_point prog_point = {0}; fwrite(&prog_point.guest_instr_count, sizeof(prog_point.guest_instr_count), 1, newlog); fseek(oldlog, ftell(rr_nondet_log->fp), SEEK_SET); // If there are items in the queue, then start copying the log // from there RR_log_entry *item = rr_get_queue_head(); if (item != NULL) fseek(oldlog, item->header.file_pos, SEEK_SET); while (prog_point.guest_instr_count < end_count && !feof(oldlog)) { prog_point = copy_entry(); } if (!feof(oldlog)) { // prog_point is the first one AFTER what we want printf("Reached end of old nondet log.\n"); } else { printf("Past desired ending point for log.\n"); } snipping = true; printf("Continuing with replay.\n"); } if (snipping && !done && count > end_count) { end_snip(); rr_end_replay_requested = 1; } return 0; }
void qmp_dump_skeys(const char *filename, Error **errp) { S390SKeysState *ss = s390_get_skeys_device(); S390SKeysClass *skeyclass = S390_SKEYS_GET_CLASS(ss); const uint64_t total_count = ram_size / TARGET_PAGE_SIZE; uint64_t handled_count = 0, cur_count; Error *lerr = NULL; vaddr cur_gfn = 0; uint8_t *buf; int ret; QEMUFile *f; /* Quick check to see if guest is using storage keys*/ if (!skeyclass->skeys_enabled(ss)) { error_setg(errp, "This guest is not using storage keys - " "nothing to dump"); return; } f = qemu_fopen(filename, "wb"); if (!f) { error_setg_file_open(errp, errno, filename); return; } buf = g_try_malloc(S390_SKEYS_BUFFER_SIZE); if (!buf) { error_setg(errp, "Could not allocate memory"); goto out; } /* we'll only dump initial memory for now */ while (handled_count < total_count) { /* Calculate how many keys to ask for & handle overflow case */ cur_count = MIN(total_count - handled_count, S390_SKEYS_BUFFER_SIZE); ret = skeyclass->get_skeys(ss, cur_gfn, cur_count, buf); if (ret < 0) { error_setg(errp, "get_keys error %d", ret); goto out_free; } /* write keys to stream */ write_keys(f, buf, cur_gfn, cur_count, &lerr); if (lerr) { goto out_free; } cur_gfn += cur_count; handled_count += cur_count; } out_free: error_propagate(errp, lerr); g_free(buf); out: qemu_fclose(f); }
static void save_vmstate(const VMStateDescription *desc, void *obj) { QEMUFile *f = open_test_file(true); /* Save file with vmstate */ vmstate_save_state(f, desc, obj); qemu_put_byte(f, QEMU_VM_EOF); g_assert(!qemu_file_get_error(f)); qemu_fclose(f); }
static int exec_close(FdMigrationState *s) { dprintf("exec_close\n"); if (s->opaque) { qemu_fclose(s->opaque); s->opaque = NULL; s->fd = -1; } return 0; }
static int ds1225y_set_to_mode(ds1225y_t *NVRAM, nvram_open_mode mode, const char *filemode) { if (NVRAM->open_mode != mode) { if (NVRAM->file) qemu_fclose(NVRAM->file); NVRAM->file = qemu_fopen(NVRAM->filename, filemode); NVRAM->open_mode = mode; } return (NVRAM->file != NULL); }
static int load_vmstate_one(const VMStateDescription *desc, void *obj, int version, uint8_t *wire, size_t size) { QEMUFile *f; int ret; f = open_test_file(true); qemu_put_buffer(f, wire, size); qemu_fclose(f); f = open_test_file(false); ret = vmstate_load_state(f, desc, obj, version); if (ret) { g_assert(qemu_file_get_error(f)); } else{ g_assert(!qemu_file_get_error(f)); } qemu_fclose(f); return ret; }
static int migrate_fd_cleanup(MigrationState *s) { int ret = 0; if (s->file) { DPRINTF("closing file\n"); ret = qemu_fclose(s->file); s->file = NULL; } assert(s->fd == -1); return ret; }
static int exec_close(MigrationState *s) { int ret = 0; DPRINTF("exec_close\n"); if (s->opaque) { ret = qemu_fclose(s->opaque); s->opaque = NULL; s->fd = -1; if (ret >= 0 && !(WIFEXITED(ret) && WEXITSTATUS(ret) == 0)) { /* close succeeded, but non-zero exit code: */ ret = -EIO; /* fake errno value */ } } return ret; }
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); }
static void exec_accept_incoming_migration(void *opaque) { QEMUFile *f = opaque; // TLC (move below to exec_start_incoming_migration() printf(" in tlc_exec_accept_incoming_migration()\n"); mthread = 1; //incoming_protocol = INCOMING_EXEC; // s'th to tell the vm not autostart tlc_migration_init(TLC_INCOMING_PAGES); process_incoming_migration(f); tlc_migration_finish(TLC_INCOMING_PAGES); mthread = 0; qemu_set_fd_handler2(qemu_stdio_fd(f), NULL, NULL, NULL, NULL); qemu_fclose(f); }
static int exec_close(MigrationState *s) { int ret = 0; DPRINTF("exec_close\n"); if (s->opaque) { ret = qemu_fclose(s->opaque); s->opaque = NULL; s->fd = -1; if (ret != -1 && WIFEXITED(ret) && WEXITSTATUS(ret) == 0) { ret = 0; } else { ret = -1; } } return ret; }
void migrate_fd_cleanup(FdMigrationState *s) { qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL); if (s->file) { dprintf("closing file\n"); qemu_fclose(s->file); } if (s->fd != -1) close(s->fd); /* Don't resume monitor until we've flushed all of the buffers */ if (s->mon_resume) monitor_resume(s->mon_resume); s->fd = -1; }
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); }
static void compare_vmstate(uint8_t *wire, size_t size) { QEMUFile *f = open_test_file(false); uint8_t result[size]; /* read back as binary */ g_assert_cmpint(qemu_get_buffer(f, result, sizeof(result)), ==, sizeof(result)); g_assert(!qemu_file_get_error(f)); /* Compare that what is on the file is the same that what we expected to be there */ SUCCESS(memcmp(result, wire, sizeof(result))); /* Must reach EOF */ qemu_get_byte(f); g_assert_cmpint(qemu_file_get_error(f), ==, -EIO); qemu_fclose(f); }
static void wav_destroy (void *opaque) { WAVState *wav = opaque; uint8_t rlen[4]; uint8_t dlen[4]; uint32_t datalen = wav->bytes; uint32_t rifflen = datalen + 36; if (wav->f) { le_store (rlen, rifflen, 4); le_store (dlen, datalen, 4); qemu_fseek (wav->f, 4, SEEK_SET); qemu_put_buffer (wav->f, rlen, 4); qemu_fseek (wav->f, 32, SEEK_CUR); qemu_put_buffer (wav->f, dlen, 4); qemu_fclose (wav->f); } g_free (wav->path); }
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; }
static void colo_process_checkpoint(MigrationState *s) { QIOChannelBuffer *bioc; QEMUFile *fb = NULL; int64_t current_time = qemu_clock_get_ms(QEMU_CLOCK_HOST); Error *local_err = NULL; int ret; failover_init_state(); s->rp_state.from_dst_file = qemu_file_get_return_path(s->to_dst_file); if (!s->rp_state.from_dst_file) { error_report("Open QEMUFile from_dst_file failed"); goto out; } /* * Wait for Secondary finish loading VM states and enter COLO * restore. */ colo_receive_check_message(s->rp_state.from_dst_file, COLO_MESSAGE_CHECKPOINT_READY, &local_err); if (local_err) { goto out; } bioc = qio_channel_buffer_new(COLO_BUFFER_BASE_SIZE); fb = qemu_fopen_channel_output(QIO_CHANNEL(bioc)); object_unref(OBJECT(bioc)); qemu_mutex_lock_iothread(); vm_start(); qemu_mutex_unlock_iothread(); trace_colo_vm_state_change("stop", "run"); timer_mod(s->colo_delay_timer, current_time + s->parameters.x_checkpoint_delay); while (s->state == MIGRATION_STATUS_COLO) { if (failover_get_state() != FAILOVER_STATUS_NONE) { error_report("failover request"); goto out; } qemu_sem_wait(&s->colo_checkpoint_sem); ret = colo_do_checkpoint_transaction(s, bioc, fb); if (ret < 0) { goto out; } } out: /* Throw the unreported error message after exited from loop */ if (local_err) { error_report_err(local_err); } if (fb) { qemu_fclose(fb); } timer_del(s->colo_delay_timer); /* Hope this not to be too long to wait here */ qemu_sem_wait(&s->colo_exit_sem); qemu_sem_destroy(&s->colo_exit_sem); /* * Must be called after failover BH is completed, * Or the failover BH may shutdown the wrong fd that * re-used by other threads after we release here. */ if (s->rp_state.from_dst_file) { qemu_fclose(s->rp_state.from_dst_file); } }