diff options
-rw-r--r-- | lib/libvfio-user.c | 17 | ||||
-rw-r--r-- | lib/private.h | 4 | ||||
-rw-r--r-- | lib/tran_sock.c | 13 | ||||
-rw-r--r-- | test/unit-tests.c | 3 |
4 files changed, 26 insertions, 11 deletions
diff --git a/lib/libvfio-user.c b/lib/libvfio-user.c index e25787d..3192fd8 100644 --- a/lib/libvfio-user.c +++ b/lib/libvfio-user.c @@ -928,20 +928,17 @@ process_request(vfu_ctx_t *vfu_ctx) ret = 0; } - if (!(hdr.flags.no_reply)) { - // FIXME: SPEC: should the reply include the command? I'd say yes? - ret = tran_sock_send_iovec(vfu_ctx->conn_fd, hdr.msg_id, true, 0, - iovecs, nr_iovecs, fds_out, nr_fds_out, - -ret); - if (unlikely(ret < 0)) { - vfu_log(vfu_ctx, LOG_ERR, "failed to complete command: %s", - strerror(-ret)); - } - } else { + if (hdr.flags.no_reply) { /* * A failed client request is not a failure of process_request() itself. */ ret = 0; + } else { + ret = vfu_ctx->trans->reply(vfu_ctx, hdr.msg_id, iovecs, nr_iovecs, + fds_out, nr_fds_out, -ret); + if (unlikely(ret < 0)) { + vfu_log(vfu_ctx, LOG_ERR, "failed to reply: %s", strerror(-ret)); + } } if (iovecs != NULL) { diff --git a/lib/private.h b/lib/private.h index d1176ff..829bc3a 100644 --- a/lib/private.h +++ b/lib/private.h @@ -57,6 +57,10 @@ struct transport_ops { int (*get_request)(vfu_ctx_t *vfu_ctx, struct vfio_user_header *hdr, int *fds, size_t *nr_fds); + int (*reply)(vfu_ctx_t *vfu_ctx, uint16_t msg_id, + struct iovec *iovecs, size_t nr_iovecs, + int *fds, int count, int err); + int (*send_msg)(vfu_ctx_t *vfu_ctx, uint16_t msg_id, enum vfio_user_command cmd, void *send_data, size_t send_len, diff --git a/lib/tran_sock.c b/lib/tran_sock.c index f8838de..311f480 100644 --- a/lib/tran_sock.c +++ b/lib/tran_sock.c @@ -174,6 +174,8 @@ tran_sock_send_iovec(int sock, uint16_t msg_id, bool is_reply, return 0; } +UNIT_TEST_SYMBOL(tran_sock_send_iovec); +#define tran_sock_send_iovec __wrap_tran_sock_send_iovec int tran_sock_send(int sock, uint16_t msg_id, bool is_reply, @@ -711,6 +713,16 @@ tran_sock_get_request(vfu_ctx_t *vfu_ctx, struct vfio_user_header *hdr, } static int +tran_sock_reply(vfu_ctx_t *vfu_ctx, uint16_t msg_id, + struct iovec *iovecs, size_t nr_iovecs, + int *fds, int count, int err) +{ + // FIXME: SPEC: should the reply include the command? I'd say yes? + return tran_sock_send_iovec(vfu_ctx->conn_fd, msg_id, true, 0, + iovecs, nr_iovecs, fds, count, err); +} + +static int tran_sock_send_msg(vfu_ctx_t *vfu_ctx, uint16_t msg_id, enum vfio_user_command cmd, void *send_data, size_t send_len, @@ -743,6 +755,7 @@ struct transport_ops tran_sock_ops = { .init = tran_sock_init, .attach = tran_sock_attach, .get_request = tran_sock_get_request, + .reply = tran_sock_reply, .send_msg = tran_sock_send_msg, .detach = tran_sock_detach, .fini = tran_sock_fini diff --git a/test/unit-tests.c b/test/unit-tests.c index 8638c10..7ec1469 100644 --- a/test/unit-tests.c +++ b/test/unit-tests.c @@ -347,7 +347,8 @@ test_process_command_free_passed_fds(void **state __attribute__((unused))) vfu_ctx_t vfu_ctx = { .conn_fd = 0xcafebabe, .client_max_fds = ARRAY_SIZE(fds), - .migration = (struct migration*)0x8badf00d + .migration = (struct migration*)0x8badf00d, + .trans = &tran_sock_ops, }; patch(device_is_stopped); |