static void write_guest_mem(TestServer *s, uint32_t seed) { uint32_t *guest_mem; int i, j; size_t size; wait_for_fds(s); /* iterate all regions */ for (i = 0; i < s->fds_num; i++) { /* We'll write only the region statring at 0x0 */ if (s->memory.regions[i].guest_phys_addr != 0x0) { continue; } g_assert_cmpint(s->memory.regions[i].memory_size, >, 1024); size = s->memory.regions[i].memory_size + s->memory.regions[i].mmap_offset; guest_mem = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, s->fds[i], 0); g_assert(guest_mem != MAP_FAILED); guest_mem += (s->memory.regions[i].mmap_offset / sizeof(*guest_mem)); for (j = 0; j < 256; j++) { guest_mem[j] = seed + j; } munmap(guest_mem, s->memory.regions[i].memory_size); break; } }
static void test_read_guest_mem(const void *arg) { enum test_memfd memfd = GPOINTER_TO_INT(arg); TestServer *server = NULL; char *qemu_cmd = NULL; QTestState *s = NULL; server = test_server_new(memfd == TEST_MEMFD_YES ? "read-guest-memfd" : "read-guest-mem"); test_server_listen(server); qemu_cmd = get_qemu_cmd(server, 512, memfd, root, "", ""); s = qtest_start(qemu_cmd); g_free(qemu_cmd); init_virtio_dev(global_qtest, server, 1u << VIRTIO_NET_F_MAC); if (!wait_for_fds(server)) { goto exit; } read_guest_mem_server(global_qtest, server); exit: uninit_virtio_dev(server); qtest_quit(s); test_server_free(server); }
static void read_guest_mem(const void *data) { TestServer *s = (void *)data; uint32_t *guest_mem; int i, j; size_t size; wait_for_fds(s); g_mutex_lock(&s->data_mutex); /* iterate all regions */ for (i = 0; i < s->fds_num; i++) { /* We'll check only the region statring at 0x0*/ if (s->memory.regions[i].guest_phys_addr != 0x0) { continue; } g_assert_cmpint(s->memory.regions[i].memory_size, >, 1024); size = s->memory.regions[i].memory_size + s->memory.regions[i].mmap_offset; guest_mem = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, s->fds[i], 0); g_assert(guest_mem != MAP_FAILED); guest_mem += (s->memory.regions[i].mmap_offset / sizeof(*guest_mem)); for (j = 0; j < 256; j++) { uint32_t a = readl(s->memory.regions[i].guest_phys_addr + j*4); uint32_t b = guest_mem[j]; g_assert_cmpint(a, ==, b); } munmap(guest_mem, s->memory.regions[i].memory_size); } g_mutex_unlock(&s->data_mutex); }
static void test_migrate(void) { TestServer *s = test_server_new("src"); TestServer *dest = test_server_new("dest"); char *uri = g_strdup_printf("%s%s", "unix:", dest->mig_path); QTestState *global = global_qtest, *from, *to; GSource *source; gchar *cmd; QDict *rsp; guint8 *log; guint64 size; test_server_listen(s); test_server_listen(dest); cmd = GET_QEMU_CMDE(s, 2, "", ""); from = qtest_start(cmd); g_free(cmd); init_virtio_dev(s, 1u << VIRTIO_NET_F_MAC); wait_for_fds(s); size = get_log_size(s); g_assert_cmpint(size, ==, (2 * 1024 * 1024) / (VHOST_LOG_PAGE * 8)); cmd = GET_QEMU_CMDE(dest, 2, "", " -incoming %s", uri); to = qtest_init(cmd); g_free(cmd); source = g_source_new(&test_migrate_source_funcs, sizeof(TestMigrateSource)); ((TestMigrateSource *)source)->src = s; ((TestMigrateSource *)source)->dest = dest; g_source_attach(source, NULL); /* slow down migration to have time to fiddle with log */ /* TODO: qtest could learn to break on some places */ rsp = qmp("{ 'execute': 'migrate_set_speed'," "'arguments': { 'value': 10 } }"); g_assert(qdict_haskey(rsp, "return")); QDECREF(rsp); cmd = g_strdup_printf("{ 'execute': 'migrate'," "'arguments': { 'uri': '%s' } }", uri); rsp = qmp(cmd); g_free(cmd); g_assert(qdict_haskey(rsp, "return")); QDECREF(rsp); wait_for_log_fd(s); log = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, s->log_fd, 0); g_assert(log != MAP_FAILED); /* modify first page */ write_guest_mem(s, 0x42); log[0] = 1; munmap(log, size); /* speed things up */ rsp = qmp("{ 'execute': 'migrate_set_speed'," "'arguments': { 'value': 0 } }"); g_assert(qdict_haskey(rsp, "return")); QDECREF(rsp); qmp_eventwait("STOP"); global_qtest = to; qmp_eventwait("RESUME"); read_guest_mem_server(dest); uninit_virtio_dev(s); g_source_destroy(source); g_source_unref(source); qtest_quit(to); test_server_free(dest); qtest_quit(from); test_server_free(s); g_free(uri); global_qtest = global; }
static void *fserv_thread_function(void *arg) { fserve_t *fclient, **trail; size_t bytes; (void)arg; while (1) { if (wait_for_fds() < 0) break; fclient = active_list; trail = &active_list; while (fclient) { /* process this client, if it is ready */ if (fclient->ready) { client_t *client = fclient->client; refbuf_t *refbuf = client->refbuf; fclient->ready = 0; if (client->pos == refbuf->len) { /* Grab a new chunk */ if (fclient->file) bytes = fread (refbuf->data, 1, BUFSIZE, fclient->file); else bytes = 0; if (bytes == 0) { if (refbuf->next == NULL) { fserve_t *to_go = fclient; fclient = fclient->next; *trail = fclient; fserve_client_destroy (to_go); fserve_clients--; client_tree_changed = 1; continue; } refbuf = refbuf->next; client->refbuf->next = NULL; refbuf_release (client->refbuf); client->refbuf = refbuf; bytes = refbuf->len; } refbuf->len = (unsigned int)bytes; client->pos = 0; } /* Now try and send current chunk. */ format_generic_write_to_client (client); if (client->con->error) { fserve_t *to_go = fclient; fclient = fclient->next; *trail = fclient; fserve_clients--; fserve_client_destroy (to_go); client_tree_changed = 1; continue; } } trail = &fclient->next; fclient = fclient->next; } } ICECAST_LOG_DEBUG("fserve handler exit"); return NULL; }
static void *fserv_thread_function(void *arg) { fserve_t *fclient, **trail; int sbytes, bytes; INFO0("file serving thread started"); while (run_fserv) { wait_for_fds(); fclient = active_list; trail = &active_list; while (fclient) { /* process this client, if it is ready */ if (fclient->ready) { fclient->ready = 0; if(fclient->offset >= fclient->datasize) { /* Grab a new chunk */ bytes = fread(fclient->buf, 1, BUFSIZE, fclient->file); if (bytes == 0) { fserve_t *to_go = fclient; fclient = fclient->next; *trail = fclient; _free_client (to_go); fserve_clients--; client_tree_changed = 1; continue; } fclient->offset = 0; fclient->datasize = bytes; } /* Now try and send current chunk. */ sbytes = client_send_bytes (fclient->client, &fclient->buf[fclient->offset], fclient->datasize - fclient->offset); /* TODO: remove clients if they take too long. */ if(sbytes > 0) { fclient->offset += sbytes; } if (fclient->client->con->error) { fserve_t *to_go = fclient; fclient = fclient->next; *trail = fclient; fserve_clients--; _free_client (to_go); client_tree_changed = 1; continue; } } trail = &fclient->next; fclient = fclient->next; } } /* Shutdown path */ thread_mutex_lock (&pending_lock); while (pending_list) { fserve_t *to_go = (fserve_t *)pending_list; pending_list = to_go->next; _free_client (to_go); } thread_mutex_unlock (&pending_lock); while (active_list) { fserve_t *to_go = active_list; active_list = to_go->next; _free_client (to_go); } return NULL; }