static int qio_channel_command_set_blocking(QIOChannel *ioc, bool enabled, Error **errp) { QIOChannelCommand *cioc = QIO_CHANNEL_COMMAND(ioc); if (enabled) { qemu_set_block(cioc->writefd); qemu_set_block(cioc->readfd); } else { qemu_set_nonblock(cioc->writefd); qemu_set_nonblock(cioc->readfd); } return 0; }
static void nbd_teardown_connection(NbdClientSession *client) { struct nbd_request request = { .type = NBD_CMD_DISC, .from = 0, .len = 0 }; nbd_send_request(client->sock, &request); /* finish any pending coroutines */ shutdown(client->sock, 2); nbd_recv_coroutines_enter_all(client); qemu_aio_set_fd_handler(client->sock, NULL, NULL, NULL); closesocket(client->sock); client->sock = -1; } void nbd_client_session_close(NbdClientSession *client) { if (!client->bs) { return; } nbd_teardown_connection(client); client->bs = NULL; } int nbd_client_session_init(NbdClientSession *client, BlockDriverState *bs, int sock, const char *export) { int ret; /* NBD handshake */ logout("session init %s\n", export); qemu_set_block(sock); ret = nbd_receive_negotiate(sock, export, &client->nbdflags, &client->size, &client->blocksize); if (ret < 0) { logout("Failed to negotiate with the NBD server\n"); closesocket(sock); return ret; } qemu_co_mutex_init(&client->send_mutex); qemu_co_mutex_init(&client->free_sema); client->bs = bs; client->sock = sock; /* Now that we're connected, set the socket to be non-blocking and * kick the reply mechanism. */ qemu_set_nonblock(sock); qemu_aio_set_fd_handler(sock, nbd_reply_ready, NULL, client); logout("Established connection with NBD server\n"); return 0; }
static ssize_t tcp_chr_recv(Chardev *chr, char *buf, size_t len) { SocketChardev *s = SOCKET_CHARDEV(chr); struct iovec iov = { .iov_base = buf, .iov_len = len }; int ret; size_t i; int *msgfds = NULL; size_t msgfds_num = 0; if (qio_channel_has_feature(s->ioc, QIO_CHANNEL_FEATURE_FD_PASS)) { ret = qio_channel_readv_full(s->ioc, &iov, 1, &msgfds, &msgfds_num, NULL); } else { ret = qio_channel_readv_full(s->ioc, &iov, 1, NULL, NULL, NULL); } if (ret == QIO_CHANNEL_ERR_BLOCK) { errno = EAGAIN; ret = -1; } else if (ret == -1) { errno = EIO; } if (msgfds_num) { /* close and clean read_msgfds */ for (i = 0; i < s->read_msgfds_num; i++) { close(s->read_msgfds[i]); } if (s->read_msgfds_num) { g_free(s->read_msgfds); } s->read_msgfds = msgfds; s->read_msgfds_num = msgfds_num; } for (i = 0; i < s->read_msgfds_num; i++) { int fd = s->read_msgfds[i]; if (fd < 0) { continue; } /* O_NONBLOCK is preserved across SCM_RIGHTS so reset it */ qemu_set_block(fd); #ifndef MSG_CMSG_CLOEXEC qemu_set_cloexec(fd); #endif } return ret; }
static int qio_channel_file_set_blocking(QIOChannel *ioc, bool enabled, Error **errp) { QIOChannelFile *fioc = QIO_CHANNEL_FILE(ioc); if (enabled) { qemu_set_block(fioc->fd); } else { qemu_set_nonblock(fioc->fd); } return 0; }
static int qio_channel_socket_set_blocking(QIOChannel *ioc, bool enabled, Error **errp) { QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc); if (enabled) { qemu_set_block(sioc->fd); } else { qemu_set_nonblock(sioc->fd); } return 0; }
static void unix_wait_for_connect(int fd, void *opaque) { MigrationState *s = opaque; if (fd < 0) { DPRINTF("migrate connect error\n"); s->fd = -1; migrate_fd_error(s); } else { DPRINTF("migrate connect success\n"); s->fd = fd; qemu_set_block(s->fd); migrate_fd_connect(s); } }
void nbd_client_close(BlockDriverState *bs) { NbdClientSession *client = nbd_get_client_session(bs); struct nbd_request request = { .type = NBD_CMD_DISC, .from = 0, .len = 0 }; if (client->sock == -1) { return; } nbd_send_request(client->sock, &request); nbd_teardown_connection(bs); } int nbd_client_init(BlockDriverState *bs, int sock, const char *export, Error **errp) { NbdClientSession *client = nbd_get_client_session(bs); int ret; /* NBD handshake */ logout("session init %s\n", export); qemu_set_block(sock); ret = nbd_receive_negotiate(sock, export, &client->nbdflags, &client->size, &client->blocksize, errp); if (ret < 0) { logout("Failed to negotiate with the NBD server\n"); closesocket(sock); return ret; } qemu_co_mutex_init(&client->send_mutex); qemu_co_mutex_init(&client->free_sema); client->sock = sock; /* Now that we're connected, set the socket to be non-blocking and * kick the reply mechanism. */ qemu_set_nonblock(sock); nbd_client_attach_aio_context(bs, bdrv_get_aio_context(bs)); logout("Established connection with NBD server\n"); return 0; }
QEMUFile *qemu_fopen_socket(int fd, const char *mode) { QEMUFileSocket *s; if (qemu_file_mode_is_not_valid(mode)) { return NULL; } s = g_malloc0(sizeof(QEMUFileSocket)); s->fd = fd; if (mode[0] == 'w') { qemu_set_block(s->fd); s->file = qemu_fopen_ops(s, &socket_write_ops); } else { s->file = qemu_fopen_ops(s, &socket_read_ops); } return s->file; }
static void qio_channel_socket_copy_fds(struct msghdr *msg, int **fds, size_t *nfds) { struct cmsghdr *cmsg; *nfds = 0; *fds = NULL; for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) { int fd_size, i; int gotfds; if (cmsg->cmsg_len < CMSG_LEN(sizeof(int)) || cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) { continue; } fd_size = cmsg->cmsg_len - CMSG_LEN(0); if (!fd_size) { continue; } gotfds = fd_size / sizeof(int); *fds = g_renew(int, *fds, *nfds + gotfds); memcpy(*fds + *nfds, CMSG_DATA(cmsg), fd_size); for (i = 0; i < gotfds; i++) { int fd = (*fds)[*nfds + i]; if (fd < 0) { continue; } /* O_NONBLOCK is preserved across SCM_RIGHTS so reset it */ qemu_set_block(fd); #ifndef MSG_CMSG_CLOEXEC qemu_set_cloexec(fd); #endif } *nfds += gotfds; } }
static int qio_channel_socket_set_blocking(QIOChannel *ioc, bool enabled, Error **errp) { QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc); if (enabled) { qemu_set_block(sioc->fd); } else { qemu_set_nonblock(sioc->fd); #ifdef WIN32 WSAEventSelect(sioc->fd, ioc->event, FD_READ | FD_ACCEPT | FD_CLOSE | FD_CONNECT | FD_WRITE | FD_OOB); #endif } return 0; }