ovsdb: Raise the jsonrpc server session limit
[cascardo/ovs.git] / ovsdb / jsonrpc-server.c
index 692830c..2ba5ddd 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc.
+/* Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -37,7 +37,7 @@
 #include "timeval.h"
 #include "transaction.h"
 #include "trigger.h"
-#include "vlog.h"
+#include "openvswitch/vlog.h"
 
 VLOG_DEFINE_THIS_MODULE(ovsdb_jsonrpc_server);
 
@@ -102,7 +102,7 @@ struct ovsdb_jsonrpc_server {
 struct ovsdb_jsonrpc_remote {
     struct ovsdb_jsonrpc_server *server;
     struct pstream *listener;   /* Listener, if passive. */
-    struct list sessions;       /* List of "struct ovsdb_jsonrpc_session"s. */
+    struct ovs_list sessions;   /* List of "struct ovsdb_jsonrpc_session"s. */
     uint8_t dscp;
 };
 
@@ -121,7 +121,7 @@ ovsdb_jsonrpc_server_create(void)
 {
     struct ovsdb_jsonrpc_server *server = xzalloc(sizeof *server);
     ovsdb_server_init(&server->up);
-    server->max_sessions = 64;
+    server->max_sessions = 330;   /* Random limit. */
     shash_init(&server->remotes);
     return server;
 }
@@ -198,10 +198,16 @@ ovsdb_jsonrpc_server_set_remotes(struct ovsdb_jsonrpc_server *svr,
     struct shash_node *node, *next;
 
     SHASH_FOR_EACH_SAFE (node, next, &svr->remotes) {
-        if (!shash_find(new_remotes, node->name)) {
+        struct ovsdb_jsonrpc_remote *remote = node->data;
+        struct ovsdb_jsonrpc_options *options
+            = shash_find_data(new_remotes, node->name);
+
+        if (!options) {
             VLOG_INFO("%s: remote deconfigured", node->name);
             ovsdb_jsonrpc_server_del_remote(node);
-        }
+        } else if (options->dscp != remote->dscp) {
+            ovsdb_jsonrpc_server_del_remote(node);
+         }
     }
     SHASH_FOR_EACH (node, new_remotes) {
         const struct ovsdb_jsonrpc_options *options = node->data;
@@ -308,20 +314,26 @@ ovsdb_jsonrpc_server_run(struct ovsdb_jsonrpc_server *svr)
     SHASH_FOR_EACH (node, &svr->remotes) {
         struct ovsdb_jsonrpc_remote *remote = node->data;
 
-        if (remote->listener && svr->n_sessions < svr->max_sessions) {
-            struct stream *stream;
-            int error;
-
-            error = pstream_accept(remote->listener, &stream);
-            if (!error) {
-                struct jsonrpc_session *js;
-                js = jsonrpc_session_open_unreliably(jsonrpc_open(stream),
-                                                     remote->dscp);
-                ovsdb_jsonrpc_session_create(remote, js);
-            } else if (error != EAGAIN) {
-                VLOG_WARN_RL(&rl, "%s: accept failed: %s",
+        if (remote->listener) {
+            if (svr->n_sessions < svr->max_sessions) {
+                struct stream *stream;
+                int error;
+
+                error = pstream_accept(remote->listener, &stream);
+                if (!error) {
+                    struct jsonrpc_session *js;
+                    js = jsonrpc_session_open_unreliably(jsonrpc_open(stream),
+                                                         remote->dscp);
+                    ovsdb_jsonrpc_session_create(remote, js);
+                } else if (error != EAGAIN) {
+                    VLOG_WARN_RL(&rl, "%s: accept failed: %s",
+                                 pstream_get_name(remote->listener),
+                                 ovs_strerror(error));
+                }
+            } else {
+                VLOG_WARN_RL(&rl, "%s: connection exceeded maximum (%d)",
                              pstream_get_name(remote->listener),
-                             ovs_strerror(error));
+                             svr->max_sessions);
             }
         }
 
@@ -364,7 +376,7 @@ ovsdb_jsonrpc_server_get_memory_usage(const struct ovsdb_jsonrpc_server *svr,
 /* JSON-RPC database server session. */
 
 struct ovsdb_jsonrpc_session {
-    struct list node;           /* Element in remote's sessions list. */
+    struct ovs_list node;       /* Element in remote's sessions list. */
     struct ovsdb_session up;
     struct ovsdb_jsonrpc_remote *remote;
 
@@ -384,8 +396,6 @@ static int ovsdb_jsonrpc_session_run(struct ovsdb_jsonrpc_session *);
 static void ovsdb_jsonrpc_session_wait(struct ovsdb_jsonrpc_session *);
 static void ovsdb_jsonrpc_session_get_memory_usage(
     const struct ovsdb_jsonrpc_session *, struct simap *usage);
-static void ovsdb_jsonrpc_session_set_options(
-    struct ovsdb_jsonrpc_session *, const struct ovsdb_jsonrpc_options *);
 static void ovsdb_jsonrpc_session_got_request(struct ovsdb_jsonrpc_session *,
                                              struct jsonrpc_msg *);
 static void ovsdb_jsonrpc_session_got_notify(struct ovsdb_jsonrpc_session *,
@@ -556,7 +566,10 @@ ovsdb_jsonrpc_session_reconnect_all(struct ovsdb_jsonrpc_remote *remote)
 }
 
 /* Sets the options for all of the JSON-RPC sessions managed by 'remote' to
- * 'options'. */
+ * 'options'.
+ *
+ * (The dscp value can't be changed directly; the caller must instead close and
+ * re-open the session.) */
 static void
 ovsdb_jsonrpc_session_set_all_options(
     struct ovsdb_jsonrpc_remote *remote,
@@ -564,22 +577,6 @@ ovsdb_jsonrpc_session_set_all_options(
 {
     struct ovsdb_jsonrpc_session *s;
 
-    if (remote->listener) {
-        int error;
-
-        error = pstream_set_dscp(remote->listener, options->dscp);
-        if (error) {
-            VLOG_ERR("%s: set_dscp failed %s",
-                     pstream_get_name(remote->listener), ovs_strerror(error));
-        } else {
-            remote->dscp = options->dscp;
-        }
-        /*
-         * XXX race window between setting dscp to listening socket
-         * and accepting socket. Accepted socket may have old dscp value.
-         * Ignore this race window for now.
-         */
-    }
     LIST_FOR_EACH (s, node, &remote->sessions) {
         ovsdb_jsonrpc_session_set_options(s, options);
     }
@@ -1139,7 +1136,7 @@ compare_ovsdb_jsonrpc_monitor_column(const void *a_, const void *b_)
     return a->column < b->column ? -1 : a->column > b->column;
 }
 
-static struct ovsdb_error * WARN_UNUSED_RESULT
+static struct ovsdb_error * OVS_WARN_UNUSED_RESULT
 ovsdb_jsonrpc_parse_monitor_request(struct ovsdb_jsonrpc_monitor_table *mt,
                                     const struct json *monitor_request,
                                     size_t *allocated_columns)
@@ -1512,8 +1509,8 @@ ovsdb_jsonrpc_monitor_change_cb(const struct ovsdb_row *old,
     return true;
 }
 
-/* Returns JSON for a <row-update> (as described in ovsdb/SPECS) for 'row'
- * within 'mt', or NULL if no row update should be sent.
+/* Returns JSON for a <row-update> (as described in RFC 7047) for 'row' within
+ * 'mt', or NULL if no row update should be sent.
  *
  * The caller should specify 'initial' as true if the returned JSON is going to
  * be used as part of the initial reply to a "monitor" request, false if it is
@@ -1596,9 +1593,9 @@ ovsdb_jsonrpc_monitor_compose_row_update(
 }
 
 /* Constructs and returns JSON for a <table-updates> object (as described in
- * ovsdb/SPECS) for all the outstanding changes within 'monitor', and deletes
- * all the outstanding changes from 'monitor'.  Returns NULL if no update needs
- * to be sent.
+ * RFC 7047) for all the outstanding changes within 'monitor', and deletes all
+ * the outstanding changes from 'monitor'.  Returns NULL if no update needs to
+ * be sent.
  *
  * The caller should specify 'initial' as true if the returned JSON is going to
  * be used as part of the initial reply to a "monitor" request, false if it is