static int ctl_close(struct tdlog_state* s) { while (s->connected) { s->connected--; tapdisk_server_unregister_event(s->connections[s->connected].id); close(s->connections[s->connected].fd); s->connections[s->connected].fd = -1; s->connections[s->connected].id = 0; } if (s->ctl.fd >= 0) { tapdisk_server_unregister_event(s->ctl.id); close(s->ctl.fd); s->ctl.fd = -1; s->ctl.id = 0; } if (s->ctlpath) { unlink(s->ctlpath); free(s->ctlpath); s->ctlpath = NULL; } /* XXX this must be fixed once requests are actually in flight */ /* could just drain the existing ring here first */ if (s->sring) { SHARED_RING_INIT(s->sring); BACK_RING_INIT(&s->bring, s->sring, SRINGSIZE); } return 0; }
/** * TODO releases a pool? */ static void tapdisk_xenio_ctx_close(struct td_xenio_ctx * const ctx) { if (!ctx) return; if (ctx->ring_event >= 0) { tapdisk_server_unregister_event(ctx->ring_event); ctx->ring_event = -1; } if (ctx->xce_handle) { xc_evtchn_close(ctx->xce_handle); ctx->xce_handle = NULL; } if (ctx->xcg_handle) { xc_gnttab_close(ctx->xcg_handle); ctx->xcg_handle = NULL; } if (ctx->gntdev_fd != -1) { close(ctx->gntdev_fd); ctx->gntdev_fd = -1; } list_del(&ctx->entry); free(ctx); }
static void tapdisk_nbdserver_disable_client(td_nbdserver_client_t *client) { ASSERT(client); ASSERT(client->client_event_id >= 0); INFO("Disable client"); tapdisk_server_unregister_event(client->client_event_id); client->client_event_id = -1; }
void td_fdreceiver_stop(struct td_fdreceiver *fdreceiver) { if (fdreceiver->client_fd >= 0) close(fdreceiver->client_fd); if (fdreceiver->client_event_id >= 0) tapdisk_server_unregister_event(fdreceiver->client_event_id); if (fdreceiver->fd >= 0) close(fdreceiver->fd); if (fdreceiver->fd_event_id >= 0) tapdisk_server_unregister_event(fdreceiver->fd_event_id); if (fdreceiver->path != NULL) { unlink(fdreceiver->path); free(fdreceiver->path); } free(fdreceiver); }
static void tapdisk_nbdserver_disable_client(td_nbdserver_client_t *client) { INFO("Disable client"); if (client->client_event_id < 0) { ERROR("Attempting to disable an already-disabled client"); return; } tapdisk_server_unregister_event(client->client_event_id); client->client_event_id = -1; }
int tapdisk_xenblkif_destroy(struct td_xenblkif * blkif) { int err; ASSERT(blkif); if (tapdisk_xenblkif_chkrng_event_id(blkif) >= 0) { tapdisk_server_unregister_event( tapdisk_xenblkif_chkrng_event_id(blkif)); blkif->chkrng_event = -1; } tapdisk_xenblkif_reqs_free(blkif); if (blkif->ctx) { if (blkif->port >= 0) xc_evtchn_unbind(blkif->ctx->xce_handle, blkif->port); if (blkif->rings.common.sring) { err = xc_gnttab_munmap(blkif->ctx->xcg_handle, blkif->rings.common.sring, blkif->ring_n_pages); if (unlikely(err)) { err = errno; EPRINTF("failed to unmap ring page %p (%d pages): %s " "(error ignored)\n", blkif->rings.common.sring, blkif->ring_n_pages, strerror(err)); err = 0; } } list_del(&blkif->entry_ctx); list_del(&blkif->entry); tapdisk_xenio_ctx_put(blkif->ctx); } err = td_metrics_vbd_stop(&blkif->vbd_stats); if (unlikely(err)) EPRINTF("failed to destroy blkfront stats file: %s\n", strerror(-err)); err = tapdisk_xenblkif_stats_destroy(blkif); if (unlikely(err)) { EPRINTF("failed to clean up ring stats file: %s (error ignored)\n", strerror(-err)); err = 0; } free(blkif); return err; }
static void tapdisk_ctl_conn_close(struct tapdisk_ctl_conn *conn) { if (conn->out.event_id >= 0) { tapdisk_server_unregister_event(conn->out.event_id); conn->out.event_id = -1; } if (conn->fd >= 0) { close(conn->fd); conn->fd = -1; tapdisk_ctl_conn_free(conn); tapdisk_server_mask_event(td_control.event_id, 0); } }
/* walk list of open sockets, close matching fd */ static int ctl_close_sock(struct tdlog_state* s, int fd) { int i; for (i = 0; i < s->connected; i++) { if (s->connections[i].fd == fd) { tapdisk_server_unregister_event(s->connections[i].id); close(s->connections[i].fd); s->connections[i].fd = -1; s->connections[i].id = 0; s->connected--; return 0; } } BWPRINTF("requested to close unknown socket %d", fd); return -1; }
static void tapdisk_lio_destroy(struct tqueue *queue) { struct lio *lio = queue->tio_data; if (!lio) return; if (lio->event_id >= 0) { tapdisk_server_unregister_event(lio->event_id); lio->event_id = -1; } tapdisk_lio_destroy_aio(queue); if (lio->aio_events) { free(lio->aio_events); lio->aio_events = NULL; } }
static void td_fdreceiver_recv_fd(event_id_t id, char mode, void *data) { struct td_fdreceiver *fdreceiver = data; int ret, cv_flags = 0, *fdp, fd = -1; long numbytes; char iobuf[UNIX_BUFFER_SIZE]; char buf[CMSG_SPACE(sizeof(fd))]; struct sockaddr_un unix_socket_name; struct msghdr msg; struct iovec vec; struct cmsghdr *cmsg; numbytes = UNIX_BUFFER_SIZE; bzero(iobuf, numbytes); msg.msg_name = &unix_socket_name; msg.msg_namelen = sizeof(unix_socket_name); vec.iov_base = iobuf; vec.iov_len = numbytes; msg.msg_iov = &vec; msg.msg_iovlen = 1; msg.msg_control = buf; msg.msg_controllen = sizeof(buf); ret = recvmsg(fdreceiver->client_fd, &msg, cv_flags); if (ret == -1) { ERROR("Failed to receive the message: %d", ret); return; } if (ret > 0 && msg.msg_controllen > 0) { cmsg = CMSG_FIRSTHDR(&msg); if (cmsg->cmsg_level == SOL_SOCKET && (cmsg->cmsg_type == SCM_RIGHTS)) { fdp = (int*)CMSG_DATA(cmsg); fd = *fdp; } else { ERROR("Failed to recieve a file descriptor"); } } else { fd = -1; } if (ret < numbytes) numbytes = ret; INFO("Received fd %d with message: %s", fd, iobuf); /* * We're done with this connection, it was only transiently used to * connect the client */ close(fdreceiver->client_fd); fdreceiver->client_fd = -1; tapdisk_server_unregister_event(fdreceiver->client_event_id); fdreceiver->client_event_id = -1; /* * It is the responsibility of this callback function to arrange that * the fd is eventually closed */ fdreceiver->callback(fd, iobuf, fdreceiver->callback_data); }