2 * Copyright (c) 2015, 2016 Nicira, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
23 #include "db-ctl-base.h"
25 #include "command-line.h"
28 #include "openvswitch/dynamic-string.h"
29 #include "fatal-signal.h"
31 #include "openvswitch/json.h"
32 #include "openvswitch/vlog.h"
33 #include "ovsdb-data.h"
34 #include "ovsdb-idl.h"
35 #include "ovsdb-idl-provider.h"
36 #include "openvswitch/shash.h"
42 VLOG_DEFINE_THIS_MODULE(db_ctl_base);
44 /* This array defines the 'show' command output format. User can check the
45 * definition in utilities/ovs-vsctl.c as reference.
47 * Particularly, if an element in 'columns[]' represents a reference to
48 * another table, the referred table must also be defined as an entry in
49 * in 'cmd_show_tables[]'.
51 * The definition must end with an all-NULL entry. It is initalized once
52 * when ctl_init() is called.
55 static const struct cmd_show_table *cmd_show_tables;
57 /* ctl_exit() is called by ctl_fatal(). User can optionally supply an exit
58 * function ctl_exit_func() via ctl_init. If supplied, this function will
59 * be called by ctl_exit()
61 static void (*ctl_exit_func)(int status) = NULL;
62 OVS_NO_RETURN static void ctl_exit(int status);
64 /* Represents all tables in the schema. User must define 'tables'
65 * in implementation and supply via ctl_init(). The definition must end
66 * with an all-NULL entry. */
67 static const struct ctl_table_class *tables;
69 static struct shash all_commands = SHASH_INITIALIZER(&all_commands);
70 static const struct ctl_table_class *get_table(const char *table_name);
71 static void set_column(const struct ctl_table_class *,
72 const struct ovsdb_idl_row *, const char *,
73 struct ovsdb_symbol_table *);
76 static struct option *
77 find_option(const char *name, struct option *options, size_t n_options)
81 for (i = 0; i < n_options; i++) {
82 if (!strcmp(options[i].name, name)) {
89 static struct option *
90 add_option(struct option **optionsp, size_t *n_optionsp,
91 size_t *allocated_optionsp)
93 if (*n_optionsp >= *allocated_optionsp) {
94 *optionsp = x2nrealloc(*optionsp, allocated_optionsp,
97 return &(*optionsp)[(*n_optionsp)++];
100 /* Converts the command arguments into format that can be parsed by
101 * bash completion script.
103 * Therein, arguments will be attached with following prefixes:
105 * !argument :: The argument is required
106 * ?argument :: The argument is optional
107 * *argument :: The argument may appear any number (0 or more) times
108 * +argument :: The argument may appear one or more times
112 print_command_arguments(const struct ctl_command_syntax *command)
115 * The argument string is parsed in reverse. We use a stack 'oew_stack' to
116 * keep track of nested optionals. Whenever a ']' is encountered, we push
117 * a bit to 'oew_stack'. The bit is set to 1 if the ']' is not nested.
118 * Subsequently, we pop an entry everytime '[' is met.
120 * We use 'whole_word_is_optional' value to decide whether or not a ! or +
121 * should be added on encountering a space: if the optional surrounds the
122 * whole word then it shouldn't be, but if it is only a part of the word
123 * (i.e. [key=]value), it should be.
125 uint32_t oew_stack = 0;
127 const char *arguments = command->arguments;
128 int length = strlen(arguments);
133 /* Output buffer, written backward from end. */
134 char *output = xmalloc(2 * length);
135 char *outp = output + 2 * length;
138 bool in_repeated = false;
139 bool whole_word_is_optional = false;
141 for (const char *inp = arguments + length; inp > arguments; ) {
145 if (inp[1] == '\0' || inp[1] == ' ' || inp[1] == '.') {
150 /* Checks if the whole word is optional, and sets the
151 * 'whole_word_is_optional' accordingly. */
152 if ((inp == arguments || inp[-1] == ' ') && oew_stack & 1) {
153 *--outp = in_repeated ? '*' : '?';
154 whole_word_is_optional = true;
157 whole_word_is_optional = false;
162 if (!whole_word_is_optional) {
163 *--outp = in_repeated ? '+' : '!';
167 whole_word_is_optional = false;
177 if (arguments[0] != '[' && outp != output + 2 * length - 1) {
178 *--outp = in_repeated ? '+' : '!';
185 die_if_error(char *error)
188 ctl_fatal("%s", error);
193 to_lower_and_underscores(unsigned c)
195 return c == '-' ? '_' : tolower(c);
199 score_partial_match(const char *name, const char *s)
203 if (!strcmp(name, s)) {
206 for (score = 0; ; score++, name++, s++) {
207 if (to_lower_and_underscores(*name) != to_lower_and_underscores(*s)) {
209 } else if (*name == '\0') {
213 return *s == '\0' ? score : 0;
216 static struct ovsdb_symbol *
217 create_symbol(struct ovsdb_symbol_table *symtab, const char *id, bool *newp)
219 struct ovsdb_symbol *symbol;
222 ctl_fatal("row id \"%s\" does not begin with \"@\"", id);
226 *newp = ovsdb_symbol_table_get(symtab, id) == NULL;
229 symbol = ovsdb_symbol_table_insert(symtab, id);
230 if (symbol->created) {
231 ctl_fatal("row id \"%s\" may only be specified on one --id option",
234 symbol->created = true;
238 static const struct ovsdb_idl_row *
239 get_row_by_id(struct ctl_context *ctx, const struct ctl_table_class *table,
240 const struct ctl_row_id *id, const char *record_id)
242 const struct ovsdb_idl_row *referrer, *final;
248 if (!id->name_column) {
249 if (strcmp(record_id, ".")) {
252 referrer = ovsdb_idl_first_row(ctx->idl, id->table);
253 if (!referrer || ovsdb_idl_next_row(referrer)) {
259 ovs_assert(id->name_column->type.value.type == OVSDB_TYPE_VOID);
261 enum ovsdb_atomic_type key = id->name_column->type.key.type;
262 if (key == OVSDB_TYPE_INTEGER) {
263 if (!record_id[0] || record_id[strspn(record_id, "0123456789")]) {
267 ovs_assert(key == OVSDB_TYPE_STRING);
270 for (const struct ovsdb_idl_row *row = ovsdb_idl_first_row(ctx->idl,
273 row = ovsdb_idl_next_row(row)) {
274 const struct ovsdb_datum *name = ovsdb_idl_get(
275 row, id->name_column, key, OVSDB_TYPE_VOID);
277 const union ovsdb_atom *atom = &name->keys[0];
278 if (key == OVSDB_TYPE_STRING
279 ? !strcmp(atom->string, record_id)
280 : atom->integer == strtoll(record_id, NULL, 10)) {
282 ctl_fatal("multiple rows in %s match \"%s\"",
283 table->class->name, record_id);
295 if (id->uuid_column) {
296 const struct ovsdb_datum *uuid;
298 ovsdb_idl_txn_verify(referrer, id->uuid_column);
299 uuid = ovsdb_idl_get(referrer, id->uuid_column,
300 OVSDB_TYPE_UUID, OVSDB_TYPE_VOID);
302 final = ovsdb_idl_get_row_for_uuid(ctx->idl, table->class,
303 &uuid->keys[0].uuid);
312 static const struct ovsdb_idl_row *
313 get_row(struct ctl_context *ctx,
314 const struct ctl_table_class *table, const char *record_id,
317 const struct ovsdb_idl_row *row;
321 if (uuid_from_string(&uuid, record_id)) {
322 row = ovsdb_idl_get_row_for_uuid(ctx->idl, table->class, &uuid);
327 for (i = 0; i < ARRAY_SIZE(table->row_ids); i++) {
328 row = get_row_by_id(ctx, table, &table->row_ids[i], record_id);
334 if (must_exist && !row) {
335 ctl_fatal("no row \"%s\" in table %s",
336 record_id, table->class->name);
342 get_column(const struct ctl_table_class *table, const char *column_name,
343 const struct ovsdb_idl_column **columnp)
345 const struct ovsdb_idl_column *best_match = NULL;
346 unsigned int best_score = 0;
349 for (i = 0; i < table->class->n_columns; i++) {
350 const struct ovsdb_idl_column *column = &table->class->columns[i];
351 unsigned int score = score_partial_match(column->name, column_name);
352 if (score > best_score) {
355 } else if (score == best_score) {
360 *columnp = best_match;
363 } else if (best_score) {
364 return xasprintf("%s contains more than one column whose name "
365 "matches \"%s\"", table->class->name, column_name);
367 return xasprintf("%s does not contain a column whose name matches "
368 "\"%s\"", table->class->name, column_name);
373 pre_get_column(struct ctl_context *ctx,
374 const struct ctl_table_class *table, const char *column_name,
375 const struct ovsdb_idl_column **columnp)
377 die_if_error(get_column(table, column_name, columnp));
378 ovsdb_idl_add_column(ctx->idl, *columnp);
381 static const struct ctl_table_class *
382 pre_get_table(struct ctl_context *ctx, const char *table_name)
384 const struct ctl_table_class *table_class;
387 table_class = get_table(table_name);
388 ovsdb_idl_add_table(ctx->idl, table_class->class);
390 for (i = 0; i < ARRAY_SIZE(table_class->row_ids); i++) {
391 const struct ctl_row_id *id = &table_class->row_ids[i];
393 ovsdb_idl_add_table(ctx->idl, id->table);
395 if (id->name_column) {
396 ovsdb_idl_add_column(ctx->idl, id->name_column);
398 if (id->uuid_column) {
399 ovsdb_idl_add_column(ctx->idl, id->uuid_column);
407 missing_operator_error(const char *arg, const char **allowed_operators,
413 ds_put_format(&s, "%s: argument does not end in ", arg);
414 ds_put_format(&s, "\"%s\"", allowed_operators[0]);
415 if (n_allowed == 2) {
416 ds_put_format(&s, " or \"%s\"", allowed_operators[1]);
417 } else if (n_allowed > 2) {
420 for (i = 1; i < n_allowed - 1; i++) {
421 ds_put_format(&s, ", \"%s\"", allowed_operators[i]);
423 ds_put_format(&s, ", or \"%s\"", allowed_operators[i]);
425 ds_put_format(&s, " followed by a value.");
427 return ds_steal_cstr(&s);
430 /* Breaks 'arg' apart into a number of fields in the following order:
432 * - The name of a column in 'table', stored into '*columnp'. The column
433 * name may be abbreviated.
435 * - Optionally ':' followed by a key string. The key is stored as a
436 * malloc()'d string into '*keyp', or NULL if no key is present in
439 * - If 'valuep' is nonnull, an operator followed by a value string. The
440 * allowed operators are the 'n_allowed' string in 'allowed_operators',
441 * or just "=" if 'n_allowed' is 0. If 'operatorp' is nonnull, then the
442 * index of the operator within 'allowed_operators' is stored into
443 * '*operatorp'. The value is stored as a malloc()'d string into
444 * '*valuep', or NULL if no value is present in 'arg'.
446 * On success, returns NULL. On failure, returned a malloc()'d string error
447 * message and stores NULL into all of the nonnull output arguments. */
448 static char * OVS_WARN_UNUSED_RESULT
449 parse_column_key_value(const char *arg,
450 const struct ctl_table_class *table,
451 const struct ovsdb_idl_column **columnp, char **keyp,
453 const char **allowed_operators, size_t n_allowed,
460 ovs_assert(!(operatorp && !valuep));
466 /* Parse column name. */
467 error = ovsdb_token_parse(&p, &column_name);
471 if (column_name[0] == '\0') {
473 error = xasprintf("%s: missing column name", arg);
476 error = get_column(table, column_name, columnp);
482 /* Parse key string. */
485 error = ovsdb_token_parse(&p, keyp);
491 /* Parse value string. */
497 if (!allowed_operators) {
498 static const char *equals = "=";
499 allowed_operators = =
505 for (i = 0; i < n_allowed; i++) {
506 const char *op = allowed_operators[i];
507 size_t op_len = strlen(op);
509 if (op_len > best_len && !strncmp(op, p, op_len) && p[op_len]) {
515 error = missing_operator_error(arg, allowed_operators, n_allowed);
522 *valuep = xstrdup(p + best_len);
525 error = xasprintf("%s: trailing garbage \"%s\" in argument",
546 static const struct ovsdb_idl_column *
547 pre_parse_column_key_value(struct ctl_context *ctx,
549 const struct ctl_table_class *table)
551 const struct ovsdb_idl_column *column;
556 die_if_error(ovsdb_token_parse(&p, &column_name));
557 if (column_name[0] == '\0') {
558 ctl_fatal("%s: missing column name", arg);
561 pre_get_column(ctx, table, column_name, &column);
568 check_mutable(const struct ovsdb_idl_row *row,
569 const struct ovsdb_idl_column *column)
571 if (!ovsdb_idl_is_mutable(row, column)) {
572 ctl_fatal("cannot modify read-only column %s in table %s",
573 column->name, row->table->class->name);
578 RELOP(RELOP_EQ, "=") \
579 RELOP(RELOP_NE, "!=") \
580 RELOP(RELOP_LT, "<") \
581 RELOP(RELOP_GT, ">") \
582 RELOP(RELOP_LE, "<=") \
583 RELOP(RELOP_GE, ">=") \
584 RELOP(RELOP_SET_EQ, "{=}") \
585 RELOP(RELOP_SET_NE, "{!=}") \
586 RELOP(RELOP_SET_LT, "{<}") \
587 RELOP(RELOP_SET_GT, "{>}") \
588 RELOP(RELOP_SET_LE, "{<=}") \
589 RELOP(RELOP_SET_GE, "{>=}")
592 #define RELOP(ENUM, STRING) ENUM,
598 is_set_operator(enum relop op)
600 return (op == RELOP_SET_EQ || op == RELOP_SET_NE ||
601 op == RELOP_SET_LT || op == RELOP_SET_GT ||
602 op == RELOP_SET_LE || op == RELOP_SET_GE);
606 evaluate_relop(const struct ovsdb_datum *a, const struct ovsdb_datum *b,
607 const struct ovsdb_type *type, enum relop op)
612 return ovsdb_datum_compare_3way(a, b, type) == 0;
615 return ovsdb_datum_compare_3way(a, b, type) != 0;
617 return ovsdb_datum_compare_3way(a, b, type) < 0;
619 return ovsdb_datum_compare_3way(a, b, type) > 0;
621 return ovsdb_datum_compare_3way(a, b, type) <= 0;
623 return ovsdb_datum_compare_3way(a, b, type) >= 0;
626 return b->n > a->n && ovsdb_datum_includes_all(a, b, type);
628 return a->n > b->n && ovsdb_datum_includes_all(b, a, type);
630 return ovsdb_datum_includes_all(a, b, type);
632 return ovsdb_datum_includes_all(b, a, type);
640 is_condition_satisfied(const struct ctl_table_class *table,
641 const struct ovsdb_idl_row *row, const char *arg,
642 struct ovsdb_symbol_table *symtab)
644 static const char *operators[] = {
645 #define RELOP(ENUM, STRING) STRING,
650 const struct ovsdb_idl_column *column;
651 const struct ovsdb_datum *have_datum;
652 char *key_string, *value_string;
653 struct ovsdb_type type;
658 error = parse_column_key_value(arg, table, &column, &key_string,
659 &operator, operators, ARRAY_SIZE(operators),
663 ctl_fatal("%s: missing value", arg);
667 type.n_max = UINT_MAX;
669 have_datum = ovsdb_idl_read(row, column);
671 union ovsdb_atom want_key;
672 struct ovsdb_datum b;
675 if (column->type.value.type == OVSDB_TYPE_VOID) {
676 ctl_fatal("cannot specify key to check for non-map column %s",
680 die_if_error(ovsdb_atom_from_string(&want_key, &column->type.key,
681 key_string, symtab));
683 type.key = type.value;
684 type.value.type = OVSDB_TYPE_VOID;
685 die_if_error(ovsdb_datum_from_string(&b, &type, value_string, symtab));
687 idx = ovsdb_datum_find_key(have_datum,
688 &want_key, column->type.key.type);
689 if (idx == UINT_MAX && !is_set_operator(operator)) {
692 struct ovsdb_datum a;
694 if (idx != UINT_MAX) {
696 a.keys = &have_datum->values[idx];
704 retval = evaluate_relop(&a, &b, &type, operator);
707 ovsdb_atom_destroy(&want_key, column->type.key.type);
708 ovsdb_datum_destroy(&b, &type);
710 struct ovsdb_datum want_datum;
712 die_if_error(ovsdb_datum_from_string(&want_datum, &column->type,
713 value_string, symtab));
714 retval = evaluate_relop(have_datum, &want_datum, &type, operator);
715 ovsdb_datum_destroy(&want_datum, &column->type);
725 invalidate_cache(struct ctl_context *ctx)
727 if (ctx->invalidate_cache) {
728 (ctx->invalidate_cache)(ctx);
733 pre_cmd_get(struct ctl_context *ctx)
735 const char *id = shash_find_data(&ctx->options, "--id");
736 const char *table_name = ctx->argv[1];
737 const struct ctl_table_class *table;
740 /* Using "get" without --id or a column name could possibly make sense.
741 * Maybe, for example, a *ctl command run wants to assert that a row
742 * exists. But it is unlikely that an interactive user would want to do
743 * that, so issue a warning if we're running on a terminal. */
744 if (!id && ctx->argc <= 3 && isatty(STDOUT_FILENO)) {
745 VLOG_WARN("\"get\" command without row arguments or \"--id\" is "
746 "possibly erroneous");
749 table = pre_get_table(ctx, table_name);
750 for (i = 3; i < ctx->argc; i++) {
751 if (!strcasecmp(ctx->argv[i], "_uuid")
752 || !strcasecmp(ctx->argv[i], "-uuid")) {
756 pre_parse_column_key_value(ctx, ctx->argv[i], table);
761 cmd_get(struct ctl_context *ctx)
763 const char *id = shash_find_data(&ctx->options, "--id");
764 bool must_exist = !shash_find(&ctx->options, "--if-exists");
765 const char *table_name = ctx->argv[1];
766 const char *record_id = ctx->argv[2];
767 const struct ctl_table_class *table;
768 const struct ovsdb_idl_row *row;
769 struct ds *out = &ctx->output;
772 if (id && !must_exist) {
773 ctl_fatal("--if-exists and --id may not be specified together");
776 table = get_table(table_name);
777 row = get_row(ctx, table, record_id, must_exist);
783 struct ovsdb_symbol *symbol;
786 symbol = create_symbol(ctx->symtab, id, &new);
788 ctl_fatal("row id \"%s\" specified on \"get\" command was used "
789 "before it was defined", id);
791 symbol->uuid = row->uuid;
793 /* This symbol refers to a row that already exists, so disable warnings
794 * about it being unreferenced. */
795 symbol->strong_ref = true;
797 for (i = 3; i < ctx->argc; i++) {
798 const struct ovsdb_idl_column *column;
799 const struct ovsdb_datum *datum;
802 /* Special case for obtaining the UUID of a row. We can't just do this
803 * through parse_column_key_value() below since it returns a "struct
804 * ovsdb_idl_column" and the UUID column doesn't have one. */
805 if (!strcasecmp(ctx->argv[i], "_uuid")
806 || !strcasecmp(ctx->argv[i], "-uuid")) {
807 ds_put_format(out, UUID_FMT"\n", UUID_ARGS(&row->uuid));
811 die_if_error(parse_column_key_value(ctx->argv[i], table,
812 &column, &key_string,
813 NULL, NULL, 0, NULL));
815 ovsdb_idl_txn_verify(row, column);
816 datum = ovsdb_idl_read(row, column);
818 union ovsdb_atom key;
821 if (column->type.value.type == OVSDB_TYPE_VOID) {
822 ctl_fatal("cannot specify key to get for non-map column %s",
826 die_if_error(ovsdb_atom_from_string(&key,
828 key_string, ctx->symtab));
830 idx = ovsdb_datum_find_key(datum, &key,
831 column->type.key.type);
832 if (idx == UINT_MAX) {
834 ctl_fatal("no key \"%s\" in %s record \"%s\" column %s",
835 key_string, table->class->name, record_id,
839 ovsdb_atom_to_string(&datum->values[idx],
840 column->type.value.type, out);
842 ovsdb_atom_destroy(&key, column->type.key.type);
844 ovsdb_datum_to_string(datum, &column->type, out);
846 ds_put_char(out, '\n');
853 parse_column_names(const char *column_names,
854 const struct ctl_table_class *table,
855 const struct ovsdb_idl_column ***columnsp,
858 const struct ovsdb_idl_column **columns;
864 n_columns = table->class->n_columns + 1;
865 columns = xmalloc(n_columns * sizeof *columns);
867 for (i = 0; i < table->class->n_columns; i++) {
868 columns[i + 1] = &table->class->columns[i];
871 char *s = xstrdup(column_names);
872 size_t allocated_columns;
873 char *save_ptr = NULL;
877 allocated_columns = n_columns = 0;
878 for (column_name = strtok_r(s, ", ", &save_ptr); column_name;
879 column_name = strtok_r(NULL, ", ", &save_ptr)) {
880 const struct ovsdb_idl_column *column;
882 if (!strcasecmp(column_name, "_uuid")) {
885 die_if_error(get_column(table, column_name, &column));
887 if (n_columns >= allocated_columns) {
888 columns = x2nrealloc(columns, &allocated_columns,
891 columns[n_columns++] = column;
896 ctl_fatal("must specify at least one column name");
900 *n_columnsp = n_columns;
904 pre_list_columns(struct ctl_context *ctx,
905 const struct ctl_table_class *table,
906 const char *column_names)
908 const struct ovsdb_idl_column **columns;
912 parse_column_names(column_names, table, &columns, &n_columns);
913 for (i = 0; i < n_columns; i++) {
915 ovsdb_idl_add_column(ctx->idl, columns[i]);
922 pre_cmd_list(struct ctl_context *ctx)
924 const char *column_names = shash_find_data(&ctx->options, "--columns");
925 const char *table_name = ctx->argv[1];
926 const struct ctl_table_class *table;
928 table = pre_get_table(ctx, table_name);
929 pre_list_columns(ctx, table, column_names);
932 static struct table *
933 list_make_table(const struct ovsdb_idl_column **columns, size_t n_columns)
938 out = xmalloc(sizeof *out);
941 for (i = 0; i < n_columns; i++) {
942 const struct ovsdb_idl_column *column = columns[i];
943 const char *column_name = column ? column->name : "_uuid";
945 table_add_column(out, "%s", column_name);
952 list_record(const struct ovsdb_idl_row *row,
953 const struct ovsdb_idl_column **columns, size_t n_columns,
963 for (i = 0; i < n_columns; i++) {
964 const struct ovsdb_idl_column *column = columns[i];
965 struct cell *cell = table_add_cell(out);
968 struct ovsdb_datum datum;
969 union ovsdb_atom atom;
971 atom.uuid = row->uuid;
977 cell->json = ovsdb_datum_to_json(&datum, &ovsdb_type_uuid);
978 cell->type = &ovsdb_type_uuid;
980 const struct ovsdb_datum *datum = ovsdb_idl_read(row, column);
982 cell->json = ovsdb_datum_to_json(datum, &column->type);
983 cell->type = &column->type;
989 cmd_list(struct ctl_context *ctx)
991 const char *column_names = shash_find_data(&ctx->options, "--columns");
992 bool must_exist = !shash_find(&ctx->options, "--if-exists");
993 const struct ovsdb_idl_column **columns;
994 const char *table_name = ctx->argv[1];
995 const struct ctl_table_class *table;
1000 table = get_table(table_name);
1001 parse_column_names(column_names, table, &columns, &n_columns);
1002 out = ctx->table = list_make_table(columns, n_columns);
1003 if (ctx->argc > 2) {
1004 for (i = 2; i < ctx->argc; i++) {
1005 list_record(get_row(ctx, table, ctx->argv[i], must_exist),
1006 columns, n_columns, out);
1009 const struct ovsdb_idl_row *row;
1011 for (row = ovsdb_idl_first_row(ctx->idl, table->class); row != NULL;
1012 row = ovsdb_idl_next_row(row)) {
1013 list_record(row, columns, n_columns, out);
1019 /* Finds and returns the "struct ctl_table_class *" with 'table_name' by
1020 * searching the 'tables'. */
1021 static const struct ctl_table_class *
1022 get_table(const char *table_name)
1024 const struct ctl_table_class *table;
1025 const struct ctl_table_class *best_match = NULL;
1026 unsigned int best_score = 0;
1028 for (table = tables; table->class; table++) {
1029 unsigned int score = score_partial_match(table->class->name,
1031 if (score > best_score) {
1034 } else if (score == best_score) {
1040 } else if (best_score) {
1041 ctl_fatal("multiple table names match \"%s\"", table_name);
1043 ctl_fatal("unknown table \"%s\"", table_name);
1049 pre_cmd_find(struct ctl_context *ctx)
1051 const char *column_names = shash_find_data(&ctx->options, "--columns");
1052 const char *table_name = ctx->argv[1];
1053 const struct ctl_table_class *table;
1056 table = pre_get_table(ctx, table_name);
1057 pre_list_columns(ctx, table, column_names);
1058 for (i = 2; i < ctx->argc; i++) {
1059 pre_parse_column_key_value(ctx, ctx->argv[i], table);
1064 cmd_find(struct ctl_context *ctx)
1066 const char *column_names = shash_find_data(&ctx->options, "--columns");
1067 const struct ovsdb_idl_column **columns;
1068 const char *table_name = ctx->argv[1];
1069 const struct ctl_table_class *table;
1070 const struct ovsdb_idl_row *row;
1074 table = get_table(table_name);
1075 parse_column_names(column_names, table, &columns, &n_columns);
1076 out = ctx->table = list_make_table(columns, n_columns);
1077 for (row = ovsdb_idl_first_row(ctx->idl, table->class); row;
1078 row = ovsdb_idl_next_row(row)) {
1081 for (i = 2; i < ctx->argc; i++) {
1082 if (!is_condition_satisfied(table, row, ctx->argv[i],
1087 list_record(row, columns, n_columns, out);
1094 /* Sets the column of 'row' in 'table'. */
1096 set_column(const struct ctl_table_class *table,
1097 const struct ovsdb_idl_row *row, const char *arg,
1098 struct ovsdb_symbol_table *symtab)
1100 const struct ovsdb_idl_column *column;
1101 char *key_string, *value_string;
1104 error = parse_column_key_value(arg, table, &column, &key_string,
1105 NULL, NULL, 0, &value_string);
1106 die_if_error(error);
1107 if (!value_string) {
1108 ctl_fatal("%s: missing value", arg);
1110 check_mutable(row, column);
1113 union ovsdb_atom key, value;
1114 struct ovsdb_datum datum;
1116 if (column->type.value.type == OVSDB_TYPE_VOID) {
1117 ctl_fatal("cannot specify key to set for non-map column %s",
1121 die_if_error(ovsdb_atom_from_string(&key, &column->type.key,
1122 key_string, symtab));
1123 die_if_error(ovsdb_atom_from_string(&value, &column->type.value,
1124 value_string, symtab));
1126 ovsdb_datum_init_empty(&datum);
1127 ovsdb_datum_add_unsafe(&datum, &key, &value, &column->type);
1129 ovsdb_atom_destroy(&key, column->type.key.type);
1130 ovsdb_atom_destroy(&value, column->type.value.type);
1132 ovsdb_datum_union(&datum, ovsdb_idl_read(row, column),
1133 &column->type, false);
1134 ovsdb_idl_txn_verify(row, column);
1135 ovsdb_idl_txn_write(row, column, &datum);
1137 struct ovsdb_datum datum;
1139 die_if_error(ovsdb_datum_from_string(&datum, &column->type,
1140 value_string, symtab));
1141 ovsdb_idl_txn_write(row, column, &datum);
1149 pre_cmd_set(struct ctl_context *ctx)
1151 const char *table_name = ctx->argv[1];
1152 const struct ctl_table_class *table;
1155 table = pre_get_table(ctx, table_name);
1156 for (i = 3; i < ctx->argc; i++) {
1157 pre_parse_column_key_value(ctx, ctx->argv[i], table);
1162 cmd_set(struct ctl_context *ctx)
1164 bool must_exist = !shash_find(&ctx->options, "--if-exists");
1165 const char *table_name = ctx->argv[1];
1166 const char *record_id = ctx->argv[2];
1167 const struct ctl_table_class *table;
1168 const struct ovsdb_idl_row *row;
1171 table = get_table(table_name);
1172 row = get_row(ctx, table, record_id, must_exist);
1177 for (i = 3; i < ctx->argc; i++) {
1178 set_column(table, row, ctx->argv[i], ctx->symtab);
1181 invalidate_cache(ctx);
1185 pre_cmd_add(struct ctl_context *ctx)
1187 const char *table_name = ctx->argv[1];
1188 const char *column_name = ctx->argv[3];
1189 const struct ctl_table_class *table;
1190 const struct ovsdb_idl_column *column;
1192 table = pre_get_table(ctx, table_name);
1193 pre_get_column(ctx, table, column_name, &column);
1197 cmd_add(struct ctl_context *ctx)
1199 bool must_exist = !shash_find(&ctx->options, "--if-exists");
1200 const char *table_name = ctx->argv[1];
1201 const char *record_id = ctx->argv[2];
1202 const char *column_name = ctx->argv[3];
1203 const struct ctl_table_class *table;
1204 const struct ovsdb_idl_column *column;
1205 const struct ovsdb_idl_row *row;
1206 const struct ovsdb_type *type;
1207 struct ovsdb_datum old;
1210 table = get_table(table_name);
1211 die_if_error(get_column(table, column_name, &column));
1212 row = get_row(ctx, table, record_id, must_exist);
1216 check_mutable(row, column);
1218 type = &column->type;
1219 ovsdb_datum_clone(&old, ovsdb_idl_read(row, column), &column->type);
1220 for (i = 4; i < ctx->argc; i++) {
1221 struct ovsdb_type add_type;
1222 struct ovsdb_datum add;
1226 add_type.n_max = UINT_MAX;
1227 die_if_error(ovsdb_datum_from_string(&add, &add_type, ctx->argv[i],
1229 ovsdb_datum_union(&old, &add, type, false);
1230 ovsdb_datum_destroy(&add, type);
1232 if (old.n > type->n_max) {
1233 ctl_fatal("\"add\" operation would put %u %s in column %s of "
1234 "table %s but the maximum number is %u",
1236 type->value.type == OVSDB_TYPE_VOID ? "values" : "pairs",
1237 column->name, table->class->name, type->n_max);
1239 ovsdb_idl_txn_verify(row, column);
1240 ovsdb_idl_txn_write(row, column, &old);
1242 invalidate_cache(ctx);
1246 pre_cmd_remove(struct ctl_context *ctx)
1248 const char *table_name = ctx->argv[1];
1249 const char *column_name = ctx->argv[3];
1250 const struct ctl_table_class *table;
1251 const struct ovsdb_idl_column *column;
1253 table = pre_get_table(ctx, table_name);
1254 pre_get_column(ctx, table, column_name, &column);
1258 cmd_remove(struct ctl_context *ctx)
1260 bool must_exist = !shash_find(&ctx->options, "--if-exists");
1261 const char *table_name = ctx->argv[1];
1262 const char *record_id = ctx->argv[2];
1263 const char *column_name = ctx->argv[3];
1264 const struct ctl_table_class *table;
1265 const struct ovsdb_idl_column *column;
1266 const struct ovsdb_idl_row *row;
1267 const struct ovsdb_type *type;
1268 struct ovsdb_datum old;
1271 table = get_table(table_name);
1272 die_if_error(get_column(table, column_name, &column));
1273 row = get_row(ctx, table, record_id, must_exist);
1277 check_mutable(row, column);
1279 type = &column->type;
1280 ovsdb_datum_clone(&old, ovsdb_idl_read(row, column), &column->type);
1281 for (i = 4; i < ctx->argc; i++) {
1282 struct ovsdb_type rm_type;
1283 struct ovsdb_datum rm;
1288 rm_type.n_max = UINT_MAX;
1289 error = ovsdb_datum_from_string(&rm, &rm_type,
1290 ctx->argv[i], ctx->symtab);
1293 if (ovsdb_type_is_map(&rm_type)) {
1294 rm_type.value.type = OVSDB_TYPE_VOID;
1296 die_if_error(ovsdb_datum_from_string(
1297 &rm, &rm_type, ctx->argv[i], ctx->symtab));
1299 ctl_fatal("%s", error);
1302 ovsdb_datum_subtract(&old, type, &rm, &rm_type);
1303 ovsdb_datum_destroy(&rm, &rm_type);
1305 if (old.n < type->n_min) {
1306 ctl_fatal("\"remove\" operation would put %u %s in column %s of "
1307 "table %s but the minimum number is %u",
1309 type->value.type == OVSDB_TYPE_VOID ? "values" : "pairs",
1310 column->name, table->class->name, type->n_min);
1312 ovsdb_idl_txn_verify(row, column);
1313 ovsdb_idl_txn_write(row, column, &old);
1315 invalidate_cache(ctx);
1319 pre_cmd_clear(struct ctl_context *ctx)
1321 const char *table_name = ctx->argv[1];
1322 const struct ctl_table_class *table;
1325 table = pre_get_table(ctx, table_name);
1326 for (i = 3; i < ctx->argc; i++) {
1327 const struct ovsdb_idl_column *column;
1329 pre_get_column(ctx, table, ctx->argv[i], &column);
1334 cmd_clear(struct ctl_context *ctx)
1336 bool must_exist = !shash_find(&ctx->options, "--if-exists");
1337 const char *table_name = ctx->argv[1];
1338 const char *record_id = ctx->argv[2];
1339 const struct ctl_table_class *table;
1340 const struct ovsdb_idl_row *row;
1343 table = get_table(table_name);
1344 row = get_row(ctx, table, record_id, must_exist);
1349 for (i = 3; i < ctx->argc; i++) {
1350 const struct ovsdb_idl_column *column;
1351 const struct ovsdb_type *type;
1352 struct ovsdb_datum datum;
1354 die_if_error(get_column(table, ctx->argv[i], &column));
1355 check_mutable(row, column);
1357 type = &column->type;
1358 if (type->n_min > 0) {
1359 ctl_fatal("\"clear\" operation cannot be applied to column %s "
1360 "of table %s, which is not allowed to be empty",
1361 column->name, table->class->name);
1364 ovsdb_datum_init_empty(&datum);
1365 ovsdb_idl_txn_write(row, column, &datum);
1368 invalidate_cache(ctx);
1372 pre_create(struct ctl_context *ctx)
1374 const char *id = shash_find_data(&ctx->options, "--id");
1375 const char *table_name = ctx->argv[1];
1376 const struct ctl_table_class *table;
1378 table = get_table(table_name);
1379 if (!id && !table->class->is_root) {
1380 VLOG_WARN("applying \"create\" command to table %s without --id "
1381 "option will have no effect", table->class->name);
1386 cmd_create(struct ctl_context *ctx)
1388 const char *id = shash_find_data(&ctx->options, "--id");
1389 const char *table_name = ctx->argv[1];
1390 const struct ctl_table_class *table = get_table(table_name);
1391 const struct ovsdb_idl_row *row;
1392 const struct uuid *uuid;
1396 struct ovsdb_symbol *symbol = create_symbol(ctx->symtab, id, NULL);
1397 if (table->class->is_root) {
1398 /* This table is in the root set, meaning that rows created in it
1399 * won't disappear even if they are unreferenced, so disable
1400 * warnings about that by pretending that there is a reference. */
1401 symbol->strong_ref = true;
1403 uuid = &symbol->uuid;
1408 row = ovsdb_idl_txn_insert(ctx->txn, table->class, uuid);
1409 for (i = 2; i < ctx->argc; i++) {
1410 set_column(table, row, ctx->argv[i], ctx->symtab);
1412 ds_put_format(&ctx->output, UUID_FMT, UUID_ARGS(&row->uuid));
1415 /* This function may be used as the 'postprocess' function for commands that
1416 * insert new rows into the database. It expects that the command's 'run'
1417 * function prints the UUID reported by ovsdb_idl_txn_insert() as the command's
1418 * sole output. It replaces that output by the row's permanent UUID assigned
1419 * by the database server and appends a new-line.
1421 * Currently we use this only for "create", because the higher-level commands
1422 * are supposed to be independent of the actual structure of the vswitch
1425 post_create(struct ctl_context *ctx)
1427 const struct uuid *real;
1430 if (!uuid_from_string(&dummy, ds_cstr(&ctx->output))) {
1433 real = ovsdb_idl_txn_get_insert_uuid(ctx->txn, &dummy);
1435 ds_clear(&ctx->output);
1436 ds_put_format(&ctx->output, UUID_FMT, UUID_ARGS(real));
1438 ds_put_char(&ctx->output, '\n');
1442 pre_cmd_destroy(struct ctl_context *ctx)
1444 const char *table_name = ctx->argv[1];
1446 pre_get_table(ctx, table_name);
1450 cmd_destroy(struct ctl_context *ctx)
1452 bool must_exist = !shash_find(&ctx->options, "--if-exists");
1453 bool delete_all = shash_find(&ctx->options, "--all");
1454 const char *table_name = ctx->argv[1];
1455 const struct ctl_table_class *table;
1458 table = get_table(table_name);
1460 if (delete_all && ctx->argc > 2) {
1461 ctl_fatal("--all and records argument should not be specified together");
1464 if (delete_all && !must_exist) {
1465 ctl_fatal("--all and --if-exists should not be specified together");
1469 const struct ovsdb_idl_row *row;
1470 const struct ovsdb_idl_row *next_row;
1472 for (row = ovsdb_idl_first_row(ctx->idl, table->class);
1474 next_row = ovsdb_idl_next_row(row);
1475 ovsdb_idl_txn_delete(row);
1479 for (i = 2; i < ctx->argc; i++) {
1480 const struct ovsdb_idl_row *row;
1482 row = get_row(ctx, table, ctx->argv[i], must_exist);
1484 ovsdb_idl_txn_delete(row);
1488 invalidate_cache(ctx);
1492 pre_cmd_wait_until(struct ctl_context *ctx)
1494 const char *table_name = ctx->argv[1];
1495 const struct ctl_table_class *table;
1498 table = pre_get_table(ctx, table_name);
1500 for (i = 3; i < ctx->argc; i++) {
1501 pre_parse_column_key_value(ctx, ctx->argv[i], table);
1506 cmd_wait_until(struct ctl_context *ctx)
1508 const char *table_name = ctx->argv[1];
1509 const char *record_id = ctx->argv[2];
1510 const struct ctl_table_class *table;
1511 const struct ovsdb_idl_row *row;
1514 table = get_table(table_name);
1516 row = get_row(ctx, table, record_id, false);
1518 ctx->try_again = true;
1522 for (i = 3; i < ctx->argc; i++) {
1523 if (!is_condition_satisfied(table, row, ctx->argv[i], ctx->symtab)) {
1524 ctx->try_again = true;
1530 /* Parses one command. */
1532 parse_command(int argc, char *argv[], struct shash *local_options,
1533 struct ctl_command *command)
1535 const struct ctl_command_syntax *p;
1536 struct shash_node *node;
1540 shash_init(&command->options);
1541 shash_swap(local_options, &command->options);
1542 for (i = 0; i < argc; i++) {
1543 const char *option = argv[i];
1547 if (option[0] != '-') {
1551 equals = strchr(option, '=');
1553 key = xmemdup0(option, equals - option);
1554 value = xstrdup(equals + 1);
1556 key = xstrdup(option);
1560 if (shash_find(&command->options, key)) {
1561 ctl_fatal("'%s' option specified multiple times", argv[i]);
1563 shash_add_nocopy(&command->options, key, value);
1566 ctl_fatal("missing command name (use --help for help)");
1569 p = shash_find_data(&all_commands, argv[i]);
1571 ctl_fatal("unknown command '%s'; use --help for help", argv[i]);
1574 SHASH_FOR_EACH (node, &command->options) {
1575 const char *s = strstr(p->options, node->name);
1576 int end = s ? s[strlen(node->name)] : EOF;
1578 if (end != '=' && end != ',' && end != ' ' && end != '\0') {
1579 ctl_fatal("'%s' command has no '%s' option",
1580 argv[i], node->name);
1582 if ((end == '=') != (node->data != NULL)) {
1584 ctl_fatal("missing argument to '%s' option on '%s' "
1585 "command", node->name, argv[i]);
1587 ctl_fatal("'%s' option on '%s' does not accept an "
1588 "argument", node->name, argv[i]);
1593 n_arg = argc - i - 1;
1594 if (n_arg < p->min_args) {
1595 ctl_fatal("'%s' command requires at least %d arguments",
1596 p->name, p->min_args);
1597 } else if (n_arg > p->max_args) {
1600 for (j = i + 1; j < argc; j++) {
1601 if (argv[j][0] == '-') {
1602 ctl_fatal("'%s' command takes at most %d arguments "
1603 "(note that options must precede command "
1604 "names and follow a \"--\" argument)",
1605 p->name, p->max_args);
1609 ctl_fatal("'%s' command takes at most %d arguments",
1610 p->name, p->max_args);
1613 command->syntax = p;
1614 command->argc = n_arg + 1;
1615 command->argv = &argv[i];
1619 pre_cmd_show(struct ctl_context *ctx)
1621 const struct cmd_show_table *show;
1623 for (show = cmd_show_tables; show->table; show++) {
1626 ovsdb_idl_add_table(ctx->idl, show->table);
1627 if (show->name_column) {
1628 ovsdb_idl_add_column(ctx->idl, show->name_column);
1630 for (i = 0; i < ARRAY_SIZE(show->columns); i++) {
1631 const struct ovsdb_idl_column *column = show->columns[i];
1633 ovsdb_idl_add_column(ctx->idl, column);
1636 if (show->wref_table.table) {
1637 ovsdb_idl_add_table(ctx->idl, show->wref_table.table);
1639 if (show->wref_table.name_column) {
1640 ovsdb_idl_add_column(ctx->idl, show->wref_table.name_column);
1642 if (show->wref_table.wref_column) {
1643 ovsdb_idl_add_column(ctx->idl, show->wref_table.wref_column);
1648 static const struct cmd_show_table *
1649 cmd_show_find_table_by_row(const struct ovsdb_idl_row *row)
1651 const struct cmd_show_table *show;
1653 for (show = cmd_show_tables; show->table; show++) {
1654 if (show->table == row->table->class) {
1661 static const struct cmd_show_table *
1662 cmd_show_find_table_by_name(const char *name)
1664 const struct cmd_show_table *show;
1666 for (show = cmd_show_tables; show->table; show++) {
1667 if (!strcmp(show->table->name, name)) {
1674 /* Prints table entries that weak reference the 'cur_row'. */
1676 cmd_show_weak_ref(struct ctl_context *ctx, const struct cmd_show_table *show,
1677 const struct ovsdb_idl_row *cur_row, int level)
1679 const struct ovsdb_idl_row *row_wref;
1680 const struct ovsdb_idl_table_class *table = show->wref_table.table;
1681 const struct ovsdb_idl_column *name_column
1682 = show->wref_table.name_column;
1683 const struct ovsdb_idl_column *wref_column
1684 = show->wref_table.wref_column;
1686 if (!table || !name_column || !wref_column) {
1690 for (row_wref = ovsdb_idl_first_row(ctx->idl, table); row_wref;
1691 row_wref = ovsdb_idl_next_row(row_wref)) {
1692 const struct ovsdb_datum *wref_datum
1693 = ovsdb_idl_read(row_wref, wref_column);
1694 /* If weak reference refers to the 'cur_row', prints it. */
1696 && uuid_equals(&cur_row->uuid, &wref_datum->keys[0].uuid)) {
1697 const struct ovsdb_datum *name_datum
1698 = ovsdb_idl_read(row_wref, name_column);
1699 ds_put_char_multiple(&ctx->output, ' ', (level + 1) * 4);
1700 ds_put_format(&ctx->output, "%s ", table->name);
1701 ovsdb_datum_to_string(name_datum, &name_column->type, &ctx->output);
1702 ds_put_char(&ctx->output, '\n');
1707 /* 'shown' records the tables that has been displayed by the current
1708 * command to avoid duplicated prints.
1711 cmd_show_row(struct ctl_context *ctx, const struct ovsdb_idl_row *row,
1712 int level, struct sset *shown)
1714 const struct cmd_show_table *show = cmd_show_find_table_by_row(row);
1717 ds_put_char_multiple(&ctx->output, ' ', level * 4);
1718 if (show && show->name_column) {
1719 const struct ovsdb_datum *datum;
1721 ds_put_format(&ctx->output, "%s ", show->table->name);
1722 datum = ovsdb_idl_read(row, show->name_column);
1723 ovsdb_datum_to_string(datum, &show->name_column->type, &ctx->output);
1725 ds_put_format(&ctx->output, UUID_FMT, UUID_ARGS(&row->uuid));
1727 ds_put_char(&ctx->output, '\n');
1729 if (!show || sset_find(shown, show->table->name)) {
1733 sset_add(shown, show->table->name);
1734 for (i = 0; i < ARRAY_SIZE(show->columns); i++) {
1735 const struct ovsdb_idl_column *column = show->columns[i];
1736 const struct ovsdb_datum *datum;
1742 datum = ovsdb_idl_read(row, column);
1743 if (column->type.key.type == OVSDB_TYPE_UUID &&
1744 column->type.key.u.uuid.refTableName) {
1745 const struct cmd_show_table *ref_show;
1748 ref_show = cmd_show_find_table_by_name(
1749 column->type.key.u.uuid.refTableName);
1751 for (j = 0; j < datum->n; j++) {
1752 const struct ovsdb_idl_row *ref_row;
1754 ref_row = ovsdb_idl_get_row_for_uuid(ctx->idl,
1756 &datum->keys[j].uuid);
1758 cmd_show_row(ctx, ref_row, level + 1, shown);
1763 } else if (ovsdb_type_is_map(&column->type) &&
1764 column->type.value.type == OVSDB_TYPE_UUID &&
1765 column->type.value.u.uuid.refTableName) {
1766 const struct cmd_show_table *ref_show;
1769 /* Prints the key to ref'ed table name map if the ref'ed table
1770 * is also defined in 'cmd_show_tables'. */
1771 ref_show = cmd_show_find_table_by_name(
1772 column->type.value.u.uuid.refTableName);
1773 if (ref_show && ref_show->name_column) {
1774 ds_put_char_multiple(&ctx->output, ' ', (level + 1) * 4);
1775 ds_put_format(&ctx->output, "%s:\n", column->name);
1776 for (j = 0; j < datum->n; j++) {
1777 const struct ovsdb_idl_row *ref_row;
1779 ref_row = ovsdb_idl_get_row_for_uuid(ctx->idl,
1781 &datum->values[j].uuid);
1783 ds_put_char_multiple(&ctx->output, ' ', (level + 2) * 4);
1784 ovsdb_atom_to_string(&datum->keys[j], column->type.key.type,
1786 ds_put_char(&ctx->output, '=');
1788 const struct ovsdb_datum *ref_datum;
1790 ref_datum = ovsdb_idl_read(ref_row,
1791 ref_show->name_column);
1792 ovsdb_datum_to_string(ref_datum,
1793 &ref_show->name_column->type,
1796 ds_put_cstr(&ctx->output, "\"<null>\"");
1798 ds_put_char(&ctx->output, '\n');
1804 if (!ovsdb_datum_is_default(datum, &column->type)) {
1805 ds_put_char_multiple(&ctx->output, ' ', (level + 1) * 4);
1806 ds_put_format(&ctx->output, "%s: ", column->name);
1807 ovsdb_datum_to_string(datum, &column->type, &ctx->output);
1808 ds_put_char(&ctx->output, '\n');
1811 cmd_show_weak_ref(ctx, show, row, level);
1812 sset_find_and_delete_assert(shown, show->table->name);
1816 cmd_show(struct ctl_context *ctx)
1818 const struct ovsdb_idl_row *row;
1819 struct sset shown = SSET_INITIALIZER(&shown);
1821 for (row = ovsdb_idl_first_row(ctx->idl, cmd_show_tables[0].table);
1822 row; row = ovsdb_idl_next_row(row)) {
1823 cmd_show_row(ctx, row, 0, &shown);
1826 ovs_assert(sset_is_empty(&shown));
1827 sset_destroy(&shown);
1831 /* Given pointer to dynamic array 'options_p', array's current size
1832 * 'allocated_options_p' and number of added options 'n_options_p',
1833 * adds all command options to the array. Enlarges the array if
1836 ctl_add_cmd_options(struct option **options_p, size_t *n_options_p,
1837 size_t *allocated_options_p, int opt_val)
1840 const struct shash_node *node;
1841 size_t n_existing_options = *n_options_p;
1843 SHASH_FOR_EACH (node, &all_commands) {
1844 const struct ctl_command_syntax *p = node->data;
1846 if (p->options[0]) {
1847 char *save_ptr = NULL;
1851 s = xstrdup(p->options);
1852 for (name = strtok_r(s, ",", &save_ptr); name != NULL;
1853 name = strtok_r(NULL, ",", &save_ptr)) {
1857 ovs_assert(name[0] == '-' && name[1] == '-' && name[2]);
1860 equals = strchr(name, '=');
1862 has_arg = required_argument;
1865 has_arg = no_argument;
1868 o = find_option(name, *options_p, *n_options_p);
1870 ovs_assert(o - *options_p >= n_existing_options);
1871 ovs_assert(o->has_arg == has_arg);
1873 o = add_option(options_p, n_options_p, allocated_options_p);
1874 o->name = xstrdup(name);
1875 o->has_arg = has_arg;
1884 o = add_option(options_p, n_options_p, allocated_options_p);
1885 memset(o, 0, sizeof *o);
1888 /* Parses command-line input for commands. */
1889 struct ctl_command *
1890 ctl_parse_commands(int argc, char *argv[], struct shash *local_options,
1891 size_t *n_commandsp)
1893 struct ctl_command *commands;
1894 size_t n_commands, allocated_commands;
1898 n_commands = allocated_commands = 0;
1900 for (start = i = 0; i <= argc; i++) {
1901 if (i == argc || !strcmp(argv[i], "--")) {
1903 if (n_commands >= allocated_commands) {
1904 struct ctl_command *c;
1906 commands = x2nrealloc(commands, &allocated_commands,
1908 for (c = commands; c < &commands[n_commands]; c++) {
1909 shash_moved(&c->options);
1912 parse_command(i - start, &argv[start], local_options,
1913 &commands[n_commands++]);
1914 } else if (!shash_is_empty(local_options)) {
1915 ctl_fatal("missing command name (use --help for help)");
1921 ctl_fatal("missing command name (use --help for help)");
1923 *n_commandsp = n_commands;
1927 /* Prints all registered commands. */
1929 ctl_print_commands(void)
1931 const struct shash_node *node;
1933 SHASH_FOR_EACH (node, &all_commands) {
1934 const struct ctl_command_syntax *p = node->data;
1935 char *options = xstrdup(p->options);
1936 char *options_begin = options;
1939 for (item = strsep(&options, ","); item != NULL;
1940 item = strsep(&options, ",")) {
1941 if (item[0] != '\0') {
1942 printf("[%s] ", item);
1945 printf(",%s,", p->name);
1946 print_command_arguments(p);
1949 free(options_begin);
1955 /* Given array of options 'options', prints them. */
1957 ctl_print_options(const struct option *options)
1959 for (; options->name; options++) {
1960 const struct option *o = options;
1962 printf("--%s%s\n", o->name, o->has_arg ? "=ARG" : "");
1963 if (o->flag == NULL && o->val > 0 && o->val <= UCHAR_MAX) {
1964 printf("-%c%s\n", o->val, o->has_arg ? " ARG" : "");
1971 /* Returns the default local database path. */
1973 ctl_default_db(void)
1977 def = xasprintf("unix:%s/db.sock", ovs_rundir());
1982 /* Returns true if it looks like this set of arguments might modify the
1983 * database, otherwise false. (Not very smart, so it's prone to false
1986 ctl_might_write_to_db(char **argv)
1988 for (; *argv; argv++) {
1989 const struct ctl_command_syntax *p = shash_find_data(&all_commands,
1991 if (p && p->mode == RW) {
1999 ctl_fatal(const char *format, ...)
2004 va_start(args, format);
2005 message = xvasprintf(format, args);
2008 vlog_set_levels(&this_module, VLF_CONSOLE, VLL_OFF);
2009 VLOG_ERR("%s", message);
2010 ovs_error(0, "%s", message);
2011 ctl_exit(EXIT_FAILURE);
2014 /* Frees the current transaction and the underlying IDL and then calls
2017 * Freeing the transaction and the IDL is not strictly necessary, but it makes
2018 * for a clean memory leak report from valgrind in the normal case. That makes
2019 * it easier to notice real memory leaks. */
2021 ctl_exit(int status)
2023 if (ctl_exit_func) {
2024 ctl_exit_func(status);
2029 /* Comman database commands to be registered. */
2030 static const struct ctl_command_syntax db_ctl_commands[] = {
2031 {"comment", 0, INT_MAX, "[ARG]...", NULL, NULL, NULL, "", RO},
2032 {"get", 2, INT_MAX, "TABLE RECORD [COLUMN[:KEY]]...",pre_cmd_get, cmd_get,
2033 NULL, "--if-exists,--id=", RO},
2034 {"list", 1, INT_MAX, "TABLE [RECORD]...", pre_cmd_list, cmd_list, NULL,
2035 "--if-exists,--columns=", RO},
2036 {"find", 1, INT_MAX, "TABLE [COLUMN[:KEY]=VALUE]...", pre_cmd_find,
2037 cmd_find, NULL, "--columns=", RO},
2038 {"set", 3, INT_MAX, "TABLE RECORD COLUMN[:KEY]=VALUE...", pre_cmd_set,
2039 cmd_set, NULL, "--if-exists", RW},
2040 {"add", 4, INT_MAX, "TABLE RECORD COLUMN [KEY=]VALUE...", pre_cmd_add,
2041 cmd_add, NULL, "--if-exists", RW},
2042 {"remove", 4, INT_MAX, "TABLE RECORD COLUMN KEY|VALUE|KEY=VALUE...",
2043 pre_cmd_remove, cmd_remove, NULL, "--if-exists", RW},
2044 {"clear", 3, INT_MAX, "TABLE RECORD COLUMN...", pre_cmd_clear, cmd_clear,
2045 NULL, "--if-exists", RW},
2046 {"create", 2, INT_MAX, "TABLE COLUMN[:KEY]=VALUE...", pre_create,
2047 cmd_create, post_create, "--id=", RW},
2048 {"destroy", 1, INT_MAX, "TABLE [RECORD]...", pre_cmd_destroy, cmd_destroy,
2049 NULL, "--if-exists,--all", RW},
2050 {"wait-until", 2, INT_MAX, "TABLE RECORD [COLUMN[:KEY]=VALUE]...",
2051 pre_cmd_wait_until, cmd_wait_until, NULL, "", RO},
2052 {NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, RO},
2056 ctl_register_command(const struct ctl_command_syntax *command)
2058 shash_add_assert(&all_commands, command->name, command);
2061 /* Registers commands represented by 'struct ctl_command_syntax's to
2062 * 'all_commands'. The last element of 'commands' must be an all-NULL
2065 ctl_register_commands(const struct ctl_command_syntax *commands)
2067 const struct ctl_command_syntax *p;
2069 for (p = commands; p->name; p++) {
2070 ctl_register_command(p);
2074 /* Registers the 'db_ctl_commands' to 'all_commands'. */
2076 ctl_init(const struct ctl_table_class tables_[],
2077 const struct cmd_show_table cmd_show_tables_[],
2078 void (*ctl_exit_func_)(int status))
2081 ctl_exit_func = ctl_exit_func_;
2082 ctl_register_commands(db_ctl_commands);
2084 cmd_show_tables = cmd_show_tables_;
2085 if (cmd_show_tables) {
2086 static const struct ctl_command_syntax show =
2087 {"show", 0, 0, "", pre_cmd_show, cmd_show, NULL, "", RO};
2088 ctl_register_command(&show);
2092 /* Returns the text for the database commands usage. */
2094 ctl_get_db_cmd_usage(void)
2096 return "Database commands:\n\
2097 list TBL [REC] list RECord (or all records) in TBL\n\
2098 find TBL CONDITION... list records satisfying CONDITION in TBL\n\
2099 get TBL REC COL[:KEY] print values of COLumns in RECord in TBL\n\
2100 set TBL REC COL[:KEY]=VALUE set COLumn values in RECord in TBL\n\
2101 add TBL REC COL [KEY=]VALUE add (KEY=)VALUE to COLumn in RECord in TBL\n\
2102 remove TBL REC COL [KEY=]VALUE remove (KEY=)VALUE from COLumn\n\
2103 clear TBL REC COL clear values from COLumn in RECord in TBL\n\
2104 create TBL COL[:KEY]=VALUE create and initialize new record\n\
2105 destroy TBL REC delete RECord from TBL\n\
2106 wait-until TBL REC [COL[:KEY]=VALUE] wait until condition is true\n\
2107 Potentially unsafe database commands require --force option.\n";
2110 /* Initializes 'ctx' from 'command'. */
2112 ctl_context_init_command(struct ctl_context *ctx,
2113 struct ctl_command *command)
2115 ctx->argc = command->argc;
2116 ctx->argv = command->argv;
2117 ctx->options = command->options;
2119 ds_swap(&ctx->output, &command->output);
2120 ctx->table = command->table;
2121 ctx->try_again = false;
2124 /* Initializes the entire 'ctx'. */
2126 ctl_context_init(struct ctl_context *ctx, struct ctl_command *command,
2127 struct ovsdb_idl *idl, struct ovsdb_idl_txn *txn,
2128 struct ovsdb_symbol_table *symtab,
2129 void (*invalidate_cache)(struct ctl_context *))
2132 ctl_context_init_command(ctx, command);
2136 ctx->symtab = symtab;
2137 ctx->invalidate_cache = invalidate_cache;
2140 /* Completes processing of 'command' within 'ctx'. */
2142 ctl_context_done_command(struct ctl_context *ctx,
2143 struct ctl_command *command)
2145 ds_swap(&ctx->output, &command->output);
2146 command->table = ctx->table;
2149 /* Finishes up with 'ctx'.
2151 * If command is nonnull, first calls ctl_context_done_command() to complete
2152 * processing that command within 'ctx'. */
2154 ctl_context_done(struct ctl_context *ctx,
2155 struct ctl_command *command)
2158 ctl_context_done_command(ctx, command);
2160 invalidate_cache(ctx);
2163 void ctl_set_column(const char *table_name,
2164 const struct ovsdb_idl_row *row, const char *arg,
2165 struct ovsdb_symbol_table *symtab)
2167 set_column(get_table(table_name), row, arg, symtab);