On Mon, Nov 30, 2020 at 8:41 AM Dumitru Ceara <dce...@redhat.com> wrote:
>
> Considering the following updates processed by an IDL client:
> 1. Delete row R1 from table A while R1 is also referenced by row R2 from
>    table B:
>    - because row R2 still refers to row R1, this will create an orphan
>      R1 but also sets row->tracked_old_datum to report to the IDL client
>      that the row has been deleted.
> 2. Insert row R1 to table A.
>    - because orphan R1 already existed in the IDL, it will be reused.
>    - R1 still has row->tracked_old_datum set (and may also be on the
>      table->track_list).
> 3. Delete row R2 from table B and row R1 from table A.
>    - row->tracked_old_datum is set again but the previous
>      tracked_old_datum was never freed.
>
> IDL clients use the deleted old_datum values so when multiple delete
> operations are received for a row, always track the first one as that
> will match the contents of the row the IDL client knew about.
>
> Running the newly added test case with valgrind, without the fix,
> produces the following report:
>
> ==23113== 327 (240 direct, 87 indirect) bytes in 1 blocks are definitely
lost in loss record 43 of 43
> ==23113==    at 0x4C29F73: malloc (vg_replace_malloc.c:309)
> ==23113==    by 0x476761: xmalloc (util.c:138)
> ==23113==    by 0x45D8B3: ovsdb_idl_insert_row (ovsdb-idl.c:3431)
> ==23113==    by 0x45B7F9: ovsdb_idl_process_update2 (ovsdb-idl.c:2670)
> ==23113==    by 0x45AFCF: ovsdb_idl_db_parse_update__ (ovsdb-idl.c:2479)
> ==23113==    by 0x45B262: ovsdb_idl_db_parse_update (ovsdb-idl.c:2542)
> ==23113==    by 0x45ABBE: ovsdb_idl_db_parse_update_rpc (ovsdb-idl.c:2358)
> ==23113==    by 0x4576DD: ovsdb_idl_process_msg (ovsdb-idl.c:865)
> ==23113==    by 0x457973: ovsdb_idl_run (ovsdb-idl.c:944)
> ==23113==    by 0x40B7B9: do_idl (test-ovsdb.c:2523)
> ==23113==    by 0x44425D: ovs_cmdl_run_command__ (command-line.c:247)
> ==23113==    by 0x44430E: ovs_cmdl_run_command (command-line.c:278)
> ==23113==    by 0x404BA6: main (test-ovsdb.c:76)
>
> Fixes: 72aeb243a52a ("ovsdb-idl: Tracking - preserve data for deleted
rows.")
> Signed-off-by: Dumitru Ceara <dce...@redhat.com>
> ---
>  lib/ovsdb-idl.c    |    2 +-
>  tests/ovsdb-idl.at |   52
++++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 53 insertions(+), 1 deletion(-)
>
> diff --git a/lib/ovsdb-idl.c b/lib/ovsdb-idl.c
> index 23648ff..6afae2d 100644
> --- a/lib/ovsdb-idl.c
> +++ b/lib/ovsdb-idl.c
> @@ -3227,7 +3227,7 @@ ovsdb_idl_row_clear_old(struct ovsdb_idl_row *row)
>  {
>      ovs_assert(row->old_datum == row->new_datum);
>      if (!ovsdb_idl_row_is_orphan(row)) {
> -        if (ovsdb_idl_track_is_set(row->table)) {
> +        if (ovsdb_idl_track_is_set(row->table) &&
!row->tracked_old_datum) {
>              row->tracked_old_datum = row->old_datum;
>          } else {
>              const struct ovsdb_idl_table_class *class =
row->table->class_;
> diff --git a/tests/ovsdb-idl.at b/tests/ovsdb-idl.at
> index 406a576..4b4791a 100644
> --- a/tests/ovsdb-idl.at
> +++ b/tests/ovsdb-idl.at
> @@ -1225,6 +1225,58 @@ OVSDB_CHECK_IDL_TRACK([track, simple idl,
initially populated, orphan weak refer
>  008: done
>  ]])
>
> +dnl This test creates database with weak references and checks that the
> +dnl content of orphaned rows created for weak references after monitor
> +dnl condition change are not leaked when the row is reinserted and
deleted.
> +OVSDB_CHECK_IDL_TRACK([track, simple idl, initially populated, orphan
rows, conditional],
> +  [['["idltest",
> +      {"op": "insert",
> +       "table": "simple",
> +       "row": {"s": "row0_s"},
> +       "uuid-name": "weak_row0"},
> +      {"op": "insert",
> +       "table": "simple",
> +       "row": {"s": "row1_s"},
> +       "uuid-name": "weak_row1"},
> +      {"op": "insert",
> +       "table": "simple6",
> +       "row": {"name": "first_row",
> +               "weak_ref": ["set",
> +                             [["named-uuid", "weak_row0"]]
> +                           ]}}]']],
> +  [['condition simple []' \
> +    'condition simple [["s","==","row0_s"]]' \
> +    'condition simple [["s","==","row1_s"]]' \
> +    'condition simple [["s","==","row0_s"]]' \
> +    '["idltest",
> +      {"op": "delete",
> +      "table": "simple6",
> +      "where": []}]']],
> +  [[000: change conditions
> +001: inserted row: uuid=<0>
> +001: name=first_row weak_ref=[] uuid=<0>
> +001: updated columns: name weak_ref
> +002: change conditions
> +003: i=0 r=0 b=false s=row0_s u=<1> ia=[] ra=[] ba=[] sa=[] ua=[]
uuid=<2>
> +003: inserted row: uuid=<2>
> +003: name=first_row weak_ref=[<2>] uuid=<0>
> +003: updated columns: s
> +004: change conditions
> +005: i=0 r=0 b=false s=row1_s u=<1> ia=[] ra=[] ba=[] sa=[] ua=[]
uuid=<3>
> +005: inserted row: uuid=<3>
> +005: updated columns: s
> +006: change conditions
> +007: deleted row: uuid=<3>
> +007: i=0 r=0 b=false s=row0_s u=<1> ia=[] ra=[] ba=[] sa=[] ua=[]
uuid=<2>
> +007: i=0 r=0 b=false s=row1_s u=<1> ia=[] ra=[] ba=[] sa=[] ua=[]
uuid=<3>
> +007: inserted row: uuid=<2>
> +007: name=first_row weak_ref=[<2>] uuid=<0>
> +007: updated columns: s
> +008: {"error":null,"result":[{"count":1}]}
> +009: i=0 r=0 b=false s=row0_s u=<1> ia=[] ra=[] ba=[] sa=[] ua=[]
uuid=<2>
> +010: done
> +]])
> +
>  OVSDB_CHECK_IDL_TRACK([track, simple idl, initially empty, various ops],
>    [],
>    [['["idltest",
>

Acked-by: Han Zhou <hz...@ovn.org>
_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to