Andy Zhou <az...@ovn.org> wrote on 05/02/2016 10:47:48 AM: > > Only a few small comments in line. > > On Wed, Feb 3, 2016 at 5:53 AM, Liran Schour <lir...@il.ibm.com> wrote: > Hold session's conditions in ovsdb_monitor_session_condition. Pass it > to ovsdb_monitor for generating "update2" notifications. > Add functions that can generate "update2" notification for a > "monitor_cond" session. > json_cache is enabled only for session's with nulled or empty condition. > "monitor_cond" and "monitor_cond_change" are RFC 7047 extensions > described by ovsdb-server(1) manpage. > > Signed-off-by: Liran Schour <lir...@il.ibm.com> > > --- > v2->v3: > * Document monitor_cond_update receives a single json condition > * Pass session's condition down to row_update function > * Do not classify modify as delete or insert since we send update > due to cond_update with empty changes list > * Allow conditions with non-monitored columns > * Bug fix: allow json cache when session's condition is NULL > * Bug fix: allow json cahce when all table's conditions are empty > --- > ovsdb/condition.c | 21 ++++ > ovsdb/condition.h | 4 + > ovsdb/jsonrpc-server.c | 37 ++++++- > ovsdb/monitor.c | 261 +++++++++++++++++++++++++++++++++++++ > +++++++---- > ovsdb/monitor.h | 40 +++++++- > ovsdb/ovsdb-server.1.in | 230 +++++++++++++++++++++++++++++++++++++++--- > 6 files changed, 551 insertions(+), 42 deletions(-) > > diff --git a/ovsdb/condition.c b/ovsdb/condition.c > index 7321640..5edee5b 100644 > --- a/ovsdb/condition.c > +++ b/ovsdb/condition.c > @@ -444,3 +444,24 @@ ovsdb_condition_clone(struct ovsdb_condition *to, > } > to->n_clauses = from->n_clauses; > } > + > +const struct ovsdb_column ** > +ovsdb_condition_get_columns(const struct ovsdb_condition *cond, > + size_t *n_columns) > +{ > + const struct ovsdb_column **columns; > + size_t i; > + > + if (!cond->n_clauses) { > + *n_columns = 0; > + return NULL; > + } > + > + columns = xmalloc(cond->n_clauses * sizeof *columns); > + for (i = 0; i < cond->n_clauses; i++) { > + columns[i] = cond->clauses[i].column; > + } > + *n_columns = i; > + > + return columns; > +} > diff --git a/ovsdb/condition.h b/ovsdb/condition.h > index 318efba..e65b8c3 100644 > --- a/ovsdb/condition.h > +++ b/ovsdb/condition.h > @@ -82,4 +82,8 @@ int ovsdb_condition_cmp(const struct ovsdb_condition *a, > void ovsdb_condition_clone(struct ovsdb_condition *to, > const struct ovsdb_condition *from); > > +const struct ovsdb_column ** > +ovsdb_condition_get_columns(const struct ovsdb_condition *cond, > + size_t *n_columns); > + > #endif /* ovsdb/condition.h */ > diff --git a/ovsdb/jsonrpc-server.c b/ovsdb/jsonrpc-server.c > index fcda8dc..fa5d5c4 100644 > --- a/ovsdb/jsonrpc-server.c > +++ b/ovsdb/jsonrpc-server.c > @@ -28,6 +28,7 @@ > #include "ovsdb-error.h" > #include "ovsdb-parser.h" > #include "ovsdb.h" > +#include "condition.h" > #include "poll-loop.h" > #include "reconnect.h" > #include "row.h" > @@ -849,14 +850,16 @@ ovsdb_jsonrpc_session_got_request(struct > ovsdb_jsonrpc_session *s, > reply = execute_transaction(s, db, request); > } > } else if (!strcmp(request->method, "monitor") || > - (monitor2_enable__ && !strcmp(request->method, "monitor2"))) { > + (monitor2_enable__ && !strcmp(request->method, "monitor2")) || > + !strcmp(request->method, "monitor_cond")) { > struct ovsdb *db = ovsdb_jsonrpc_lookup_db(s, request, &reply); > if (!reply) { > int l = strlen(request->method) - strlen("monitor"); > enum ovsdb_monitor_version version = l ? OVSDB_MONITOR_V2 > : OVSDB_MONITOR_V1; > reply = ovsdb_jsonrpc_monitor_create(s, db, request->params, > - version, request->id); > + version, > + request->id); > Is this change intentional? >
No. Will remove it. } > } else if (!strcmp(request->method, "monitor_cancel")) { > reply = ovsdb_jsonrpc_monitor_cancel(s, json_array(request->params), > @@ -1048,6 +1051,7 @@ struct ovsdb_jsonrpc_monitor { > uint64_t unflushed; /* The first transaction that has not been > flushed to the jsonrpc > remote client. */ > enum ovsdb_monitor_version version; > + struct ovsdb_monitor_session_condition *condition;/* Session's > condition */ > }; > > static struct ovsdb_jsonrpc_monitor * > @@ -1077,18 +1081,24 @@ parse_bool(struct ovsdb_parser *parser, > const char *name, bool default_value) > static struct ovsdb_error * OVS_WARN_UNUSED_RESULT > ovsdb_jsonrpc_parse_monitor_request(struct ovsdb_monitor *dbmon, > const struct ovsdb_table *table, > + struct > ovsdb_monitor_session_condition *cond, > const struct json *monitor_request) > { > const struct ovsdb_table_schema *ts = table->schema; > enum ovsdb_monitor_selection select; > - const struct json *columns, *select_json; > + const struct json *columns, *select_json, *where = NULL; > struct ovsdb_parser parser; > struct ovsdb_error *error; > > ovsdb_parser_init(&parser, monitor_request, "table %s", ts->name); > + if (cond) { > + where = ovsdb_parser_member(&parser, "where", OP_ARRAY | > OP_OPTIONAL); > + } > columns = ovsdb_parser_member(&parser, "columns", OP_ARRAY | > OP_OPTIONAL); > + > select_json = ovsdb_parser_member(&parser, "select", > OP_OBJECT | OP_OPTIONAL); > + > error = ovsdb_parser_finish(&parser); > if (error) { > return error; > @@ -1155,6 +1165,12 @@ ovsdb_jsonrpc_parse_monitor_request(struct > ovsdb_monitor *dbmon, > } > } > } > + if (cond) { > + error = ovsdb_monitor_table_condition_add(cond, table, where); > + if (error) { > + return error; > + } > + } > > return NULL; > } > @@ -1193,6 +1209,9 @@ ovsdb_jsonrpc_monitor_create(struct > ovsdb_jsonrpc_session *s, struct ovsdb *db, > m->session = s; > m->db = db; > m->dbmon = ovsdb_monitor_create(db, m); > + if (version == OVSDB_MONITOR_V2) { > + m->condition = ovsdb_monitor_session_condition_create(); > + } > m->unflushed = 0; > m->version = version; > hmap_insert(&s->monitors, &m->node, json_hash(monitor_id, 0)); > @@ -1221,6 +1240,7 @@ ovsdb_jsonrpc_monitor_create(struct > ovsdb_jsonrpc_session *s, struct ovsdb *db, > for (i = 0; i < array->n; i++) { > error = ovsdb_jsonrpc_parse_monitor_request(m->dbmon, > table, > + m->condition, > array->elems[i]); > if (error) { > goto error; > @@ -1229,6 +1249,7 @@ ovsdb_jsonrpc_monitor_create(struct > ovsdb_jsonrpc_session *s, struct ovsdb *db, > } else { > error = ovsdb_jsonrpc_parse_monitor_request(m->dbmon, > table, > + m->condition, > mr_value); > if (error) { > goto error; > @@ -1253,6 +1274,11 @@ ovsdb_jsonrpc_monitor_create(struct > ovsdb_jsonrpc_session *s, struct ovsdb *db, > m->dbmon = dbmon; > } > > + /* We only add conditions columns here to simplify ovsdb_monitor_add */ > + if (m->condition) { > + ovsdb_monitor_add_all_condition_columns(m->dbmon, m->condition); > + } > + > ovsdb_monitor_get_initial(m->dbmon); > json = ovsdb_jsonrpc_monitor_compose_update(m, true); > json = json ? json : json_object_create(); > @@ -1305,7 +1331,7 @@ ovsdb_jsonrpc_monitor_compose_update(struct > ovsdb_jsonrpc_monitor *m, > bool initial) > { > return ovsdb_monitor_get_update(m->dbmon, initial, &m->unflushed, > - m->version); > + m->condition, m->version); > } > > static bool > @@ -1328,6 +1354,9 @@ ovsdb_jsonrpc_monitor_destroy(struct > ovsdb_jsonrpc_monitor *m) > json_destroy(m->monitor_id); > hmap_remove(&m->session->monitors, &m->node); > ovsdb_monitor_remove_jsonrpc_monitor(m->dbmon, m); > + if (m->condition) { > + ovsdb_monitor_session_condition_destroy(m->condition); > + } > free(m); > } > > diff --git a/ovsdb/monitor.c b/ovsdb/monitor.c > index 7802560..1614d67 100644 > --- a/ovsdb/monitor.c > +++ b/ovsdb/monitor.c > @@ -27,6 +27,7 @@ > #include "ovsdb-parser.h" > #include "ovsdb.h" > #include "row.h" > +#include "condition.h" > #include "simap.h" > #include "hash.h" > #include "table.h" > @@ -41,6 +42,20 @@ > static const struct ovsdb_replica_class ovsdb_jsonrpc_replica_class; > static struct hmap ovsdb_monitors = HMAP_INITIALIZER(&ovsdb_monitors); > > +/* Keep state of session's conditions */ > +struct ovsdb_monitor_session_condition { > + size_t n_empty_cnd; > + struct shash tables; /* Contains > + * "struct > ovsdb_monitor_table_condition *"s. */ > +}; > + > +/* Monitored table session's conditions */ > +struct ovsdb_monitor_table_condition { > + const struct ovsdb_table *table; > + struct ovsdb_condition old_condition; > + struct ovsdb_condition new_condition; > +}; > + > /* Backend monitor. > * > * ovsdb_monitor keep track of the ovsdb changes. > @@ -108,6 +123,7 @@ struct ovsdb_monitor_changes { > /* A particular table being monitored. */ > struct ovsdb_monitor_table { > const struct ovsdb_table *table; > + const struct ovsdb_monitor *dbmon; > > /* This is the union (bitwise-OR) of the 'select' values in all of the > * members of 'columns' below. */ > @@ -129,9 +145,11 @@ struct ovsdb_monitor_table { > }; > > typedef struct json * > -(*compose_row_update_cb_func)(const struct ovsdb_monitor_table *mt, > - const struct ovsdb_monitor_row *row, > - bool initial, unsigned long int *changed); > +(*compose_row_update_cb_func) > + (const struct ovsdb_monitor_table *mt, > + const struct ovsdb_monitor_session_condition * condition, > + const struct ovsdb_monitor_row *row, > + bool initial, unsigned long int *changed); > > static void ovsdb_monitor_destroy(struct ovsdb_monitor *dbmon); > static struct ovsdb_monitor_changes * ovsdb_monitor_table_add_changes( > @@ -372,6 +390,7 @@ ovsdb_monitor_add_table(struct ovsdb_monitor *m, > > mt = xzalloc(sizeof *mt); > mt->table = table; > + mt->dbmon = m; > shash_add(&m->tables, table->schema->name, mt); > hmap_init(&mt->changes); > mt->columns_index_map = > @@ -390,9 +409,20 @@ ovsdb_monitor_add_column(struct ovsdb_monitor *dbmon, > { > struct ovsdb_monitor_table *mt; > struct ovsdb_monitor_column *c; > + int i; > > mt = shash_find_data(&dbmon->tables, table->schema->name); > > + /* Check duplication only for non-monitored columns */ > + if (!monitored) { > + for (i = 0; i < mt->n_columns; i++) { > + if (mt->columns[i].column == column) { > + /* column exists */ > + return; > + } > + } > + } > + > if (mt->n_columns >= mt->allocated_columns) { > mt->columns = x2nrealloc(mt->columns, &mt->allocated_columns, > sizeof *mt->columns); > @@ -409,6 +439,39 @@ ovsdb_monitor_add_column(struct ovsdb_monitor *dbmon, > } > } > > +static void > +ovsdb_monitor_condition_add_columns(struct ovsdb_monitor *dbmon, > + const struct ovsdb_table *table, > + struct ovsdb_condition *condition) > +{ > + size_t n_columns; > + int i; > + const struct ovsdb_column **columns = > + ovsdb_condition_get_columns(condition, &n_columns); > + > + for (i = 0; i < n_columns; i++) { > + ovsdb_monitor_add_column(dbmon, table, columns[i], > + OJMS_NONE, false); > + } > + if (n_columns) { > + free(columns); > + } > +} > + > +void > +ovsdb_monitor_add_all_condition_columns( > + struct ovsdb_monitor *dbmon, > + struct ovsdb_monitor_session_condition *cond) > +{ > + struct shash_node *node; > + > + SHASH_FOR_EACH(node, &cond->tables) { > + struct ovsdb_monitor_table_condition *mtc = node->data; > + > + ovsdb_monitor_condition_add_columns(dbmon, mtc->table, > &mtc->new_condition); > + } > +} > + > /* Check for duplicated column names. Return the first > * duplicated column's name if found. Otherwise return > * NULL. */ > @@ -519,6 +582,153 @@ ovsdb_monitor_row_update_type(bool initial, > const bool old, const bool new) > : !new ? OJMS_DELETE > : OJMS_MODIFY; > } > + > +/* Returnes an empty allocated session's condition state holder */ > +struct ovsdb_monitor_session_condition * > +ovsdb_monitor_session_condition_create(void) > +{ > + struct ovsdb_monitor_session_condition *condition; > + > + condition = xzalloc(sizeof *condition); > + shash_init(&condition->tables); > + > + return condition; > +} > + > +void > +ovsdb_monitor_session_condition_destroy( > + struct ovsdb_monitor_session_condition *condition) > +{ > + struct shash_node *node, *next; > + > + SHASH_FOR_EACH_SAFE (node, next, &condition->tables) { > + struct ovsdb_monitor_table_condition *mtc = node->data; > + > + ovsdb_condition_destroy(&mtc->new_condition); > + ovsdb_condition_destroy(&mtc->old_condition); > + shash_delete(&condition->tables, node); > + free(mtc); > + } > + free(condition); > +} > + > +struct ovsdb_error * > +ovsdb_monitor_table_condition_add( > + struct ovsdb_monitor_session_condition *condition, > + const struct ovsdb_table *table, > + const struct json *json_cnd) > +{ > + struct ovsdb_monitor_table_condition *mtc; > + struct ovsdb_error *error; > + > + mtc = xzalloc(sizeof *mtc); > + shash_add(&condition->tables, table->schema->name, mtc); > + mtc->table = table; > + ovsdb_condition_init(&mtc->old_condition); > + ovsdb_condition_init(&mtc->new_condition); > + > + if (json_cnd) { > + error = ovsdb_condition_from_json(table->schema, > + json_cnd, > + NULL, > + &mtc->old_condition); > + if (error) { > + return ovsdb_syntax_error(json_cnd, > + NULL, "array of conditions expected"); > + } > + } > + ovsdb_condition_clone(&mtc->new_condition, &mtc->old_condition); > + if (ovsdb_condition_empty(&mtc->old_condition)) { > + condition->n_empty_cnd++; > + } > + > + return NULL; > +} > + > +static inline bool > +ovsdb_can_cache(const struct ovsdb_monitor_session_condition *condition) > +{ > + return shash_count(&condition->tables) == condition->n_empty_cnd; > +} > + > +static bool > +ovsdb_monitor_get_table_conditions( > + const struct ovsdb_monitor_table *mt, > + const struct ovsdb_monitor_session_condition > *condition, > + struct ovsdb_condition **old_condition, > + struct ovsdb_condition **new_condition) > +{ > + if (!condition) { > + return false; > + } > + > + struct ovsdb_monitor_table_condition *mtc = > + shash_find_data(&condition->tables, mt->table->schema->name); > + > + if (!mtc) { > + return false; > + } > + *old_condition = &mtc->old_condition; > + *new_condition = &mtc->new_condition; > + > + return true; > +} > + > +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, > + const struct ovsdb_datum *old, > + const struct ovsdb_datum *new, > + const bool index_map) > +{ > + struct ovsdb_condition *old_condition, *new_condition; > + unsigned int *columns_index_map = index_map ? mt->columns_index_map > + : NULL; > + enum ovsdb_monitor_selection type = > + ovsdb_monitor_row_update_type(initial, old, new); > + > + if (ovsdb_monitor_get_table_conditions(mt, > + condition, > + &old_condition, > + &new_condition)) { > + bool old_cond = !old ? false > + : ovsdb_condition_evaluate_or_datum(old, > + old_condition, > + columns_index_map); > + bool new_cond = !new ? false > + : ovsdb_condition_evaluate_or_datum(new, > + new_condition, > + columns_index_map); > + > + if (!old_cond && !new_cond) { > + type = OJMS_NONE; > + } > + > + switch (type) { > + case OJMS_INITIAL: > + case OJMS_INSERT: > + if (!new_cond) { > + type = OJMS_NONE; > + } > + break; > + case OJMS_MODIFY: > + type = !old_cond ? OJMS_INSERT : !new_cond > + ? OJMS_DELETE : OJMS_MODIFY; > + break; > + case OJMS_DELETE: > + if (!old_cond) { > + type = OJMS_NONE; > + } > + break; > + case OJMS_NONE: > + break; > + } > + } > + return type; > +} > + > static bool > ovsdb_monitor_row_skip_update(const struct ovsdb_monitor_table *mt, > const struct ovsdb_monitor_row *row, > @@ -563,6 +773,7 @@ ovsdb_monitor_row_skip_update(const struct > ovsdb_monitor_table *mt, > 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, > bool initial, unsigned long int *changed) > { > @@ -624,6 +835,7 @@ ovsdb_monitor_compose_row_update( > 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, > bool initial, unsigned long int *changed) > { > @@ -631,7 +843,8 @@ ovsdb_monitor_compose_row_update2( > struct json *row_update2, *diff_json; > size_t i; > > - type = ovsdb_monitor_row_update_type(initial, row->old, row->new); > + type = ovsdb_monitor_row_update_type_condition(mt, condition, initial, > + row->old, row->new, true); > if (ovsdb_monitor_row_skip_update(mt, row, type, changed)) { > return NULL; > } > @@ -701,9 +914,11 @@ ovsdb_monitor_max_columns(struct ovsdb_monitor *dbmon) > * RFC 7047) for all the outstanding changes within 'monitor', starting from > * 'transaction'. */ > static struct json* > -ovsdb_monitor_compose_update(struct ovsdb_monitor *dbmon, > - bool initial, uint64_t transaction, > - compose_row_update_cb_func row_update) > +ovsdb_monitor_compose_update( > + struct ovsdb_monitor *dbmon, > + bool initial, uint64_t transaction, > + const struct ovsdb_monitor_session_condition > *condition, > + compose_row_update_cb_func row_update) > { > struct shash_node *node; > struct json *json; > @@ -725,7 +940,7 @@ ovsdb_monitor_compose_update(struct ovsdb_monitor *dbmon, > HMAP_FOR_EACH_SAFE (row, next, hmap_node, &changes->rows) { > struct json *row_json; > > - row_json = (*row_update)(mt, row, initial, changed); > + row_json = (*row_update)(mt, condition, row, initial, changed); > if (row_json) { > char uuid[UUID_LEN + 1]; > > @@ -759,11 +974,13 @@ ovsdb_monitor_compose_update(struct > ovsdb_monitor *dbmon, > * be used as part of the initial reply to a "monitor" request, > false if it is > * going to be used as part of an "update" notification. */ > struct json * > -ovsdb_monitor_get_update(struct ovsdb_monitor *dbmon, > - bool initial, uint64_t *unflushed, > - enum ovsdb_monitor_version version) > +ovsdb_monitor_get_update( > + struct ovsdb_monitor *dbmon, > + bool initial, uint64_t *unflushed, > + const struct ovsdb_monitor_session_condition *condition, > + enum ovsdb_monitor_version version) > { > - struct ovsdb_monitor_json_cache_node *cache_node; > + struct ovsdb_monitor_json_cache_node *cache_node = NULL; > struct shash_node *node; > struct json *json; > uint64_t prev_txn = *unflushed; > @@ -771,19 +988,27 @@ ovsdb_monitor_get_update(struct ovsdb_monitor *dbmon, > > /* Return a clone of cached json if one exists. Otherwise, > * generate a new one and add it to the cache. */ > - cache_node = ovsdb_monitor_json_cache_search(dbmon, version, prev_txn); > + if (!condition || (condition && ovsdb_can_cache(condition))) { > + cache_node = ovsdb_monitor_json_cache_search(dbmon, > version, prev_txn); > + } > if (cache_node) { > json = cache_node->json ? json_clone(cache_node->json) : NULL; > } else { > if (version == OVSDB_MONITOR_V1) { > - json = ovsdb_monitor_compose_update(dbmon, initial, prev_txn, > - ovsdb_monitor_compose_row_update); > + json = > + ovsdb_monitor_compose_update(dbmon, initial, prev_txn, > + condition, > + > ovsdb_monitor_compose_row_update); > } else { > ovs_assert(version == OVSDB_MONITOR_V2); > - json = ovsdb_monitor_compose_update(dbmon, initial, prev_txn, > - ovsdb_monitor_compose_row_update2); > + json = > + ovsdb_monitor_compose_update(dbmon, initial, prev_txn, > + condition, > + > ovsdb_monitor_compose_row_update2); > + } > + if (!condition || (condition && ovsdb_can_cache(condition))) { > + ovsdb_monitor_json_cache_insert(dbmon, version, prev_txn, json); > } > - ovsdb_monitor_json_cache_insert(dbmon, version, prev_txn, json); > } > > /* Maintain transaction id of 'changes'. */ > diff --git a/ovsdb/monitor.h b/ovsdb/monitor.h > index 1f3dc6e..0529e5a 100644 > --- a/ovsdb/monitor.h > +++ b/ovsdb/monitor.h > @@ -19,8 +19,11 @@ > > struct ovsdb_monitor; > struct ovsdb_jsonrpc_monitor; > +struct ovsdb_monitor_session_condition; > +struct ovsdb_condition; > > enum ovsdb_monitor_selection { > + OJMS_NONE = 0, /* None for this iteration */ > OJMS_INITIAL = 1 << 0, /* All rows when monitor is created. */ > OJMS_INSERT = 1 << 1, /* New rows. */ > OJMS_DELETE = 1 << 2, /* Deleted rows. */ > @@ -60,21 +63,50 @@ void ovsdb_monitor_add_column(struct ovsdb_monitor *dbmon, > enum ovsdb_monitor_selection select, > bool monitored); > > +void ovsdb_monitor_add_all_condition_columns(struct ovsdb_monitor *dbmon, > + struct ovsdb_monitor_session_condition *cond); > + > const char * OVS_WARN_UNUSED_RESULT > ovsdb_monitor_table_check_duplicates(struct ovsdb_monitor *, > const struct ovsdb_table *); > > -struct json *ovsdb_monitor_get_update(struct ovsdb_monitor *dbmon, > - bool initial, > - uint64_t *unflushed_transaction, > - enum ovsdb_monitor_version version); > +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); > > void ovsdb_monitor_table_add_select(struct ovsdb_monitor *dbmon, > const struct ovsdb_table *table, > enum ovsdb_monitor_selection select); > > +struct ovsdb_condition * > +ovsdb_monitor_table_get_condition(struct ovsdb_monitor *dbmon, > + const struct ovsdb_table *table); > + > +void ovsdb_monitor_table_set_conditional(struct ovsdb_monitor *dbmon, > + const struct ovsdb_table *table); > + > bool ovsdb_monitor_needs_flush(struct ovsdb_monitor *dbmon, > uint64_t next_transaction); > > void ovsdb_monitor_get_initial(const struct ovsdb_monitor *dbmon); > + > +struct ovsdb_monitor_session_condition * > +ovsdb_monitor_session_condition_create(void); > + > +void > +ovsdb_monitor_session_condition_destroy( > + struct ovsdb_monitor_session_condition *condition); > +struct ovsdb_error * > +ovsdb_monitor_table_condition_add( > + struct ovsdb_monitor_session_condition *condition, > + const struct ovsdb_table *table, > + const struct json *json_cnd); > + > +void ovsdb_monitor_session_condition_bind( > + const struct ovsdb_monitor_session_condition *, > + const struct ovsdb_monitor *); > Is this function defined? No. Will remove this. Thanks. _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev