From 0a140468ddcff3f767a3069fe3303c7ae000a855 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Tue, 8 Feb 2011 10:21:59 -0800 Subject: [PATCH] ovs-vsctl: Add new "find" command. 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 | 21 ++++++++++++++- utilities/ovs-vsctl.8.in | 12 +++++++++ utilities/ovs-vsctl.c | 55 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 1 deletion(-) diff --git a/tests/ovs-vsctl.at b/tests/ovs-vsctl.at index a6f0dbf7..7488e3dd 100644 --- a/tests/ovs-vsctl.at +++ b/tests/ovs-vsctl.at @@ -565,6 +565,23 @@ 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 \ @@ -589,7 +606,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 79a14862..553985bc 100644 --- a/utilities/ovs-vsctl.8.in +++ b/utilities/ovs-vsctl.8.in @@ -551,6 +551,18 @@ 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 "[\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 18bf63b7..66ba4181 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_satisfied(const struct vsctl_table_class *, + const struct ovsdb_idl_row *, + const char *arg, + struct ovsdb_symbol_table *); + int main(int argc, char *argv[]) { @@ -508,6 +513,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\ @@ -2790,6 +2796,54 @@ 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_satisfied(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 pre_cmd_set(struct vsctl_context *ctx) { @@ -3494,6 +3548,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}, -- 2.30.2