From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39943) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W0pCn-0006yF-Uj for qemu-devel@nongnu.org; Wed, 08 Jan 2014 04:13:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1W0pCe-0008Aw-Pq for qemu-devel@nongnu.org; Wed, 08 Jan 2014 04:13:41 -0500 Received: from e28smtp06.in.ibm.com ([122.248.162.6]:46905) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W0pCa-00086y-Hw for qemu-devel@nongnu.org; Wed, 08 Jan 2014 04:13:32 -0500 Received: from /spool/local by e28smtp06.in.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 8 Jan 2014 14:43:15 +0530 Received: from d28relay02.in.ibm.com (d28relay02.in.ibm.com [9.184.220.59]) by d28dlp03.in.ibm.com (Postfix) with ESMTP id 1F0571258056 for ; Wed, 8 Jan 2014 14:44:42 +0530 (IST) Received: from d28av01.in.ibm.com (d28av01.in.ibm.com [9.184.220.63]) by d28relay02.in.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id s089D4xb48168996 for ; Wed, 8 Jan 2014 14:43:04 +0530 Received: from d28av01.in.ibm.com (localhost [127.0.0.1]) by d28av01.in.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id s089DAde015125 for ; Wed, 8 Jan 2014 14:43:10 +0530 From: Lei Li Date: Wed, 8 Jan 2014 17:12:51 +0800 Message-Id: <1389172376-30636-2-git-send-email-lilei@linux.vnet.ibm.com> In-Reply-To: <1389172376-30636-1-git-send-email-lilei@linux.vnet.ibm.com> References: <1389172376-30636-1-git-send-email-lilei@linux.vnet.ibm.com> Subject: [Qemu-devel] [PATCH 1/6] qemu-fd-exchange: provide common methods for exchange fd List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: pbonzini@redhat.com, mohan@in.ibm.com, Lei Li Signed-off-by: Lei Li --- include/qemu/fd-exchange.h | 25 +++++++++++ util/Makefile.objs | 1 + util/qemu-fd-exchange.c | 97 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 123 insertions(+), 0 deletions(-) create mode 100644 include/qemu/fd-exchange.h create mode 100644 util/qemu-fd-exchange.c diff --git a/include/qemu/fd-exchange.h b/include/qemu/fd-exchange.h new file mode 100644 index 0000000..6929026 --- /dev/null +++ b/include/qemu/fd-exchange.h @@ -0,0 +1,25 @@ +/* + * Internel common methods for exchange of FD + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + */ + +#ifndef FD_EXCHANGE_H +#define FD_EXCHANGE_H + +#include + +union MsgControl { + struct cmsghdr cmsg; + char control[CMSG_SPACE(sizeof(int))]; +}; + +ssize_t qemu_send_with_fd(int sockfd, int passed_fd, + const void *buf, size_t len); + +ssize_t qemu_recv_with_fd(int sockfd, int *passed_fd, + void *buf, size_t len); + +#endif diff --git a/util/Makefile.objs b/util/Makefile.objs index af3e5cb..2fb42bf 100644 --- a/util/Makefile.objs +++ b/util/Makefile.objs @@ -13,3 +13,4 @@ util-obj-y += hexdump.o util-obj-y += crc32c.o util-obj-y += throttle.o util-obj-y += getauxval.o +util-obj-y += qemu-fd-exchange.o diff --git a/util/qemu-fd-exchange.c b/util/qemu-fd-exchange.c new file mode 100644 index 0000000..70a3206 --- /dev/null +++ b/util/qemu-fd-exchange.c @@ -0,0 +1,97 @@ +/* + * Internel common methods for exchange of FD + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + */ + +#include "qemu/fd-exchange.h" +#include "qemu-common.h" + + +ssize_t qemu_send_with_fd(int sockfd, int passed_fd, + const void *buf, size_t len) +{ + struct msghdr msg; + struct iovec iov; + struct cmsghdr *cmsg; + union MsgControl msg_control; + int retval; + + iov.iov_base = (int *)buf; + iov.iov_len = len; + + memset(&msg, 0, sizeof(msg)); + msg.msg_iov = &iov; + msg.msg_iovlen = len; + msg.msg_control = &msg_control; + msg.msg_controllen = sizeof(msg_control); + + if (passed_fd < 0) { + *(int *)buf = passed_fd; + } else { + msg.msg_control = &msg_control; + msg.msg_controllen = sizeof(msg_control); + + cmsg = &msg_control.cmsg; + cmsg->cmsg_len = CMSG_LEN(sizeof(passed_fd)); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + memcpy(CMSG_DATA(cmsg), &passed_fd, sizeof(passed_fd)); + + } + + do { + retval = sendmsg(sockfd, &msg, 0); + } while (retval < 0 && errno == EINTR); + + return retval; +} + +ssize_t qemu_recv_with_fd(int sockfd, int *passed_fd, + void *buf, size_t len) +{ + struct iovec iov; + struct msghdr msg; + struct cmsghdr *cmsg; + union MsgControl msg_control; + int retval; + int data = *(int *)buf; + + iov.iov_base = buf; + iov.iov_len = len; + + memset(&msg, 0, sizeof(msg)); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = &msg_control; + msg.msg_controllen = sizeof(msg_control); + + do { + retval = recvmsg(sockfd, &msg, 0); + } while (retval < 0 && errno == EINTR); + + if (retval <= 0) { + return retval; + } + + if (data != *(int *)buf) { + *passed_fd = data; + return 0; + } + + for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { + if (cmsg->cmsg_len != CMSG_LEN(sizeof(int)) || + cmsg->cmsg_level != SOL_SOCKET || + cmsg->cmsg_type != SCM_RIGHTS) { + continue; + } + + memcpy(passed_fd, CMSG_DATA(cmsg), sizeof(*passed_fd)); + return 0; + } + + *passed_fd = -ENFILE; + return retval; +} -- 1.7.7.6