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 void ovsdb_jsonrpc_session_get_status(
+ const struct ovsdb_jsonrpc_remote *,
+ struct shash *);
/* Triggers. */
static void ovsdb_jsonrpc_trigger_create(struct ovsdb_jsonrpc_session *,
free(remote);
}
+void
+ovsdb_jsonrpc_server_get_remote_status(const struct ovsdb_jsonrpc_server *svr,
+ struct shash *statuses)
+{
+ struct shash_node *node;
+
+ shash_init(statuses);
+
+ SHASH_FOR_EACH (node, &svr->remotes) {
+ const struct ovsdb_jsonrpc_remote *remote = node->data;
+
+ ovsdb_jsonrpc_session_get_status(remote, statuses);
+ }
+}
+
/* Forces all of the JSON-RPC sessions managed by 'svr' to disconnect and
* reconnect. */
void
}
}
+static void
+ovsdb_jsonrpc_session_get_status(const struct ovsdb_jsonrpc_remote *remote,
+ struct shash *shash)
+{
+ const struct ovsdb_jsonrpc_session *s;
+ const struct jsonrpc_session *js;
+ const char *name;
+ struct ovsdb_jsonrpc_remote_status *status;
+ struct reconnect_stats rstats;
+
+ /* We only look at the first session in the list. There should be only one
+ * node in the list for outbound connections. We don't track status for
+ * each individual inbound connection if someone configures the DB that
+ * way. Since outbound connections are the norm, this is fine. */
+ if (list_is_empty(&remote->sessions)) {
+ return;
+ }
+ s = CONTAINER_OF(remote->sessions.next, struct ovsdb_jsonrpc_session, node);
+ js = s->js;
+ if (!js) {
+ return;
+ }
+ name = jsonrpc_session_get_name(js);
+
+ status = xzalloc(sizeof *status);
+ shash_add(shash, name, status);
+
+ 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->state_elapsed = rstats.state_elapsed;
+
+ return;
+}
+
static const char *
get_db_name(const struct ovsdb_jsonrpc_session *s)
{
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,
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) {
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
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) {