From: Numan Siddique <[email protected]> This patch adds 2 new APIs in the ovsdb-idl client library - ovsdb_idl_has_table() and ovsdb_idl_has_column_in_table() to query if a table and a column is present in the IDL or not. This is required for scenarios where the server schema is old and missing a table or column and the client (built with a new schema version) does a transaction with the missing table or column. This results in a continuous loop of transaction failures.
OVN would require the API - ovsdb_idl_has_table() to address this issue when an old ovsdb-server is used (OVS 2.11) which has the 'datapath' table missing. A recent commit in OVN creates a 'datapath' row in the local ovsdb-server. ovsdb_idl_has_column_in_table() would be useful to have. Related issue: https://bugzilla.redhat.com/show_bug.cgi?id=1992705 Signed-off-by: Numan Siddique <[email protected]> --- lib/ovsdb-idl.c | 25 ++++++++++++++++++ lib/ovsdb-idl.h | 4 +++ tests/ovsdb-idl.at | 17 +++++++++++++ tests/test-ovsdb.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 109 insertions(+) diff --git a/lib/ovsdb-idl.c b/lib/ovsdb-idl.c index 2198c69c6..c5795fb7f 100644 --- a/lib/ovsdb-idl.c +++ b/lib/ovsdb-idl.c @@ -4256,3 +4256,28 @@ ovsdb_idl_loop_commit_and_wait(struct ovsdb_idl_loop *loop) return retval; } + +bool +ovsdb_idl_has_table(struct ovsdb_idl *idl, const char *table_name) +{ + struct ovsdb_idl_table *table = shash_find_data(&idl->table_by_name, + table_name); + return table ? true: false; +} + +bool +ovsdb_idl_has_column_in_table(struct ovsdb_idl *idl, const char *table_name, + const char *column_name) +{ + struct ovsdb_idl_table *table = shash_find_data(&idl->table_by_name, + table_name); + if (!table) { + return false; + } + + if (shash_find_data(&table->columns, column_name)) { + return true; + } + + return false; +} diff --git a/lib/ovsdb-idl.h b/lib/ovsdb-idl.h index d93483245..216db4c6d 100644 --- a/lib/ovsdb-idl.h +++ b/lib/ovsdb-idl.h @@ -474,6 +474,10 @@ void ovsdb_idl_cursor_next_eq(struct ovsdb_idl_cursor *); struct ovsdb_idl_row *ovsdb_idl_cursor_data(struct ovsdb_idl_cursor *); +bool ovsdb_idl_has_table(struct ovsdb_idl *idl, const char *table_name); +bool ovsdb_idl_has_column_in_table(struct ovsdb_idl *idl, + const char *table_name, + const char *column_name); #ifdef __cplusplus } #endif diff --git a/tests/ovsdb-idl.at b/tests/ovsdb-idl.at index 1386f1377..c1464095d 100644 --- a/tests/ovsdb-idl.at +++ b/tests/ovsdb-idl.at @@ -2372,3 +2372,20 @@ OVSDB_CHECK_CLUSTER_IDL([simple idl, initially empty, force reconnect], [], [], reconnect.*waiting .* seconds before reconnect) + +AT_SETUP([idl table and column presence check]) +AT_KEYWORDS([ovsdb server idl table column check]) +AT_CHECK([ovsdb_start_idltest]) + +AT_CHECK([test-ovsdb -vconsole:off -t10 idl-table-column-check unix:socket simple5 foo bar simple5:irefmap simple5:foo foo:foocol], + [0], [dnl +table simple5 is present +table foo is not present +table bar is not present +column irefmap in table simple5 is present +column foo in table simple5 is not present +table foo is not present +]) + +OVSDB_SERVER_SHUTDOWN +AT_CLEANUP diff --git a/tests/test-ovsdb.c b/tests/test-ovsdb.c index daa55dab7..6b94f7fb5 100644 --- a/tests/test-ovsdb.c +++ b/tests/test-ovsdb.c @@ -3268,6 +3268,67 @@ do_idl_compound_index(struct ovs_cmdl_context *ctx) printf("%03d: done\n", step); } +static void +do_idl_table_column_check(struct ovs_cmdl_context *ctx) +{ + struct jsonrpc *rpc; + struct ovsdb_idl *idl; + unsigned int seqno = 0; + int error; + int i; + + if (ctx->argc < 3) { + exit(1); + } + + idl = ovsdb_idl_create(ctx->argv[1], &idltest_idl_class, true, true); + ovsdb_idl_set_leader_only(idl, false); + struct stream *stream; + + error = stream_open_block(jsonrpc_stream_open(ctx->argv[1], &stream, + DSCP_DEFAULT), -1, &stream); + if (error) { + ovs_fatal(error, "failed to connect to \"%s\"", ctx->argv[1]); + } + rpc = jsonrpc_open(stream); + + /* Wait for update. */ + for (;;) { + ovsdb_idl_run(idl); + ovsdb_idl_check_consistency(idl); + if (ovsdb_idl_get_seqno(idl) != seqno) { + break; + } + jsonrpc_run(rpc); + + ovsdb_idl_wait(idl); + jsonrpc_wait(rpc); + poll_block(); + } + + for (i = 2; i < ctx->argc; i++) { + char *save_ptr2 = NULL; + char *table_name = strtok_r(ctx->argv[i], ":", &save_ptr2); + char *column_name = strtok_r(NULL, ":", &save_ptr2); + + bool table_present = ovsdb_idl_has_table(idl, table_name) ; + if (!table_present || !column_name) { + printf("table %s %s present\n", table_name, + table_present ? "is" : "is not"); + } + if (table_present && column_name) { + printf("column %s in table %s %s present\n", column_name, + table_name, + ovsdb_idl_has_column_in_table(idl, table_name, + column_name) ? + "is" : "is not"); + } + } + + jsonrpc_close(rpc); + ovsdb_idl_destroy(idl); +} + static struct ovs_cmdl_command all_commands[] = { { "log-io", NULL, 2, INT_MAX, do_log_io, OVS_RO }, { "default-atoms", NULL, 0, 0, do_default_atoms, OVS_RO }, @@ -3306,6 +3367,8 @@ static struct ovs_cmdl_command all_commands[] = { do_idl_partial_update_map_column, OVS_RO }, { "idl-partial-update-set-column", NULL, 1, INT_MAX, do_idl_partial_update_set_column, OVS_RO }, + { "idl-table-column-check", NULL, 1, INT_MAX, + do_idl_table_column_check, OVS_RO }, { "help", NULL, 0, INT_MAX, do_help, OVS_RO }, { NULL, NULL, 0, 0, NULL, OVS_RO }, }; -- 2.31.1 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
