Skip to content

Commit

Permalink
python: Workaround UNIX socket path length limits
Browse files Browse the repository at this point in the history
From aa28e8bfb646a54ba91e3545f3c0b9db39eddb7f Mon Sep 17 00:00:00 2001
From: James Page <[email protected]>
Date: Wed, 16 Jan 2013 10:52:59 +0000
Subject: [PATCH] python: Workaround UNIX socket path length limits
To: [email protected]

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 <[email protected]>
Signed-off-by: Ben Pfaff <[email protected]>
  • Loading branch information
javacruft authored and blp committed Jan 16, 2013
1 parent c964dc7 commit 89d7ffa
Showing 1 changed file with 37 additions and 2 deletions.
39 changes: 37 additions & 2 deletions python/ovs/socket_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down

0 comments on commit 89d7ffa

Please sign in to comment.