From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49405) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W40JJ-0003Rf-QI for qemu-devel@nongnu.org; Thu, 16 Jan 2014 22:41:42 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1W40JA-0004fA-S6 for qemu-devel@nongnu.org; Thu, 16 Jan 2014 22:41:33 -0500 Received: from e23smtp08.au.ibm.com ([202.81.31.141]:32983) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W40J2-0004dk-HE for qemu-devel@nongnu.org; Thu, 16 Jan 2014 22:41:24 -0500 Received: from /spool/local by e23smtp08.au.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 17 Jan 2014 13:41:08 +1000 Received: from d23relay04.au.ibm.com (d23relay04.au.ibm.com [9.190.234.120]) by d23dlp01.au.ibm.com (Postfix) with ESMTP id EB5A52CE802D for ; Fri, 17 Jan 2014 14:41:05 +1100 (EST) Received: from d23av04.au.ibm.com (d23av04.au.ibm.com [9.190.235.139]) by d23relay04.au.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id s0H3M9EN41418968 for ; Fri, 17 Jan 2014 14:22:09 +1100 Received: from d23av04.au.ibm.com (localhost [127.0.0.1]) by d23av04.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id s0H3f58d030026 for ; Fri, 17 Jan 2014 14:41:05 +1100 Message-ID: <52D8A64F.9040007@linux.vnet.ibm.com> Date: Fri, 17 Jan 2014 11:41:03 +0800 From: Lei Li MIME-Version: 1.0 References: <1389172376-30636-1-git-send-email-lilei@linux.vnet.ibm.com> <1389172376-30636-2-git-send-email-lilei@linux.vnet.ibm.com> <52D7FA1E.9040102@redhat.com> In-Reply-To: <52D7FA1E.9040102@redhat.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [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: Eric Blake Cc: pbonzini@redhat.com, mohan@in.ibm.com, qemu-devel@nongnu.org On 01/16/2014 11:26 PM, Eric Blake wrote: > On 01/08/2014 02:12 AM, Lei Li wrote: >> 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 > s/Internel/Internal/ > > >> +++ b/util/qemu-fd-exchange.c >> @@ -0,0 +1,97 @@ >> +/* >> + * Internel common methods for exchange of FD > and again. Good catch! Thanks. > >> +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; > Is it safe to assume that buf is aligned well enough to be casting it to > int* then dereferencing it? Why not just type the parameter correctly That's because there would be different type for this parameter. > to begin with? And why are you even writing into the caller's buffer > when they pass a negative fd, but leaving it alone when they pass a > non-negative fd? That's just the original logical of exchange fd for proxy fs driver, if (fd < 0) { data = fd; } else { data = V9FS_FD_VALID; .... } This common method don't leave it alone when a non-negative fd passed, it'll be the same as the check value passed from the caller. >> +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; > Again, why not type buf correctly, since otherwise you risk a user > passing in a buffer that is unsuitably aligned for dereferencing as an > int pointer. > >> + >> + 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); >> + > Should you take advantage of Linux' ability to use MSG_CMSG_CLOEXEC to > guarantee the received fd is atomically marked cloexec when possible? Whether close the fd in the common method depends on the process of these current users (they are not the same). It'd be better to let the users handling the close of fd to fit it. > >> + 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; >> + } > And even when MSG_CMSG_CLOEXEC is not available, shouldn't you ensure > that cloexec is set after the fact? That's a good suggestion, thanks. -- Lei