From: Ben Pfaff Date: Mon, 19 Nov 2012 23:55:54 +0000 (-0800) Subject: socket-util: Avoid using SO_ERROR. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d6cedfd9d29df4f9e9b7575c03ffcd2d84588c62;p=openvswitch socket-util: Avoid using SO_ERROR. ESX doesn't implement it, and there's another approach that should work everywhere, so drop back to that. Signed-off-by: Ben Pfaff Acked-by: Ethan Jackson --- diff --git a/lib/socket-util.c b/lib/socket-util.c index 4edf956b..4843cc54 100644 --- a/lib/socket-util.c +++ b/lib/socket-util.c @@ -221,6 +221,7 @@ get_socket_error(int fd) int check_connection_completion(int fd) { + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 10); struct pollfd pfd; int retval; @@ -230,9 +231,17 @@ check_connection_completion(int fd) retval = poll(&pfd, 1, 0); } while (retval < 0 && errno == EINTR); if (retval == 1) { - return get_socket_error(fd); + if (pfd.revents & POLLERR) { + ssize_t n = send(fd, "", 1, MSG_DONTWAIT); + if (n < 0) { + return errno; + } else { + VLOG_ERR_RL(&rl, "poll return POLLERR but send succeeded"); + return EPROTO; + } + } + return 0; } else if (retval < 0) { - static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 10); VLOG_ERR_RL(&rl, "poll: %s", strerror(errno)); return errno; } else { diff --git a/python/ovs/socket_util.py b/python/ovs/socket_util.py index f54b9040..e6b6fcef 100644 --- a/python/ovs/socket_util.py +++ b/python/ovs/socket_util.py @@ -78,8 +78,22 @@ def make_unix_socket(style, nonblock, bind_path, connect_path): def check_connection_completion(sock): p = ovs.poller.SelectPoll() p.register(sock, ovs.poller.POLLOUT) - if len(p.poll(0)) == 1: - return get_socket_error(sock) + pfds = p.poll(0) + if len(pfds) == 1: + revents = pfds[0][1] + if revents & ovs.poller.POLLERR: + try: + # The following should raise an exception. + socket.send("\0", socket.MSG_DONTWAIT) + + # (Here's where we end up if it didn't.) + # XXX rate-limit + vlog.err("poll return POLLERR but send succeeded") + return errno.EPROTO + except socket.error, e: + return get_exception_errno(e) + else: + return 0 else: return errno.EAGAIN