Skip to content

Commit

Permalink
ovsdb: relay: Fix handling of XOR updates with size constraints.
Browse files Browse the repository at this point in the history
XOR updates contain datum diffs, and datum diffs can be larger than
the type constraints.  Currently, relay will fail to parse such update
into ovsdb row trigerring a syntax error and a re-connection.

Fix that by relaxing the size constraints for this kind of updates.

Fixes: 026c77c ("ovsdb: New ovsdb 'relay' service model.")
Signed-off-by: Ilya Maximets <[email protected]>
  • Loading branch information
igsilya committed Jul 24, 2023
1 parent 8bcae92 commit bf02a19
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 14 deletions.
4 changes: 2 additions & 2 deletions ovsdb/execution.c
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ parse_row(const struct json *json, const struct ovsdb_table *table,
}

row = ovsdb_row_create(table);
error = ovsdb_row_from_json(row, json, symtab, columns);
error = ovsdb_row_from_json(row, json, symtab, columns, false);
if (error) {
ovsdb_row_destroy(row);
return error;
Expand Down Expand Up @@ -764,7 +764,7 @@ ovsdb_execute_wait(struct ovsdb_execution *x, struct ovsdb_parser *parser,

row = ovsdb_row_create(table);
error = ovsdb_row_from_json(row, rows->array.elems[i], x->symtab,
NULL);
NULL, false);
if (error) {
ovsdb_row_destroy(row);
break;
Expand Down
13 changes: 10 additions & 3 deletions ovsdb/row.c
Original file line number Diff line number Diff line change
Expand Up @@ -302,12 +302,14 @@ ovsdb_row_columns_to_string(const struct ovsdb_row *row,
struct ovsdb_error *
ovsdb_row_from_json(struct ovsdb_row *row, const struct json *json,
struct ovsdb_symbol_table *symtab,
struct ovsdb_column_set *included)
struct ovsdb_column_set *included, bool is_diff)
{
struct ovsdb_table_schema *schema = row->table->schema;
struct ovsdb_error *error;
struct shash_node *node;

ovs_assert(!is_diff || !symtab);

if (json->type != JSON_OBJECT) {
return ovsdb_syntax_error(json, NULL, "row must be JSON object");
}
Expand All @@ -324,8 +326,13 @@ ovsdb_row_from_json(struct ovsdb_row *row, const struct json *json,
column_name, schema->name);
}

error = ovsdb_datum_from_json(&datum, &column->type, node->data,
symtab);
if (is_diff) {
error = ovsdb_transient_datum_from_json(&datum, &column->type,
node->data);
} else {
error = ovsdb_datum_from_json(&datum, &column->type, node->data,
symtab);
}
if (error) {
return error;
}
Expand Down
3 changes: 2 additions & 1 deletion ovsdb/row.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,8 @@ void ovsdb_row_columns_to_string(const struct ovsdb_row *,
struct ovsdb_error *ovsdb_row_from_json(struct ovsdb_row *,
const struct json *,
struct ovsdb_symbol_table *,
struct ovsdb_column_set *included)
struct ovsdb_column_set *included,
bool is_diff)
OVS_WARN_UNUSED_RESULT;
struct json *ovsdb_row_to_json(const struct ovsdb_row *,
const struct ovsdb_column_set *include);
Expand Down
5 changes: 3 additions & 2 deletions ovsdb/table.c
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,8 @@ ovsdb_table_execute_insert(struct ovsdb_txn *txn, const struct uuid *row_uuid,

struct ovsdb_row *row = ovsdb_row_create(table);

struct ovsdb_error *error = ovsdb_row_from_json(row, json_row, NULL, NULL);
struct ovsdb_error *error = ovsdb_row_from_json(row, json_row,
NULL, NULL, false);
if (!error) {
*ovsdb_row_get_uuid_rw(row) = *row_uuid;
ovsdb_txn_row_insert(txn, row);
Expand Down Expand Up @@ -411,7 +412,7 @@ ovsdb_table_execute_update(struct ovsdb_txn *txn, const struct uuid *row_uuid,
struct ovsdb_column_set columns = OVSDB_COLUMN_SET_INITIALIZER;
struct ovsdb_row *update = ovsdb_row_create(table);
struct ovsdb_error *error = ovsdb_row_from_json(update, json_row,
NULL, &columns);
NULL, &columns, xor);

if (!error && (xor || !ovsdb_row_equal_columns(row, update, &columns))) {
error = ovsdb_row_update_columns(ovsdb_txn_row_modify(txn, row),
Expand Down
13 changes: 7 additions & 6 deletions tests/test-ovsdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -870,7 +870,8 @@ do_parse_rows(struct ovs_cmdl_context *ctx)
row = ovsdb_row_create(table);

json = unbox_json(parse_json(ctx->argv[i]));
check_ovsdb_error(ovsdb_row_from_json(row, json, NULL, &columns));
check_ovsdb_error(ovsdb_row_from_json(row, json, NULL,
&columns, false));
json_destroy(json);

print_and_free_json(ovsdb_row_to_json(row, &all_columns));
Expand Down Expand Up @@ -937,7 +938,7 @@ do_compare_rows(struct ovs_cmdl_context *ctx)
}
names[i] = xstrdup(json->array.elems[0]->string);
check_ovsdb_error(ovsdb_row_from_json(rows[i], json->array.elems[1],
NULL, NULL));
NULL, NULL, false));
json_destroy(json);
}
for (i = 0; i < n_rows; i++) {
Expand Down Expand Up @@ -1050,7 +1051,7 @@ do_evaluate_condition__(struct ovs_cmdl_context *ctx, int mode)
for (i = 0; i < n_rows; i++) {
rows[i] = ovsdb_row_create(table);
check_ovsdb_error(ovsdb_row_from_json(rows[i], json->array.elems[i],
NULL, NULL));
NULL, NULL, false));
}
json_destroy(json);

Expand Down Expand Up @@ -1224,7 +1225,7 @@ do_execute_mutations(struct ovs_cmdl_context *ctx)
for (i = 0; i < n_rows; i++) {
rows[i] = ovsdb_row_create(table);
check_ovsdb_error(ovsdb_row_from_json(rows[i], json->array.elems[i],
NULL, NULL));
NULL, NULL, false));
}
json_destroy(json);

Expand Down Expand Up @@ -1338,7 +1339,7 @@ do_query(struct ovs_cmdl_context *ctx)
struct ovsdb_row *row = ovsdb_row_create(table);
uuid_generate(ovsdb_row_get_uuid_rw(row));
check_ovsdb_error(ovsdb_row_from_json(row, json->array.elems[i],
NULL, NULL));
NULL, NULL, false));
if (ovsdb_table_get_row(table, ovsdb_row_get_uuid(row))) {
ovs_fatal(0, "duplicate UUID "UUID_FMT" in table",
UUID_ARGS(ovsdb_row_get_uuid(row)));
Expand Down Expand Up @@ -1445,7 +1446,7 @@ do_query_distinct(struct ovs_cmdl_context *ctx)
row = ovsdb_row_create(table);
uuid_generate(ovsdb_row_get_uuid_rw(row));
check_ovsdb_error(ovsdb_row_from_json(row, json->array.elems[i],
NULL, NULL));
NULL, NULL, false));

/* Initialize row and find equivalence class. */
rows[i].uuid = *ovsdb_row_get_uuid(row);
Expand Down

0 comments on commit bf02a19

Please sign in to comment.