static void test_io_channel_file(void) { QIOChannel *src, *dst; QIOChannelTest *test; #define TEST_FILE "tests/test-io-channel-file.txt" unlink(TEST_FILE); src = QIO_CHANNEL(qio_channel_file_new_path( TEST_FILE, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0600, &error_abort)); dst = QIO_CHANNEL(qio_channel_file_new_path( TEST_FILE, O_RDONLY | O_BINARY, 0, &error_abort)); test = qio_channel_test_new(); qio_channel_test_run_writer(test, src); qio_channel_test_run_reader(test, dst); qio_channel_test_validate(test); unlink(TEST_FILE); object_unref(OBJECT(src)); object_unref(OBJECT(dst)); }
static int tcp_chr_wait_connected(Chardev *chr, Error **errp) { SocketChardev *s = SOCKET_CHARDEV(chr); QIOChannelSocket *sioc; /* It can't wait on s->connected, since it is set asynchronously * in TLS and telnet cases, only wait for an accepted socket */ while (!s->ioc) { if (s->is_listen) { error_report("QEMU waiting for connection on: %s", chr->filename); qio_channel_set_blocking(QIO_CHANNEL(s->listen_ioc), true, NULL); tcp_chr_accept(QIO_CHANNEL(s->listen_ioc), G_IO_IN, chr); qio_channel_set_blocking(QIO_CHANNEL(s->listen_ioc), false, NULL); } else { sioc = qio_channel_socket_new(); tcp_chr_set_client_ioc_name(chr, sioc); if (qio_channel_socket_connect_sync(sioc, s->addr, errp) < 0) { object_unref(OBJECT(sioc)); return -1; } tcp_chr_new_client(chr, sioc); object_unref(OBJECT(sioc)); } } return 0; }
static gboolean socket_accept_incoming_migration(QIOChannel *ioc, GIOCondition condition, gpointer opaque) { QIOChannelSocket *sioc; Error *err = NULL; sioc = qio_channel_socket_accept(QIO_CHANNEL_SOCKET(ioc), &err); if (!sioc) { error_report("could not accept migration connection (%s)", error_get_pretty(err)); goto out; } trace_migration_socket_incoming_accepted(); qio_channel_set_name(QIO_CHANNEL(sioc), "migration-socket-incoming"); migration_channel_process_incoming(migrate_get_current(), QIO_CHANNEL(sioc)); object_unref(OBJECT(sioc)); out: /* Close listening socket as its no longer needed */ qio_channel_close(ioc, NULL); return FALSE; /* unregister */ }
static void char_pty_open(Chardev *chr, ChardevBackend *backend, bool *be_opened, Error **errp) { PtyChardev *s; int master_fd, slave_fd; char pty_name[PATH_MAX]; char *name; master_fd = qemu_openpty_raw(&slave_fd, pty_name); if (master_fd < 0) { error_setg_errno(errp, errno, "Failed to create PTY"); return; } close(slave_fd); qemu_set_nonblock(master_fd); chr->filename = g_strdup_printf("pty:%s", pty_name); error_report("char device redirected to %s (label %s)", pty_name, chr->label); s = PTY_CHARDEV(chr); s->ioc = QIO_CHANNEL(qio_channel_file_new_fd(master_fd)); name = g_strdup_printf("chardev-pty-%s", chr->label); qio_channel_set_name(QIO_CHANNEL(s->ioc), name); g_free(name); s->timer_src = NULL; *be_opened = false; }
static void test_io_channel_setup_sync(SocketAddress *listen_addr, SocketAddress *connect_addr, QIOChannel **src, QIOChannel **dst) { QIOChannelSocket *lioc; lioc = qio_channel_socket_new(); qio_channel_socket_listen_sync(lioc, listen_addr, &error_abort); if (listen_addr->type == SOCKET_ADDRESS_TYPE_INET) { SocketAddress *laddr = qio_channel_socket_get_local_address( lioc, &error_abort); g_free(connect_addr->u.inet.port); connect_addr->u.inet.port = g_strdup(laddr->u.inet.port); qapi_free_SocketAddress(laddr); } *src = QIO_CHANNEL(qio_channel_socket_new()); qio_channel_socket_connect_sync( QIO_CHANNEL_SOCKET(*src), connect_addr, &error_abort); qio_channel_set_delay(*src, false); qio_channel_wait(QIO_CHANNEL(lioc), G_IO_IN); *dst = QIO_CHANNEL(qio_channel_socket_accept(lioc, &error_abort)); g_assert(*dst); test_io_channel_set_socket_bufs(*src, *dst); object_unref(OBJECT(lioc)); }
static QIOChannel *nbd_receive_starttls(QIOChannel *ioc, QCryptoTLSCreds *tlscreds, const char *hostname, Error **errp) { nbd_opt_reply reply; QIOChannelTLS *tioc; struct NBDTLSHandshakeData data = { 0 }; trace_nbd_receive_starttls_request(); if (nbd_send_option_request(ioc, NBD_OPT_STARTTLS, 0, NULL, errp) < 0) { return NULL; } trace_nbd_receive_starttls_reply(); if (nbd_receive_option_reply(ioc, NBD_OPT_STARTTLS, &reply, errp) < 0) { return NULL; } if (reply.type != NBD_REP_ACK) { error_setg(errp, "Server rejected request to start TLS %" PRIx32, reply.type); nbd_send_opt_abort(ioc); return NULL; } if (reply.length != 0) { error_setg(errp, "Start TLS response was not zero %" PRIu32, reply.length); nbd_send_opt_abort(ioc); return NULL; } trace_nbd_receive_starttls_new_client(); tioc = qio_channel_tls_new_client(ioc, tlscreds, hostname, errp); if (!tioc) { return NULL; } qio_channel_set_name(QIO_CHANNEL(tioc), "nbd-client-tls"); data.loop = g_main_loop_new(g_main_context_default(), FALSE); trace_nbd_receive_starttls_tls_handshake(); qio_channel_tls_handshake(tioc, nbd_tls_handshake, &data, NULL); if (!data.complete) { g_main_loop_run(data.loop); } g_main_loop_unref(data.loop); if (data.error) { error_propagate(errp, data.error); object_unref(OBJECT(tioc)); return NULL; } return QIO_CHANNEL(tioc); }
static void test_io_channel_setup_async(SocketAddress *listen_addr, SocketAddress *connect_addr, QIOChannel **srv, QIOChannel **src, QIOChannel **dst) { QIOChannelSocket *lioc; struct TestIOChannelData data; data.loop = g_main_loop_new(g_main_context_default(), TRUE); lioc = qio_channel_socket_new(); qio_channel_socket_listen_async( lioc, listen_addr, test_io_channel_complete, &data, NULL, NULL); g_main_loop_run(data.loop); g_main_context_iteration(g_main_context_default(), FALSE); g_assert(!data.err); if (listen_addr->type == SOCKET_ADDRESS_TYPE_INET) { SocketAddress *laddr = qio_channel_socket_get_local_address( lioc, &error_abort); g_free(connect_addr->u.inet.port); connect_addr->u.inet.port = g_strdup(laddr->u.inet.port); qapi_free_SocketAddress(laddr); } *src = QIO_CHANNEL(qio_channel_socket_new()); qio_channel_socket_connect_async( QIO_CHANNEL_SOCKET(*src), connect_addr, test_io_channel_complete, &data, NULL, NULL); g_main_loop_run(data.loop); g_main_context_iteration(g_main_context_default(), FALSE); g_assert(!data.err); qio_channel_wait(QIO_CHANNEL(lioc), G_IO_IN); *dst = QIO_CHANNEL(qio_channel_socket_accept(lioc, &error_abort)); g_assert(*dst); qio_channel_set_delay(*src, false); test_io_channel_set_socket_bufs(*src, *dst); *srv = QIO_CHANNEL(lioc); g_main_loop_unref(data.loop); }
QIOChannelSocket * qio_channel_socket_accept(QIOChannelSocket *ioc, Error **errp) { QIOChannelSocket *cioc; cioc = QIO_CHANNEL_SOCKET(object_new(TYPE_QIO_CHANNEL_SOCKET)); cioc->fd = -1; cioc->remoteAddrLen = sizeof(ioc->remoteAddr); cioc->localAddrLen = sizeof(ioc->localAddr); #ifdef WIN32 QIO_CHANNEL(cioc)->event = CreateEvent(NULL, FALSE, FALSE, NULL); #endif retry: trace_qio_channel_socket_accept(ioc); cioc->fd = qemu_accept(ioc->fd, (struct sockaddr *)&cioc->remoteAddr, &cioc->remoteAddrLen); if (cioc->fd < 0) { trace_qio_channel_socket_accept_fail(ioc); if (errno == EINTR) { goto retry; } goto error; } if (getsockname(cioc->fd, (struct sockaddr *)&cioc->localAddr, &cioc->localAddrLen) < 0) { error_setg_errno(errp, errno, "Unable to query local socket address"); goto error; } #ifndef WIN32 if (cioc->localAddr.ss_family == AF_UNIX) { QIOChannel *ioc_local = QIO_CHANNEL(cioc); qio_channel_set_feature(ioc_local, QIO_CHANNEL_FEATURE_FD_PASS); } #endif /* WIN32 */ trace_qio_channel_socket_accept_complete(ioc, cioc, cioc->fd); return cioc; error: object_unref(OBJECT(cioc)); return NULL; }
static int protocol_client_vencrypt_auth(VncState *vs, uint8_t *data, size_t len) { int auth = read_u32(data, 0); trace_vnc_auth_vencrypt_subauth(vs, auth); if (auth != vs->subauth) { trace_vnc_auth_fail(vs, vs->auth, "Unsupported sub-auth version", ""); vnc_write_u8(vs, 0); /* Reject auth */ vnc_flush(vs); vnc_client_error(vs); } else { Error *err = NULL; QIOChannelTLS *tls; vnc_write_u8(vs, 1); /* Accept auth */ vnc_flush(vs); if (vs->ioc_tag) { g_source_remove(vs->ioc_tag); vs->ioc_tag = 0; } tls = qio_channel_tls_new_server( vs->ioc, vs->vd->tlscreds, vs->vd->tlsauthzid, &err); if (!tls) { trace_vnc_auth_fail(vs, vs->auth, "TLS setup failed", error_get_pretty(err)); error_free(err); vnc_client_error(vs); return 0; } qio_channel_set_name(QIO_CHANNEL(tls), "vnc-server-tls"); object_unref(OBJECT(vs->ioc)); vs->ioc = QIO_CHANNEL(tls); trace_vnc_client_io_wrap(vs, vs->ioc, "tls"); vs->tls = qio_channel_tls_get_session(tls); qio_channel_tls_handshake(tls, vnc_tls_handshake_done, vs, NULL, NULL); } return 0; }
void nbd_client_attach_aio_context(BlockDriverState *bs, AioContext *new_context) { NBDClientSession *client = nbd_get_client_session(bs); qio_channel_attach_aio_context(QIO_CHANNEL(client->ioc), new_context); aio_co_schedule(new_context, client->read_reply_co); }
static int tcp_chr_new_client(Chardev *chr, QIOChannelSocket *sioc) { SocketChardev *s = SOCKET_CHARDEV(chr); if (s->ioc != NULL) { return -1; } s->ioc = QIO_CHANNEL(sioc); object_ref(OBJECT(sioc)); s->sioc = sioc; object_ref(OBJECT(sioc)); qio_channel_set_blocking(s->ioc, false, NULL); if (s->do_nodelay) { qio_channel_set_delay(s->ioc, false); } if (s->listen_tag) { g_source_remove(s->listen_tag); s->listen_tag = 0; } if (s->tls_creds) { tcp_chr_tls_init(chr); } else { if (s->do_telnetopt) { tcp_chr_telnet_init(chr); } else { tcp_chr_connect(chr); } } return 0; }
/* open a character device to a unix fd */ void qemu_chr_open_fd(Chardev *chr, int fd_in, int fd_out) { FDChardev *s = FD_CHARDEV(chr); char *name; s->ioc_in = QIO_CHANNEL(qio_channel_file_new_fd(fd_in)); name = g_strdup_printf("chardev-file-in-%s", chr->label); qio_channel_set_name(QIO_CHANNEL(s->ioc_in), name); g_free(name); s->ioc_out = QIO_CHANNEL(qio_channel_file_new_fd(fd_out)); name = g_strdup_printf("chardev-file-out-%s", chr->label); qio_channel_set_name(QIO_CHANNEL(s->ioc_out), name); g_free(name); qemu_set_nonblock(fd_out); s->chr = chr; }
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_nbd_server_start(SocketAddress *addr, bool has_tls_creds, const char *tls_creds, Error **errp) { if (nbd_server) { error_setg(errp, "NBD server already running"); return; } nbd_server = g_new0(NBDServerData, 1); nbd_server->watch = -1; nbd_server->listen_ioc = qio_channel_socket_new(); qio_channel_set_name(QIO_CHANNEL(nbd_server->listen_ioc), "nbd-listener"); if (qio_channel_socket_listen_sync( nbd_server->listen_ioc, addr, errp) < 0) { goto error; } if (has_tls_creds) { nbd_server->tlscreds = nbd_get_tls_creds(tls_creds, errp); if (!nbd_server->tlscreds) { goto error; } /* TODO SOCKET_ADDRESS_KIND_FD where fd has AF_INET or AF_INET6 */ if (addr->type != SOCKET_ADDRESS_KIND_INET) { error_setg(errp, "TLS is only supported with IPv4/IPv6"); goto error; } } nbd_server->watch = qio_channel_add_watch( QIO_CHANNEL(nbd_server->listen_ioc), G_IO_IN, nbd_accept, NULL, NULL); return; error: nbd_server_free(nbd_server); nbd_server = NULL; }
static QIOChannel *nbd_receive_starttls(QIOChannel *ioc, QCryptoTLSCreds *tlscreds, const char *hostname, Error **errp) { int ret; QIOChannelTLS *tioc; struct NBDTLSHandshakeData data = { 0 }; ret = nbd_request_simple_option(ioc, NBD_OPT_STARTTLS, errp); if (ret <= 0) { if (ret == 0) { error_setg(errp, "Server don't support STARTTLS option"); nbd_send_opt_abort(ioc); } return NULL; } trace_nbd_receive_starttls_new_client(); tioc = qio_channel_tls_new_client(ioc, tlscreds, hostname, errp); if (!tioc) { return NULL; } qio_channel_set_name(QIO_CHANNEL(tioc), "nbd-client-tls"); data.loop = g_main_loop_new(g_main_context_default(), FALSE); trace_nbd_receive_starttls_tls_handshake(); qio_channel_tls_handshake(tioc, nbd_tls_handshake, &data, NULL); if (!data.complete) { g_main_loop_run(data.loop); } g_main_loop_unref(data.loop); if (data.error) { error_propagate(errp, data.error); object_unref(OBJECT(tioc)); return NULL; } return QIO_CHANNEL(tioc); }
static void socket_start_incoming_migration(SocketAddress *saddr, Error **errp) { QIOChannelSocket *listen_ioc = qio_channel_socket_new(); qio_channel_set_name(QIO_CHANNEL(listen_ioc), "migration-socket-listener"); if (qio_channel_socket_listen_sync(listen_ioc, saddr, errp) < 0) { object_unref(OBJECT(listen_ioc)); qapi_free_SocketAddress(saddr); return; } qio_channel_add_watch(QIO_CHANNEL(listen_ioc), G_IO_IN, socket_accept_incoming_migration, listen_ioc, (GDestroyNotify)object_unref); qapi_free_SocketAddress(saddr); }
static void test_io_channel_pipe(bool async) { QIOChannel *src, *dst; QIOChannelTest *test; int fd[2]; if (pipe(fd) < 0) { perror("pipe"); abort(); } src = QIO_CHANNEL(qio_channel_file_new_fd(fd[1])); dst = QIO_CHANNEL(qio_channel_file_new_fd(fd[0])); test = qio_channel_test_new(); qio_channel_test_run_threads(test, async, src, dst); qio_channel_test_validate(test); object_unref(OBJECT(src)); object_unref(OBJECT(dst)); }
static void qio_channel_finalize(Object *obj) { QIOChannel *ioc = QIO_CHANNEL(obj); g_free(ioc->name); #ifdef _WIN32 if (ioc->event) { CloseHandle(ioc->event); } #endif }
static void tcp_chr_set_client_ioc_name(Chardev *chr, QIOChannelSocket *sioc) { SocketChardev *s = SOCKET_CHARDEV(chr); char *name; name = g_strdup_printf("chardev-tcp-%s-%s", s->is_listen ? "server" : "client", chr->label); qio_channel_set_name(QIO_CHANNEL(sioc), name); g_free(name); }
static void migration_tls_incoming_handshake(Object *src, Error *err, gpointer opaque) { QIOChannel *ioc = QIO_CHANNEL(src); if (err) { trace_migration_tls_incoming_handshake_error(error_get_pretty(err)); error_report("%s", error_get_pretty(err)); } else { trace_migration_tls_incoming_handshake_complete(); migration_set_incoming_channel(migrate_get_current(), ioc); } object_unref(OBJECT(ioc)); }
static void tcp_chr_tls_init(Chardev *chr) { SocketChardev *s = SOCKET_CHARDEV(chr); QIOChannelTLS *tioc; Error *err = NULL; gchar *name; if (s->is_listen) { tioc = qio_channel_tls_new_server( s->ioc, s->tls_creds, NULL, /* XXX Use an ACL */ &err); } else { tioc = qio_channel_tls_new_client( s->ioc, s->tls_creds, s->addr->u.inet.data->host, &err); } if (tioc == NULL) { error_free(err); tcp_chr_disconnect(chr); return; } name = g_strdup_printf("chardev-tls-%s-%s", s->is_listen ? "server" : "client", chr->label); qio_channel_set_name(QIO_CHANNEL(tioc), name); g_free(name); object_unref(OBJECT(s->ioc)); s->ioc = QIO_CHANNEL(tioc); qio_channel_tls_handshake(tioc, tcp_chr_tls_handshake, chr, NULL); }
static void vncws_tls_handshake_done(Object *source, Error *err, gpointer user_data) { VncState *vs = user_data; if (err) { VNC_DEBUG("Handshake failed %s\n", error_get_pretty(err)); vnc_client_error(vs); } else { VNC_DEBUG("TLS handshake complete, starting websocket handshake\n"); vs->ioc_tag = qio_channel_add_watch( QIO_CHANNEL(vs->ioc), G_IO_IN, vncws_handshake_io, vs, NULL); } }
static void nbd_update_server_watch(void) { if (nbd_can_accept()) { if (server_watch == -1) { server_watch = qio_channel_add_watch(QIO_CHANNEL(server_ioc), G_IO_IN, nbd_accept, NULL, NULL); } } else { if (server_watch != -1) { g_source_remove(server_watch); server_watch = -1; } } }
static int qio_channel_socket_set_fd(QIOChannelSocket *sioc, int fd, Error **errp) { if (sioc->fd != -1) { error_setg(errp, "Socket is already open"); return -1; } sioc->fd = fd; sioc->remoteAddrLen = sizeof(sioc->remoteAddr); sioc->localAddrLen = sizeof(sioc->localAddr); if (getpeername(fd, (struct sockaddr *)&sioc->remoteAddr, &sioc->remoteAddrLen) < 0) { if (errno == ENOTCONN) { memset(&sioc->remoteAddr, 0, sizeof(sioc->remoteAddr)); sioc->remoteAddrLen = sizeof(sioc->remoteAddr); } else { error_setg_errno(errp, errno, "Unable to query remote socket address"); goto error; } } if (getsockname(fd, (struct sockaddr *)&sioc->localAddr, &sioc->localAddrLen) < 0) { error_setg_errno(errp, errno, "Unable to query local socket address"); goto error; } #ifndef WIN32 if (sioc->localAddr.ss_family == AF_UNIX) { QIOChannel *ioc = QIO_CHANNEL(sioc); qio_channel_set_feature(ioc, QIO_CHANNEL_FEATURE_FD_PASS); } #endif /* WIN32 */ return 0; error: sioc->fd = -1; /* Let the caller close FD on failure */ return -1; }
static void migration_tls_outgoing_handshake(Object *src, Error *err, gpointer opaque) { MigrationState *s = opaque; QIOChannel *ioc = QIO_CHANNEL(src); if (err) { trace_migration_tls_outgoing_handshake_error(error_get_pretty(err)); s->to_dst_file = NULL; migrate_fd_error(s, err); } else { trace_migration_tls_outgoing_handshake_complete(); migration_set_outgoing_channel(s, ioc, NULL); } object_unref(OBJECT(ioc)); }
void exec_start_outgoing_migration(MigrationState *s, const char *command, Error **errp) { QIOChannel *ioc; const char *argv[] = { "/bin/sh", "-c", command, NULL }; trace_migration_exec_outgoing(command); ioc = QIO_CHANNEL(qio_channel_command_new_spawn(argv, O_RDWR, errp)); if (!ioc) { return; } qio_channel_set_name(ioc, "migration-exec-outgoing"); migration_channel_connect(s, ioc, NULL, NULL); object_unref(OBJECT(ioc)); }
static int protocol_client_vencrypt_auth(VncState *vs, uint8_t *data, size_t len) { int auth = read_u32(data, 0); if (auth != vs->subauth) { VNC_DEBUG("Rejecting auth %d\n", auth); vnc_write_u8(vs, 0); /* Reject auth */ vnc_flush(vs); vnc_client_error(vs); } else { Error *err = NULL; QIOChannelTLS *tls; VNC_DEBUG("Accepting auth %d, setting up TLS for handshake\n", auth); vnc_write_u8(vs, 1); /* Accept auth */ vnc_flush(vs); if (vs->ioc_tag) { g_source_remove(vs->ioc_tag); vs->ioc_tag = 0; } tls = qio_channel_tls_new_server( vs->ioc, vs->vd->tlscreds, vs->vd->tlsaclname, &err); if (!tls) { VNC_DEBUG("Failed to setup TLS %s\n", error_get_pretty(err)); error_free(err); vnc_client_error(vs); return 0; } VNC_DEBUG("Start TLS VeNCrypt handshake process\n"); object_unref(OBJECT(vs->ioc)); vs->ioc = QIO_CHANNEL(tls); vs->tls = qio_channel_tls_get_session(tls); qio_channel_tls_handshake(tls, vnc_tls_handshake_done, vs, NULL); } return 0; }
QIOChannelWebsock * qio_channel_websock_new_server(QIOChannel *master) { QIOChannelWebsock *wioc; QIOChannel *ioc; wioc = QIO_CHANNEL_WEBSOCK(object_new(TYPE_QIO_CHANNEL_WEBSOCK)); ioc = QIO_CHANNEL(wioc); wioc->master = master; if (master->features & (1 << QIO_CHANNEL_FEATURE_SHUTDOWN)) { ioc->features |= (1 << QIO_CHANNEL_FEATURE_SHUTDOWN); } object_ref(OBJECT(master)); trace_qio_channel_websock_new_server(wioc, master); return wioc; }
static void socket_outgoing_migration(QIOTask *task, gpointer opaque) { struct SocketConnectData *data = opaque; QIOChannel *sioc = QIO_CHANNEL(qio_task_get_source(task)); Error *err = NULL; if (qio_task_propagate_error(task, &err)) { trace_migration_socket_outgoing_error(error_get_pretty(err)); data->s->to_dst_file = NULL; migrate_fd_error(data->s, err); error_free(err); } else { trace_migration_socket_outgoing_connected(data->hostname); migration_channel_connect(data->s, sioc, data->hostname); } object_unref(OBJECT(sioc)); }
void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error **errp) { QIOChannel *ioc; int fd = monitor_get_fd(cur_mon, fdname, errp); if (fd == -1) { return; } trace_migration_fd_outgoing(fd); ioc = qio_channel_new_fd(fd, errp); if (!ioc) { close(fd); return; } qio_channel_set_name(QIO_CHANNEL(ioc), "migration-fd-outgoing"); migration_channel_connect(s, ioc, NULL); object_unref(OBJECT(ioc)); }