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 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 void qio_channel_socket_connect_worker(QIOTask *task, gpointer opaque) { QIOChannelSocket *ioc = QIO_CHANNEL_SOCKET(qio_task_get_source(task)); SocketAddress *addr = opaque; Error *err = NULL; qio_channel_socket_connect_sync(ioc, addr, &err); qio_task_set_error(task, err); }
static int qio_channel_socket_connect_worker(QIOTask *task, Error **errp, gpointer opaque) { QIOChannelSocket *ioc = QIO_CHANNEL_SOCKET(qio_task_get_source(task)); SocketAddress *addr = opaque; int ret; ret = qio_channel_socket_connect_sync(ioc, addr, errp); object_unref(OBJECT(ioc)); return ret; }
static void *nbd_client_thread(void *arg) { char *device = arg; NBDExportInfo info = { .request_sizes = false, }; QIOChannelSocket *sioc; int fd; int ret; pthread_t show_parts_thread; Error *local_error = NULL; sioc = qio_channel_socket_new(); if (qio_channel_socket_connect_sync(sioc, saddr, &local_error) < 0) { error_report_err(local_error); goto out; } ret = nbd_receive_negotiate(QIO_CHANNEL(sioc), NULL, NULL, NULL, NULL, &info, &local_error); if (ret < 0) { if (local_error) { error_report_err(local_error); } goto out_socket; } fd = open(device, O_RDWR); if (fd < 0) { /* Linux-only, we can use %m in printf. */ error_report("Failed to open %s: %m", device); goto out_socket; } ret = nbd_init(fd, sioc, &info, &local_error); if (ret < 0) { error_report_err(local_error); goto out_fd; } /* update partition table */ pthread_create(&show_parts_thread, NULL, show_parts, device); if (verbose) { fprintf(stderr, "NBD device %s is now connected to %s\n", device, srcpath); } else { /* Close stderr so that the qemu-nbd process exits. */ dup2(STDOUT_FILENO, STDERR_FILENO); } ret = nbd_client(fd); if (ret) { goto out_fd; } close(fd); object_unref(OBJECT(sioc)); kill(getpid(), SIGTERM); return (void *) EXIT_SUCCESS; out_fd: close(fd); out_socket: object_unref(OBJECT(sioc)); out: kill(getpid(), SIGTERM); return (void *) EXIT_FAILURE; } static int nbd_can_accept(void) { return state == RUNNING && nb_fds < shared; } static void nbd_export_closed(NBDExport *exp) { assert(state == TERMINATING); state = TERMINATED; }
static void *nbd_client_thread(void *arg) { char *device = arg; off_t size; uint32_t nbdflags; QIOChannelSocket *sioc; int fd; int ret; pthread_t show_parts_thread; Error *local_error = NULL; sioc = qio_channel_socket_new(); if (qio_channel_socket_connect_sync(sioc, saddr, &local_error) < 0) { error_report_err(local_error); goto out; } ret = nbd_receive_negotiate(QIO_CHANNEL(sioc), NULL, &nbdflags, NULL, NULL, NULL, &size, &local_error); if (ret < 0) { if (local_error) { error_report_err(local_error); } goto out_socket; } fd = open(device, O_RDWR); if (fd < 0) { /* Linux-only, we can use %m in printf. */ error_report("Failed to open %s: %m", device); goto out_socket; } ret = nbd_init(fd, sioc, nbdflags, size); if (ret < 0) { goto out_fd; } /* update partition table */ pthread_create(&show_parts_thread, NULL, show_parts, device); if (verbose) { fprintf(stderr, "NBD device %s is now connected to %s\n", device, srcpath); } else { /* Close stderr so that the qemu-nbd process exits. */ dup2(STDOUT_FILENO, STDERR_FILENO); } ret = nbd_client(fd); if (ret) { goto out_fd; } close(fd); object_unref(OBJECT(sioc)); kill(getpid(), SIGTERM); return (void *) EXIT_SUCCESS; out_fd: close(fd); out_socket: object_unref(OBJECT(sioc)); out: kill(getpid(), SIGTERM); return (void *) EXIT_FAILURE; }