X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=python%2Fovs%2Fsocket_util.py;h=7dac5bb377932b61a610d57772c5756d5a0d31c1;hb=a6e73618f53138eb6f55e2c66ff8c649794fd8dd;hp=dd45fe4b92520561442d990ffdbe55f3ec2d5623;hpb=7c690f462fec1af60d76c67fac226fc648ea9149;p=sliver-openvswitch.git diff --git a/python/ovs/socket_util.py b/python/ovs/socket_util.py index dd45fe4b9..7dac5bb37 100644 --- a/python/ovs/socket_util.py +++ b/python/ovs/socket_util.py @@ -70,16 +70,65 @@ def make_unix_socket(style, nonblock, bind_path, connect_path): return 0, sock except socket.error, e: sock.close() - if bind_path is not None: + if (bind_path is not None and + os.path.exists(bind_path)): ovs.fatal_signal.unlink_file_now(bind_path) - return get_exception_errno(e), None + eno = ovs.socket_util.get_exception_errno(e) + if (eno == "AF_UNIX path too long" and + os.uname()[0] == "Linux"): + short_connect_path = None + short_bind_path = None + connect_dirfd = None + bind_dirfd = None + # Try workaround using /proc/self/fd + if connect_path is not None: + dirname = os.path.dirname(connect_path) + basename = os.path.basename(connect_path) + try: + connect_dirfd = os.open(dirname, os.O_DIRECTORY | os.O_RDONLY) + except OSError, err: + return get_exception_errno(err), None + short_connect_path = "/proc/self/fd/%d/%s" % (connect_dirfd, basename) + + if bind_path is not None: + dirname = os.path.dirname(bind_path) + basename = os.path.basename(bind_path) + try: + bind_dirfd = os.open(dirname, os.O_DIRECTORY | os.O_RDONLY) + except OSError, err: + return get_exception_errno(err), None + short_bind_path = "/proc/self/fd/%d/%s" % (bind_dirfd, basename) + + try: + return make_unix_socket(style, nonblock, short_bind_path, short_connect_path) + finally: + if connect_dirfd is not None: + os.close(connect_dirfd) + if bind_dirfd is not None: + os.close(bind_dirfd) + else: + return get_exception_errno(e), None def check_connection_completion(sock): p = ovs.poller.SelectPoll() - p.register(sock, select.POLLOUT) - if len(p.poll(0)) == 1: - return get_socket_error(sock) + p.register(sock, ovs.poller.POLLOUT) + 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 @@ -119,12 +168,6 @@ def inet_open_active(style, target, default_port, dscp): return get_exception_errno(e), None -def get_socket_error(sock): - """Returns the errno value associated with 'socket' (0 if no error) and - resets the socket's error status.""" - return sock.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) - - def get_exception_errno(e): """A lot of methods on Python socket objects raise socket.error, but that exception is documented as having two completely different forms of @@ -182,7 +225,7 @@ def set_nonblocking(sock): sock.setblocking(0) except socket.error, e: vlog.err("could not set nonblocking mode on socket: %s" - % os.strerror(get_socket_error(e))) + % os.strerror(get_exception_errno(e))) def set_dscp(sock, dscp):