Thanks. I applied this to master.
On Thu, Jul 13, 2017 at 10:46:44AM +0800, Gao Zhenyu wrote: > LGTM. > > Thanks > Zhenyu Gao > > 2017-07-13 8:39 GMT+08:00 Ben Pfaff <[email protected]>: > > > This will have its first user in an upcoming commit. > > > > Signed-off-by: Ben Pfaff <[email protected]> > > --- > > v1->v2: Note that FreeBSD also has sendmmsg. Fix sendmsg() return type. > > > > configure.ac | 3 ++- > > include/sparse/sys/socket.h | 5 +++++ > > lib/socket-util.c | 38 ++++++++++++++++++++++++++++++++++++++ > > lib/socket-util.h | 27 +++++++++++++++++++++++++++ > > 4 files changed, 72 insertions(+), 1 deletion(-) > > > > diff --git a/configure.ac b/configure.ac > > index 6404b5fc1222..9ef6aad3a36e 100644 > > --- a/configure.ac > > +++ b/configure.ac > > @@ -106,7 +106,8 @@ AC_CHECK_DECLS([sys_siglist], [], [], [[#include > > <signal.h>]]) > > AC_CHECK_MEMBERS([struct stat.st_mtim.tv_nsec, struct stat.st_mtimensec], > > [], [], [[#include <sys/stat.h>]]) > > AC_CHECK_MEMBERS([struct ifreq.ifr_flagshigh], [], [], [[#include > > <net/if.h>]]) > > -AC_CHECK_FUNCS([mlockall strnlen getloadavg statvfs getmntent_r]) > > +AC_CHECK_MEMBERS([struct mmsghdr.msg_len], [], [], [[#include > > <sys/socket.h>]]) > > +AC_CHECK_FUNCS([mlockall strnlen getloadavg statvfs getmntent_r sendmmsg]) > > AC_CHECK_HEADERS([mntent.h sys/statvfs.h linux/types.h linux/if_ether.h > > stdatomic.h]) > > AC_CHECK_HEADERS([net/if_mib.h], [], [], [[#include <sys/types.h> > > #include <net/if.h>]]) > > diff --git a/include/sparse/sys/socket.h b/include/sparse/sys/socket.h > > index 3212bf4b7f13..88a5387e7f9b 100644 > > --- a/include/sparse/sys/socket.h > > +++ b/include/sparse/sys/socket.h > > @@ -75,6 +75,11 @@ __cmsg_nxthdr(struct msghdr *msg, struct cmsghdr *cmsg) > > : NULL); > > } > > > > +struct mmsghdr { > > + struct msghdr msg_hdr; > > + unsigned int msg_len; > > +}; > > + > > enum { > > SCM_RIGHTS = 1 > > }; > > diff --git a/lib/socket-util.c b/lib/socket-util.c > > index 2c0f1e62bd99..7148ae3da67c 100644 > > --- a/lib/socket-util.c > > +++ b/lib/socket-util.c > > @@ -1020,3 +1020,41 @@ sock_strerror(int error) > > return ovs_strerror(error); > > #endif > > } > > + > > +static int > > +emulate_sendmmsg(int fd, struct mmsghdr *msgs, unsigned int n, > > + unsigned int flags) > > +{ > > + for (unsigned int i = 0; i < n; i++) { > > + ssize_t retval = sendmsg(fd, &msgs[i].msg_hdr, flags); > > + if (retval < 0) { > > + return i ? i : retval; > > + } > > + msgs[i].msg_len = retval; > > + } > > + return n; > > +} > > + > > +#ifndef HAVE_SENDMMSG > > +int > > +sendmmsg(int fd, struct mmsghdr *msgs, unsigned int n, unsigned int flags) > > +{ > > + return emulate_sendmmsg(fd, msgs, n, flags); > > +} > > +#else > > +int > > +wrap_sendmmsg(int fd, struct mmsghdr *msgs, unsigned int n, unsigned int > > flags) > > +{ > > + static bool sendmmsg_broken = false; > > + if (!sendmmsg_broken) { > > + int save_errno = errno; > > + int retval = sendmmsg(fd, msgs, n, flags); > > + if (retval >= 0 || errno != ENOSYS) { > > + return retval; > > + } > > + sendmmsg_broken = true; > > + errno = save_errno; > > + } > > + return emulate_sendmmsg(fd, msgs, n, flags); > > +} > > +#endif > > diff --git a/lib/socket-util.h b/lib/socket-util.h > > index 5bf76a40eb84..ef316cb8cc72 100644 > > --- a/lib/socket-util.h > > +++ b/lib/socket-util.h > > @@ -87,6 +87,33 @@ int make_unix_socket(int style, bool nonblock, > > const char *bind_path, const char *connect_path); > > int get_unix_name_len(const struct sockaddr_un *sun, socklen_t sun_len); > > > > +/* Universal sendmmsg support. > > + * > > + * Some platforms, such as new enough Linux and FreeBSD, support > > sendmmsg, but > > + * other platforms (or older ones) do not. We add the following > > infrastructure > > + * to allow all code to use sendmmsg, regardless of platform support: > > + * > > + * - For platforms that lack sendmmsg entirely, we emulate it. > > + * > > + * - Some platforms have sendmmsg() in the C library but not in the > > kernel. > > + * For example, this is true if a Linux system has a newer glibc with > > an > > + * old kernel. To compensate, even if sendmmsg() appears to be > > available, > > + * we still wrap it with a handler that uses our emulation if > > sendmmsg() > > + * returns ENOSYS. > > + */ > > +#ifndef HAVE_STRUCT_MMSGHDR_MSG_LEN > > +struct mmsghdr { > > + struct msghdr msg_hdr; > > + unsigned int msg_len; > > +}; > > +#endif > > +#ifndef HAVE_SENDMMSG > > +int sendmmsg(int, struct mmsghdr *, unsigned int, unsigned int); > > +#else > > +#define sendmmsg wrap_sendmmsg > > +int wrap_sendmmsg(int, struct mmsghdr *, unsigned int, unsigned int); > > +#endif > > + > > /* Helpers for calling ioctl() on an AF_INET socket. */ > > struct ifreq; > > int af_inet_ioctl(unsigned long int command, const void *arg); > > -- > > 2.10.2 > > > > _______________________________________________ > > dev mailing list > > [email protected] > > https://mail.openvswitch.org/mailman/listinfo/ovs-dev > > _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
