-/* 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.
#include "timeval.h"
#include "transaction.h"
#include "trigger.h"
-#include "vlog.h"
+#include "openvswitch/vlog.h"
VLOG_DEFINE_THIS_MODULE(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;
};
{
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;
}
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;
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);
}
}
/* 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;
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 *,
}
/* 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,
{
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);
}
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)
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
}
/* 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