[ovs-dev] [so_error 2/3] socket-util: Avoid using SO_ERROR.
Ben Pfaff
blp at nicira.com
Mon Nov 19 23:57:46 UTC 2012
ESX doesn't implement it, and there's another approach that should work
everywhere, so drop back to that.
Signed-off-by: Ben Pfaff <blp at nicira.com>
---
lib/socket-util.c | 13 +++++++++++--
python/ovs/socket_util.py | 18 ++++++++++++++++--
2 files changed, 27 insertions(+), 4 deletions(-)
diff --git a/lib/socket-util.c b/lib/socket-util.c
index 4edf956..4843cc5 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 f54b904..e6b6fce 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
--
1.7.2.5
More information about the dev
mailing list