diff options
Diffstat (limited to 'lib/tran_sock.c')
-rw-r--r-- | lib/tran_sock.c | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/lib/tran_sock.c b/lib/tran_sock.c index 3f4c8c3..8a652c7 100644 --- a/lib/tran_sock.c +++ b/lib/tran_sock.c @@ -46,6 +46,7 @@ typedef struct { int listen_fd; int conn_fd; + int client_cmd_socket_fd; } tran_sock_t; int @@ -380,6 +381,7 @@ tran_sock_init(vfu_ctx_t *vfu_ctx) ts->listen_fd = -1; ts->conn_fd = -1; + ts->client_cmd_socket_fd = -1; if ((ts->listen_fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { ret = errno; @@ -464,7 +466,7 @@ tran_sock_attach(vfu_ctx_t *vfu_ctx) return -1; } - ret = tran_negotiate(vfu_ctx); + ret = tran_negotiate(vfu_ctx, &ts->client_cmd_socket_fd); if (ret < 0) { close_safely(&ts->conn_fd); return -1; @@ -607,6 +609,21 @@ tran_sock_reply(vfu_ctx_t *vfu_ctx, vfu_msg_t *msg, int err) return ret; } +static void maybe_print_cmd_collision_warning(vfu_ctx_t *vfu_ctx) { + static bool warning_printed = false; + static const char *warning_msg = + "You are using libvfio-user in a configuration that issues " + "client-to-server commands, but without the twin_socket feature " + "enabled. This is known to break when client and server send a command " + "at the same time. See " + "https://github.com/nutanix/libvfio-user/issues/279 for details."; + + if (!warning_printed) { + vfu_log(vfu_ctx, LOG_WARNING, "%s", warning_msg); + warning_printed = true; + } +} + static int tran_sock_send_msg(vfu_ctx_t *vfu_ctx, uint16_t msg_id, enum vfio_user_command cmd, @@ -615,14 +632,21 @@ tran_sock_send_msg(vfu_ctx_t *vfu_ctx, uint16_t msg_id, void *recv_data, size_t recv_len) { tran_sock_t *ts; + int fd; assert(vfu_ctx != NULL); assert(vfu_ctx->tran_data != NULL); ts = vfu_ctx->tran_data; - return tran_sock_msg(ts->conn_fd, msg_id, cmd, send_data, send_len, - hdr, recv_data, recv_len); + fd = ts->client_cmd_socket_fd; + if (fd == -1) { + maybe_print_cmd_collision_warning(vfu_ctx); + fd = ts->conn_fd; + } + + return tran_sock_msg(fd, msg_id, cmd, send_data, send_len, hdr, recv_data, + recv_len); } static void @@ -636,6 +660,7 @@ tran_sock_detach(vfu_ctx_t *vfu_ctx) if (ts != NULL) { close_safely(&ts->conn_fd); + close_safely(&ts->client_cmd_socket_fd); } } |