Relay servers apply updates via ovsdb_table_execute_update().  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 triggering a syntax error and a re-connection.

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

Fixes: 026c77c58ddb ("ovsdb: New ovsdb 'relay' service model.")
Signed-off-by: Ilya Maximets <[email protected]>
---
 ovsdb/execution.c  |  4 ++--
 ovsdb/row.c        | 13 ++++++++++---
 ovsdb/row.h        |  3 ++-
 ovsdb/table.c      |  5 +++--
 tests/test-ovsdb.c | 13 +++++++------
 5 files changed, 24 insertions(+), 14 deletions(-)

diff --git a/ovsdb/execution.c b/ovsdb/execution.c
index f9b8067d0..5587ef96f 100644
--- a/ovsdb/execution.c
+++ b/ovsdb/execution.c
@@ -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;
@@ -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;
diff --git a/ovsdb/row.c b/ovsdb/row.c
index d7bfbdd36..2b52b6816 100644
--- a/ovsdb/row.c
+++ b/ovsdb/row.c
@@ -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");
     }
@@ -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;
         }
diff --git a/ovsdb/row.h b/ovsdb/row.h
index ff91288fe..59f498a20 100644
--- a/ovsdb/row.h
+++ b/ovsdb/row.h
@@ -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);
diff --git a/ovsdb/table.c b/ovsdb/table.c
index 66071ce2f..0792e1580 100644
--- a/ovsdb/table.c
+++ b/ovsdb/table.c
@@ -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);
@@ -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),
diff --git a/tests/test-ovsdb.c b/tests/test-ovsdb.c
index 1bc5ac17a..c761822e6 100644
--- a/tests/test-ovsdb.c
+++ b/tests/test-ovsdb.c
@@ -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));
@@ -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++) {
@@ -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);
 
@@ -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);
 
@@ -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)));
@@ -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);
-- 
2.40.1

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to