[ovs-dev] [PATCH] Add Passive TCP connection to IDL

ofer.benyacov at gmail.com ofer.benyacov at gmail.com
Thu Dec 3 07:56:20 UTC 2015


From: Ofer Ben Yacov <ofer.benyacov at gmail.com>

---
 python/ovs/db/idl.py  | 18 +++++++++++++++---
 python/ovs/jsonrpc.py | 19 +++++++++++--------
 python/ovs/stream.py  | 13 ++++++-------
 3 files changed, 32 insertions(+), 18 deletions(-)

diff --git a/python/ovs/db/idl.py b/python/ovs/db/idl.py
index c8990c7..4b492fe 100644
--- a/python/ovs/db/idl.py
+++ b/python/ovs/db/idl.py
@@ -83,7 +83,7 @@ class Idl(object):
       currently being constructed, if there is one, or None otherwise.
 """
 
-    def __init__(self, remote, schema):
+    def __init__(self, remote, schema, session = None):
         """Creates and returns a connection to the database named 'db_name' on
         'remote', which should be in a form acceptable to
         ovs.jsonrpc.session.open().  The connection will maintain an in-memory
@@ -101,7 +101,16 @@ class Idl(object):
         As a convenience to users, 'schema' may also be an instance of the
         SchemaHelper class.
 
-        The IDL uses and modifies 'schema' directly."""
+        The IDL uses and modifies 'schema' directly.
+
+        In passive mode ( where the OVSDB connects to its manager ),
+        we first need to wait for the OVSDB to connect and then
+        pass the 'session' object (while the it is still open ) and
+        the schema we retrieved from the open session to the IDL to use it.
+
+        If in active mode, do not pass 'session' and it will be created
+        by IDL by using 'remote'.
+        """
 
         assert isinstance(schema, SchemaHelper)
         schema = schema.get_idl_schema()
@@ -109,7 +118,10 @@ class Idl(object):
         self.tables = schema.tables
         self.readonly = schema.readonly
         self._db = schema
-        self._session = ovs.jsonrpc.Session.open(remote)
+        if session:
+            self._session = session
+        else:
+            self._session = ovs.jsonrpc.Session.open(remote)
         self._monitor_request_id = None
         self._last_seqno = None
         self.change_seqno = 0
diff --git a/python/ovs/jsonrpc.py b/python/ovs/jsonrpc.py
index d54d74b..1b68d3f 100644
--- a/python/ovs/jsonrpc.py
+++ b/python/ovs/jsonrpc.py
@@ -418,23 +418,25 @@ class Session(object):
         self.__disconnect()
 
         name = self.reconnect.get_name()
-        if not self.reconnect.is_passive():
-            error, self.stream = ovs.stream.Stream.open(name)
+        if self.reconnect.is_passive():
+            if self.pstream is not None:
+                self.pstream.close()
+            error, self.pstream = ovs.stream.PassiveStream.open(name)
             if not error:
-                self.reconnect.connecting(ovs.timeval.msec())
+                self.reconnect.listening(ovs.timeval.msec())
             else:
                 self.reconnect.connect_failed(ovs.timeval.msec(), error)
-        elif self.pstream is not None:
-            error, self.pstream = ovs.stream.PassiveStream.open(name)
+        else:
+            error, self.stream = ovs.stream.Stream.open(name)
             if not error:
-                self.reconnect.listening(ovs.timeval.msec())
+                self.reconnect.connecting(ovs.timeval.msec())
             else:
                 self.reconnect.connect_failed(ovs.timeval.msec(), error)
 
         self.seqno += 1
 
     def run(self):
-        if self.pstream is not None:
+        if self.pstream is not None and self.stream is None:
             error, stream = self.pstream.accept()
             if error == 0:
                 if self.rpc or self.stream:
@@ -444,11 +446,11 @@ class Session(object):
                     self.__disconnect()
                 self.reconnect.connected(ovs.timeval.msec())
                 self.rpc = Connection(stream)
+                self.stream = stream
             elif error != errno.EAGAIN:
                 self.reconnect.listen_error(ovs.timeval.msec(), error)
                 self.pstream.close()
                 self.pstream = None
-
         if self.rpc:
             backlog = self.rpc.get_backlog()
             self.rpc.run()
@@ -559,3 +561,4 @@ class Session(object):
 
     def force_reconnect(self):
         self.reconnect.force_reconnect(ovs.timeval.msec())
+
diff --git a/python/ovs/stream.py b/python/ovs/stream.py
index dfb24d7..a8be6e0 100644
--- a/python/ovs/stream.py
+++ b/python/ovs/stream.py
@@ -45,9 +45,9 @@ class Stream(object):
     __S_DISCONNECTED = 2
 
     # Kinds of events that one might wait for.
-    W_CONNECT = 0  # Connect complete (success or failure).
-    W_RECV = 1  # Data received.
-    W_SEND = 2  # Send buffer room available.
+    W_CONNECT = 0               # Connect complete (success or failure).
+    W_RECV = 1                  # Data received.
+    W_SEND = 2                  # Send buffer room available.
 
     _SOCKET_METHODS = {}
 
@@ -260,8 +260,8 @@ class PassiveStream(object):
     @staticmethod
     def is_valid_name(name):
         """Returns True if 'name' is a passive stream name in the form
-        "TYPE:ARGS" and TYPE is a supported passive stream type (currently only
-        "punix:"), otherwise False."""
+        "TYPE:ARGS" and TYPE is a supported passive stream type,
+        otherwise False."""
         return name.startswith("punix:") or name.startswith("ptcp:")
 
     def __init__(self, sock, name, bind_path=None):
@@ -273,8 +273,7 @@ class PassiveStream(object):
     def open(name):
         """Attempts to start listening for remote stream connections.  'name'
         is a connection name in the form "TYPE:ARGS", where TYPE is an passive
-        stream class's name and ARGS are stream class-specific.  Currently the
-        only supported TYPE is "punix".
+        stream class's name and ARGS are stream class-specific.
 
         Returns (error, pstream): on success 'error' is 0 and 'pstream' is the
         new PassiveStream, on failure 'error' is a positive errno value and
-- 
2.1.4




More information about the dev mailing list