aboutsummaryrefslogtreecommitdiff
path: root/lib/tran_sock.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/tran_sock.c')
-rw-r--r--lib/tran_sock.c31
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);
}
}