From 31d0b6c9420fdd960d4e58475c8089b1f52f3494 Mon Sep 17 00:00:00 2001
From: Ben Pfaff <blp@nicira.com>
Date: Thu, 24 Jun 2010 12:56:30 -0700
Subject: [PATCH] ovsdb-server: Implement unixctl command to reconnect JSON-RPC
 connections.

This feature may be useful for debugging.

Feature #2222.
---
 ovsdb/jsonrpc-server.c  | 31 +++++++++++++++++++++++++++++++
 ovsdb/jsonrpc-server.h  |  2 ++
 ovsdb/ovsdb-server.1.in |  8 ++++++++
 ovsdb/ovsdb-server.c    | 15 +++++++++++++++
 4 files changed, 56 insertions(+)

diff --git a/ovsdb/jsonrpc-server.c b/ovsdb/jsonrpc-server.c
index 84243d58..18f59c50 100644
--- a/ovsdb/jsonrpc-server.c
+++ b/ovsdb/jsonrpc-server.c
@@ -50,6 +50,7 @@ static struct ovsdb_jsonrpc_session *ovsdb_jsonrpc_session_create(
 static void ovsdb_jsonrpc_session_run_all(struct ovsdb_jsonrpc_remote *);
 static void ovsdb_jsonrpc_session_wait_all(struct ovsdb_jsonrpc_remote *);
 static void ovsdb_jsonrpc_session_close_all(struct ovsdb_jsonrpc_remote *);
+static void ovsdb_jsonrpc_session_reconnect_all(struct ovsdb_jsonrpc_remote *);
 
 /* Triggers. */
 static void ovsdb_jsonrpc_trigger_create(struct ovsdb_jsonrpc_session *,
@@ -172,6 +173,20 @@ ovsdb_jsonrpc_server_del_remote(struct shash_node *node)
     free(remote);
 }
 
+/* Forces all of the JSON-RPC sessions managed by 'svr' to disconnect and
+ * reconnect. */
+void
+ovsdb_jsonrpc_server_reconnect(struct ovsdb_jsonrpc_server *svr)
+{
+    struct shash_node *node;
+
+    SHASH_FOR_EACH (node, &svr->remotes) {
+        struct ovsdb_jsonrpc_remote *remote = node->data;
+
+        ovsdb_jsonrpc_session_reconnect_all(remote);
+    }
+}
+
 void
 ovsdb_jsonrpc_server_run(struct ovsdb_jsonrpc_server *svr)
 {
@@ -347,6 +362,22 @@ ovsdb_jsonrpc_session_close_all(struct ovsdb_jsonrpc_remote *remote)
     }
 }
 
+/* Forces all of the JSON-RPC sessions managed by 'remote' to disconnect and
+ * reconnect. */
+static void
+ovsdb_jsonrpc_session_reconnect_all(struct ovsdb_jsonrpc_remote *remote)
+{
+    struct ovsdb_jsonrpc_session *s, *next;
+
+    LIST_FOR_EACH_SAFE (s, next, struct ovsdb_jsonrpc_session, node,
+                        &remote->sessions) {
+        jsonrpc_session_force_reconnect(s->js);
+        if (!jsonrpc_session_is_alive(s->js)) {
+            ovsdb_jsonrpc_session_close(s);
+        }
+    }
+}
+
 static const char *
 get_db_name(const struct ovsdb_jsonrpc_session *s)
 {
diff --git a/ovsdb/jsonrpc-server.h b/ovsdb/jsonrpc-server.h
index 6c4acd7f..66dfa975 100644
--- a/ovsdb/jsonrpc-server.h
+++ b/ovsdb/jsonrpc-server.h
@@ -25,6 +25,8 @@ void ovsdb_jsonrpc_server_destroy(struct ovsdb_jsonrpc_server *);
 void ovsdb_jsonrpc_server_set_remotes(struct ovsdb_jsonrpc_server *,
                                       const struct shash *);
 
+void ovsdb_jsonrpc_server_reconnect(struct ovsdb_jsonrpc_server *);
+
 void ovsdb_jsonrpc_server_run(struct ovsdb_jsonrpc_server *);
 void ovsdb_jsonrpc_server_wait(struct ovsdb_jsonrpc_server *);
 
diff --git a/ovsdb/ovsdb-server.1.in b/ovsdb/ovsdb-server.1.in
index 7909b9ea..b36c61d2 100644
--- a/ovsdb/ovsdb-server.1.in
+++ b/ovsdb/ovsdb-server.1.in
@@ -85,6 +85,14 @@ Causes \fBovsdb\-server\fR to gracefully terminate.
 .IP "\fBovsdb-server/compact\fR"
 Compacts the database in-place.  The database is also automatically
 compacted occasionally.
+.
+.IP "\fBovsdb\-server/reconnect\fR"
+Makes \fBovsdb\-server\fR drop all of the JSON\-RPC
+connections to database clients and reconnect.
+.IP
+This command might be useful for debugging issues with database
+clients.
+.
 .so lib/vlog-unixctl.man
 .SH "SEE ALSO"
 .
diff --git a/ovsdb/ovsdb-server.c b/ovsdb/ovsdb-server.c
index 0d95cb2e..3b71442d 100644
--- a/ovsdb/ovsdb-server.c
+++ b/ovsdb/ovsdb-server.c
@@ -59,6 +59,7 @@ static bool bootstrap_ca_cert;
 
 static unixctl_cb_func ovsdb_server_exit;
 static unixctl_cb_func ovsdb_server_compact;
+static unixctl_cb_func ovsdb_server_reconnect;
 
 static void parse_options(int argc, char *argv[], char **file_namep,
                           struct shash *remotes, char **unixctl_pathp,
@@ -131,6 +132,8 @@ main(int argc, char *argv[])
     unixctl_command_register("exit", ovsdb_server_exit, &exiting);
     unixctl_command_register("ovsdb-server/compact", ovsdb_server_compact,
                              file);
+    unixctl_command_register("ovsdb-server/reconnect", ovsdb_server_reconnect,
+                             jsonrpc);
 
     exiting = false;
     while (!exiting) {
@@ -317,6 +320,18 @@ ovsdb_server_compact(struct unixctl_conn *conn, const char *args OVS_UNUSED,
     }
 }
 
+/* "ovsdb-server/reconnect": makes ovsdb-server drop all of its JSON-RPC
+ * connections and reconnect. */
+static void
+ovsdb_server_reconnect(struct unixctl_conn *conn, const char *args OVS_UNUSED,
+                       void *jsonrpc_)
+{
+    struct ovsdb_jsonrpc_server *jsonrpc = jsonrpc_;
+
+    ovsdb_jsonrpc_server_reconnect(jsonrpc);
+    unixctl_command_reply(conn, 200, NULL);
+}
+
 static void
 parse_options(int argc, char *argv[], char **file_namep,
               struct shash *remotes, char **unixctl_pathp,
-- 
2.30.2