diff options
author | John Levon <john.levon@nutanix.com> | 2021-02-15 15:40:21 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-15 15:40:21 +0000 |
commit | 62b681a42879db18ee7c8b64e750b639a92f6f8d (patch) | |
tree | 0bd8a4943b81db8b2e82680c41a67f653b35ee6c | |
parent | a0e38496e33699da1b96a34a3d947ccb0718db7e (diff) | |
download | libvfio-user-62b681a42879db18ee7c8b64e750b639a92f6f8d.zip libvfio-user-62b681a42879db18ee7c8b64e750b639a92f6f8d.tar.gz libvfio-user-62b681a42879db18ee7c8b64e750b639a92f6f8d.tar.bz2 |
add vfu_get_poll_fd() (#322)
Library users can use this to sleep on either a newly-attached socket client, or
a new message.
Signed-off-by: John Levon <john.levon@nutanix.com>
Reviewed-by: Thanos Makatos <thanos.makatos@nutanix.com>
-rw-r--r-- | include/libvfio-user.h | 7 | ||||
-rw-r--r-- | lib/libvfio-user.c | 27 | ||||
-rw-r--r-- | lib/private.h | 3 | ||||
-rw-r--r-- | lib/tran_sock.c | 157 |
4 files changed, 113 insertions, 81 deletions
diff --git a/include/libvfio-user.h b/include/libvfio-user.h index 11666d0..68307cb 100644 --- a/include/libvfio-user.h +++ b/include/libvfio-user.h @@ -130,6 +130,13 @@ int vfu_attach_ctx(vfu_ctx_t *vfu_ctx); /** + * Return a file descriptor suitable for waiting on via epoll() or similar. This + * should not be cached, as it may change after a successful vfu_attach_ctx(). + */ +int +vfu_get_poll_fd(vfu_ctx_t *vfu_ctx); + +/** * Polls the vfu_ctx and processes the command recieved from client. * - Blocking vfu_ctx: * Blocks until new request is received from client and continues processing diff --git a/lib/libvfio-user.c b/lib/libvfio-user.c index 738d3b7..2dccd62 100644 --- a/lib/libvfio-user.c +++ b/lib/libvfio-user.c @@ -1111,15 +1111,6 @@ vfu_get_private(vfu_ctx_t *vfu_ctx) return vfu_ctx->pvt; } -int -vfu_attach_ctx(vfu_ctx_t *vfu_ctx) -{ - - assert(vfu_ctx != NULL); - - return vfu_ctx->tran->attach(vfu_ctx); -} - vfu_ctx_t * vfu_create_ctx(vfu_trans_t trans, const char *path, int flags, void *pvt, vfu_dev_type_t dev_type) @@ -1197,6 +1188,24 @@ err_out: } int +vfu_attach_ctx(vfu_ctx_t *vfu_ctx) +{ + + assert(vfu_ctx != NULL); + + return vfu_ctx->tran->attach(vfu_ctx); +} + +int +vfu_get_poll_fd(vfu_ctx_t *vfu_ctx) +{ + + assert(vfu_ctx != NULL); + + return vfu_ctx->tran->get_poll_fd(vfu_ctx); +} + +int vfu_setup_log(vfu_ctx_t *vfu_ctx, vfu_log_fn_t *log, int log_level) { diff --git a/lib/private.h b/lib/private.h index 5ea25be..787cae9 100644 --- a/lib/private.h +++ b/lib/private.h @@ -52,6 +52,9 @@ ERROR_PTR(int err) struct transport_ops { int (*init)(vfu_ctx_t *vfu_ctx); + + int (*get_poll_fd)(vfu_ctx_t *vfu_ctx); + int (*attach)(vfu_ctx_t *vfu_ctx); int (*get_request)(vfu_ctx_t *vfu_ctx, struct vfio_user_header *hdr, diff --git a/lib/tran_sock.c b/lib/tran_sock.c index 4aa4ee0..419588d 100644 --- a/lib/tran_sock.c +++ b/lib/tran_sock.c @@ -56,78 +56,6 @@ typedef struct { int conn_fd; } tran_sock_t; -static int -tran_sock_init(vfu_ctx_t *vfu_ctx) -{ - struct sockaddr_un addr = { .sun_family = AF_UNIX }; - tran_sock_t *ts = NULL; - mode_t mode; - int ret; - - assert(vfu_ctx != NULL); - - /* FIXME SPDK can't easily run as non-root */ - mode = umask(0000); - - ts = calloc(1, sizeof(tran_sock_t)); - - if (ts == NULL) { - ret = -errno; - goto out; - } - - ts->listen_fd = -1; - ts->conn_fd = -1; - - if ((ts->listen_fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { - ret = -errno; - goto out; - } - - if (vfu_ctx->flags & LIBVFIO_USER_FLAG_ATTACH_NB) { - ret = fcntl(ts->listen_fd, F_SETFL, - fcntl(ts->listen_fd, F_GETFL, 0) | O_NONBLOCK); - if (ret < 0) { - ret = -errno; - goto out; - } - } - - ret = snprintf(addr.sun_path, sizeof addr.sun_path, "%s", vfu_ctx->uuid); - if (ret >= (int)sizeof(addr.sun_path)) { - ret = -ENAMETOOLONG; - } - if (ret < 0) { - goto out; - } - - /* start listening business */ - ret = bind(ts->listen_fd, (struct sockaddr *)&addr, sizeof(addr)); - if (ret < 0) { - ret = -errno; - goto out; - } - - ret = listen(ts->listen_fd, 0); - if (ret < 0) { - ret = -errno; - } - -out: - umask(mode); - - if (ret != 0) { - if (ts->listen_fd != -1) { - close(ts->listen_fd); - } - free(ts); - return ret; - } - - vfu_ctx->tran_data = ts; - return 0; -} - int tran_sock_send_iovec(int sock, uint16_t msg_id, bool is_reply, enum vfio_user_command cmd, @@ -444,6 +372,90 @@ tran_sock_msg(int sock, uint16_t msg_id, enum vfio_user_command cmd, recv_data, recv_len, NULL, NULL); } +static int +tran_sock_init(vfu_ctx_t *vfu_ctx) +{ + struct sockaddr_un addr = { .sun_family = AF_UNIX }; + tran_sock_t *ts = NULL; + mode_t mode; + int ret; + + assert(vfu_ctx != NULL); + + /* FIXME SPDK can't easily run as non-root */ + mode = umask(0000); + + ts = calloc(1, sizeof(tran_sock_t)); + + if (ts == NULL) { + ret = -errno; + goto out; + } + + ts->listen_fd = -1; + ts->conn_fd = -1; + + if ((ts->listen_fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { + ret = -errno; + goto out; + } + + if (vfu_ctx->flags & LIBVFIO_USER_FLAG_ATTACH_NB) { + ret = fcntl(ts->listen_fd, F_SETFL, + fcntl(ts->listen_fd, F_GETFL, 0) | O_NONBLOCK); + if (ret < 0) { + ret = -errno; + goto out; + } + } + + ret = snprintf(addr.sun_path, sizeof addr.sun_path, "%s", vfu_ctx->uuid); + if (ret >= (int)sizeof(addr.sun_path)) { + ret = -ENAMETOOLONG; + } + if (ret < 0) { + goto out; + } + + /* start listening business */ + ret = bind(ts->listen_fd, (struct sockaddr *)&addr, sizeof(addr)); + if (ret < 0) { + ret = -errno; + goto out; + } + + ret = listen(ts->listen_fd, 0); + if (ret < 0) { + ret = -errno; + } + +out: + umask(mode); + + if (ret != 0) { + if (ts->listen_fd != -1) { + close(ts->listen_fd); + } + free(ts); + return ret; + } + + vfu_ctx->tran_data = ts; + return 0; +} + +int +tran_sock_get_poll_fd(vfu_ctx_t *vfu_ctx) +{ + tran_sock_t *ts = vfu_ctx->tran_data; + + if (ts->conn_fd != -1) { + return ts->conn_fd; + } + + return ts->listen_fd; +} + /* * Expected JSON is of the form: * @@ -857,6 +869,7 @@ tran_sock_fini(vfu_ctx_t *vfu_ctx) struct transport_ops tran_sock_ops = { .init = tran_sock_init, + .get_poll_fd = tran_sock_get_poll_fd, .attach = tran_sock_attach, .get_request = tran_sock_get_request, .recv_body = tran_sock_recv_body, |