From patchwork Wed Jul 6 12:38:29 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Boca X-Patchwork-Id: 645278 X-Patchwork-Delegate: guru@ovn.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from archives.nicira.com (archives.nicira.com [96.126.127.54]) by ozlabs.org (Postfix) with ESMTP id 3rl0jD4ML4z9sRZ for ; Wed, 6 Jul 2016 22:40:48 +1000 (AEST) Received: from archives.nicira.com (localhost [127.0.0.1]) by archives.nicira.com (Postfix) with ESMTP id D656322C3EA; Wed, 6 Jul 2016 05:40:47 -0700 (PDT) X-Original-To: dev@openvswitch.org Delivered-To: dev@openvswitch.org Received: from mx1e4.cudamail.com (mx1.cudamail.com [69.90.118.67]) by archives.nicira.com (Postfix) with ESMTPS id 097E822C3EA for ; Wed, 6 Jul 2016 05:40:46 -0700 (PDT) Received: from bar5.cudamail.com (unknown [192.168.21.12]) by mx1e4.cudamail.com (Postfix) with ESMTPS id 8A4A31E02C0 for ; Wed, 6 Jul 2016 06:40:45 -0600 (MDT) X-ASG-Debug-ID: 1467808844-09eadd1b18106110001-byXFYA Received: from mx1-pf2.cudamail.com ([192.168.24.2]) by bar5.cudamail.com with ESMTP id dOP5Uwrj7RzKWyCc (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Wed, 06 Jul 2016 06:40:44 -0600 (MDT) X-Barracuda-Envelope-From: pboca@cloudbasesolutions.com X-Barracuda-RBL-Trusted-Forwarder: 192.168.24.2 Received: from unknown (HELO cbssmtp1.cloudbase.local) (91.232.152.5) by mx1-pf2.cudamail.com with SMTP; 6 Jul 2016 12:40:43 -0000 Received-SPF: pass (mx1-pf2.cudamail.com: SPF record at cloudbasesolutions.com designates 91.232.152.5 as permitted sender) X-Barracuda-Apparent-Source-IP: 91.232.152.5 X-Barracuda-RBL-IP: 91.232.152.5 Received: from localhost (localhost [127.0.0.1]) by cbssmtp1.cloudbase.local (Postfix) with ESMTP id 15EA2405C5 for ; Wed, 6 Jul 2016 15:40:43 +0300 (EEST) X-Virus-Scanned: amavisd-new at cloudbasesolutions.com Received: from cbssmtp1.cloudbase.local ([127.0.0.1]) by localhost (cbssmtp1.cloudbase.local [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id lMkgv11lXuFj for ; Wed, 6 Jul 2016 15:40:22 +0300 (EEST) Received: from CBSEX1.cloudbase.local (unknown [10.77.78.3]) by cbssmtp1.cloudbase.local (Postfix) with ESMTP id A0AD240157 for ; Wed, 6 Jul 2016 15:38:30 +0300 (EEST) Received: from CBSEX1.cloudbase.local ([10.77.78.3]) by CBSEX1.cloudbase.local ([10.77.78.3]) with mapi id 14.03.0301.000; Wed, 6 Jul 2016 14:38:30 +0200 X-CudaMail-Envelope-Sender: pboca@cloudbasesolutions.com From: Paul Boca To: "dev@openvswitch.org" X-CudaMail-MID: CM-E2-705012137 X-CudaMail-DTE: 070616 X-CudaMail-Originating-IP: 91.232.152.5 Thread-Topic: [PATCH V6 11/17] python tests: Ported UNIX sockets to Windows X-ASG-Orig-Subj: [##CM-E2-705012137##][PATCH V6 11/17] python tests: Ported UNIX sockets to Windows Thread-Index: AQHR14NM9+jUM48hykqwpe6Sg8dS5g== Date: Wed, 6 Jul 2016 12:38:29 +0000 Message-ID: <1467808691-17280-12-git-send-email-pboca@cloudbasesolutions.com> References: <1467808691-17280-1-git-send-email-pboca@cloudbasesolutions.com> In-Reply-To: <1467808691-17280-1-git-send-email-pboca@cloudbasesolutions.com> Accept-Language: en-US, it-IT Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.77.78.1] MIME-Version: 1.0 X-GBUdb-Analysis: 0, 91.232.152.5, Ugly c=0.318533 p=-0.363636 Source Normal X-MessageSniffer-Rules: 0-0-0-16515-c X-Barracuda-Connect: UNKNOWN[192.168.24.2] X-Barracuda-Start-Time: 1467808844 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://web.cudamail.com:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at cudamail.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.60 X-Barracuda-Spam-Status: No, SCORE=1.60 using global scores of TAG_LEVEL=3.5 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=4.0 tests=BSF_SC0_MV0713, BSF_SC0_MV0713_3, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.31058 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 0.50 BSF_SC0_MV0713 Custom rule MV0713 1.00 BSF_SC0_MV0713_3 BSF_SC0_MV0713_3 Subject: [ovs-dev] [PATCH V6 11/17] python tests: Ported UNIX sockets to Windows X-BeenThere: dev@openvswitch.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@openvswitch.org Sender: "dev" 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 Acked-by: Alin Gabriel Serdean --- 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 --- python/ovs/jsonrpc.py | 3 +++ python/ovs/socket_util.py | 53 ++++++++++++++++++++++++++++++++++++-------- python/ovs/stream.py | 6 +++-- python/ovs/unixctl/server.py | 15 +++++++++---- 4 files changed, 62 insertions(+), 15 deletions(-) diff --git a/python/ovs/jsonrpc.py b/python/ovs/jsonrpc.py index 6300c67..74438c9 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,8 @@ 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..81120a8 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 @@ -53,6 +54,23 @@ def free_short_name(short_name): link_name = os.path.dirname(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 @@ -65,7 +83,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 +102,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 +260,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..fd894d9 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,7 +340,7 @@ 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) diff --git a/python/ovs/unixctl/server.py b/python/ovs/unixctl/server.py index cc712bf..4aa02bb 100644 --- a/python/ovs/unixctl/server.py +++ b/python/ovs/unixctl/server.py @@ -15,6 +15,7 @@ import copy import errno import os +import sys import six from six.moves import range @@ -147,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)) @@ -154,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() @@ -188,8 +191,12 @@ class UnixctlServer(object): if path is not None: path = "punix:%s" % ovs.util.abs_file_name(ovs.dirs.RUNDIR, path) else: - path = "punix:%s/%s.%d.ctl" % (ovs.dirs.RUNDIR, - ovs.util.PROGRAM_NAME, os.getpid()) + if sys.platform == "win32": + path = "punix:%s/%s.ctl" % (ovs.dirs.RUNDIR, + ovs.util.PROGRAM_NAME) + else: + path = "punix:%s/%s.%d.ctl" % (ovs.dirs.RUNDIR, + ovs.util.PROGRAM_NAME, os.getpid()) if version is None: version = ovs.version.VERSION