mirror of https://github.com/xemu-project/xemu.git
vhost-user: support receiving file descriptors in slave_read
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
703878e2e0
commit
1f3a4519b1
|
@ -852,14 +852,44 @@ static void slave_read(void *opaque)
|
||||||
VhostUserHeader hdr = { 0, };
|
VhostUserHeader hdr = { 0, };
|
||||||
VhostUserPayload payload = { 0, };
|
VhostUserPayload payload = { 0, };
|
||||||
int size, ret = 0;
|
int size, ret = 0;
|
||||||
|
struct iovec iov;
|
||||||
|
struct msghdr msgh;
|
||||||
|
int fd = -1;
|
||||||
|
char control[CMSG_SPACE(sizeof(fd))];
|
||||||
|
struct cmsghdr *cmsg;
|
||||||
|
size_t fdsize;
|
||||||
|
|
||||||
|
memset(&msgh, 0, sizeof(msgh));
|
||||||
|
msgh.msg_iov = &iov;
|
||||||
|
msgh.msg_iovlen = 1;
|
||||||
|
msgh.msg_control = control;
|
||||||
|
msgh.msg_controllen = sizeof(control);
|
||||||
|
|
||||||
/* Read header */
|
/* Read header */
|
||||||
size = read(u->slave_fd, &hdr, VHOST_USER_HDR_SIZE);
|
iov.iov_base = &hdr;
|
||||||
|
iov.iov_len = VHOST_USER_HDR_SIZE;
|
||||||
|
|
||||||
|
size = recvmsg(u->slave_fd, &msgh, 0);
|
||||||
if (size != VHOST_USER_HDR_SIZE) {
|
if (size != VHOST_USER_HDR_SIZE) {
|
||||||
error_report("Failed to read from slave.");
|
error_report("Failed to read from slave.");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (msgh.msg_flags & MSG_CTRUNC) {
|
||||||
|
error_report("Truncated message.");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg != NULL;
|
||||||
|
cmsg = CMSG_NXTHDR(&msgh, cmsg)) {
|
||||||
|
if (cmsg->cmsg_level == SOL_SOCKET &&
|
||||||
|
cmsg->cmsg_type == SCM_RIGHTS) {
|
||||||
|
fdsize = cmsg->cmsg_len - CMSG_LEN(0);
|
||||||
|
memcpy(&fd, CMSG_DATA(cmsg), fdsize);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (hdr.size > VHOST_USER_PAYLOAD_SIZE) {
|
if (hdr.size > VHOST_USER_PAYLOAD_SIZE) {
|
||||||
error_report("Failed to read msg header."
|
error_report("Failed to read msg header."
|
||||||
" Size %d exceeds the maximum %zu.", hdr.size,
|
" Size %d exceeds the maximum %zu.", hdr.size,
|
||||||
|
@ -883,9 +913,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. */
|
||||||
|
fd = -1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* REPLY_ACK feature handling. Other reply types has to be managed
|
* REPLY_ACK feature handling. Other reply types has to be managed
|
||||||
* directly in their request handlers.
|
* directly in their request handlers.
|
||||||
|
@ -918,6 +954,9 @@ 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) {
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue