On 3 Dec 2025, at 12:01, Ilya Maximets wrote:

> The message about conflicting rows is trying to order the two rows
> in a consistent manner, so the log messages do not change in tests.
> But it fails to do so, because the order of columns in the column
> set depends on the order of columns inside the hash map, which
> depends on the hash function and the internal implementation details
> of the hash map.  This results in random test failures, when two
> rows end up in the opposite order.
>
> Uncovered while testing a different hash map implementation, but the
> failure is technically possible even without any changes in the code,
> e.g., by running on a different CPU architecture or with different
> compiler flags.
>
> Fix that by introducing a new function that constructs the column
> set with columns in a predictable order and without UUID columns that
> have random values in most cases and so not actually comparable.

Thanks, Ilya.

The patch looks good to me. I reviewed the code, and OVSDB_TYPE_UUID is not 
used for indexing.

Acked-by: Eelco Chaudron [email protected]

>
> Fixes: 6910a6e6f25f ("ovsdb: Implement table uniqueness constraints 
> ("indexes").")
> Reported-by: Rosemarie O'Riorden <[email protected]>
> Signed-off-by: Ilya Maximets <[email protected]>
> ---
>  ovsdb/column.c      | 19 +++++++++++++++++++
>  ovsdb/column.h      |  2 ++
>  ovsdb/transaction.c |  2 +-
>  3 files changed, 22 insertions(+), 1 deletion(-)
>
> diff --git a/ovsdb/column.c b/ovsdb/column.c
> index f4dc5bea6..a261cb61a 100644
> --- a/ovsdb/column.c
> +++ b/ovsdb/column.c
> @@ -257,6 +257,25 @@ ovsdb_column_set_add_all(struct ovsdb_column_set *set,
>      }
>  }
>
> +void
> +ovsdb_column_set_add_all_comparable(struct ovsdb_column_set *set,
> +                                    const struct ovsdb_table *table)
> +{
> +    const struct shash_node **nodes = shash_sort(&table->schema->columns);
> +    size_t i, n = shash_count(&table->schema->columns);
> +
> +    for (i = 0; i < n; i++) {
> +        const struct ovsdb_column *column = nodes[i]->data;
> +
> +        /* UUIDs would cause a random order if used for comparison. */
> +        if (column->type.key.type != OVSDB_TYPE_UUID
> +            && column->type.value.type != OVSDB_TYPE_UUID) {
> +            ovsdb_column_set_add(set, column);
> +        }
> +    }
> +    free(nodes);
> +}
> +
>  bool
>  ovsdb_column_set_contains(const struct ovsdb_column_set *set,
>                            unsigned int column_index)
> diff --git a/ovsdb/column.h b/ovsdb/column.h
> index f75a1076d..bae62567f 100644
> --- a/ovsdb/column.h
> +++ b/ovsdb/column.h
> @@ -79,6 +79,8 @@ void ovsdb_column_set_add(struct ovsdb_column_set *,
>                            const struct ovsdb_column *);
>  void ovsdb_column_set_add_all(struct ovsdb_column_set *,
>                                const struct ovsdb_table *);
> +void ovsdb_column_set_add_all_comparable(struct ovsdb_column_set *,
> +                                         const struct ovsdb_table *);
>  bool ovsdb_column_set_contains(const struct ovsdb_column_set *,
>                                 unsigned int column_index);
>  bool ovsdb_column_set_equals(const struct ovsdb_column_set *,
> diff --git a/ovsdb/transaction.c b/ovsdb/transaction.c
> index d16f4daa3..0d0d27b61 100644
> --- a/ovsdb/transaction.c
> +++ b/ovsdb/transaction.c
> @@ -924,7 +924,7 @@ duplicate_index_row(const struct ovsdb_column_set *index,
>      /* Put 'a' and 'b' in a predictable order to make error messages
>       * reproducible for testing. */
>      ovsdb_column_set_init(&all_columns);
> -    ovsdb_column_set_add_all(&all_columns, a->table);
> +    ovsdb_column_set_add_all_comparable(&all_columns, a->table);
>      if (ovsdb_row_compare_columns_3way(a, b, &all_columns) < 0) {
>          const struct ovsdb_row *tmp = a;
>          a = b;
> -- 
> 2.51.1
>
> _______________________________________________
> dev mailing list
> [email protected]
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev

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

Reply via email to