vhost-user: allow slave to send fds via slave channel
Introduce VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD protocol feature to allow slave to send at most 8 descriptors in each message to master via ancillary data using the slave channel. Suggested-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Tiwei Bie <tiwei.bie@intel.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
988a27754b
commit
5f57fbeaaf
@ -367,6 +367,10 @@ The fd is provided via VHOST_USER_SET_SLAVE_REQ_FD ancillary data.
|
|||||||
A slave may then send VHOST_USER_SLAVE_* messages to the master
|
A slave may then send VHOST_USER_SLAVE_* messages to the master
|
||||||
using this fd communication channel.
|
using this fd communication channel.
|
||||||
|
|
||||||
|
If VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD protocol feature is negotiated,
|
||||||
|
slave can send file descriptors (at most 8 descriptors in each message)
|
||||||
|
to master via ancillary data using this fd communication channel.
|
||||||
|
|
||||||
Protocol features
|
Protocol features
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
@ -380,6 +384,7 @@ Protocol features
|
|||||||
#define VHOST_USER_PROTOCOL_F_CRYPTO_SESSION 7
|
#define VHOST_USER_PROTOCOL_F_CRYPTO_SESSION 7
|
||||||
#define VHOST_USER_PROTOCOL_F_PAGEFAULT 8
|
#define VHOST_USER_PROTOCOL_F_PAGEFAULT 8
|
||||||
#define VHOST_USER_PROTOCOL_F_CONFIG 9
|
#define VHOST_USER_PROTOCOL_F_CONFIG 9
|
||||||
|
#define VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD 10
|
||||||
|
|
||||||
Master message types
|
Master message types
|
||||||
--------------------
|
--------------------
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#define VHOST_MEMORY_MAX_NREGIONS 8
|
#define VHOST_MEMORY_MAX_NREGIONS 8
|
||||||
#define VHOST_USER_F_PROTOCOL_FEATURES 30
|
#define VHOST_USER_F_PROTOCOL_FEATURES 30
|
||||||
|
#define VHOST_USER_SLAVE_MAX_FDS 8
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Maximum size of virtio device config space
|
* Maximum size of virtio device config space
|
||||||
@ -47,6 +48,7 @@ enum VhostUserProtocolFeature {
|
|||||||
VHOST_USER_PROTOCOL_F_CRYPTO_SESSION = 7,
|
VHOST_USER_PROTOCOL_F_CRYPTO_SESSION = 7,
|
||||||
VHOST_USER_PROTOCOL_F_PAGEFAULT = 8,
|
VHOST_USER_PROTOCOL_F_PAGEFAULT = 8,
|
||||||
VHOST_USER_PROTOCOL_F_CONFIG = 9,
|
VHOST_USER_PROTOCOL_F_CONFIG = 9,
|
||||||
|
VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD = 10,
|
||||||
VHOST_USER_PROTOCOL_F_MAX
|
VHOST_USER_PROTOCOL_F_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -854,10 +856,10 @@ static void slave_read(void *opaque)
|
|||||||
int size, ret = 0;
|
int size, ret = 0;
|
||||||
struct iovec iov;
|
struct iovec iov;
|
||||||
struct msghdr msgh;
|
struct msghdr msgh;
|
||||||
int fd = -1;
|
int fd[VHOST_USER_SLAVE_MAX_FDS];
|
||||||
char control[CMSG_SPACE(sizeof(fd))];
|
char control[CMSG_SPACE(sizeof(fd))];
|
||||||
struct cmsghdr *cmsg;
|
struct cmsghdr *cmsg;
|
||||||
size_t fdsize;
|
int i, fdsize = 0;
|
||||||
|
|
||||||
memset(&msgh, 0, sizeof(msgh));
|
memset(&msgh, 0, sizeof(msgh));
|
||||||
msgh.msg_iov = &iov;
|
msgh.msg_iov = &iov;
|
||||||
@ -865,6 +867,8 @@ static void slave_read(void *opaque)
|
|||||||
msgh.msg_control = control;
|
msgh.msg_control = control;
|
||||||
msgh.msg_controllen = sizeof(control);
|
msgh.msg_controllen = sizeof(control);
|
||||||
|
|
||||||
|
memset(fd, -1, sizeof(fd));
|
||||||
|
|
||||||
/* Read header */
|
/* Read header */
|
||||||
iov.iov_base = &hdr;
|
iov.iov_base = &hdr;
|
||||||
iov.iov_len = VHOST_USER_HDR_SIZE;
|
iov.iov_len = VHOST_USER_HDR_SIZE;
|
||||||
@ -885,7 +889,7 @@ static void slave_read(void *opaque)
|
|||||||
if (cmsg->cmsg_level == SOL_SOCKET &&
|
if (cmsg->cmsg_level == SOL_SOCKET &&
|
||||||
cmsg->cmsg_type == SCM_RIGHTS) {
|
cmsg->cmsg_type == SCM_RIGHTS) {
|
||||||
fdsize = cmsg->cmsg_len - CMSG_LEN(0);
|
fdsize = cmsg->cmsg_len - CMSG_LEN(0);
|
||||||
memcpy(&fd, CMSG_DATA(cmsg), fdsize);
|
memcpy(fd, CMSG_DATA(cmsg), fdsize);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -913,14 +917,15 @@ static void slave_read(void *opaque)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
error_report("Received unexpected msg type.");
|
error_report("Received unexpected msg type.");
|
||||||
if (fd != -1) {
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Message handlers need to make sure that fd will be consumed. */
|
/* Close the remaining file descriptors. */
|
||||||
fd = -1;
|
for (i = 0; i < fdsize; i++) {
|
||||||
|
if (fd[i] != -1) {
|
||||||
|
close(fd[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* REPLY_ACK feature handling. Other reply types has to be managed
|
* REPLY_ACK feature handling. Other reply types has to be managed
|
||||||
@ -954,8 +959,10 @@ err:
|
|||||||
qemu_set_fd_handler(u->slave_fd, NULL, NULL, NULL);
|
qemu_set_fd_handler(u->slave_fd, NULL, NULL, NULL);
|
||||||
close(u->slave_fd);
|
close(u->slave_fd);
|
||||||
u->slave_fd = -1;
|
u->slave_fd = -1;
|
||||||
if (fd != -1) {
|
for (i = 0; i < fdsize; i++) {
|
||||||
close(fd);
|
if (fd[i] != -1) {
|
||||||
|
close(fd[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user