X-Git-Url: http://git.cascardo.eti.br/?a=blobdiff_plain;f=lib%2Fdb-ctl-base.c;h=b018bad1db96e45d1c03e0e53b92da6ef48d0de2;hb=016e46846db5decbe6337500230cb56fd4b1bdf7;hp=e3c0373d29c0b8cfca182432628f8af3d34cd3a7;hpb=ce6f1d1fc55a26e3ae56d81fadfffde566937c62;p=cascardo%2Fovs.git diff --git a/lib/db-ctl-base.c b/lib/db-ctl-base.c index e3c0373d2..b018bad1d 100644 --- a/lib/db-ctl-base.c +++ b/lib/db-ctl-base.c @@ -34,6 +34,7 @@ #include "ovsdb-idl.h" #include "ovsdb-idl-provider.h" #include "shash.h" +#include "sset.h" #include "string.h" #include "table.h" #include "util.h" @@ -51,7 +52,7 @@ VLOG_DEFINE_THIS_MODULE(db_ctl_base); * when ctl_init() is called. * * */ -extern struct cmd_show_table cmd_show_tables[]; +static const struct cmd_show_table *cmd_show_tables; /* ctl_exit() is called by ctl_fatal(). User can optionally supply an exit * function ctl_exit_func() via ctl_init. If supplied, this function will @@ -1604,7 +1605,7 @@ parse_command(int argc, char *argv[], struct shash *local_options, static void pre_cmd_show(struct ctl_context *ctx) { - struct cmd_show_table *show; + const struct cmd_show_table *show; for (show = cmd_show_tables; show->table; show++) { size_t i; @@ -1619,13 +1620,22 @@ pre_cmd_show(struct ctl_context *ctx) ovsdb_idl_add_column(ctx->idl, column); } } + if (show->wref_table.table) { + ovsdb_idl_add_table(ctx->idl, show->wref_table.table); + } + if (show->wref_table.name_column) { + ovsdb_idl_add_column(ctx->idl, show->wref_table.name_column); + } + if (show->wref_table.wref_column) { + ovsdb_idl_add_column(ctx->idl, show->wref_table.wref_column); + } } } -static struct cmd_show_table * +static const struct cmd_show_table * cmd_show_find_table_by_row(const struct ovsdb_idl_row *row) { - struct cmd_show_table *show; + const struct cmd_show_table *show; for (show = cmd_show_tables; show->table; show++) { if (show->table == row->table->class) { @@ -1635,10 +1645,10 @@ cmd_show_find_table_by_row(const struct ovsdb_idl_row *row) return NULL; } -static struct cmd_show_table * +static const struct cmd_show_table * cmd_show_find_table_by_name(const char *name) { - struct cmd_show_table *show; + const struct cmd_show_table *show; for (show = cmd_show_tables; show->table; show++) { if (!strcmp(show->table->name, name)) { @@ -1648,11 +1658,47 @@ cmd_show_find_table_by_name(const char *name) return NULL; } +/* Prints table entries that weak reference the 'cur_row'. */ +static void +cmd_show_weak_ref(struct ctl_context *ctx, const struct cmd_show_table *show, + const struct ovsdb_idl_row *cur_row, int level) +{ + const struct ovsdb_idl_row *row_wref; + const struct ovsdb_idl_table_class *table = show->wref_table.table; + const struct ovsdb_idl_column *name_column + = show->wref_table.name_column; + const struct ovsdb_idl_column *wref_column + = show->wref_table.wref_column; + + if (!table || !name_column || !wref_column) { + return; + } + + for (row_wref = ovsdb_idl_first_row(ctx->idl, table); row_wref; + row_wref = ovsdb_idl_next_row(row_wref)) { + const struct ovsdb_datum *wref_datum + = ovsdb_idl_read(row_wref, wref_column); + /* If weak reference refers to the 'cur_row', prints it. */ + if (wref_datum->n + && uuid_equals(&cur_row->uuid, &wref_datum->keys[0].uuid)) { + const struct ovsdb_datum *name_datum + = ovsdb_idl_read(row_wref, name_column); + ds_put_char_multiple(&ctx->output, ' ', (level + 1) * 4); + ds_put_format(&ctx->output, "%s ", table->name); + ovsdb_datum_to_string(name_datum, &name_column->type, &ctx->output); + ds_put_char(&ctx->output, '\n'); + } + } +} + +/* 'shown' records the tables that has been displayed by the current + * command to avoid duplicated prints. + */ static void cmd_show_row(struct ctl_context *ctx, const struct ovsdb_idl_row *row, - int level) + int level, struct sset *shown) { - struct cmd_show_table *show = cmd_show_find_table_by_row(row); + const struct cmd_show_table *show = cmd_show_find_table_by_row(row); size_t i; ds_put_char_multiple(&ctx->output, ' ', level * 4); @@ -1667,11 +1713,11 @@ cmd_show_row(struct ctl_context *ctx, const struct ovsdb_idl_row *row, } ds_put_char(&ctx->output, '\n'); - if (!show || show->recurse) { + if (!show || sset_find(shown, show->table->name)) { return; } - show->recurse = true; + sset_add(shown, show->table->name); for (i = 0; i < ARRAY_SIZE(show->columns); i++) { const struct ovsdb_idl_column *column = show->columns[i]; const struct ovsdb_datum *datum; @@ -1683,7 +1729,7 @@ cmd_show_row(struct ctl_context *ctx, const struct ovsdb_idl_row *row, 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; + const struct cmd_show_table *ref_show; size_t j; ref_show = cmd_show_find_table_by_name( @@ -1696,7 +1742,7 @@ cmd_show_row(struct ctl_context *ctx, const struct ovsdb_idl_row *row, ref_show->table, &datum->keys[j].uuid); if (ref_row) { - cmd_show_row(ctx, ref_row, level + 1); + cmd_show_row(ctx, ref_row, level + 1, shown); } } continue; @@ -1704,7 +1750,7 @@ cmd_show_row(struct ctl_context *ctx, const struct ovsdb_idl_row *row, } else if (ovsdb_type_is_map(&column->type) && column->type.value.type == OVSDB_TYPE_UUID && column->type.value.u.uuid.refTableName) { - struct cmd_show_table *ref_show; + const struct cmd_show_table *ref_show; size_t j; /* Prints the key to ref'ed table name map if the ref'ed table @@ -1749,18 +1795,23 @@ cmd_show_row(struct ctl_context *ctx, const struct ovsdb_idl_row *row, ds_put_char(&ctx->output, '\n'); } } - show->recurse = false; + cmd_show_weak_ref(ctx, show, row, level); + sset_find_and_delete_assert(shown, show->table->name); } static void cmd_show(struct ctl_context *ctx) { const struct ovsdb_idl_row *row; + struct sset shown = SSET_INITIALIZER(&shown); 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); + cmd_show_row(ctx, row, 0, &shown); } + + ovs_assert(sset_is_empty(&shown)); + sset_destroy(&shown); } @@ -1953,7 +2004,7 @@ ctl_fatal(const char *format, ...) * Freeing the transaction and the IDL is not strictly necessary, but it makes * for a clean memory leak report from valgrind in the normal case. That makes * it easier to notice real memory leaks. */ -void +static void ctl_exit(int status) { if (ctl_exit_func) { @@ -2005,9 +2056,11 @@ ctl_register_commands(const struct ctl_command_syntax *commands) /* Registers the 'db_ctl_commands' to 'all_commands'. */ void ctl_init(const struct ctl_table_class tables_[], + const struct cmd_show_table cmd_show_tables_[], void (*ctl_exit_func_)(int status)) { tables = tables_; + cmd_show_tables = cmd_show_tables_; ctl_exit_func = ctl_exit_func_; ctl_register_commands(db_ctl_commands); }