This commit extracts the 'show' command code and puts it into the db-ctl-base module.
Signed-off-by: Alex Wang <al...@nicira.com> --- lib/db-ctl-base.c | 130 +++++++++++++++++++++++++++++++++++++++++++++ lib/db-ctl-base.h | 34 ++++++++++++ utilities/ovs-vsctl.c | 141 ++----------------------------------------------- 3 files changed, 167 insertions(+), 138 deletions(-) diff --git a/lib/db-ctl-base.c b/lib/db-ctl-base.c index d1dc8f7..a1147aa 100644 --- a/lib/db-ctl-base.c +++ b/lib/db-ctl-base.c @@ -1495,6 +1495,129 @@ parse_command(int argc, char *argv[], struct shash *local_options, command->argv = &argv[i]; } +static void +pre_cmd_show(struct ctl_context *ctx) +{ + struct cmd_show_table *show; + + for (show = cmd_show_tables; show->table; show++) { + size_t i; + + ovsdb_idl_add_table(ctx->idl, show->table); + if (show->name_column) { + ovsdb_idl_add_column(ctx->idl, show->name_column); + } + for (i = 0; i < ARRAY_SIZE(show->columns); i++) { + const struct ovsdb_idl_column *column = show->columns[i]; + if (column) { + ovsdb_idl_add_column(ctx->idl, column); + } + } + } +} + +static struct cmd_show_table * +cmd_show_find_table_by_row(const struct ovsdb_idl_row *row) +{ + struct cmd_show_table *show; + + for (show = cmd_show_tables; show->table; show++) { + if (show->table == row->table->class) { + return show; + } + } + return NULL; +} + +static struct cmd_show_table * +cmd_show_find_table_by_name(const char *name) +{ + struct cmd_show_table *show; + + for (show = cmd_show_tables; show->table; show++) { + if (!strcmp(show->table->name, name)) { + return show; + } + } + return NULL; +} + +static void +cmd_show_row(struct ctl_context *ctx, const struct ovsdb_idl_row *row, + int level) +{ + struct cmd_show_table *show = cmd_show_find_table_by_row(row); + size_t i; + + ds_put_char_multiple(&ctx->output, ' ', level * 4); + if (show && show->name_column) { + const struct ovsdb_datum *datum; + + ds_put_format(&ctx->output, "%s ", show->table->name); + datum = ovsdb_idl_read(row, show->name_column); + ovsdb_datum_to_string(datum, &show->name_column->type, &ctx->output); + } else { + ds_put_format(&ctx->output, UUID_FMT, UUID_ARGS(&row->uuid)); + } + ds_put_char(&ctx->output, '\n'); + + if (!show || show->recurse) { + return; + } + + show->recurse = true; + for (i = 0; i < ARRAY_SIZE(show->columns); i++) { + const struct ovsdb_idl_column *column = show->columns[i]; + const struct ovsdb_datum *datum; + + if (!column) { + break; + } + + datum = ovsdb_idl_read(row, column); + if (column->type.key.type == OVSDB_TYPE_UUID && + column->type.key.u.uuid.refTableName) { + struct cmd_show_table *ref_show; + size_t j; + + ref_show = cmd_show_find_table_by_name( + column->type.key.u.uuid.refTableName); + if (ref_show) { + for (j = 0; j < datum->n; j++) { + const struct ovsdb_idl_row *ref_row; + + ref_row = ovsdb_idl_get_row_for_uuid(ctx->idl, + ref_show->table, + &datum->keys[j].uuid); + if (ref_row) { + cmd_show_row(ctx, ref_row, level + 1); + } + } + continue; + } + } + + if (!ovsdb_datum_is_default(datum, &column->type)) { + ds_put_char_multiple(&ctx->output, ' ', (level + 1) * 4); + ds_put_format(&ctx->output, "%s: ", column->name); + ovsdb_datum_to_string(datum, &column->type, &ctx->output); + ds_put_char(&ctx->output, '\n'); + } + } + show->recurse = false; +} + +static void +cmd_show(struct ctl_context *ctx) +{ + const struct ovsdb_idl_row *row; + + for (row = ovsdb_idl_first_row(ctx->idl, cmd_show_tables[0].table); + row; row = ovsdb_idl_next_row(row)) { + cmd_show_row(ctx, row, 0); + } +} + /* Given pointer to dynamic array 'options_p', array's current size * 'allocated_options_p' and number of added options 'n_options_p', @@ -1695,6 +1818,12 @@ ctl_exit(int status) exit(status); } +/* Command for showing overview of database contents. */ +static const struct ctl_command_syntax db_ctl_show_command[] = { + {"show", 0, 0, "", pre_cmd_show, cmd_show, NULL, "", RO}, + {NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, RO}, +}; + /* Comman database commands to be registered. */ static const struct ctl_command_syntax db_ctl_commands[] = { {"comment", 0, INT_MAX, "[ARG]...", NULL, NULL, NULL, "", RO}, @@ -1739,6 +1868,7 @@ void ctl_init(void) { ctl_register_commands(db_ctl_commands); + ctl_register_commands(db_ctl_show_command); } /* Returns 'all_commands'. */ diff --git a/lib/db-ctl-base.h b/lib/db-ctl-base.h index eaa6bc6..ba177f2 100644 --- a/lib/db-ctl-base.h +++ b/lib/db-ctl-base.h @@ -35,6 +35,8 @@ struct table; * * - the 'the_idl' and 'the_idl_txn'. * + * - the 'cmd_show_tables'. (See 'struct cmd_show_table' for more info). + * * - the command syntaxes for each command. (See 'struct ctl_command_syntax' * for more info) and regiters them using ctl_register_commands(). * @@ -155,6 +157,38 @@ const struct shash *ctl_get_all_commands(void); struct ctl_command *ctl_parse_commands(int argc, char *argv[], struct shash *local_options, size_t *n_commandsp); + +/* This struct is for organizing the 'show' command output where: + * + * - 'table' is the table to show. + * + * - if 'name_column' is not null, it is used as the name for each row + * in 'table'. + * + * - 'columns[]' allows user to specify the print of additional columns + * in 'table'. + * + * - 'recurse' is used to avoid duplicate print. + * + * */ +struct cmd_show_table { + const struct ovsdb_idl_table_class *table; + const struct ovsdb_idl_column *name_column; + const struct ovsdb_idl_column *columns[3]; /* Seems like a good number. */ + bool recurse; +}; + +/* This array defines the 'show' command output format. User can check the + * definition in utilities/ovs-vsctl.c as reference. + * + * Particularly, if an element in 'columns[]' represents a reference to + * another table, the referred table must also be defined as an entry in + * in 'cmd_show_tables[]'. + * + * The definition must end with an all-NULL entry. + * */ +extern struct cmd_show_table cmd_show_tables[]; + /* The base context struct for conducting the common database * operations (commands listed in 'db_ctl_commands'). User should diff --git a/utilities/ovs-vsctl.c b/utilities/ovs-vsctl.c index 6bc6818..c9af355 100644 --- a/utilities/ovs-vsctl.c +++ b/utilities/ovs-vsctl.c @@ -970,14 +970,7 @@ cmd_init(struct ctl_context *ctx OVS_UNUSED) { } -struct cmd_show_table { - const struct ovsdb_idl_table_class *table; - const struct ovsdb_idl_column *name_column; - const struct ovsdb_idl_column *columns[3]; - bool recurse; -}; - -static struct cmd_show_table cmd_show_tables[] = { +struct cmd_show_table cmd_show_tables[] = { {&ovsrec_table_open_vswitch, NULL, {&ovsrec_open_vswitch_col_manager_options, @@ -1019,136 +1012,9 @@ static struct cmd_show_table cmd_show_tables[] = { NULL, NULL}, false}, -}; - -static void -pre_cmd_show(struct ctl_context *ctx) -{ - struct cmd_show_table *show; - - for (show = cmd_show_tables; - show < &cmd_show_tables[ARRAY_SIZE(cmd_show_tables)]; - show++) { - size_t i; - - ovsdb_idl_add_table(ctx->idl, show->table); - if (show->name_column) { - ovsdb_idl_add_column(ctx->idl, show->name_column); - } - for (i = 0; i < ARRAY_SIZE(show->columns); i++) { - const struct ovsdb_idl_column *column = show->columns[i]; - if (column) { - ovsdb_idl_add_column(ctx->idl, column); - } - } - } -} - -static struct cmd_show_table * -cmd_show_find_table_by_row(const struct ovsdb_idl_row *row) -{ - struct cmd_show_table *show; - for (show = cmd_show_tables; - show < &cmd_show_tables[ARRAY_SIZE(cmd_show_tables)]; - show++) { - if (show->table == row->table->class) { - return show; - } - } - return NULL; -} - -static struct cmd_show_table * -cmd_show_find_table_by_name(const char *name) -{ - struct cmd_show_table *show; - - for (show = cmd_show_tables; - show < &cmd_show_tables[ARRAY_SIZE(cmd_show_tables)]; - show++) { - if (!strcmp(show->table->name, name)) { - return show; - } - } - return NULL; -} - -static void -cmd_show_row(struct ctl_context *ctx, const struct ovsdb_idl_row *row, - int level) -{ - struct cmd_show_table *show = cmd_show_find_table_by_row(row); - size_t i; - - ds_put_char_multiple(&ctx->output, ' ', level * 4); - if (show && show->name_column) { - const struct ovsdb_datum *datum; - - ds_put_format(&ctx->output, "%s ", show->table->name); - datum = ovsdb_idl_read(row, show->name_column); - ovsdb_datum_to_string(datum, &show->name_column->type, &ctx->output); - } else { - ds_put_format(&ctx->output, UUID_FMT, UUID_ARGS(&row->uuid)); - } - ds_put_char(&ctx->output, '\n'); - - if (!show || show->recurse) { - return; - } - - show->recurse = true; - for (i = 0; i < ARRAY_SIZE(show->columns); i++) { - const struct ovsdb_idl_column *column = show->columns[i]; - const struct ovsdb_datum *datum; - - if (!column) { - break; - } - - datum = ovsdb_idl_read(row, column); - if (column->type.key.type == OVSDB_TYPE_UUID && - column->type.key.u.uuid.refTableName) { - struct cmd_show_table *ref_show; - size_t j; - - ref_show = cmd_show_find_table_by_name( - column->type.key.u.uuid.refTableName); - if (ref_show) { - for (j = 0; j < datum->n; j++) { - const struct ovsdb_idl_row *ref_row; - - ref_row = ovsdb_idl_get_row_for_uuid(ctx->idl, - ref_show->table, - &datum->keys[j].uuid); - if (ref_row) { - cmd_show_row(ctx, ref_row, level + 1); - } - } - continue; - } - } - - if (!ovsdb_datum_is_default(datum, &column->type)) { - ds_put_char_multiple(&ctx->output, ' ', (level + 1) * 4); - ds_put_format(&ctx->output, "%s: ", column->name); - ovsdb_datum_to_string(datum, &column->type, &ctx->output); - ds_put_char(&ctx->output, '\n'); - } - } - show->recurse = false; -} - -static void -cmd_show(struct ctl_context *ctx) -{ - const struct ovsdb_idl_row *row; - - for (row = ovsdb_idl_first_row(ctx->idl, cmd_show_tables[0].table); - row; row = ovsdb_idl_next_row(row)) { - cmd_show_row(ctx, row, 0); - } -} + {NULL, NULL, {NULL, NULL, NULL}, false} +}; static void pre_cmd_emer_reset(struct ctl_context *ctx) @@ -2803,7 +2669,6 @@ try_again: static const struct ctl_command_syntax vsctl_commands[] = { /* Open vSwitch commands. */ {"init", 0, 0, "", NULL, cmd_init, NULL, "", RW}, - {"show", 0, 0, "", pre_cmd_show, cmd_show, NULL, "", RO}, /* Bridge commands. */ {"add-br", 1, 3, "NEW-BRIDGE [PARENT] [NEW-VLAN]", pre_get_info, -- 1.7.9.5 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev