[ovs-dev] [kernel-reload 4/8] ovs-vsctl: Add new "find" command.

Ben Pfaff blp at nicira.com
Wed Feb 2 22:31:18 UTC 2011


This allows listing records that match specified criteria, instead
of just records that have specific names.

This will be used in an upcoming patch, along with --columns, to
list all of the interfaces whose type is 'internal'.
---
 tests/ovs-vsctl.at       |   22 +++++++++++++++++-
 utilities/ovs-vsctl.8.in |   12 ++++++++++
 utilities/ovs-vsctl.c    |   54 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 87 insertions(+), 1 deletions(-)

diff --git a/tests/ovs-vsctl.at b/tests/ovs-vsctl.at
index cb32b32..ee69003 100644
--- a/tests/ovs-vsctl.at
+++ b/tests/ovs-vsctl.at
@@ -539,6 +539,24 @@ AT_CHECK(
 name                : "br0"
 datapath_type       : ""
 ]], [ignore], [test ! -e pid || kill `cat pid`])
+AT_CHECK(
+  [RUN_OVS_VSCTL([--columns=fail_mode,name,datapath_type find b])],
+  [0],
+  [[fail_mode           : []
+name                : "br0"
+datapath_type       : ""
+]], [ignore], [test ! -e pid || kill `cat pid`])
+AT_CHECK([RUN_OVS_VSCTL([create b name=br1 datapath_type="foo"],
+                        [create b name=br2 external-ids:bar=quux])],
+  [0], [stdout], [], [OVS_VSCTL_CLEANUP])
+AT_CHECK(
+  [RUN_OVS_VSCTL([--columns=name find b datapath_type!=foo])], [0], [stdout],
+  [ignore], [test ! -e pid || kill `cat pid`])
+AT_CHECK([sed -n '/./p' stdout | sort], [0],
+  [[name                : "br0"
+name                : "br2"
+]])
+AT_CHECK(
   [RUN_OVS_VSCTL(
     [set bridge br0 \
       'other_config:datapath_id="0123456789ab"' \
@@ -562,7 +580,9 @@ AT_CHECK([RUN_OVS_VSCTL([remove br br0 other_config 'datapath_id="0123456789ab"'
 AT_CHECK([RUN_OVS_VSCTL([clear br br0 external-ids -- get br br0 external_ids])], 
   [0], [{}
 ], [], [OVS_VSCTL_CLEANUP])
-AT_CHECK([RUN_OVS_VSCTL([destroy b br0])], 
+AT_CHECK([RUN_OVS_VSCTL_TOGETHER([destroy b br0],
+                                 [destroy b br1],
+                                 [destroy b br2])],
   [0], [stdout], [], [OVS_VSCTL_CLEANUP])
 AT_CHECK([RUN_OVS_VSCTL([list b])], 
   [0], [], [], [OVS_VSCTL_CLEANUP])
diff --git a/utilities/ovs-vsctl.8.in b/utilities/ovs-vsctl.8.in
index a75e8b7..31a5378 100644
--- a/utilities/ovs-vsctl.8.in
+++ b/utilities/ovs-vsctl.8.in
@@ -530,6 +530,18 @@ alphabetical order by column name.
 The UUIDs shown for rows created in the same \fBovs\-vsctl\fR
 invocation will be wrong.
 .
+.IP "[\fB\-\-columns=\fIcolumn\fR[\fB,\fIcolumn\fR]...] \fBfind \fItable \fR[\fIcolumn\fR[\fB:\fIkey\fR]\fB=\fIvalue\fR]..."
+Lists the data in each record in \fItable\fR whose \fIcolumn\fR equals
+\fIvalue\fR or, if \fIkey\fR is specified, whose \fIcolumn\fR contains
+a \fIkey\fR with the specified \fIvalue\fR.  Any of the operators
+\fB!=\fR, \fB<\fR, \fB>\fR, \fB<=\fR, or \fB>=\fR may be substituted
+for \fB=\fR to test for inequality, less than, greater than, less than
+or equal to, or greater than or equal to, respectively.  (Don't forget
+to escape \fB<\fR or \fB>\fR from interpretation by the shell.)
+.IP
+If \fB\-\-columns\fR is specified, only the requested columns are
+listed, in the specified order.  Otherwise all columns are listed, in
+alphabetical order by column name.
 .IP
 The UUIDs shown for rows created in the same \fBovs\-vsctl\fR
 invocation will be wrong.
diff --git a/utilities/ovs-vsctl.c b/utilities/ovs-vsctl.c
index 9c8569a..c064c9a 100644
--- a/utilities/ovs-vsctl.c
+++ b/utilities/ovs-vsctl.c
@@ -138,6 +138,11 @@ static void set_column(const struct vsctl_table_class *,
                        const struct ovsdb_idl_row *, const char *arg,
                        struct ovsdb_symbol_table *);
 
+static bool is_condition_satified(const struct vsctl_table_class *,
+                                  const struct ovsdb_idl_row *,
+                                  const char *arg,
+                                  struct ovsdb_symbol_table *);
+
 int
 main(int argc, char *argv[])
 {
@@ -503,6 +508,7 @@ Switch commands:\n\
 \n\
 Database commands:\n\
   list TBL [REC]              list RECord (or all records) in TBL\n\
+  find TBL CONDITION...       list records satisfying CONDITION in TBL\n\
   get TBL REC COL[:KEY]       print values of COLumns in RECord in TBL\n\
   set TBL REC COL[:KEY]=VALUE set COLumn values in RECord in TBL\n\
   add TBL REC COL [KEY=]VALUE add (KEY=)VALUE to COLumn in RECord in TBL\n\
@@ -2667,6 +2673,53 @@ cmd_list(struct vsctl_context *ctx)
     }
     free(columns);
 }
+
+static void
+pre_cmd_find(struct vsctl_context *ctx)
+{
+    const char *column_names = shash_find_data(&ctx->options, "--columns");
+    const char *table_name = ctx->argv[1];
+    const struct vsctl_table_class *table;
+    int i;
+
+    table = pre_get_table(ctx, table_name);
+    pre_list_columns(ctx, table, column_names);
+    for (i = 2; i < ctx->argc; i++) {
+        pre_parse_column_key_value(ctx, ctx->argv[i], table);
+    }
+}
+
+static void
+cmd_find(struct vsctl_context *ctx)
+{
+    const char *column_names = shash_find_data(&ctx->options, "--columns");
+    const struct ovsdb_idl_column **columns;
+    const char *table_name = ctx->argv[1];
+    const struct vsctl_table_class *table;
+    const struct ovsdb_idl_row *row;
+    struct ds *out = &ctx->output;
+    size_t n_columns;
+
+    table = get_table(table_name);
+    parse_column_names(column_names, table, &columns, &n_columns);
+
+    for (row = ovsdb_idl_first_row(ctx->idl, table->class); row;
+         row = ovsdb_idl_next_row(row)) {
+        int i;
+
+        for (i = 2; i < ctx->argc; i++) {
+            if (!is_condition_satified(table, row, ctx->argv[i],
+                                       ctx->symtab)) {
+                goto next_row;
+            }
+        }
+        if (out->length) {
+            ds_put_char(out, '\n');
+        }
+        list_record(row, columns, n_columns, out);
+
+    next_row: ;
+    }
 }
 
 static void
@@ -3368,6 +3421,7 @@ static const struct vsctl_command_syntax all_commands[] = {
     /* Parameter commands. */
     {"get", 2, INT_MAX, pre_cmd_get, cmd_get, NULL, "--if-exists,--id=", RO},
     {"list", 1, INT_MAX, pre_cmd_list, cmd_list, NULL, "--columns=", RO},
+    {"find", 1, INT_MAX, pre_cmd_find, cmd_find, NULL, "--columns=", RO},
     {"set", 3, INT_MAX, pre_cmd_set, cmd_set, NULL, "", RW},
     {"add", 4, INT_MAX, pre_cmd_add, cmd_add, NULL, "", RW},
     {"remove", 4, INT_MAX, pre_cmd_remove, cmd_remove, NULL, "", RW},
-- 
1.7.1





More information about the dev mailing list