From: Liran Schour Date: Mon, 18 Jul 2016 08:45:53 +0000 (+0300) Subject: ovsdb: enable jsonrpc-server to service "monitor_cond_change" request X-Git-Url: http://git.cascardo.eti.br/?p=cascardo%2Fovs.git;a=commitdiff_plain;h=845a1187073a7ee1ead82ba0391f834e39124a5d ovsdb: enable jsonrpc-server to service "monitor_cond_change" request ovsdb-server now accepts "monitor_cond_change" request. After conditions change we compose update notification according to the current state of the database without using a change list before sending reply to the monitor_cond_change request. Sees ovsdb-server (1) man page for details of monitor_cond_change. Signed-off-by: Liran Schour Signed-off-by: Ben Pfaff --- diff --git a/ovsdb/jsonrpc-server.c b/ovsdb/jsonrpc-server.c index 8fa4a1ee3..536a04471 100644 --- a/ovsdb/jsonrpc-server.c +++ b/ovsdb/jsonrpc-server.c @@ -90,6 +90,10 @@ static void ovsdb_jsonrpc_trigger_complete_done( static struct jsonrpc_msg *ovsdb_jsonrpc_monitor_create( struct ovsdb_jsonrpc_session *, struct ovsdb *, struct json *params, enum ovsdb_monitor_version, const struct json *request_id); +static struct jsonrpc_msg *ovsdb_jsonrpc_monitor_cond_change( + struct ovsdb_jsonrpc_session *s, + struct json *params, + const struct json *request_id); static struct jsonrpc_msg *ovsdb_jsonrpc_monitor_cancel( struct ovsdb_jsonrpc_session *, struct json_array *params, @@ -99,6 +103,9 @@ static void ovsdb_jsonrpc_monitor_flush_all(struct ovsdb_jsonrpc_session *); static bool ovsdb_jsonrpc_monitor_needs_flush(struct ovsdb_jsonrpc_session *); static struct json *ovsdb_jsonrpc_monitor_compose_update( struct ovsdb_jsonrpc_monitor *monitor, bool initial); +static struct jsonrpc_msg * ovsdb_jsonrpc_create_notify( + const struct ovsdb_jsonrpc_monitor *m, + struct json *params); /* JSON-RPC database server. */ @@ -415,7 +422,7 @@ 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_got_request(struct ovsdb_jsonrpc_session *, - struct jsonrpc_msg *); + struct jsonrpc_msg *); static void ovsdb_jsonrpc_session_got_notify(struct ovsdb_jsonrpc_session *, struct jsonrpc_msg *); @@ -876,6 +883,9 @@ ovsdb_jsonrpc_session_got_request(struct ovsdb_jsonrpc_session *s, reply = ovsdb_jsonrpc_monitor_create(s, db, request->params, version, request->id); } + } else if (!strcmp(request->method, "monitor_cond_change")) { + reply = ovsdb_jsonrpc_monitor_cond_change(s, request->params, + request->id); } else if (!strcmp(request->method, "monitor_cancel")) { reply = ovsdb_jsonrpc_monitor_cancel(s, json_array(request->params), request->id); @@ -1308,6 +1318,136 @@ error: return jsonrpc_create_error(json, request_id); } +static struct ovsdb_error * +ovsdb_jsonrpc_parse_monitor_cond_change_request( + struct ovsdb_jsonrpc_monitor *m, + const struct ovsdb_table *table, + const struct json *cond_change_req) +{ + const struct ovsdb_table_schema *ts = table->schema; + const struct json *condition, *columns; + struct ovsdb_parser parser; + struct ovsdb_error *error; + + ovsdb_parser_init(&parser, cond_change_req, "table %s", ts->name); + columns = ovsdb_parser_member(&parser, "columns", OP_ARRAY | OP_OPTIONAL); + condition = ovsdb_parser_member(&parser, "where", OP_ARRAY | OP_OPTIONAL); + + error = ovsdb_parser_finish(&parser); + if (error) { + return error; + } + + if (columns) { + error = ovsdb_syntax_error(cond_change_req, NULL, "changing columns " + "is unsupported"); + return error; + } + error = ovsdb_monitor_table_condition_update(m->dbmon, m->condition, table, + condition); + + return error; +} + +static struct jsonrpc_msg * +ovsdb_jsonrpc_monitor_cond_change(struct ovsdb_jsonrpc_session *s, + struct json *params, + const struct json *request_id) +{ + struct ovsdb_error *error; + struct ovsdb_jsonrpc_monitor *m; + struct json *monitor_cond_change_reqs; + struct shash_node *node; + struct json *json; + + if (json_array(params)->n != 3) { + error = ovsdb_syntax_error(params, NULL, "invalid parameters"); + goto error; + } + + m = ovsdb_jsonrpc_monitor_find(s, params->u.array.elems[0]); + if (!m) { + error = ovsdb_syntax_error(request_id, NULL, + "unknown monitor session"); + goto error; + } + + monitor_cond_change_reqs = params->u.array.elems[2]; + if (monitor_cond_change_reqs->type != JSON_OBJECT) { + error = + ovsdb_syntax_error(NULL, NULL, + "monitor-cond-change-requests must be object"); + goto error; + } + + SHASH_FOR_EACH (node, json_object(monitor_cond_change_reqs)) { + const struct ovsdb_table *table; + const struct json *mr_value; + size_t i; + + table = ovsdb_get_table(m->db, node->name); + if (!table) { + error = ovsdb_syntax_error(NULL, NULL, + "no table named %s", node->name); + goto error; + } + if (!ovsdb_monitor_table_exists(m->dbmon, table)) { + error = ovsdb_syntax_error(NULL, NULL, + "no table named %s in monitor session", + node->name); + goto error; + } + + mr_value = node->data; + if (mr_value->type == JSON_ARRAY) { + const struct json_array *array = &mr_value->u.array; + + for (i = 0; i < array->n; i++) { + error = ovsdb_jsonrpc_parse_monitor_cond_change_request( + m, table, array->elems[i]); + if (error) { + goto error; + } + } + } else { + error = ovsdb_syntax_error( + NULL, NULL, + "table %s no monitor-cond-change JSON array", + node->name); + goto error; + } + } + + /* Change monitor id */ + hmap_remove(&s->monitors, &m->node); + json_destroy(m->monitor_id); + m->monitor_id = json_clone(params->u.array.elems[1]); + hmap_insert(&s->monitors, &m->node, json_hash(m->monitor_id, 0)); + + /* Send the new update, if any, represents the difference from the old + * condition and the new one. */ + struct json *update_json; + + update_json = ovsdb_monitor_get_update(m->dbmon, false, true, + &m->unflushed, m->condition, m->version); + if (update_json) { + struct jsonrpc_msg *msg; + struct json *params; + + params = json_array_create_2(json_clone(m->monitor_id), update_json); + msg = ovsdb_jsonrpc_create_notify(m, params); + jsonrpc_session_send(s->js, msg); + } + + return jsonrpc_create_reply(json_object_create(), request_id); + +error: + + json = ovsdb_error_to_json(error); + ovsdb_error_destroy(error); + return jsonrpc_create_error(json, request_id); +} + static struct jsonrpc_msg * ovsdb_jsonrpc_monitor_cancel(struct ovsdb_jsonrpc_session *s, struct json_array *params, @@ -1344,12 +1484,13 @@ static struct json * ovsdb_jsonrpc_monitor_compose_update(struct ovsdb_jsonrpc_monitor *m, bool initial) { + if (!ovsdb_monitor_needs_flush(m->dbmon, m->unflushed)) { return NULL; } - return ovsdb_monitor_get_update(m->dbmon, initial, &m->unflushed, - m->condition, m->version); + return ovsdb_monitor_get_update(m->dbmon, initial, false, + &m->unflushed, m->condition, m->version); } static bool diff --git a/ovsdb/monitor.c b/ovsdb/monitor.c index b60ed6762..9a07bffaf 100644 --- a/ovsdb/monitor.c +++ b/ovsdb/monitor.c @@ -146,11 +146,17 @@ struct ovsdb_monitor_table { struct hmap changes; }; +enum ovsdb_monitor_row_type { + OVSDB_ROW, + OVSDB_MONITOR_ROW +}; + typedef struct json * (*compose_row_update_cb_func) (const struct ovsdb_monitor_table *mt, const struct ovsdb_monitor_session_condition * condition, - const struct ovsdb_monitor_row *row, + enum ovsdb_monitor_row_type row_type, + const void *, bool initial, unsigned long int *changed); static void ovsdb_monitor_destroy(struct ovsdb_monitor *dbmon); @@ -477,6 +483,13 @@ ovsdb_monitor_condition_bind(struct ovsdb_monitor *dbmon, } } +bool +ovsdb_monitor_table_exists(struct ovsdb_monitor *m, + const struct ovsdb_table *table) +{ + return shash_find_data(&m->tables, table->schema->name); +} + static struct ovsdb_monitor_changes * ovsdb_monitor_table_add_changes(struct ovsdb_monitor_table *mt, uint64_t next_txn) @@ -665,11 +678,70 @@ ovsdb_monitor_get_table_conditions( return true; } +struct ovsdb_error * +ovsdb_monitor_table_condition_update( + struct ovsdb_monitor *dbmon, + struct ovsdb_monitor_session_condition *condition, + const struct ovsdb_table *table, + const struct json *cond_json) +{ + struct ovsdb_monitor_table_condition *mtc = + shash_find_data(&condition->tables, table->schema->name); + struct ovsdb_error *error; + struct ovsdb_condition cond = OVSDB_CONDITION_INITIALIZER; + + if (!condition) { + return NULL; + } + + error = ovsdb_condition_from_json(table->schema, cond_json, + NULL, &cond); + if (error) { + return error; + } + ovsdb_condition_destroy(&mtc->new_condition); + ovsdb_condition_clone(&mtc->new_condition, &cond); + ovsdb_condition_destroy(&cond); + ovsdb_monitor_condition_add_columns(dbmon, + table, + &mtc->new_condition); + + return NULL; +} + +static void +ovsdb_monitor_table_condition_updated(struct ovsdb_monitor_table *mt, + struct ovsdb_monitor_session_condition *condition) +{ + struct ovsdb_monitor_table_condition *mtc = + shash_find_data(&condition->tables, mt->table->schema->name); + + if (mtc) { + /* If conditional monitoring - set old condition to new condition */ + if (ovsdb_condition_cmp_3way(&mtc->old_condition, + &mtc->new_condition)) { + if (ovsdb_condition_is_true(&mtc->new_condition)) { + if (!ovsdb_condition_is_true(&mtc->old_condition)) { + condition->n_true_cnd++; + } + } else { + if (ovsdb_condition_is_true(&mtc->old_condition)) { + condition->n_true_cnd--; + } + } + ovsdb_condition_destroy(&mtc->old_condition); + ovsdb_condition_clone(&mtc->old_condition, &mtc->new_condition); + ovsdb_monitor_session_condition_set_mode(condition); + } + } +} + static enum ovsdb_monitor_selection ovsdb_monitor_row_update_type_condition( const struct ovsdb_monitor_table *mt, const struct ovsdb_monitor_session_condition *condition, bool initial, + enum ovsdb_monitor_row_type row_type, const struct ovsdb_datum *old, const struct ovsdb_datum *new) { @@ -683,12 +755,16 @@ ovsdb_monitor_row_update_type_condition( &new_condition)) { bool old_cond = !old ? false : ovsdb_condition_empty_or_match_any(old, - old_condition, - mt->columns_index_map); + old_condition, + row_type == OVSDB_MONITOR_ROW ? + mt->columns_index_map : + NULL); bool new_cond = !new ? false : ovsdb_condition_empty_or_match_any(new, - new_condition, - mt->columns_index_map); + new_condition, + row_type == OVSDB_MONITOR_ROW ? + mt->columns_index_map : + NULL); if (!old_cond && !new_cond) { type = OJMS_NONE; @@ -719,7 +795,9 @@ ovsdb_monitor_row_update_type_condition( static bool ovsdb_monitor_row_skip_update(const struct ovsdb_monitor_table *mt, - const struct ovsdb_monitor_row *row, + enum ovsdb_monitor_row_type row_type, + const struct ovsdb_datum *old, + const struct ovsdb_datum *new, enum ovsdb_monitor_selection type, unsigned long int *changed) { @@ -734,7 +812,8 @@ ovsdb_monitor_row_skip_update(const struct ovsdb_monitor_table *mt, memset(changed, 0, bitmap_n_bytes(mt->n_columns)); for (i = 0; i < mt->n_columns; i++) { const struct ovsdb_column *c = mt->columns[i].column; - if (!ovsdb_datum_equals(&row->old[i], &row->new[i], &c->type)) { + size_t index = row_type == OVSDB_ROW ? c->index : i; + if (!ovsdb_datum_equals(&old[index], &new[index], &c->type)) { bitmap_set1(changed, i); n_changes++; } @@ -762,16 +841,20 @@ static struct json * ovsdb_monitor_compose_row_update( const struct ovsdb_monitor_table *mt, const struct ovsdb_monitor_session_condition *condition OVS_UNUSED, - const struct ovsdb_monitor_row *row, + enum ovsdb_monitor_row_type row_type OVS_UNUSED, + const void *_row, bool initial, unsigned long int *changed) { + const struct ovsdb_monitor_row *row = _row; enum ovsdb_monitor_selection type; struct json *old_json, *new_json; struct json *row_json; size_t i; + ovs_assert(row_type == OVSDB_MONITOR_ROW); type = ovsdb_monitor_row_update_type(initial, row->old, row->new); - if (ovsdb_monitor_row_skip_update(mt, row, type, changed)) { + if (ovsdb_monitor_row_skip_update(mt, row_type, row->old, + row->new, type, changed)) { return NULL; } @@ -815,7 +898,7 @@ ovsdb_monitor_compose_row_update( * 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 "monitor2" request, + * going to be used as part of the initial reply to a "monitor_cond" request, * false if it is going to be used as part of an "update2" notification. * * 'changed' must be a scratch buffer for internal use that is at least @@ -824,16 +907,25 @@ static struct json * ovsdb_monitor_compose_row_update2( const struct ovsdb_monitor_table *mt, const struct ovsdb_monitor_session_condition *condition, - const struct ovsdb_monitor_row *row, + enum ovsdb_monitor_row_type row_type, + const void *_row, bool initial, unsigned long int *changed) { enum ovsdb_monitor_selection type; struct json *row_update2, *diff_json; + const struct ovsdb_datum *old, *new; size_t i; + if (row_type == OVSDB_MONITOR_ROW) { + old = ((const struct ovsdb_monitor_row *)_row)->old;; + new = ((const struct ovsdb_monitor_row *)_row)->new; + } else { + old = new = ((const struct ovsdb_row *)_row)->fields; + } + type = ovsdb_monitor_row_update_type_condition(mt, condition, initial, - row->old, row->new); - if (ovsdb_monitor_row_skip_update(mt, row, type, changed)) { + row_type, old, new); + if (ovsdb_monitor_row_skip_update(mt, row_type, old, new, type, changed)) { return NULL; } @@ -846,7 +938,7 @@ ovsdb_monitor_compose_row_update2( for (i = 0; i < mt->n_monitored_columns; i++) { const struct ovsdb_monitor_column *c = &mt->columns[i]; - + size_t index = row_type == OVSDB_ROW ? c->column->index : i; if (!c->monitored || !(type & c->select)) { /* We don't care about this type of change for this * particular column (but we will care about it for some @@ -861,15 +953,15 @@ ovsdb_monitor_compose_row_update2( continue; } - ovsdb_datum_diff(&diff ,&row->old[i], &row->new[i], + ovsdb_datum_diff(&diff ,&old[index], &new[index], &c->column->type); json_object_put(diff_json, c->column->name, ovsdb_datum_to_json(&diff, &c->column->type)); ovsdb_datum_destroy(&diff, &c->column->type); } else { - if (!ovsdb_datum_is_default(&row->new[i], &c->column->type)) { + if (!ovsdb_datum_is_default(&new[index], &c->column->type)) { json_object_put(diff_json, c->column->name, - ovsdb_datum_to_json(&row->new[i], + ovsdb_datum_to_json(&new[index], &c->column->type)); } } @@ -898,6 +990,29 @@ ovsdb_monitor_max_columns(struct ovsdb_monitor *dbmon) return max_columns; } +static void +ovsdb_monitor_add_json_row(struct json **json, const char *table_name, + struct json **table_json, struct json *row_json, + const struct uuid *row_uuid) +{ + char uuid[UUID_LEN + 1]; + + /* Create JSON object for transaction overall. */ + if (!*json) { + *json = json_object_create(); + } + + /* Create JSON object for transaction on this table. */ + if (!*table_json) { + *table_json = json_object_create(); + json_object_put(*json, table_name, *table_json); + } + + /* Add JSON row to JSON table. */ + snprintf(uuid, sizeof uuid, UUID_FMT, UUID_ARGS(row_uuid)); + json_object_put(*table_json, uuid, row_json); +} + /* Constructs and returns JSON for a object (as described in * RFC 7047) for all the outstanding changes within 'monitor', starting from * 'transaction'. */ @@ -925,29 +1040,61 @@ ovsdb_monitor_compose_update( continue; } - HMAP_FOR_EACH_SAFE (row, next, hmap_node, &changes->rows) { - struct json *row_json; + HMAP_FOR_EACH_SAFE (row, next, hmap_node, &changes->rows) { + struct json *row_json; + row_json = (*row_update)(mt, condition, OVSDB_MONITOR_ROW, row, + initial, changed); + if (row_json) { + ovsdb_monitor_add_json_row(&json, mt->table->schema->name, + &table_json, row_json, + &row->uuid); + } + } + } + free(changed); - row_json = (*row_update)(mt, condition, row, initial, changed); - if (row_json) { - char uuid[UUID_LEN + 1]; + return json; +} - /* Create JSON object for transaction overall. */ - if (!json) { - json = json_object_create(); - } +static struct json* +ovsdb_monitor_compose_cond_change_update( + struct ovsdb_monitor *dbmon, + struct ovsdb_monitor_session_condition *condition) +{ + struct shash_node *node; + struct json *json = NULL; + size_t max_columns = ovsdb_monitor_max_columns(dbmon); + unsigned long int *changed = xmalloc(bitmap_n_bytes(max_columns)); - /* Create JSON object for transaction on this table. */ - if (!table_json) { - table_json = json_object_create(); - json_object_put(json, mt->table->schema->name, table_json); - } + SHASH_FOR_EACH (node, &dbmon->tables) { + struct ovsdb_monitor_table *mt = node->data; + struct ovsdb_row *row; + struct json *table_json = NULL; + struct ovsdb_condition *old_condition, *new_condition; + + if (!ovsdb_monitor_get_table_conditions(mt, + condition, + &old_condition, + &new_condition) || + !ovsdb_condition_cmp_3way(old_condition, new_condition)) { + /* Nothing to update on this table */ + continue; + } + + /* Iterate over all rows in table */ + HMAP_FOR_EACH (row, hmap_node, &mt->table->rows) { + struct json *row_json; - /* Add JSON row to JSON table. */ - snprintf(uuid, sizeof uuid, UUID_FMT, UUID_ARGS(&row->uuid)); - json_object_put(table_json, uuid, row_json); + row_json = ovsdb_monitor_compose_row_update2(mt, condition, + OVSDB_ROW, row, + false, changed); + if (row_json) { + ovsdb_monitor_add_json_row(&json, mt->table->schema->name, + &table_json, row_json, + ovsdb_row_get_uuid(row)); } } + ovsdb_monitor_table_condition_updated(mt, condition); } free(changed); @@ -956,7 +1103,9 @@ ovsdb_monitor_compose_update( /* Returns JSON for a object (as described in RFC 7047) * for all the outstanding changes within 'monitor' that starts from - * '*unflushed' transaction id. + * '*unflushed'. + * If cond_updated is true all rows in the db that match conditions will 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 @@ -964,8 +1113,9 @@ ovsdb_monitor_compose_update( struct json * ovsdb_monitor_get_update( struct ovsdb_monitor *dbmon, - bool initial, uint64_t *unflushed_, - const struct ovsdb_monitor_session_condition *condition, + bool initial, bool cond_updated, + uint64_t *unflushed_, + struct ovsdb_monitor_session_condition *condition, enum ovsdb_monitor_version version) { struct ovsdb_monitor_json_cache_node *cache_node = NULL; @@ -974,9 +1124,11 @@ ovsdb_monitor_get_update( const uint64_t unflushed = *unflushed_; const uint64_t next_unflushed = dbmon->n_transactions + 1; + ovs_assert(cond_updated ? unflushed == next_unflushed : true); + /* Return a clone of cached json if one exists. Otherwise, * generate a new one and add it to the cache. */ - if (!condition || !condition->conditional) { + if (!condition || (!condition->conditional && !cond_updated)) { cache_node = ovsdb_monitor_json_cache_search(dbmon, version, unflushed); } @@ -990,14 +1142,22 @@ ovsdb_monitor_get_update( ovsdb_monitor_compose_row_update); } else { ovs_assert(version == OVSDB_MONITOR_V2); - json = - ovsdb_monitor_compose_update(dbmon, initial, unflushed, - condition, - ovsdb_monitor_compose_row_update2); - } - if (!condition || !condition->conditional) { - ovsdb_monitor_json_cache_insert(dbmon, version, unflushed, json); - } + if (!cond_updated) { + json = ovsdb_monitor_compose_update(dbmon, initial, unflushed, + condition, + ovsdb_monitor_compose_row_update2); + + if (!condition || !condition->conditional) { + ovsdb_monitor_json_cache_insert(dbmon, version, unflushed, + json); + } + } else { + /* Compose update on whole db due to condition update. + Session must be flushed (change list is empty)*/ + json = + ovsdb_monitor_compose_cond_change_update(dbmon, condition); + } + } } /* Maintain transaction id of 'changes'. */ @@ -1187,10 +1347,8 @@ ovsdb_monitor_change_cb(const struct ovsdb_row *old, void ovsdb_monitor_get_initial(const struct ovsdb_monitor *dbmon) { - struct ovsdb_monitor_aux aux; struct shash_node *node; - ovsdb_monitor_init_aux(&aux, dbmon); SHASH_FOR_EACH (node, &dbmon->tables) { struct ovsdb_monitor_table *mt = node->data; diff --git a/ovsdb/monitor.h b/ovsdb/monitor.h index a5495a431..21f27c621 100644 --- a/ovsdb/monitor.h +++ b/ovsdb/monitor.h @@ -56,17 +56,20 @@ void ovsdb_monitor_add_table(struct ovsdb_monitor *m, const struct ovsdb_table *table); const char * ovsdb_monitor_add_column(struct ovsdb_monitor *dbmon, - const struct ovsdb_table *table, - const struct ovsdb_column *column, - enum ovsdb_monitor_selection select, - bool monitored); - -struct json *ovsdb_monitor_get_update( - struct ovsdb_monitor *dbmon, - bool initial, - uint64_t *unflushed_transaction, - const struct ovsdb_monitor_session_condition *condition, - enum ovsdb_monitor_version version); + const struct ovsdb_table *table, + const struct ovsdb_column *column, + enum ovsdb_monitor_selection select, + bool monitored); +bool +ovsdb_monitor_table_exists(struct ovsdb_monitor *m, + const struct ovsdb_table *table); + +struct json *ovsdb_monitor_get_update(struct ovsdb_monitor *dbmon, + bool initial, + bool cond_updated, + uint64_t *unflushed_transaction, + struct ovsdb_monitor_session_condition *condition, + enum ovsdb_monitor_version version); void ovsdb_monitor_table_add_select(struct ovsdb_monitor *dbmon, const struct ovsdb_table *table, @@ -95,4 +98,11 @@ void ovsdb_monitor_condition_bind(struct ovsdb_monitor *dbmon, struct ovsdb_monitor_session_condition *cond); +struct ovsdb_error * +ovsdb_monitor_table_condition_update( + struct ovsdb_monitor *dbmon, + struct ovsdb_monitor_session_condition *condition, + const struct ovsdb_table *table, + const struct json *cond_json); + #endif diff --git a/ovsdb/ovsdb-server.1.in b/ovsdb/ovsdb-server.1.in index 1d8fff78f..37ec68da3 100644 --- a/ovsdb/ovsdb-server.1.in +++ b/ovsdb/ovsdb-server.1.in @@ -258,7 +258,7 @@ active monitors. \fBovsdb\-server\fR rejects attempt to create two monitors with the same identifier. . .IP "4.1.12. Monitor_cond" -A new monitor method added in Open vSwitch version 2.5. The monitor_cond +A new monitor method added in Open vSwitch version 2.6. The monitor_cond request enables a client to replicate subsets of tables within an OVSDB database by requesting notifications of changes to rows matching one of the conditions specified in "where" by receiving the specified contents @@ -389,6 +389,78 @@ Both monitor and monitor_cond sessions can exist concurrently. However, monitor and monitor_cond shares the same parameter space; it must be unique among all monitor and monitor_cond sessions. . +.IP "4.1.13. Monitor_cond_change" +The "monitor_cond_change" request enables a client to change an existing +"monitor_cond" replication of the database by specifying a new condition +and columns for each replicated table. Currently changing the columns set +is not supported. +. +.IP +The request object has the following members: +. +.IP +.RS +.nf +"method": "monitor_cond_change" +"params": [, , ] +"id": +.fi +.RE +. +.IP +The parameter should have a value of an existing conditional +monitoring session from this client. The second in params array +is the requested value for this session. This value is valid only after +"monitor_cond_change" is committed. A user can use these values to distinguish +between update messages before conditions update and after. The + object maps the name of the table to an array of +. +. +.IP +Each is an object with the following members: +. +.IP +.RS +.nf +"columns": [*] optional +"where": [*] optional +.fi +.RE +. +.IP +The "columns" specify a new array of columns to be monitored +(Currently unsupported). +. +.IP +The "where" specify a new array of conditions to be applied to this monitoring +session. +. +.IP +The response object has the following members: +. +.IP +.RS +.nf +"result": null +"error": null +"id": same "id" as request +.fi +.RE +.IP +Subsequent notifications are described in detail in Section +4.1.14 in the RFC. If insert contents are requested by original monitor_cond +request, will contain rows that match the new condition and +do not match the old condition. +If deleted contents are requested by origin monitor request, +will contain any matched rows by old condition and not matched by the new +condition. +. +.IP +Changes according to the new conditions are automatically sent to the client +using the "update2" monitor notification. An update, if any, as a result of a +condition change, will be sent to the client before the reply to the +"monitor_cond_change" request. +. .IP "4.1.14. Update2 notification" The "update2" notification is sent by the server to the client to report changes in tables that are being monitored following a "monitor_cond" request