@@ -3082,6 +3082,16 @@ ovsdb_idl_txn_commit(struct ovsdb_idl_txn *txn)
HMAP_FOR_EACH (row, txn_node, &txn->txn_rows) {
const struct ovsdb_idl_table_class *class = row->table->class_;
+ if (!row->table->in_server_schema) {
+ /* The table is not present in the server schema. Do not
+ * include it in the transaction. */
+ static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1);
+ VLOG_WARN_RL(&rl, "%s database lacks %s table, excluding from "
+ "the txn.", row->table->idl->class_->database,
+ row->table->class_->name);
+ continue;
+ }
+
if (!row->new_datum) {
if (class->is_root) {
struct json *op = json_object_create();
@@ -3380,6 +3390,12 @@ ovsdb_idl_txn_write__(const struct ovsdb_idl_row *row_,
}
class = row->table->class_;
+
+ if (!ovsdb_idl_has_column_in_table(row->table->idl, class->name,
+ column->name)) {
+ goto discard_datum;
+ }
+
column_idx = column - class->columns;
write_only = row->table->modes[column_idx] == OVSDB_IDL_MONITOR;
@@ -210,6 +210,15 @@
},
"isRoot": true
},
+ "simple7" : {
+ "columns" : {
+ "name" : {
+ "type": "string"
+ },
+ "id": {"type": "string"}
+ },
+ "isRoot" : true
+ },
"singleton" : {
"columns" : {
"name" : {
@@ -139,6 +139,13 @@
"type": "string"
}
}
+ },
+ "simple7" : {
+ "columns" : {
+ "name" : {
+ "type": "string"
+ }
+ }
}
}
}
@@ -999,6 +999,7 @@ test-ovsdb|ovsdb_idl|idltest database lacks simple5 table (database needs upgrad
test-ovsdb|ovsdb_idl|idltest database lacks simple6 table (database needs upgrade?)
test-ovsdb|ovsdb_idl|idltest database lacks singleton table (database needs upgrade?)
test-ovsdb|ovsdb_idl|link1 table in idltest database lacks l2 column (database needs upgrade?)
+test-ovsdb|ovsdb_idl|simple7 table in idltest database lacks id column (database needs upgrade?)
])
# Check that ovsdb-idl sent on "monitor" request and that it didn't
@@ -2412,3 +2413,39 @@ column l2 in table link1 is present
OVSDB_SERVER_SHUTDOWN
AT_CLEANUP
+
+AT_SETUP([idl transaction handling of missing tables and columns - C])
+AT_KEYWORDS([ovsdb client idl txn])
+
+# idltest2.ovsschema is the same as idltest.ovsschema, except that
+# few tables and columns are missing. This test checks that idl doesn't
+# include the missing tables and columns in the transactions.
+# idl-missing-table-column-txn inserts
+# - a row for table - 'simple'
+# - a row for table - 'simple5' which is missing. This should not be
+# included in the transaction.
+# - a row for table - 'simple7 with the missing column 'id'.
+
+AT_CHECK([ovsdb_start_idltest "" "$abs_srcdir/idltest2.ovsschema"])
+AT_CHECK([test-ovsdb '-vPATTERN:console:test-ovsdb|%c|%m' -vjsonrpc -t10 idl-missing-table-column-txn unix:socket],
+ [0], [stdout], [stderr])
+AT_CHECK([sort stdout | uuidfilt], [0],
+ [[000: After inserting simple, simple5 and simple7
+001: table simple7: name=simple7 id= uuid=<0>
+001: table simple: i=0 r=0 b=false s=simple u=<1> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<2>
+002: End test
+]])
+
+AT_CHECK([grep ovsdb_idl stderr | sort], [0], [dnl
+test-ovsdb|ovsdb_idl|idltest database lacks indexed table (database needs upgrade?)
+test-ovsdb|ovsdb_idl|idltest database lacks link2 table (database needs upgrade?)
+test-ovsdb|ovsdb_idl|idltest database lacks simple5 table (database needs upgrade?)
+test-ovsdb|ovsdb_idl|idltest database lacks simple5 table, excluding from the txn.
+test-ovsdb|ovsdb_idl|idltest database lacks simple6 table (database needs upgrade?)
+test-ovsdb|ovsdb_idl|idltest database lacks singleton table (database needs upgrade?)
+test-ovsdb|ovsdb_idl|link1 table in idltest database lacks l2 column (database needs upgrade?)
+test-ovsdb|ovsdb_idl|simple7 table in idltest database lacks id column (database needs upgrade?)
+])
+
+OVSDB_SERVER_SHUTDOWN
+AT_CLEANUP
@@ -2140,6 +2140,17 @@ print_idl_row_simple6(const struct idltest_simple6 *s6, int step)
print_idl_row_updated_simple6(s6, step);
}
+static void
+print_idl_row_simple7(const struct idltest_simple7 *s7, int step)
+{
+ struct ds msg = DS_EMPTY_INITIALIZER;
+ ds_put_format(&msg, "name=%s id=%s", s7->name, s7->id);
+ char *row_msg = format_idl_row(&s7->header_, step, ds_cstr(&msg));
+ print_and_log("%s", row_msg);
+ ds_destroy(&msg);
+ free(row_msg);
+}
+
static void
print_idl_row_singleton(const struct idltest_singleton *sng, int step)
{
@@ -2164,6 +2175,7 @@ print_idl(struct ovsdb_idl *idl, int step)
const struct idltest_link1 *l1;
const struct idltest_link2 *l2;
const struct idltest_singleton *sng;
+ const struct idltest_simple7 *s7;
int n = 0;
IDLTEST_SIMPLE_FOR_EACH (s, idl) {
@@ -2194,6 +2206,10 @@ print_idl(struct ovsdb_idl *idl, int step)
print_idl_row_singleton(sng, step);
n++;
}
+ IDLTEST_SIMPLE7_FOR_EACH (s7, idl) {
+ print_idl_row_simple7(s7, step);
+ n++;
+ }
if (!n) {
print_and_log("%03d: empty", step);
}
@@ -3338,6 +3354,41 @@ do_idl_table_column_check(struct ovs_cmdl_context *ctx)
ovsdb_idl_destroy(idl);
}
+static void
+do_idl_missing_table_column_txn(struct ovs_cmdl_context *ctx)
+{
+ struct ovsdb_idl *idl;
+ struct ovsdb_idl_txn *myTxn;
+ int step = 0;
+
+ idl = ovsdb_idl_create(ctx->argv[1], &idltest_idl_class, true, true);
+
+ ovsdb_idl_get_initial_snapshot(idl);
+
+ ovsdb_idl_run(idl);
+
+ /* Insert a row in simple2. */
+ myTxn = ovsdb_idl_txn_create(idl);
+ struct idltest_simple *simple_row = idltest_simple_insert(myTxn);
+ idltest_simple_set_s(simple_row, "simple");
+
+ /* Insert a row in simple5. simple5 table doesn't exist. */
+ struct idltest_simple5 *simple5_row = idltest_simple5_insert(myTxn);
+ idltest_simple5_set_name(simple5_row, "simple");
+
+ struct idltest_simple7 *simple7_row = idltest_simple7_insert(myTxn);
+ idltest_simple7_set_name(simple7_row, "simple7");
+ idltest_simple7_set_id(simple7_row, "simple7_id");
+
+ ovsdb_idl_txn_commit_block(myTxn);
+ ovsdb_idl_txn_destroy(myTxn);
+ ovsdb_idl_get_initial_snapshot(idl);
+ printf("%03d: After inserting simple, simple5 and simple7\n", step++);
+ print_idl(idl, step++);
+ ovsdb_idl_destroy(idl);
+ printf("%03d: End test\n", step);
+}
+
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 },
@@ -3378,6 +3429,8 @@ static struct ovs_cmdl_command all_commands[] = {
do_idl_partial_update_set_column, OVS_RO },
{ "idl-table-column-check", NULL, 2, INT_MAX,
do_idl_table_column_check, OVS_RO },
+ { "idl-missing-table-column-txn", NULL, 1, INT_MAX,
+ do_idl_missing_table_column_txn, OVS_RO },
{ "help", NULL, 0, INT_MAX, do_help, OVS_RO },
{ NULL, NULL, 0, 0, NULL, OVS_RO },
};