From: Ben Pfaff Date: Wed, 3 Mar 2010 17:59:47 +0000 (-0800) Subject: ovsdb-idl: Fix iteration over rows in IDL tables. X-Git-Tag: v1.0.0~259^2~59 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=f2ba3c0a425ba0745cd2640d38dc7e816333d1c6;p=sliver-openvswitch.git ovsdb-idl: Fix iteration over rows in IDL tables. The IDL was returning rows that had existed in the database and were deleted by the current transaction (that is, row->old && !row->new). This commit fixes the problem. The condition used by next_real_row() was just blatantly wrong and illogical. The correct condition is row->new != NULL. The old condition only got one case wrong (the one mentioned above), even though it didn't make much sense. This fixes an ovs-vsctl call that assert-failed in a "set" command that iterated through a table from which a previous ovs-vsctl command (in the same invocation) had deleted a row. --- diff --git a/lib/ovsdb-idl.c b/lib/ovsdb-idl.c index 4826d62ed..cc9deac91 100644 --- a/lib/ovsdb-idl.c +++ b/lib/ovsdb-idl.c @@ -545,6 +545,26 @@ static bool ovsdb_idl_row_is_orphan(const struct ovsdb_idl_row *row) { return !row->old; +/* Returns true if 'row' is conceptually part of the database as modified by + * the current transaction (if any), false otherwise. + * + * This function will return true if 'row' is not an orphan (see the comment on + * ovsdb_idl_row_is_orphan()) and: + * + * - 'row' exists in the database and has not been deleted within the + * current transaction (if any). + * + * - 'row' was inserted within the current transaction and has not been + * deleted. (In the latter case you should not have passed 'row' in at + * all, because ovsdb_idl_txn_delete() freed it.) + * + * This function will return false if 'row' is an orphan or if 'row' was + * deleted within the current transaction. + */ +static bool +ovsdb_idl_row_exists(const struct ovsdb_idl_row *row) +{ + return row->new != NULL; } static void @@ -810,7 +830,7 @@ next_real_row(struct ovsdb_idl_table *table, struct hmap_node *node) struct ovsdb_idl_row *row; row = CONTAINER_OF(node, struct ovsdb_idl_row, hmap_node); - if (row->new || !ovsdb_idl_row_is_orphan(row)) { + if (ovsdb_idl_row_exists(row)) { return row; } }