ovsdb: Report the number of connections for inbound Managers.
[sliver-openvswitch.git] / ovsdb / jsonrpc-server.c
index 3edcfff..14dd425 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, 2010 Nicira Networks
+/* Copyright (c) 2009, 2010, 2011 Nicira Networks
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -22,6 +22,7 @@
 
 #include "bitmap.h"
 #include "column.h"
+#include "dynamic-string.h"
 #include "json.h"
 #include "jsonrpc.h"
 #include "ovsdb-error.h"
@@ -42,7 +43,7 @@ struct ovsdb_jsonrpc_remote;
 struct ovsdb_jsonrpc_session;
 
 /* Message rate-limiting. */
-struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
+static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
 
 /* Sessions. */
 static struct ovsdb_jsonrpc_session *ovsdb_jsonrpc_session_create(
@@ -53,6 +54,9 @@ static void ovsdb_jsonrpc_session_close_all(struct ovsdb_jsonrpc_remote *);
 static void ovsdb_jsonrpc_session_reconnect_all(struct ovsdb_jsonrpc_remote *);
 static void ovsdb_jsonrpc_session_set_all_options(
     struct ovsdb_jsonrpc_remote *, const struct ovsdb_jsonrpc_options *);
+static bool ovsdb_jsonrpc_session_get_status(
+    const struct ovsdb_jsonrpc_remote *,
+    struct ovsdb_jsonrpc_remote_status *);
 
 /* Triggers. */
 static void ovsdb_jsonrpc_trigger_create(struct ovsdb_jsonrpc_session *,
@@ -138,6 +142,7 @@ ovsdb_jsonrpc_server_set_remotes(struct ovsdb_jsonrpc_server *svr,
 
     SHASH_FOR_EACH_SAFE (node, next, &svr->remotes) {
         if (!shash_find(new_remotes, node->name)) {
+            VLOG_INFO("%s: remote deconfigured", node->name);
             ovsdb_jsonrpc_server_del_remote(node);
         }
     }
@@ -194,6 +199,25 @@ ovsdb_jsonrpc_server_del_remote(struct shash_node *node)
     free(remote);
 }
 
+/* Stores status information for the remote named 'target', which should have
+ * been configured on 'svr' with a call to ovsdb_jsonrpc_server_set_remotes(),
+ * into '*status'.  On success returns true, on failure (if 'svr' doesn't have
+ * a remote named 'target' or if that remote is an inbound remote that has no
+ * active connections) returns false.  On failure, 'status' will be zeroed.
+ */
+bool
+ovsdb_jsonrpc_server_get_remote_status(
+    const struct ovsdb_jsonrpc_server *svr, const char *target,
+    struct ovsdb_jsonrpc_remote_status *status)
+{
+    const struct ovsdb_jsonrpc_remote *remote;
+
+    memset(status, 0, sizeof *status);
+
+    remote = shash_find_data(&svr->remotes, target);
+    return remote && ovsdb_jsonrpc_session_get_status(remote, status);
+}
+
 /* Forces all of the JSON-RPC sessions managed by 'svr' to disconnect and
  * reconnect. */
 void
@@ -420,6 +444,35 @@ ovsdb_jsonrpc_session_set_all_options(
     }
 }
 
+static bool
+ovsdb_jsonrpc_session_get_status(const struct ovsdb_jsonrpc_remote *remote,
+                                 struct ovsdb_jsonrpc_remote_status *status)
+{
+    const struct ovsdb_jsonrpc_session *s;
+    const struct jsonrpc_session *js;
+    struct reconnect_stats rstats;
+
+    if (list_is_empty(&remote->sessions)) {
+        return false;
+    }
+    s = CONTAINER_OF(remote->sessions.next, struct ovsdb_jsonrpc_session, node);
+    js = s->js;
+
+    status->is_connected = jsonrpc_session_is_connected(js);
+    status->last_error = jsonrpc_session_get_status(js);
+
+    jsonrpc_session_get_reconnect_stats(js, &rstats);
+    status->state = rstats.state;
+    status->sec_since_connect = rstats.msec_since_connect == UINT_MAX
+        ? UINT_MAX : rstats.msec_since_connect / 1000;
+    status->sec_since_disconnect = rstats.msec_since_disconnect == UINT_MAX
+        ? UINT_MAX : rstats.msec_since_disconnect / 1000;
+
+    status->n_connections = list_size(&remote->sessions);
+
+    return true;
+}
+
 static const char *
 get_db_name(const struct ovsdb_jsonrpc_session *s)
 {