ovsdb-idl: Suppress "delete" operations for garbage-collected tables.
authorBen Pfaff <blp@nicira.com>
Tue, 12 Apr 2011 18:31:58 +0000 (11:31 -0700)
committerBen Pfaff <blp@nicira.com>
Tue, 12 Apr 2011 18:31:58 +0000 (11:31 -0700)
Deciding what delete operations to issue on garbage-collected tables has
been a bit of a difficult issue for ovs-vsctl.  When garbage collection was
introduced in commit c5f341a "ovsdb: Implement garbage collection",
ovs-vsctl did not issue any deletions for these tables at all.  As a side
effect, ovs-vsctl did not notice that records were going to be deleted.
That meant that when multiple commands were issued in one ovs-vsctl run,
ovs-vsctl could get confused by apparent duplicate records that did not
in fact exist.  Commit 28a14bf "ovs-vsctl: Back out garbage collection
changes" fixed the problem by putting all of the explicit deletions back
into ovs-vsctl.

However, adding these explicit deletions had the price that it then became
(again) impossible to use ovs-vsctl commands to delete duplicates, for
example to use "ovs-vsctl del-br" to delete a bridge that points to the
same Port records that some other Bridge record also does.  This commit
makes that possible again, by implementing a compromise:

    * Internally, ovs-vsctl deletes the records that it believes should be
      deleted.

    * ovsdb-idl suppresses the deletions when it makes the RPC call into
      the database server.

Bug #5358.
Reported-by: Henrik Amren <henrik@nicira.com>
lib/ovsdb-idl.c
utilities/ovs-vsctl.8.in

index 911d7b8860ebefc0bb0e2c70fe2eac67a17d9c29..e1b53f4eb3730de0aaf3ec3f1153722d20847d17 100644 (file)
@@ -1397,12 +1397,16 @@ ovsdb_idl_txn_commit(struct ovsdb_idl_txn *txn)
         if (row->old == row->new) {
             continue;
         } else if (!row->new) {
-            struct json *op = json_object_create();
-            json_object_put_string(op, "op", "delete");
-            json_object_put_string(op, "table", class->name);
-            json_object_put(op, "where", where_uuid_equals(&row->uuid));
-            json_array_add(operations, op);
-            any_updates = true;
+            if (class->is_root) {
+                struct json *op = json_object_create();
+                json_object_put_string(op, "op", "delete");
+                json_object_put_string(op, "table", class->name);
+                json_object_put(op, "where", where_uuid_equals(&row->uuid));
+                json_array_add(operations, op);
+                any_updates = true;
+            } else {
+                /* Let ovsdb-server decide whether to really delete it. */
+            }
         } else {
             struct json *row_json;
             struct json *op;
index ee76b83215b7d867da88cb0f9a3904788603f1f1..0b3e164efec4b0a7572a49f220ab492ff9075cc1 100644 (file)
@@ -657,12 +657,13 @@ this.
 Deletes each specified \fIrecord\fR from \fItable\fR.  Unless
 \fB\-\-if\-exists\fR is specified, each \fIrecord\fRs must exist.
 .IP
-It is often unnecessary to specify explicit \fBdestroy\fR commands,
-because (except for records in the \fBQoS\fR or \fBQueue\fR tables)
-records that are not reachable from the \fBOpen_vSwitch\fR table are
-automatically deleted from the database.  This means that deleting the
-last reference to a record is sufficient for deleting the record
-itself.  See the \fBEXAMPLES\fR section below for more information.
+The \fBdestroy\fR command is only useful for records in the \fBQoS\fR
+or \fBQueue\fR tables.  Records in other tables are automatically
+deleted from the database when they become unreachable from the
+\fBOpen_vSwitch\fR table.  This means that deleting the last reference
+to a record is sufficient for deleting the record itself.  For records
+in these tables, \fBdestroy\fR is silently ignored.  See the
+\fBEXAMPLES\fR section below for more information.
 .
 .IP "\fBwait\-until \fItable record \fR[\fIcolumn\fR[\fB:\fIkey\fR]\fB=\fIvalue\fR]..."
 Waits until \fItable\fR contains a record named \fIrecord\fR whose