[ovs-dev] [PATCH V9 11/17] python tests: Ported UNIX sockets to Windows
Paul Boca
pboca at cloudbasesolutions.com
Tue Jul 26 12:01:12 UTC 2016
AF_UNIX sockets are not supported on Windows.
Instead of an AF_UNIX socket use localhost tcp connections to communicate
between components. This makes the python sockets compatible with
the ones used in Windows applications.
In case the socket returns WSAEWOULDBLOCK, it is replaced by EAGAIN error
in order to be compatible with Windows.
Signed-off-by: Paul-Daniel Boca <pboca at cloudbasesolutions.com>
Acked-by: Alin Gabriel Serdean <aserdean at cloudbasesolutions.com>
---
V2: Fixed Python function inet_open_active, treat WSAEWOULDBLOCK error as
EINPROGRESS on Windows
V3: Use context managers for file handle leaks
V4: No changes
V5: No changes
V6: No changes
V7: Fix for JSON-RPC tests - treat WSAEWOULDBLOCK error as EAGAIN
for compatibility
V8: No changes
V9: No changes
---
python/ovs/jsonrpc.py | 4 ++++
python/ovs/socket_util.py | 56 +++++++++++++++++++++++++++++++++++++-------
python/ovs/stream.py | 9 +++++--
python/ovs/unixctl/server.py | 6 +++--
4 files changed, 62 insertions(+), 13 deletions(-)
diff --git a/python/ovs/jsonrpc.py b/python/ovs/jsonrpc.py
index 6300c67..1bc3493 100644
--- a/python/ovs/jsonrpc.py
+++ b/python/ovs/jsonrpc.py
@@ -14,6 +14,7 @@
import errno
import os
+import sys
import six
@@ -274,6 +275,9 @@ class Connection(object):
except UnicodeError:
error = errno.EILSEQ
if error:
+ if (sys.platform == "win32"
+ and error == errno.WSAEWOULDBLOCK):
+ error = errno.EAGAIN
if error == errno.EAGAIN:
return error, None
else:
diff --git a/python/ovs/socket_util.py b/python/ovs/socket_util.py
index b358b05..949d27a 100644
--- a/python/ovs/socket_util.py
+++ b/python/ovs/socket_util.py
@@ -17,6 +17,7 @@ import os
import os.path
import random
import socket
+import sys
import six
from six.moves import range
@@ -54,6 +55,26 @@ def free_short_name(short_name):
ovs.fatal_signal.unlink_file_now(link_name)
+def compat_read_unix_socket(path):
+ try:
+ with open(path, "r+") as file_handle:
+ ret = int(file_handle.readline())
+ except IOError as e:
+ vlog.warn("%s: open: %s" % (path, e.strerror))
+ raise socket.error(errno.ENOENT)
+
+ return ret
+
+
+def compat_write_unix_socket(path, port):
+ try:
+ with open(path, "w") as file_handle:
+ file_handle.write(str(port))
+ except IOError as e:
+ vlog.warn("%s: open: %s" % (path, e.strerror))
+ raise socket.error(errno.ENOENT)
+
+
def make_unix_socket(style, nonblock, bind_path, connect_path, short=False):
"""Creates a Unix domain socket in the given 'style' (either
socket.SOCK_DGRAM or socket.SOCK_STREAM) that is bound to 'bind_path' (if
@@ -65,7 +86,10 @@ def make_unix_socket(style, nonblock, bind_path, connect_path, short=False):
None."""
try:
- sock = socket.socket(socket.AF_UNIX, style)
+ if sys.platform == "win32":
+ sock = socket.socket(socket.AF_INET, style)
+ else:
+ sock = socket.socket(socket.AF_UNIX, style)
except socket.error as e:
return get_exception_errno(e), None
@@ -81,17 +105,28 @@ def make_unix_socket(style, nonblock, bind_path, connect_path, short=False):
return e.errno, None
ovs.fatal_signal.add_file_to_unlink(bind_path)
- sock.bind(bind_path)
+ if sys.platform == "win32":
+ sock.bind(("127.0.0.1", 0))
+ compat_write_unix_socket(bind_path, sock.getsockname()[1])
+ else:
+ sock.bind(bind_path)
- try:
- os.fchmod(sock.fileno(), 0o700)
- except OSError as e:
- pass
+ try:
+ os.fchmod(sock.fileno(), 0o700)
+ except OSError as e:
+ pass
if connect_path is not None:
try:
- sock.connect(connect_path)
+ if sys.platform == "win32":
+ port = compat_read_unix_socket(connect_path)
+ sock.connect(("127.0.0.1", port))
+ else:
+ sock.connect(connect_path)
except socket.error as e:
- if get_exception_errno(e) != errno.EINPROGRESS:
+ error = get_exception_errno(e)
+ if sys.platform == "win32" and error == errno.WSAEWOULDBLOCK:
+ error = errno.EINPROGRESS
+ if error != errno.EINPROGRESS:
raise
return 0, sock
except socket.error as e:
@@ -228,7 +263,10 @@ def inet_open_active(style, target, default_port, dscp):
try:
sock.connect(address)
except socket.error as e:
- if get_exception_errno(e) != errno.EINPROGRESS:
+ error = get_exception_errno(e)
+ if sys.platform == "win32" and error == errno.WSAEWOULDBLOCK:
+ error = errno.EINPROGRESS
+ if error != errno.EINPROGRESS:
raise
return 0, sock
except socket.error as e:
diff --git a/python/ovs/stream.py b/python/ovs/stream.py
index 97b22ac..b3aa5d9 100644
--- a/python/ovs/stream.py
+++ b/python/ovs/stream.py
@@ -15,7 +15,7 @@
import errno
import os
import socket
-
+import sys
import six
import ovs.poller
@@ -136,6 +136,8 @@ class Stream(object):
if not error:
while True:
error = stream.connect()
+ if sys.platform == "win32" and error == errno.WSAEWOULDBLOCK:
+ error = errno.EAGAIN
if error != errno.EAGAIN:
break
stream.run()
@@ -338,12 +340,15 @@ class PassiveStream(object):
try:
sock, addr = self.socket.accept()
ovs.socket_util.set_nonblocking(sock)
- if (sock.family == socket.AF_UNIX):
+ if (sys.platform != "win32"
+ and sock.family == socket.AF_UNIX):
return 0, Stream(sock, "unix:%s" % addr, 0)
return 0, Stream(sock, 'ptcp:%s:%s' % (addr[0],
str(addr[1])), 0)
except socket.error as e:
error = ovs.socket_util.get_exception_errno(e)
+ if sys.platform == "win32" and error == errno.WSAEWOULDBLOCK:
+ error = errno.EAGAIN
if error != errno.EAGAIN:
# XXX rate-limit
vlog.dbg("accept: %s" % os.strerror(error))
diff --git a/python/ovs/unixctl/server.py b/python/ovs/unixctl/server.py
index 8595ed8..749a335 100644
--- a/python/ovs/unixctl/server.py
+++ b/python/ovs/unixctl/server.py
@@ -148,6 +148,8 @@ class UnixctlServer(object):
def run(self):
for _ in range(10):
error, stream = self._listener.accept()
+ if sys.platform == "win32" and error == errno.WSAEWOULDBLOCK:
+ error = errno.EAGAIN
if not error:
rpc = ovs.jsonrpc.Connection(stream)
self._conns.append(UnixctlConnection(rpc))
@@ -155,8 +157,8 @@ class UnixctlServer(object):
break
else:
# XXX: rate-limit
- vlog.warn("%s: accept failed: %s" % (self._listener.name,
- os.strerror(error)))
+ vlog.warn("%s: accept failed: %s %d %d"
+ % (self._listener.name, os.strerror(error), error))
for conn in copy.copy(self._conns):
error = conn.run()
--
2.7.2.windows.1
More information about the dev
mailing list