ovsdb: constify should apply to all pointer types.
[sliver-openvswitch.git] / ovsdb / jsonrpc-server.c
index 3c439ee..3edcfff 100644 (file)
@@ -51,6 +51,8 @@ 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 *);
+static void ovsdb_jsonrpc_session_set_all_options(
+    struct ovsdb_jsonrpc_remote *, const struct ovsdb_jsonrpc_options *);
 
 /* Triggers. */
 static void ovsdb_jsonrpc_trigger_create(struct ovsdb_jsonrpc_session *,
@@ -88,8 +90,8 @@ struct ovsdb_jsonrpc_remote {
     struct list sessions;       /* List of "struct ovsdb_jsonrpc_session"s. */
 };
 
-static void ovsdb_jsonrpc_server_add_remote(struct ovsdb_jsonrpc_server *,
-                                            const char *name);
+static struct ovsdb_jsonrpc_remote *ovsdb_jsonrpc_server_add_remote(
+    struct ovsdb_jsonrpc_server *, const char *name);
 static void ovsdb_jsonrpc_server_del_remote(struct shash_node *);
 
 struct ovsdb_jsonrpc_server *
@@ -114,8 +116,17 @@ ovsdb_jsonrpc_server_destroy(struct ovsdb_jsonrpc_server *svr)
     free(svr);
 }
 
-/* Sets 'svr''s current set of remotes to the names in 'new_remotes'.  The data
- * values in 'new_remotes' are ignored.
+struct ovsdb_jsonrpc_options *
+ovsdb_jsonrpc_default_options(void)
+{
+    struct ovsdb_jsonrpc_options *options = xzalloc(sizeof *options);
+    options->probe_interval = RECONNECT_DEFAULT_PROBE_INTERVAL;
+    options->max_backoff = RECONNECT_DEFAULT_MAX_BACKOFF;
+    return options;
+}
+
+/* Sets 'svr''s current set of remotes to the names in 'new_remotes', with
+ * options in the struct ovsdb_jsonrpc_options supplied as the data values.
  *
  * A remote is an active or passive stream connection method, e.g. "pssl:" or
  * "tcp:1.2.3.4". */
@@ -131,13 +142,22 @@ ovsdb_jsonrpc_server_set_remotes(struct ovsdb_jsonrpc_server *svr,
         }
     }
     SHASH_FOR_EACH (node, new_remotes) {
-        if (!shash_find(&svr->remotes, node->name)) {
-            ovsdb_jsonrpc_server_add_remote(svr, node->name);
+        const struct ovsdb_jsonrpc_options *options = node->data;
+        struct ovsdb_jsonrpc_remote *remote;
+
+        remote = shash_find_data(&svr->remotes, node->name);
+        if (!remote) {
+            remote = ovsdb_jsonrpc_server_add_remote(svr, node->name);
+            if (!remote) {
+                continue;
+            }
         }
+
+        ovsdb_jsonrpc_session_set_all_options(remote, options);
     }
 }
 
-static void
+static struct ovsdb_jsonrpc_remote *
 ovsdb_jsonrpc_server_add_remote(struct ovsdb_jsonrpc_server *svr,
                                 const char *name)
 {
@@ -148,7 +168,7 @@ ovsdb_jsonrpc_server_add_remote(struct ovsdb_jsonrpc_server *svr,
     error = jsonrpc_pstream_open(name, &listener);
     if (error && error != EAFNOSUPPORT) {
         VLOG_ERR_RL(&rl, "%s: listen failed: %s", name, strerror(error));
-        return;
+        return NULL;
     }
 
     remote = xmalloc(sizeof *remote);
@@ -160,6 +180,7 @@ ovsdb_jsonrpc_server_add_remote(struct ovsdb_jsonrpc_server *svr,
     if (!listener) {
         ovsdb_jsonrpc_session_create(remote, jsonrpc_session_open(name));
     }
+    return remote;
 }
 
 static void
@@ -252,6 +273,8 @@ struct ovsdb_jsonrpc_session {
 static void ovsdb_jsonrpc_session_close(struct ovsdb_jsonrpc_session *);
 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_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 *,
@@ -318,6 +341,14 @@ ovsdb_jsonrpc_session_run(struct ovsdb_jsonrpc_session *s)
     return jsonrpc_session_is_alive(s->js) ? 0 : ETIMEDOUT;
 }
 
+static void
+ovsdb_jsonrpc_session_set_options(struct ovsdb_jsonrpc_session *session,
+                                  const struct ovsdb_jsonrpc_options *options)
+{
+    jsonrpc_session_set_max_backoff(session->js, options->max_backoff);
+    jsonrpc_session_set_probe_interval(session->js, options->probe_interval);
+}
+
 static void
 ovsdb_jsonrpc_session_run_all(struct ovsdb_jsonrpc_remote *remote)
 {
@@ -375,6 +406,20 @@ 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'. */
+static void
+ovsdb_jsonrpc_session_set_all_options(
+    struct ovsdb_jsonrpc_remote *remote,
+    const struct ovsdb_jsonrpc_options *options)
+{
+    struct ovsdb_jsonrpc_session *s;
+
+    LIST_FOR_EACH (s, node, &remote->sessions) {
+        ovsdb_jsonrpc_session_set_options(s, options);
+    }
+}
+
 static const char *
 get_db_name(const struct ovsdb_jsonrpc_session *s)
 {
@@ -935,6 +980,24 @@ struct ovsdb_jsonrpc_monitor_aux {
     struct json *table_json;    /* JSON for table's transaction. */
 };
 
+static bool
+any_reportable_change(const struct ovsdb_jsonrpc_monitor_table *mt,
+                      const unsigned long int *changed)
+{
+    size_t i;
+
+    for (i = 0; i < mt->n_columns; i++) {
+        const struct ovsdb_jsonrpc_monitor_column *c = &mt->columns[i];
+        unsigned int idx = c->column->index;
+
+        if (c->select & OJMS_MODIFY && bitmap_is_set(changed, idx)) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
 static bool
 ovsdb_jsonrpc_monitor_change_cb(const struct ovsdb_row *old,
                                 const struct ovsdb_row *new,
@@ -948,7 +1011,6 @@ ovsdb_jsonrpc_monitor_change_cb(const struct ovsdb_row *old,
     struct json *old_json, *new_json;
     struct json *row_json;
     char uuid[UUID_LEN + 1];
-    int n_changed;
     size_t i;
 
     if (!aux->mt || table != aux->mt->table) {
@@ -971,13 +1033,22 @@ ovsdb_jsonrpc_monitor_change_cb(const struct ovsdb_row *old,
         return true;
     }
 
+    if (type == OJMS_MODIFY && !any_reportable_change(aux->mt, changed)) {
+        /* Nothing of interest changed. */
+        return true;
+    }
+
     old_json = new_json = NULL;
-    n_changed = 0;
+    if (type & (OJMS_DELETE | OJMS_MODIFY)) {
+        old_json = json_object_create();
+    }
+    if (type & (OJMS_INITIAL | OJMS_INSERT | OJMS_MODIFY)) {
+        new_json = json_object_create();
+    }
     for (i = 0; i < aux->mt->n_columns; i++) {
         const struct ovsdb_jsonrpc_monitor_column *c = &aux->mt->columns[i];
         const struct ovsdb_column *column = c->column;
         unsigned int idx = c->column->index;
-        bool column_changed = false;
 
         if (!(type & c->select)) {
             /* We don't care about this type of change for this particular
@@ -985,33 +1056,18 @@ ovsdb_jsonrpc_monitor_change_cb(const struct ovsdb_row *old,
             continue;
         }
 
-        if (type == OJMS_MODIFY) {
-            column_changed = bitmap_is_set(changed, idx);
-            n_changed += column_changed;
-        }
-        if (column_changed || type == OJMS_DELETE) {
-            if (!old_json) {
-                old_json = json_object_create();
-            }
+        if ((type == OJMS_MODIFY && bitmap_is_set(changed, idx))
+            || type == OJMS_DELETE) {
             json_object_put(old_json, column->name,
                             ovsdb_datum_to_json(&old->fields[idx],
                                                 &column->type));
         }
         if (type & (OJMS_INITIAL | OJMS_INSERT | OJMS_MODIFY)) {
-            if (!new_json) {
-                new_json = json_object_create();
-            }
             json_object_put(new_json, column->name,
                             ovsdb_datum_to_json(&new->fields[idx],
                                                 &column->type));
         }
     }
-    if ((type == OJMS_MODIFY && !n_changed) || (!old_json && !new_json)) {
-        /* No reportable changes. */
-        json_destroy(old_json);
-        json_destroy(new_json);
-        return true;
-    }
 
     /* Create JSON object for transaction overall. */
     if (!aux->json) {