From 89d7ffa9941b15bd4e9952226983dc90e9f7fa9a Mon Sep 17 00:00:00 2001 From: James Page Date: Wed, 16 Jan 2013 11:12:09 +0000 Subject: [PATCH] python: Workaround UNIX socket path length limits From aa28e8bfb646a54ba91e3545f3c0b9db39eddb7f Mon Sep 17 00:00:00 2001 From: James Page Date: Wed, 16 Jan 2013 10:52:59 +0000 Subject: [PATCH] python: Workaround UNIX socket path length limits To: dev@openvswitch.org UNIX socket paths have a limit in terms of length. On Linux this is 103 characters. This is a problem in Debian/Ubuntu buildds which can generate quite long paths. This patch works around this issue by detecting when socket connection/binding fails due to this issue and accessing the socket path using a file descriptor path in /proc/self/fd. The workaround is limited to Linux. This is based on similar code in the C parts of OpenvSwitch. Signed-off-by: James Page Signed-off-by: Ben Pfaff --- python/ovs/socket_util.py | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/python/ovs/socket_util.py b/python/ovs/socket_util.py index 8fecbc79c..7bfefc49c 100644 --- a/python/ovs/socket_util.py +++ b/python/ovs/socket_util.py @@ -70,9 +70,44 @@ 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(e), 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(e), 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): -- 2.43.0