Hey Isaku,<div><br></div><div>Thanks for the patch.</div><div>I have applied it to master.</div><div><br></div><div>thanx!</div><div>mehak<br><br><div class="gmail_quote">On Wed, Sep 26, 2012 at 12:12 AM, Isaku Yamahata <span dir="ltr">&lt;<a href="mailto:yamahata@valinux.co.jp" target="_blank">yamahata@valinux.co.jp</a>&gt;</span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Thus ovsdb-client aborts as follows.<br>
<br>
&gt; # ovs-vsctl set-manager ptcp:6634<br>
&gt; # ovsdb-client get-schema tcp:<a href="http://127.0.0.1:6634" target="_blank">127.0.0.1:6634</a><br>
&gt; 2012-09-14T05:38:26Z|00001|jsonrpc|WARN|tcp:<a href="http://127.0.0.1:6634" target="_blank">127.0.0.1:6634</a>: receive error: Connection reset by peer<br>
&gt; ovsdb-client: transaction failed (Connection reset by peer)<br>
NOTE: This occurs intermittently depending on how ovsdb-server runs.<br>
      Running ovsdb-client on a remote machine increases the possibility.<br>
<br>
This is because ovsdb-server closes newly accepted tcp connection.<br>
The following changesets caused it. struct jsonrpc_session::dscp isn&#39;t set<br>
based on listening socket&#39;s dscp value.<br>
<br>
- ovsdb-server creates passive connection and listens on it.<br>
- ovsdb-server accepts connection by ovsdb_jsonrpc_server_run().<br>
  The accepted socket inherits from the listening sockets.<br>
  ovsdb_jsonrpc_server_run() creates json session, but leaves dscp of<br>
  struct jsonrpc_session zero.<br>
- On calling reconfigure_from_db(), it resets dscp value to<br>
  all jsonrpc sessions. Eventually jsonrpc_session_set_dscp() is called.<br>
  Then jsonrpc_session_force_reconnect() closes the connection.<br>
<br>
With this patch,<br>
- struct jsonrpc_session::dscp is correctly set based on<br>
  listening sockets dscp value.<br>
- dscp of listening socket is changed dynamically by setsockopt.<br>
  This leaves a window where accepted socket may have old dscp.<br>
  But it is ignored for now because it would complicates codes<br>
  too much.<br>
<br>
The related change sets:<br>
- 0442efd9b1a88d923b56eab6b72b6be8231a49f7<br>
  Reapplying the dscp changes: No need to restart DB/OVS on changing<br>
  dscp value.<br>
- 59efa47adf3234ec51541405726d033173851285<br>
  Revert DSCP update changes.<br>
- b2e18db292cd4962af3248f11e9f17e6eaf9c033<br>
  No need to restart DB / OVS on changing dscp value.<br>
- f125905cdd3dc0339ad968c0a70128807884b400<br>
  Allow configuring DSCP on controller and manager connections.   5<br>
<br>
Signed-off-by: Isaku Yamahata &lt;<a href="mailto:yamahata@valinux.co.jp" target="_blank">yamahata@valinux.co.jp</a>&gt;<br>
---<br>
Changes v1 -&gt; v2:<br>
- addressed listening socket<br>
---<br>
 lib/jsonrpc.c          |   17 ++++++++++++++-<br>
 lib/jsonrpc.h          |    3 +-<br>
 ovsdb/jsonrpc-server.c |   20 ++++++++++++++++++-<br>
 tests/<a href="http://ovsdb-server.at" target="_blank">ovsdb-server.at</a>  |   49 ++++++++++++++++++++++++++++++++++++++++++++++++<br>
 4 files changed, 85 insertions(+), 4 deletions(-)<br>
<br>
diff --git a/lib/jsonrpc.c b/lib/jsonrpc.c<br>
index 0e1788c..d6e11c3 100644<br>
--- a/lib/jsonrpc.c<br>
+++ b/lib/jsonrpc.c<br>
@@ -791,7 +791,7 @@ jsonrpc_session_open(const char *name)<br>
  * On the assumption that such connections are likely to be short-lived<br>
  * (e.g. from ovs-vsctl), informational logging for them is suppressed. */<br>
 struct jsonrpc_session *<br>
-jsonrpc_session_open_unreliably(struct jsonrpc *jsonrpc)<br>
+jsonrpc_session_open_unreliably(struct jsonrpc *jsonrpc, uint8_t dscp)<br>
 {<br>
     struct jsonrpc_session *s;<br>
<br>
@@ -801,7 +801,7 @@ jsonrpc_session_open_unreliably(struct jsonrpc *jsonrpc)<br>
     reconnect_set_name(s-&gt;reconnect, jsonrpc_get_name(jsonrpc));<br>
     reconnect_set_max_tries(s-&gt;reconnect, 0);<br>
     reconnect_connected(s-&gt;reconnect, time_msec());<br>
-    s-&gt;dscp = 0;<br>
+    s-&gt;dscp = dscp;<br>
     s-&gt;rpc = jsonrpc;<br>
     s-&gt;stream = NULL;<br>
     s-&gt;pstream = NULL;<br>
@@ -1093,6 +1093,19 @@ jsonrpc_session_set_dscp(struct jsonrpc_session *s,<br>
                          uint8_t dscp)<br>
 {<br>
     if (s-&gt;dscp != dscp) {<br>
+        if (s-&gt;pstream) {<br>
+            int error;<br>
+            error = pstream_set_dscp(s-&gt;pstream, dscp);<br>
+            if (error) {<br>
+                VLOG_ERR(&quot;%s: failed set_dscp %s&quot;,<br>
+                         reconnect_get_name(s-&gt;reconnect), strerror(error));<br>
+            }<br>
+            /*<br>
+             * TODO:XXX race window between setting dscp to listening socket<br>
+             * and accepting socket. accepted socket may have old dscp value.<br>
+             * Ignore this race window for now.<br>
+             */<br>
+        }<br>
         s-&gt;dscp = dscp;<br>
         jsonrpc_session_force_reconnect(s);<br>
     }<br>
diff --git a/lib/jsonrpc.h b/lib/jsonrpc.h<br>
index 44ae06f..b5acf89 100644<br>
--- a/lib/jsonrpc.h<br>
+++ b/lib/jsonrpc.h<br>
@@ -99,7 +99,8 @@ struct json *jsonrpc_msg_to_json(struct jsonrpc_msg *);<br>
 /* A JSON-RPC session with reconnection. */<br>
<br>
 struct jsonrpc_session *jsonrpc_session_open(const char *name);<br>
-struct jsonrpc_session *jsonrpc_session_open_unreliably(struct jsonrpc *);<br>
+struct jsonrpc_session *jsonrpc_session_open_unreliably(struct jsonrpc *,<br>
+                                                        uint8_t);<br>
 void jsonrpc_session_close(struct jsonrpc_session *);<br>
<br>
 void jsonrpc_session_run(struct jsonrpc_session *);<br>
diff --git a/ovsdb/jsonrpc-server.c b/ovsdb/jsonrpc-server.c<br>
index bc0c89e..6a67f2e 100644<br>
--- a/ovsdb/jsonrpc-server.c<br>
+++ b/ovsdb/jsonrpc-server.c<br>
@@ -98,6 +98,7 @@ struct ovsdb_jsonrpc_remote {<br>
     struct ovsdb_jsonrpc_server *server;<br>
     struct pstream *listener;   /* Listener, if passive. */<br>
     struct list sessions;       /* List of &quot;struct ovsdb_jsonrpc_session&quot;s. */<br>
+    uint8_t dscp;<br>
 };<br>
<br>
 static struct ovsdb_jsonrpc_remote *ovsdb_jsonrpc_server_add_remote(<br>
@@ -193,6 +194,7 @@ ovsdb_jsonrpc_server_add_remote(struct ovsdb_jsonrpc_server *svr,<br>
     remote-&gt;server = svr;<br>
     remote-&gt;listener = listener;<br>
     list_init(&amp;remote-&gt;sessions);<br>
+    remote-&gt;dscp = options-&gt;dscp;<br>
     shash_add(&amp;svr-&gt;remotes, name, remote);<br>
<br>
     if (!listener) {<br>
@@ -269,7 +271,8 @@ ovsdb_jsonrpc_server_run(struct ovsdb_jsonrpc_server *svr)<br>
             error = pstream_accept(remote-&gt;listener, &amp;stream);<br>
             if (!error) {<br>
                 struct jsonrpc_session *js;<br>
-                js = jsonrpc_session_open_unreliably(jsonrpc_open(stream));<br>
+                js = jsonrpc_session_open_unreliably(jsonrpc_open(stream),<br>
+                                                     remote-&gt;dscp);<br>
                 ovsdb_jsonrpc_session_create(remote, js);<br>
             } else if (error != EAGAIN) {<br>
                 VLOG_WARN_RL(&amp;rl, &quot;%s: accept failed: %s&quot;,<br>
@@ -505,6 +508,21 @@ ovsdb_jsonrpc_session_set_all_options(<br>
 {<br>
     struct ovsdb_jsonrpc_session *s;<br>
<br>
+    if (remote-&gt;listener) {<br>
+        int error;<br>
+        error = pstream_set_dscp(remote-&gt;listener, options-&gt;dscp);<br>
+        if (error) {<br>
+            VLOG_ERR(&quot;%s: set_dscp failed %s&quot;,<br>
+                     pstream_get_name(remote-&gt;listener), strerror(error));<br>
+        } else {<br>
+            remote-&gt;dscp = options-&gt;dscp;<br>
+        }<br>
+        /*<br>
+         * TODO:XXX race window between setting dscp to listening socket<br>
+         * and accepting socket. Accepted socket may have old dscp value.<br>
+         * Ignore this race window for now.<br>
+         */<br>
+    }<br>
     LIST_FOR_EACH (s, node, &amp;remote-&gt;sessions) {<br>
         ovsdb_jsonrpc_session_set_options(s, options);<br>
     }<br>
diff --git a/tests/<a href="http://ovsdb-server.at" target="_blank">ovsdb-server.at</a> b/tests/<a href="http://ovsdb-server.at" target="_blank">ovsdb-server.at</a><br>
index b0a3377..87046f6 100644<br>
--- a/tests/<a href="http://ovsdb-server.at" target="_blank">ovsdb-server.at</a><br>
+++ b/tests/<a href="http://ovsdb-server.at" target="_blank">ovsdb-server.at</a><br>
@@ -415,6 +415,55 @@ cat stdout &gt;&gt; output<br>
<br>
 EXECUTION_EXAMPLES<br>
<br>
+AT_BANNER([OVSDB -- ovsdb-server transactions (TCP sockets)])<br>
+<br>
+AT_SETUP([ovsdb-client get-schema-version - tcp socket])<br>
+AT_KEYWORDS([ovsdb server positive tcp])<br>
+ordinal_schema &gt; schema<br>
+AT_CHECK([perl $srcdir/<a href="http://choose-port.pl" target="_blank">choose-port.pl</a>], [0], [stdout])<br>
+TCP_PORT=`cat stdout`<br>
+AT_CHECK([ovsdb-tool create db schema], [0], [ignore], [ignore])<br>
+AT_CHECK([ovsdb-server --detach --no-chdir --pidfile=&quot;`pwd`&quot;/pid --unixctl=&quot;`pwd`&quot;/unixctl --remote=ptcp:$TCP_PORT:127.0.0.1 db], [0], [ignore], [ignore])<br>
+AT_CHECK([ovsdb-client get-schema-version tcp:127.0.0.1:$TCP_PORT ordinals], [0], [5.1.3<br>
+])<br>
+OVSDB_SERVER_SHUTDOWN<br>
+AT_CLEANUP])<br>
+<br>
+# OVSDB_CHECK_EXECUTION(TITLE, SCHEMA, TRANSACTIONS, OUTPUT, [KEYWORDS])<br>
+#<br>
+# Creates a database with the given SCHEMA, starts an ovsdb-server on<br>
+# that database, and runs each of the TRANSACTIONS (which should be a<br>
+# quoted list of quoted strings) against it with ovsdb-client one at a<br>
+# time.<br>
+#<br>
+# Checks that the overall output is OUTPUT, but UUIDs in the output<br>
+# are replaced by markers of the form &lt;N&gt; where N is a number.  The<br>
+# first unique UUID is replaced by &lt;0&gt;, the next by &lt;1&gt;, and so on.<br>
+# If a given UUID appears more than once it is always replaced by the<br>
+# same marker.<br>
+#<br>
+# TITLE is provided to AT_SETUP and KEYWORDS to AT_KEYWORDS.<br>
+m4_define([OVSDB_CHECK_EXECUTION],<br>
+  [AT_SETUP([$1])<br>
+   AT_KEYWORDS([ovsdb server positive tcp $5])<br>
+   $2 &gt; schema<br>
+   AT_CHECK([perl $srcdir/<a href="http://choose-port.pl" target="_blank">choose-port.pl</a>], [0], [stdout])<br>
+   TCP_PORT=`cat stdout`<br>
+   PKIDIR=$abs_top_builddir/tests<br>
+   AT_CHECK([ovsdb-tool create db schema], [0], [stdout], [ignore])<br>
+   AT_CHECK([ovsdb-server --detach --no-chdir --pidfile=&quot;`pwd`&quot;/pid --remote=ptcp:$TCP_PORT:127.0.0.1 --unixctl=&quot;`pwd`&quot;/unixctl db], [0], [ignore], [ignore])<br>
+   m4_foreach([txn], [$3],<br>
+     [AT_CHECK([ovsdb-client transact tcp:127.0.0.1:$TCP_PORT &#39;txn&#39;], [0], [stdout], [ignore],<br>
+     [test ! -e pid || kill `cat pid`])<br>
+cat stdout &gt;&gt; output<br>
+])<br>
+   AT_CHECK([perl $srcdir/<a href="http://uuidfilt.pl" target="_blank">uuidfilt.pl</a> output], [0], [$4], [ignore],<br>
+            [test ! -e pid || kill `cat pid`])<br>
+   OVSDB_SERVER_SHUTDOWN<br>
+   AT_CLEANUP])<br>
+<br>
+EXECUTION_EXAMPLES<br>
+ <br>
 AT_BANNER([OVSDB -- transactions on transient ovsdb-server])<br>
<br>
 # OVSDB_CHECK_EXECUTION(TITLE, SCHEMA, TRANSACTIONS, OUTPUT, [KEYWORDS])<br>
<span><font color="#888888">--<br>
1.7.1.1<br>
<br>
</font></span></blockquote></div><br></div>