2 * Copyright (c) 2015 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 "dynamic-string.h"
29 #include "fatal-signal.h"
32 #include "openvswitch/vlog.h"
33 #include "ovsdb-data.h"
34 #include "ovsdb-idl.h"
35 #include "ovsdb-idl-provider.h"
41 VLOG_DEFINE_THIS_MODULE(db_ctl_base);
43 /* The IDL we're using and the current transaction, if any.
44 * This is for use by ctl_exit() only, to allow it to clean up.
45 * Other code should use its context arguments. */
46 struct ovsdb_idl *the_idl;
47 struct ovsdb_idl_txn *the_idl_txn;
49 static struct shash all_commands = SHASH_INITIALIZER(&all_commands);
52 static struct option *
53 find_option(const char *name, struct option *options, size_t n_options)
57 for (i = 0; i < n_options; i++) {
58 if (!strcmp(options[i].name, name)) {
65 static struct option *
66 add_option(struct option **optionsp, size_t *n_optionsp,
67 size_t *allocated_optionsp)
69 if (*n_optionsp >= *allocated_optionsp) {
70 *optionsp = x2nrealloc(*optionsp, allocated_optionsp,
73 return &(*optionsp)[(*n_optionsp)++];
76 /* Converts the command arguments into format that can be parsed by
77 * bash completion script.
79 * Therein, arguments will be attached with following prefixes:
81 * !argument :: The argument is required
82 * ?argument :: The argument is optional
83 * *argument :: The argument may appear any number (0 or more) times
84 * +argument :: The argument may appear one or more times
88 print_command_arguments(const struct ctl_command_syntax *command)
91 * The argument string is parsed in reverse. We use a stack 'oew_stack' to
92 * keep track of nested optionals. Whenever a ']' is encountered, we push
93 * a bit to 'oew_stack'. The bit is set to 1 if the ']' is not nested.
94 * Subsequently, we pop an entry everytime '[' is met.
96 * We use 'whole_word_is_optional' value to decide whether or not a ! or +
97 * should be added on encountering a space: if the optional surrounds the
98 * whole word then it shouldn't be, but if it is only a part of the word
99 * (i.e. [key=]value), it should be.
101 uint32_t oew_stack = 0;
103 const char *arguments = command->arguments;
104 int length = strlen(arguments);
109 /* Output buffer, written backward from end. */
110 char *output = xmalloc(2 * length);
111 char *outp = output + 2 * length;
114 bool in_repeated = false;
115 bool whole_word_is_optional = false;
117 for (const char *inp = arguments + length; inp > arguments; ) {
121 if (inp[1] == '\0' || inp[1] == ' ' || inp[1] == '.') {
126 /* Checks if the whole word is optional, and sets the
127 * 'whole_word_is_optional' accordingly. */
128 if ((inp == arguments || inp[-1] == ' ') && oew_stack & 1) {
129 *--outp = in_repeated ? '*' : '?';
130 whole_word_is_optional = true;
133 whole_word_is_optional = false;
138 if (!whole_word_is_optional) {
139 *--outp = in_repeated ? '+' : '!';
143 whole_word_is_optional = false;
153 if (arguments[0] != '[' && outp != output + 2 * length - 1) {
154 *--outp = in_repeated ? '+' : '!';
161 die_if_error(char *error)
164 ctl_fatal("%s", error);
169 to_lower_and_underscores(unsigned c)
171 return c == '-' ? '_' : tolower(c);
175 score_partial_match(const char *name, const char *s)
179 if (!strcmp(name, s)) {
182 for (score = 0; ; score++, name++, s++) {
183 if (to_lower_and_underscores(*name) != to_lower_and_underscores(*s)) {
185 } else if (*name == '\0') {
189 return *s == '\0' ? score : 0;
192 static struct ovsdb_symbol *
193 create_symbol(struct ovsdb_symbol_table *symtab, const char *id, bool *newp)
195 struct ovsdb_symbol *symbol;
198 ctl_fatal("row id \"%s\" does not begin with \"@\"", id);
202 *newp = ovsdb_symbol_table_get(symtab, id) == NULL;
205 symbol = ovsdb_symbol_table_insert(symtab, id);
206 if (symbol->created) {
207 ctl_fatal("row id \"%s\" may only be specified on one --id option",
210 symbol->created = true;
214 static const struct ovsdb_idl_row *
215 get_row_by_id(struct ctl_context *ctx, const struct ctl_table_class *table,
216 const struct ctl_row_id *id, const char *record_id)
218 const struct ovsdb_idl_row *referrer, *final;
224 if (!id->name_column) {
225 if (strcmp(record_id, ".")) {
228 referrer = ovsdb_idl_first_row(ctx->idl, id->table);
229 if (!referrer || ovsdb_idl_next_row(referrer)) {
233 const struct ovsdb_idl_row *row;
236 for (row = ovsdb_idl_first_row(ctx->idl, id->table);
238 row = ovsdb_idl_next_row(row))
240 const struct ovsdb_datum *name;
242 name = ovsdb_idl_get(row, id->name_column,
243 OVSDB_TYPE_STRING, OVSDB_TYPE_VOID);
244 if (name->n == 1 && !strcmp(name->keys[0].string, record_id)) {
246 ctl_fatal("multiple rows in %s match \"%s\"",
247 table->class->name, record_id);
258 if (id->uuid_column) {
259 const struct ovsdb_datum *uuid;
261 ovsdb_idl_txn_verify(referrer, id->uuid_column);
262 uuid = ovsdb_idl_get(referrer, id->uuid_column,
263 OVSDB_TYPE_UUID, OVSDB_TYPE_VOID);
265 final = ovsdb_idl_get_row_for_uuid(ctx->idl, table->class,
266 &uuid->keys[0].uuid);
275 static const struct ovsdb_idl_row *
276 get_row(struct ctl_context *ctx,
277 const struct ctl_table_class *table, const char *record_id,
280 const struct ovsdb_idl_row *row;
284 if (uuid_from_string(&uuid, record_id)) {
285 row = ovsdb_idl_get_row_for_uuid(ctx->idl, table->class, &uuid);
290 for (i = 0; i < ARRAY_SIZE(table->row_ids); i++) {
291 row = get_row_by_id(ctx, table, &table->row_ids[i], record_id);
297 if (must_exist && !row) {
298 ctl_fatal("no row \"%s\" in table %s",
299 record_id, table->class->name);
305 get_column(const struct ctl_table_class *table, const char *column_name,
306 const struct ovsdb_idl_column **columnp)
308 const struct ovsdb_idl_column *best_match = NULL;
309 unsigned int best_score = 0;
312 for (i = 0; i < table->class->n_columns; i++) {
313 const struct ovsdb_idl_column *column = &table->class->columns[i];
314 unsigned int score = score_partial_match(column->name, column_name);
315 if (score > best_score) {
318 } else if (score == best_score) {
323 *columnp = best_match;
326 } else if (best_score) {
327 return xasprintf("%s contains more than one column whose name "
328 "matches \"%s\"", table->class->name, column_name);
330 return xasprintf("%s does not contain a column whose name matches "
331 "\"%s\"", table->class->name, column_name);
336 pre_get_column(struct ctl_context *ctx,
337 const struct ctl_table_class *table, const char *column_name,
338 const struct ovsdb_idl_column **columnp)
340 die_if_error(get_column(table, column_name, columnp));
341 ovsdb_idl_add_column(ctx->idl, *columnp);
344 static const struct ctl_table_class *
345 pre_get_table(struct ctl_context *ctx, const char *table_name)
347 const struct ctl_table_class *table_class;
350 table_class = get_table(table_name);
351 ovsdb_idl_add_table(ctx->idl, table_class->class);
353 for (i = 0; i < ARRAY_SIZE(table_class->row_ids); i++) {
354 const struct ctl_row_id *id = &table_class->row_ids[i];
356 ovsdb_idl_add_table(ctx->idl, id->table);
358 if (id->name_column) {
359 ovsdb_idl_add_column(ctx->idl, id->name_column);
361 if (id->uuid_column) {
362 ovsdb_idl_add_column(ctx->idl, id->uuid_column);
370 missing_operator_error(const char *arg, const char **allowed_operators,
376 ds_put_format(&s, "%s: argument does not end in ", arg);
377 ds_put_format(&s, "\"%s\"", allowed_operators[0]);
378 if (n_allowed == 2) {
379 ds_put_format(&s, " or \"%s\"", allowed_operators[1]);
380 } else if (n_allowed > 2) {
383 for (i = 1; i < n_allowed - 1; i++) {
384 ds_put_format(&s, ", \"%s\"", allowed_operators[i]);
386 ds_put_format(&s, ", or \"%s\"", allowed_operators[i]);
388 ds_put_format(&s, " followed by a value.");
390 return ds_steal_cstr(&s);
393 /* Breaks 'arg' apart into a number of fields in the following order:
395 * - The name of a column in 'table', stored into '*columnp'. The column
396 * name may be abbreviated.
398 * - Optionally ':' followed by a key string. The key is stored as a
399 * malloc()'d string into '*keyp', or NULL if no key is present in
402 * - If 'valuep' is nonnull, an operator followed by a value string. The
403 * allowed operators are the 'n_allowed' string in 'allowed_operators',
404 * or just "=" if 'n_allowed' is 0. If 'operatorp' is nonnull, then the
405 * index of the operator within 'allowed_operators' is stored into
406 * '*operatorp'. The value is stored as a malloc()'d string into
407 * '*valuep', or NULL if no value is present in 'arg'.
409 * On success, returns NULL. On failure, returned a malloc()'d string error
410 * message and stores NULL into all of the nonnull output arguments. */
411 static char * OVS_WARN_UNUSED_RESULT
412 parse_column_key_value(const char *arg,
413 const struct ctl_table_class *table,
414 const struct ovsdb_idl_column **columnp, char **keyp,
416 const char **allowed_operators, size_t n_allowed,
423 ovs_assert(!(operatorp && !valuep));
429 /* Parse column name. */
430 error = ovsdb_token_parse(&p, &column_name);
434 if (column_name[0] == '\0') {
436 error = xasprintf("%s: missing column name", arg);
439 error = get_column(table, column_name, columnp);
445 /* Parse key string. */
448 error = ovsdb_token_parse(&p, keyp);
454 /* Parse value string. */
460 if (!allowed_operators) {
461 static const char *equals = "=";
462 allowed_operators = =
468 for (i = 0; i < n_allowed; i++) {
469 const char *op = allowed_operators[i];
470 size_t op_len = strlen(op);
472 if (op_len > best_len && !strncmp(op, p, op_len) && p[op_len]) {
478 error = missing_operator_error(arg, allowed_operators, n_allowed);
485 *valuep = xstrdup(p + best_len);
488 error = xasprintf("%s: trailing garbage \"%s\" in argument",
509 static const struct ovsdb_idl_column *
510 pre_parse_column_key_value(struct ctl_context *ctx,
512 const struct ctl_table_class *table)
514 const struct ovsdb_idl_column *column;
519 die_if_error(ovsdb_token_parse(&p, &column_name));
520 if (column_name[0] == '\0') {
521 ctl_fatal("%s: missing column name", arg);
524 pre_get_column(ctx, table, column_name, &column);
531 check_mutable(const struct ovsdb_idl_row *row,
532 const struct ovsdb_idl_column *column)
534 if (!ovsdb_idl_is_mutable(row, column)) {
535 ctl_fatal("cannot modify read-only column %s in table %s",
536 column->name, row->table->class->name);
541 RELOP(RELOP_EQ, "=") \
542 RELOP(RELOP_NE, "!=") \
543 RELOP(RELOP_LT, "<") \
544 RELOP(RELOP_GT, ">") \
545 RELOP(RELOP_LE, "<=") \
546 RELOP(RELOP_GE, ">=") \
547 RELOP(RELOP_SET_EQ, "{=}") \
548 RELOP(RELOP_SET_NE, "{!=}") \
549 RELOP(RELOP_SET_LT, "{<}") \
550 RELOP(RELOP_SET_GT, "{>}") \
551 RELOP(RELOP_SET_LE, "{<=}") \
552 RELOP(RELOP_SET_GE, "{>=}")
555 #define RELOP(ENUM, STRING) ENUM,
561 is_set_operator(enum relop op)
563 return (op == RELOP_SET_EQ || op == RELOP_SET_NE ||
564 op == RELOP_SET_LT || op == RELOP_SET_GT ||
565 op == RELOP_SET_LE || op == RELOP_SET_GE);
569 evaluate_relop(const struct ovsdb_datum *a, const struct ovsdb_datum *b,
570 const struct ovsdb_type *type, enum relop op)
575 return ovsdb_datum_compare_3way(a, b, type) == 0;
578 return ovsdb_datum_compare_3way(a, b, type) != 0;
580 return ovsdb_datum_compare_3way(a, b, type) < 0;
582 return ovsdb_datum_compare_3way(a, b, type) > 0;
584 return ovsdb_datum_compare_3way(a, b, type) <= 0;
586 return ovsdb_datum_compare_3way(a, b, type) >= 0;
589 return b->n > a->n && ovsdb_datum_includes_all(a, b, type);
591 return a->n > b->n && ovsdb_datum_includes_all(b, a, type);
593 return ovsdb_datum_includes_all(a, b, type);
595 return ovsdb_datum_includes_all(b, a, type);
603 is_condition_satisfied(const struct ctl_table_class *table,
604 const struct ovsdb_idl_row *row, const char *arg,
605 struct ovsdb_symbol_table *symtab)
607 static const char *operators[] = {
608 #define RELOP(ENUM, STRING) STRING,
613 const struct ovsdb_idl_column *column;
614 const struct ovsdb_datum *have_datum;
615 char *key_string, *value_string;
616 struct ovsdb_type type;
621 error = parse_column_key_value(arg, table, &column, &key_string,
622 &operator, operators, ARRAY_SIZE(operators),
626 ctl_fatal("%s: missing value", arg);
630 type.n_max = UINT_MAX;
632 have_datum = ovsdb_idl_read(row, column);
634 union ovsdb_atom want_key;
635 struct ovsdb_datum b;
638 if (column->type.value.type == OVSDB_TYPE_VOID) {
639 ctl_fatal("cannot specify key to check for non-map column %s",
643 die_if_error(ovsdb_atom_from_string(&want_key, &column->type.key,
644 key_string, symtab));
646 type.key = type.value;
647 type.value.type = OVSDB_TYPE_VOID;
648 die_if_error(ovsdb_datum_from_string(&b, &type, value_string, symtab));
650 idx = ovsdb_datum_find_key(have_datum,
651 &want_key, column->type.key.type);
652 if (idx == UINT_MAX && !is_set_operator(operator)) {
655 struct ovsdb_datum a;
657 if (idx != UINT_MAX) {
659 a.keys = &have_datum->values[idx];
667 retval = evaluate_relop(&a, &b, &type, operator);
670 ovsdb_atom_destroy(&want_key, column->type.key.type);
671 ovsdb_datum_destroy(&b, &type);
673 struct ovsdb_datum want_datum;
675 die_if_error(ovsdb_datum_from_string(&want_datum, &column->type,
676 value_string, symtab));
677 retval = evaluate_relop(have_datum, &want_datum, &type, operator);
678 ovsdb_datum_destroy(&want_datum, &column->type);
688 invalidate_cache(struct ctl_context *ctx)
690 if (ctx->invalidate_cache) {
691 (ctx->invalidate_cache)(ctx);
696 pre_cmd_get(struct ctl_context *ctx)
698 const char *id = shash_find_data(&ctx->options, "--id");
699 const char *table_name = ctx->argv[1];
700 const struct ctl_table_class *table;
703 /* Using "get" without --id or a column name could possibly make sense.
704 * Maybe, for example, a *ctl command run wants to assert that a row
705 * exists. But it is unlikely that an interactive user would want to do
706 * that, so issue a warning if we're running on a terminal. */
707 if (!id && ctx->argc <= 3 && isatty(STDOUT_FILENO)) {
708 VLOG_WARN("\"get\" command without row arguments or \"--id\" is "
709 "possibly erroneous");
712 table = pre_get_table(ctx, table_name);
713 for (i = 3; i < ctx->argc; i++) {
714 if (!strcasecmp(ctx->argv[i], "_uuid")
715 || !strcasecmp(ctx->argv[i], "-uuid")) {
719 pre_parse_column_key_value(ctx, ctx->argv[i], table);
724 cmd_get(struct ctl_context *ctx)
726 const char *id = shash_find_data(&ctx->options, "--id");
727 bool must_exist = !shash_find(&ctx->options, "--if-exists");
728 const char *table_name = ctx->argv[1];
729 const char *record_id = ctx->argv[2];
730 const struct ctl_table_class *table;
731 const struct ovsdb_idl_row *row;
732 struct ds *out = &ctx->output;
735 if (id && !must_exist) {
736 ctl_fatal("--if-exists and --id may not be specified together");
739 table = get_table(table_name);
740 row = get_row(ctx, table, record_id, must_exist);
746 struct ovsdb_symbol *symbol;
749 symbol = create_symbol(ctx->symtab, id, &new);
751 ctl_fatal("row id \"%s\" specified on \"get\" command was used "
752 "before it was defined", id);
754 symbol->uuid = row->uuid;
756 /* This symbol refers to a row that already exists, so disable warnings
757 * about it being unreferenced. */
758 symbol->strong_ref = true;
760 for (i = 3; i < ctx->argc; i++) {
761 const struct ovsdb_idl_column *column;
762 const struct ovsdb_datum *datum;
765 /* Special case for obtaining the UUID of a row. We can't just do this
766 * through parse_column_key_value() below since it returns a "struct
767 * ovsdb_idl_column" and the UUID column doesn't have one. */
768 if (!strcasecmp(ctx->argv[i], "_uuid")
769 || !strcasecmp(ctx->argv[i], "-uuid")) {
770 ds_put_format(out, UUID_FMT"\n", UUID_ARGS(&row->uuid));
774 die_if_error(parse_column_key_value(ctx->argv[i], table,
775 &column, &key_string,
776 NULL, NULL, 0, NULL));
778 ovsdb_idl_txn_verify(row, column);
779 datum = ovsdb_idl_read(row, column);
781 union ovsdb_atom key;
784 if (column->type.value.type == OVSDB_TYPE_VOID) {
785 ctl_fatal("cannot specify key to get for non-map column %s",
789 die_if_error(ovsdb_atom_from_string(&key,
791 key_string, ctx->symtab));
793 idx = ovsdb_datum_find_key(datum, &key,
794 column->type.key.type);
795 if (idx == UINT_MAX) {
797 ctl_fatal("no key \"%s\" in %s record \"%s\" column %s",
798 key_string, table->class->name, record_id,
802 ovsdb_atom_to_string(&datum->values[idx],
803 column->type.value.type, out);
805 ovsdb_atom_destroy(&key, column->type.key.type);
807 ovsdb_datum_to_string(datum, &column->type, out);
809 ds_put_char(out, '\n');
816 parse_column_names(const char *column_names,
817 const struct ctl_table_class *table,
818 const struct ovsdb_idl_column ***columnsp,
821 const struct ovsdb_idl_column **columns;
827 n_columns = table->class->n_columns + 1;
828 columns = xmalloc(n_columns * sizeof *columns);
830 for (i = 0; i < table->class->n_columns; i++) {
831 columns[i + 1] = &table->class->columns[i];
834 char *s = xstrdup(column_names);
835 size_t allocated_columns;
836 char *save_ptr = NULL;
840 allocated_columns = n_columns = 0;
841 for (column_name = strtok_r(s, ", ", &save_ptr); column_name;
842 column_name = strtok_r(NULL, ", ", &save_ptr)) {
843 const struct ovsdb_idl_column *column;
845 if (!strcasecmp(column_name, "_uuid")) {
848 die_if_error(get_column(table, column_name, &column));
850 if (n_columns >= allocated_columns) {
851 columns = x2nrealloc(columns, &allocated_columns,
854 columns[n_columns++] = column;
859 ctl_fatal("must specify at least one column name");
863 *n_columnsp = n_columns;
867 pre_list_columns(struct ctl_context *ctx,
868 const struct ctl_table_class *table,
869 const char *column_names)
871 const struct ovsdb_idl_column **columns;
875 parse_column_names(column_names, table, &columns, &n_columns);
876 for (i = 0; i < n_columns; i++) {
878 ovsdb_idl_add_column(ctx->idl, columns[i]);
885 pre_cmd_list(struct ctl_context *ctx)
887 const char *column_names = shash_find_data(&ctx->options, "--columns");
888 const char *table_name = ctx->argv[1];
889 const struct ctl_table_class *table;
891 table = pre_get_table(ctx, table_name);
892 pre_list_columns(ctx, table, column_names);
895 static struct table *
896 list_make_table(const struct ovsdb_idl_column **columns, size_t n_columns)
901 out = xmalloc(sizeof *out);
904 for (i = 0; i < n_columns; i++) {
905 const struct ovsdb_idl_column *column = columns[i];
906 const char *column_name = column ? column->name : "_uuid";
908 table_add_column(out, "%s", column_name);
915 list_record(const struct ovsdb_idl_row *row,
916 const struct ovsdb_idl_column **columns, size_t n_columns,
926 for (i = 0; i < n_columns; i++) {
927 const struct ovsdb_idl_column *column = columns[i];
928 struct cell *cell = table_add_cell(out);
931 struct ovsdb_datum datum;
932 union ovsdb_atom atom;
934 atom.uuid = row->uuid;
940 cell->json = ovsdb_datum_to_json(&datum, &ovsdb_type_uuid);
941 cell->type = &ovsdb_type_uuid;
943 const struct ovsdb_datum *datum = ovsdb_idl_read(row, column);
945 cell->json = ovsdb_datum_to_json(datum, &column->type);
946 cell->type = &column->type;
952 cmd_list(struct ctl_context *ctx)
954 const char *column_names = shash_find_data(&ctx->options, "--columns");
955 bool must_exist = !shash_find(&ctx->options, "--if-exists");
956 const struct ovsdb_idl_column **columns;
957 const char *table_name = ctx->argv[1];
958 const struct ctl_table_class *table;
963 table = get_table(table_name);
964 parse_column_names(column_names, table, &columns, &n_columns);
965 out = ctx->table = list_make_table(columns, n_columns);
967 for (i = 2; i < ctx->argc; i++) {
968 list_record(get_row(ctx, table, ctx->argv[i], must_exist),
969 columns, n_columns, out);
972 const struct ovsdb_idl_row *row;
974 for (row = ovsdb_idl_first_row(ctx->idl, table->class); row != NULL;
975 row = ovsdb_idl_next_row(row)) {
976 list_record(row, columns, n_columns, out);
983 pre_cmd_find(struct ctl_context *ctx)
985 const char *column_names = shash_find_data(&ctx->options, "--columns");
986 const char *table_name = ctx->argv[1];
987 const struct ctl_table_class *table;
990 table = pre_get_table(ctx, table_name);
991 pre_list_columns(ctx, table, column_names);
992 for (i = 2; i < ctx->argc; i++) {
993 pre_parse_column_key_value(ctx, ctx->argv[i], table);
998 cmd_find(struct ctl_context *ctx)
1000 const char *column_names = shash_find_data(&ctx->options, "--columns");
1001 const struct ovsdb_idl_column **columns;
1002 const char *table_name = ctx->argv[1];
1003 const struct ctl_table_class *table;
1004 const struct ovsdb_idl_row *row;
1008 table = get_table(table_name);
1009 parse_column_names(column_names, table, &columns, &n_columns);
1010 out = ctx->table = list_make_table(columns, n_columns);
1011 for (row = ovsdb_idl_first_row(ctx->idl, table->class); row;
1012 row = ovsdb_idl_next_row(row)) {
1015 for (i = 2; i < ctx->argc; i++) {
1016 if (!is_condition_satisfied(table, row, ctx->argv[i],
1021 list_record(row, columns, n_columns, out);
1029 pre_cmd_set(struct ctl_context *ctx)
1031 const char *table_name = ctx->argv[1];
1032 const struct ctl_table_class *table;
1035 table = pre_get_table(ctx, table_name);
1036 for (i = 3; i < ctx->argc; i++) {
1037 pre_parse_column_key_value(ctx, ctx->argv[i], table);
1042 cmd_set(struct ctl_context *ctx)
1044 bool must_exist = !shash_find(&ctx->options, "--if-exists");
1045 const char *table_name = ctx->argv[1];
1046 const char *record_id = ctx->argv[2];
1047 const struct ctl_table_class*table;
1048 const struct ovsdb_idl_row *row;
1051 table = get_table(table_name);
1052 row = get_row(ctx, table, record_id, must_exist);
1057 for (i = 3; i < ctx->argc; i++) {
1058 set_column(table, row, ctx->argv[i], ctx->symtab);
1061 invalidate_cache(ctx);
1065 pre_cmd_add(struct ctl_context *ctx)
1067 const char *table_name = ctx->argv[1];
1068 const char *column_name = ctx->argv[3];
1069 const struct ctl_table_class *table;
1070 const struct ovsdb_idl_column *column;
1072 table = pre_get_table(ctx, table_name);
1073 pre_get_column(ctx, table, column_name, &column);
1077 cmd_add(struct ctl_context *ctx)
1079 bool must_exist = !shash_find(&ctx->options, "--if-exists");
1080 const char *table_name = ctx->argv[1];
1081 const char *record_id = ctx->argv[2];
1082 const char *column_name = ctx->argv[3];
1083 const struct ctl_table_class *table;
1084 const struct ovsdb_idl_column *column;
1085 const struct ovsdb_idl_row *row;
1086 const struct ovsdb_type *type;
1087 struct ovsdb_datum old;
1090 table = get_table(table_name);
1091 die_if_error(get_column(table, column_name, &column));
1092 row = get_row(ctx, table, record_id, must_exist);
1096 check_mutable(row, column);
1098 type = &column->type;
1099 ovsdb_datum_clone(&old, ovsdb_idl_read(row, column), &column->type);
1100 for (i = 4; i < ctx->argc; i++) {
1101 struct ovsdb_type add_type;
1102 struct ovsdb_datum add;
1106 add_type.n_max = UINT_MAX;
1107 die_if_error(ovsdb_datum_from_string(&add, &add_type, ctx->argv[i],
1109 ovsdb_datum_union(&old, &add, type, false);
1110 ovsdb_datum_destroy(&add, type);
1112 if (old.n > type->n_max) {
1113 ctl_fatal("\"add\" operation would put %u %s in column %s of "
1114 "table %s but the maximum number is %u",
1116 type->value.type == OVSDB_TYPE_VOID ? "values" : "pairs",
1117 column->name, table->class->name, type->n_max);
1119 ovsdb_idl_txn_verify(row, column);
1120 ovsdb_idl_txn_write(row, column, &old);
1122 invalidate_cache(ctx);
1126 pre_cmd_remove(struct ctl_context *ctx)
1128 const char *table_name = ctx->argv[1];
1129 const char *column_name = ctx->argv[3];
1130 const struct ctl_table_class *table;
1131 const struct ovsdb_idl_column *column;
1133 table = pre_get_table(ctx, table_name);
1134 pre_get_column(ctx, table, column_name, &column);
1138 cmd_remove(struct ctl_context *ctx)
1140 bool must_exist = !shash_find(&ctx->options, "--if-exists");
1141 const char *table_name = ctx->argv[1];
1142 const char *record_id = ctx->argv[2];
1143 const char *column_name = ctx->argv[3];
1144 const struct ctl_table_class *table;
1145 const struct ovsdb_idl_column *column;
1146 const struct ovsdb_idl_row *row;
1147 const struct ovsdb_type *type;
1148 struct ovsdb_datum old;
1151 table = get_table(table_name);
1152 die_if_error(get_column(table, column_name, &column));
1153 row = get_row(ctx, table, record_id, must_exist);
1157 check_mutable(row, column);
1159 type = &column->type;
1160 ovsdb_datum_clone(&old, ovsdb_idl_read(row, column), &column->type);
1161 for (i = 4; i < ctx->argc; i++) {
1162 struct ovsdb_type rm_type;
1163 struct ovsdb_datum rm;
1168 rm_type.n_max = UINT_MAX;
1169 error = ovsdb_datum_from_string(&rm, &rm_type,
1170 ctx->argv[i], ctx->symtab);
1173 if (ovsdb_type_is_map(&rm_type)) {
1174 rm_type.value.type = OVSDB_TYPE_VOID;
1176 die_if_error(ovsdb_datum_from_string(
1177 &rm, &rm_type, ctx->argv[i], ctx->symtab));
1179 ctl_fatal("%s", error);
1182 ovsdb_datum_subtract(&old, type, &rm, &rm_type);
1183 ovsdb_datum_destroy(&rm, &rm_type);
1185 if (old.n < type->n_min) {
1186 ctl_fatal("\"remove\" operation would put %u %s in column %s of "
1187 "table %s but the minimum number is %u",
1189 type->value.type == OVSDB_TYPE_VOID ? "values" : "pairs",
1190 column->name, table->class->name, type->n_min);
1192 ovsdb_idl_txn_verify(row, column);
1193 ovsdb_idl_txn_write(row, column, &old);
1195 invalidate_cache(ctx);
1199 pre_cmd_clear(struct ctl_context *ctx)
1201 const char *table_name = ctx->argv[1];
1202 const struct ctl_table_class *table;
1205 table = pre_get_table(ctx, table_name);
1206 for (i = 3; i < ctx->argc; i++) {
1207 const struct ovsdb_idl_column *column;
1209 pre_get_column(ctx, table, ctx->argv[i], &column);
1214 cmd_clear(struct ctl_context *ctx)
1216 bool must_exist = !shash_find(&ctx->options, "--if-exists");
1217 const char *table_name = ctx->argv[1];
1218 const char *record_id = ctx->argv[2];
1219 const struct ctl_table_class *table;
1220 const struct ovsdb_idl_row *row;
1223 table = get_table(table_name);
1224 row = get_row(ctx, table, record_id, must_exist);
1229 for (i = 3; i < ctx->argc; i++) {
1230 const struct ovsdb_idl_column *column;
1231 const struct ovsdb_type *type;
1232 struct ovsdb_datum datum;
1234 die_if_error(get_column(table, ctx->argv[i], &column));
1235 check_mutable(row, column);
1237 type = &column->type;
1238 if (type->n_min > 0) {
1239 ctl_fatal("\"clear\" operation cannot be applied to column %s "
1240 "of table %s, which is not allowed to be empty",
1241 column->name, table->class->name);
1244 ovsdb_datum_init_empty(&datum);
1245 ovsdb_idl_txn_write(row, column, &datum);
1248 invalidate_cache(ctx);
1252 pre_create(struct ctl_context *ctx)
1254 const char *id = shash_find_data(&ctx->options, "--id");
1255 const char *table_name = ctx->argv[1];
1256 const struct ctl_table_class *table;
1258 table = get_table(table_name);
1259 if (!id && !table->class->is_root) {
1260 VLOG_WARN("applying \"create\" command to table %s without --id "
1261 "option will have no effect", table->class->name);
1266 cmd_create(struct ctl_context *ctx)
1268 const char *id = shash_find_data(&ctx->options, "--id");
1269 const char *table_name = ctx->argv[1];
1270 const struct ctl_table_class *table = get_table(table_name);
1271 const struct ovsdb_idl_row *row;
1272 const struct uuid *uuid;
1276 struct ovsdb_symbol *symbol = create_symbol(ctx->symtab, id, NULL);
1277 if (table->class->is_root) {
1278 /* This table is in the root set, meaning that rows created in it
1279 * won't disappear even if they are unreferenced, so disable
1280 * warnings about that by pretending that there is a reference. */
1281 symbol->strong_ref = true;
1283 uuid = &symbol->uuid;
1288 row = ovsdb_idl_txn_insert(ctx->txn, table->class, uuid);
1289 for (i = 2; i < ctx->argc; i++) {
1290 set_column(table, row, ctx->argv[i], ctx->symtab);
1292 ds_put_format(&ctx->output, UUID_FMT, UUID_ARGS(&row->uuid));
1295 /* This function may be used as the 'postprocess' function for commands that
1296 * insert new rows into the database. It expects that the command's 'run'
1297 * function prints the UUID reported by ovsdb_idl_txn_insert() as the command's
1298 * sole output. It replaces that output by the row's permanent UUID assigned
1299 * by the database server and appends a new-line.
1301 * Currently we use this only for "create", because the higher-level commands
1302 * are supposed to be independent of the actual structure of the vswitch
1305 post_create(struct ctl_context *ctx)
1307 const struct uuid *real;
1310 if (!uuid_from_string(&dummy, ds_cstr(&ctx->output))) {
1313 real = ovsdb_idl_txn_get_insert_uuid(ctx->txn, &dummy);
1315 ds_clear(&ctx->output);
1316 ds_put_format(&ctx->output, UUID_FMT, UUID_ARGS(real));
1318 ds_put_char(&ctx->output, '\n');
1322 pre_cmd_destroy(struct ctl_context *ctx)
1324 const char *table_name = ctx->argv[1];
1326 pre_get_table(ctx, table_name);
1330 cmd_destroy(struct ctl_context *ctx)
1332 bool must_exist = !shash_find(&ctx->options, "--if-exists");
1333 bool delete_all = shash_find(&ctx->options, "--all");
1334 const char *table_name = ctx->argv[1];
1335 const struct ctl_table_class *table;
1338 table = get_table(table_name);
1340 if (delete_all && ctx->argc > 2) {
1341 ctl_fatal("--all and records argument should not be specified together");
1344 if (delete_all && !must_exist) {
1345 ctl_fatal("--all and --if-exists should not be specified together");
1349 const struct ovsdb_idl_row *row;
1350 const struct ovsdb_idl_row *next_row;
1352 for (row = ovsdb_idl_first_row(ctx->idl, table->class);
1354 next_row = ovsdb_idl_next_row(row);
1355 ovsdb_idl_txn_delete(row);
1359 for (i = 2; i < ctx->argc; i++) {
1360 const struct ovsdb_idl_row *row;
1362 row = get_row(ctx, table, ctx->argv[i], must_exist);
1364 ovsdb_idl_txn_delete(row);
1368 invalidate_cache(ctx);
1372 pre_cmd_wait_until(struct ctl_context *ctx)
1374 const char *table_name = ctx->argv[1];
1375 const struct ctl_table_class *table;
1378 table = pre_get_table(ctx, table_name);
1380 for (i = 3; i < ctx->argc; i++) {
1381 pre_parse_column_key_value(ctx, ctx->argv[i], table);
1386 cmd_wait_until(struct ctl_context *ctx)
1388 const char *table_name = ctx->argv[1];
1389 const char *record_id = ctx->argv[2];
1390 const struct ctl_table_class *table;
1391 const struct ovsdb_idl_row *row;
1394 table = get_table(table_name);
1396 row = get_row(ctx, table, record_id, false);
1398 ctx->try_again = true;
1402 for (i = 3; i < ctx->argc; i++) {
1403 if (!is_condition_satisfied(table, row, ctx->argv[i], ctx->symtab)) {
1404 ctx->try_again = true;
1410 /* Parses one command. */
1412 parse_command(int argc, char *argv[], struct shash *local_options,
1413 struct ctl_command *command)
1415 const struct ctl_command_syntax *p;
1416 struct shash_node *node;
1420 shash_init(&command->options);
1421 shash_swap(local_options, &command->options);
1422 for (i = 0; i < argc; i++) {
1423 const char *option = argv[i];
1427 if (option[0] != '-') {
1431 equals = strchr(option, '=');
1433 key = xmemdup0(option, equals - option);
1434 value = xstrdup(equals + 1);
1436 key = xstrdup(option);
1440 if (shash_find(&command->options, key)) {
1441 ctl_fatal("'%s' option specified multiple times", argv[i]);
1443 shash_add_nocopy(&command->options, key, value);
1446 ctl_fatal("missing command name (use --help for help)");
1449 p = shash_find_data(&all_commands, argv[i]);
1451 ctl_fatal("unknown command '%s'; use --help for help", argv[i]);
1454 SHASH_FOR_EACH (node, &command->options) {
1455 const char *s = strstr(p->options, node->name);
1456 int end = s ? s[strlen(node->name)] : EOF;
1458 if (end != '=' && end != ',' && end != ' ' && end != '\0') {
1459 ctl_fatal("'%s' command has no '%s' option",
1460 argv[i], node->name);
1462 if ((end == '=') != (node->data != NULL)) {
1464 ctl_fatal("missing argument to '%s' option on '%s' "
1465 "command", node->name, argv[i]);
1467 ctl_fatal("'%s' option on '%s' does not accept an "
1468 "argument", node->name, argv[i]);
1473 n_arg = argc - i - 1;
1474 if (n_arg < p->min_args) {
1475 ctl_fatal("'%s' command requires at least %d arguments",
1476 p->name, p->min_args);
1477 } else if (n_arg > p->max_args) {
1480 for (j = i + 1; j < argc; j++) {
1481 if (argv[j][0] == '-') {
1482 ctl_fatal("'%s' command takes at most %d arguments "
1483 "(note that options must precede command "
1484 "names and follow a \"--\" argument)",
1485 p->name, p->max_args);
1489 ctl_fatal("'%s' command takes at most %d arguments",
1490 p->name, p->max_args);
1493 command->syntax = p;
1494 command->argc = n_arg + 1;
1495 command->argv = &argv[i];
1499 pre_cmd_show(struct ctl_context *ctx)
1501 struct cmd_show_table *show;
1503 for (show = cmd_show_tables; show->table; show++) {
1506 ovsdb_idl_add_table(ctx->idl, show->table);
1507 if (show->name_column) {
1508 ovsdb_idl_add_column(ctx->idl, show->name_column);
1510 for (i = 0; i < ARRAY_SIZE(show->columns); i++) {
1511 const struct ovsdb_idl_column *column = show->columns[i];
1513 ovsdb_idl_add_column(ctx->idl, column);
1519 static struct cmd_show_table *
1520 cmd_show_find_table_by_row(const struct ovsdb_idl_row *row)
1522 struct cmd_show_table *show;
1524 for (show = cmd_show_tables; show->table; show++) {
1525 if (show->table == row->table->class) {
1532 static struct cmd_show_table *
1533 cmd_show_find_table_by_name(const char *name)
1535 struct cmd_show_table *show;
1537 for (show = cmd_show_tables; show->table; show++) {
1538 if (!strcmp(show->table->name, name)) {
1546 cmd_show_row(struct ctl_context *ctx, const struct ovsdb_idl_row *row,
1549 struct cmd_show_table *show = cmd_show_find_table_by_row(row);
1552 ds_put_char_multiple(&ctx->output, ' ', level * 4);
1553 if (show && show->name_column) {
1554 const struct ovsdb_datum *datum;
1556 ds_put_format(&ctx->output, "%s ", show->table->name);
1557 datum = ovsdb_idl_read(row, show->name_column);
1558 ovsdb_datum_to_string(datum, &show->name_column->type, &ctx->output);
1560 ds_put_format(&ctx->output, UUID_FMT, UUID_ARGS(&row->uuid));
1562 ds_put_char(&ctx->output, '\n');
1564 if (!show || show->recurse) {
1568 show->recurse = true;
1569 for (i = 0; i < ARRAY_SIZE(show->columns); i++) {
1570 const struct ovsdb_idl_column *column = show->columns[i];
1571 const struct ovsdb_datum *datum;
1577 datum = ovsdb_idl_read(row, column);
1578 if (column->type.key.type == OVSDB_TYPE_UUID &&
1579 column->type.key.u.uuid.refTableName) {
1580 struct cmd_show_table *ref_show;
1583 ref_show = cmd_show_find_table_by_name(
1584 column->type.key.u.uuid.refTableName);
1586 for (j = 0; j < datum->n; j++) {
1587 const struct ovsdb_idl_row *ref_row;
1589 ref_row = ovsdb_idl_get_row_for_uuid(ctx->idl,
1591 &datum->keys[j].uuid);
1593 cmd_show_row(ctx, ref_row, level + 1);
1598 } else if (ovsdb_type_is_map(&column->type) &&
1599 column->type.value.type == OVSDB_TYPE_UUID &&
1600 column->type.value.u.uuid.refTableName) {
1601 struct cmd_show_table *ref_show;
1604 /* Prints the key to ref'ed table name map if the ref'ed table
1605 * is also defined in 'cmd_show_tables'. */
1606 ref_show = cmd_show_find_table_by_name(
1607 column->type.value.u.uuid.refTableName);
1608 if (ref_show && ref_show->name_column) {
1609 ds_put_char_multiple(&ctx->output, ' ', (level + 1) * 4);
1610 ds_put_format(&ctx->output, "%s:\n", column->name);
1611 for (j = 0; j < datum->n; j++) {
1612 const struct ovsdb_idl_row *ref_row;
1614 ref_row = ovsdb_idl_get_row_for_uuid(ctx->idl,
1616 &datum->values[j].uuid);
1618 ds_put_char_multiple(&ctx->output, ' ', (level + 2) * 4);
1619 ovsdb_atom_to_string(&datum->keys[j], column->type.key.type,
1621 ds_put_char(&ctx->output, '=');
1623 const struct ovsdb_datum *ref_datum;
1625 ref_datum = ovsdb_idl_read(ref_row,
1626 ref_show->name_column);
1627 ovsdb_datum_to_string(ref_datum,
1628 &ref_show->name_column->type,
1631 ds_put_cstr(&ctx->output, "\"<null>\"");
1633 ds_put_char(&ctx->output, '\n');
1639 if (!ovsdb_datum_is_default(datum, &column->type)) {
1640 ds_put_char_multiple(&ctx->output, ' ', (level + 1) * 4);
1641 ds_put_format(&ctx->output, "%s: ", column->name);
1642 ovsdb_datum_to_string(datum, &column->type, &ctx->output);
1643 ds_put_char(&ctx->output, '\n');
1646 show->recurse = false;
1650 cmd_show(struct ctl_context *ctx)
1652 const struct ovsdb_idl_row *row;
1654 for (row = ovsdb_idl_first_row(ctx->idl, cmd_show_tables[0].table);
1655 row; row = ovsdb_idl_next_row(row)) {
1656 cmd_show_row(ctx, row, 0);
1661 /* Given pointer to dynamic array 'options_p', array's current size
1662 * 'allocated_options_p' and number of added options 'n_options_p',
1663 * adds all command options to the array. Enlarges the array if
1666 ctl_add_cmd_options(struct option **options_p, size_t *n_options_p,
1667 size_t *allocated_options_p, int opt_val)
1670 const struct shash_node *node;
1671 size_t n_existing_options = *n_options_p;
1673 SHASH_FOR_EACH (node, ctl_get_all_commands()) {
1674 const struct ctl_command_syntax *p = node->data;
1676 if (p->options[0]) {
1677 char *save_ptr = NULL;
1681 s = xstrdup(p->options);
1682 for (name = strtok_r(s, ",", &save_ptr); name != NULL;
1683 name = strtok_r(NULL, ",", &save_ptr)) {
1687 ovs_assert(name[0] == '-' && name[1] == '-' && name[2]);
1690 equals = strchr(name, '=');
1692 has_arg = required_argument;
1695 has_arg = no_argument;
1698 o = find_option(name, *options_p, *n_options_p);
1700 ovs_assert(o - *options_p >= n_existing_options);
1701 ovs_assert(o->has_arg == has_arg);
1703 o = add_option(options_p, n_options_p, allocated_options_p);
1704 o->name = xstrdup(name);
1705 o->has_arg = has_arg;
1714 o = add_option(options_p, n_options_p, allocated_options_p);
1715 memset(o, 0, sizeof *o);
1718 /* Parses command-line input for commands. */
1719 struct ctl_command *
1720 ctl_parse_commands(int argc, char *argv[], struct shash *local_options,
1721 size_t *n_commandsp)
1723 struct ctl_command *commands;
1724 size_t n_commands, allocated_commands;
1728 n_commands = allocated_commands = 0;
1730 for (start = i = 0; i <= argc; i++) {
1731 if (i == argc || !strcmp(argv[i], "--")) {
1733 if (n_commands >= allocated_commands) {
1734 struct ctl_command *c;
1736 commands = x2nrealloc(commands, &allocated_commands,
1738 for (c = commands; c < &commands[n_commands]; c++) {
1739 shash_moved(&c->options);
1742 parse_command(i - start, &argv[start], local_options,
1743 &commands[n_commands++]);
1744 } else if (!shash_is_empty(local_options)) {
1745 ctl_fatal("missing command name (use --help for help)");
1751 ctl_fatal("missing command name (use --help for help)");
1753 *n_commandsp = n_commands;
1757 /* Prints all registered commands. */
1759 ctl_print_commands(void)
1761 const struct shash_node *node;
1763 SHASH_FOR_EACH (node, ctl_get_all_commands()) {
1764 const struct ctl_command_syntax *p = node->data;
1765 char *options = xstrdup(p->options);
1766 char *options_begin = options;
1769 for (item = strsep(&options, ","); item != NULL;
1770 item = strsep(&options, ",")) {
1771 if (item[0] != '\0') {
1772 printf("[%s] ", item);
1775 printf(",%s,", p->name);
1776 print_command_arguments(p);
1779 free(options_begin);
1785 /* Given array of options 'options', prints them. */
1787 ctl_print_options(const struct option *options)
1789 for (; options->name; options++) {
1790 const struct option *o = options;
1792 printf("--%s%s\n", o->name, o->has_arg ? "=ARG" : "");
1793 if (o->flag == NULL && o->val > 0 && o->val <= UCHAR_MAX) {
1794 printf("-%c%s\n", o->val, o->has_arg ? " ARG" : "");
1801 /* Returns the default local database path. */
1803 ctl_default_db(void)
1807 def = xasprintf("unix:%s/db.sock", ovs_rundir());
1812 /* Returns true if it looks like this set of arguments might modify the
1813 * database, otherwise false. (Not very smart, so it's prone to false
1816 ctl_might_write_to_db(char **argv)
1818 for (; *argv; argv++) {
1819 const struct ctl_command_syntax *p = shash_find_data(&all_commands, *argv);
1820 if (p && p->mode == RW) {
1828 ctl_fatal(const char *format, ...)
1833 va_start(args, format);
1834 message = xvasprintf(format, args);
1837 vlog_set_levels(&VLM_db_ctl_base, VLF_CONSOLE, VLL_OFF);
1838 VLOG_ERR("%s", message);
1839 ovs_error(0, "%s", message);
1840 ctl_exit(EXIT_FAILURE);
1843 /* Frees the current transaction and the underlying IDL and then calls
1846 * Freeing the transaction and the IDL is not strictly necessary, but it makes
1847 * for a clean memory leak report from valgrind in the normal case. That makes
1848 * it easier to notice real memory leaks. */
1850 ctl_exit(int status)
1853 ovsdb_idl_txn_abort(the_idl_txn);
1854 ovsdb_idl_txn_destroy(the_idl_txn);
1856 ovsdb_idl_destroy(the_idl);
1860 /* Command for showing overview of database contents. */
1861 static const struct ctl_command_syntax db_ctl_show_command[] = {
1862 {"show", 0, 0, "", pre_cmd_show, cmd_show, NULL, "", RO},
1863 {NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, RO},
1866 /* Comman database commands to be registered. */
1867 static const struct ctl_command_syntax db_ctl_commands[] = {
1868 {"comment", 0, INT_MAX, "[ARG]...", NULL, NULL, NULL, "", RO},
1869 {"get", 2, INT_MAX, "TABLE RECORD [COLUMN[:KEY]]...",pre_cmd_get, cmd_get,
1870 NULL, "--if-exists,--id=", RO},
1871 {"list", 1, INT_MAX, "TABLE [RECORD]...", pre_cmd_list, cmd_list, NULL,
1872 "--if-exists,--columns=", RO},
1873 {"find", 1, INT_MAX, "TABLE [COLUMN[:KEY]=VALUE]...", pre_cmd_find,
1874 cmd_find, NULL, "--columns=", RO},
1875 {"set", 3, INT_MAX, "TABLE RECORD COLUMN[:KEY]=VALUE...", pre_cmd_set,
1876 cmd_set, NULL, "--if-exists", RW},
1877 {"add", 4, INT_MAX, "TABLE RECORD COLUMN [KEY=]VALUE...", pre_cmd_add,
1878 cmd_add, NULL, "--if-exists", RW},
1879 {"remove", 4, INT_MAX, "TABLE RECORD COLUMN KEY|VALUE|KEY=VALUE...",
1880 pre_cmd_remove, cmd_remove, NULL, "--if-exists", RW},
1881 {"clear", 3, INT_MAX, "TABLE RECORD COLUMN...", pre_cmd_clear, cmd_clear,
1882 NULL, "--if-exists", RW},
1883 {"create", 2, INT_MAX, "TABLE COLUMN[:KEY]=VALUE...", pre_create,
1884 cmd_create, post_create, "--id=", RW},
1885 {"destroy", 1, INT_MAX, "TABLE [RECORD]...", pre_cmd_destroy, cmd_destroy,
1886 NULL, "--if-exists,--all", RW},
1887 {"wait-until", 2, INT_MAX, "TABLE RECORD [COLUMN[:KEY]=VALUE]...",
1888 pre_cmd_wait_until, cmd_wait_until, NULL, "", RO},
1889 {NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, RO},
1892 /* Registers commands represented by 'struct ctl_command_syntax's to
1893 * 'all_commands'. The last element of 'commands' must be an all-NULL
1896 ctl_register_commands(const struct ctl_command_syntax *commands)
1898 const struct ctl_command_syntax *p;
1900 for (p = commands; p->name; p++) {
1901 shash_add_assert(&all_commands, p->name, p);
1905 /* Registers the 'db_ctl_commands' to 'all_commands'. */
1909 ctl_register_commands(db_ctl_commands);
1910 ctl_register_commands(db_ctl_show_command);
1913 /* Returns 'all_commands'. */
1914 const struct shash *
1915 ctl_get_all_commands(void)
1917 return &all_commands;
1920 /* Returns the text for the database commands usage. */
1922 ctl_get_db_cmd_usage(void)
1924 return "Database commands:\n\
1925 list TBL [REC] list RECord (or all records) in TBL\n\
1926 find TBL CONDITION... list records satisfying CONDITION in TBL\n\
1927 get TBL REC COL[:KEY] print values of COLumns in RECord in TBL\n\
1928 set TBL REC COL[:KEY]=VALUE set COLumn values in RECord in TBL\n\
1929 add TBL REC COL [KEY=]VALUE add (KEY=)VALUE to COLumn in RECord in TBL\n\
1930 remove TBL REC COL [KEY=]VALUE remove (KEY=)VALUE from COLumn\n\
1931 clear TBL REC COL clear values from COLumn in RECord in TBL\n\
1932 create TBL COL[:KEY]=VALUE create and initialize new record\n\
1933 destroy TBL REC delete RECord from TBL\n\
1934 wait-until TBL REC [COL[:KEY]=VALUE] wait until condition is true\n\
1935 Potentially unsafe database commands require --force option.\n";
1938 /* Initializes 'ctx' from 'command'. */
1940 ctl_context_init_command(struct ctl_context *ctx,
1941 struct ctl_command *command)
1943 ctx->argc = command->argc;
1944 ctx->argv = command->argv;
1945 ctx->options = command->options;
1947 ds_swap(&ctx->output, &command->output);
1948 ctx->table = command->table;
1949 ctx->try_again = false;
1952 /* Initializes the entire 'ctx'. */
1954 ctl_context_init(struct ctl_context *ctx, struct ctl_command *command,
1955 struct ovsdb_idl *idl, struct ovsdb_idl_txn *txn,
1956 struct ovsdb_symbol_table *symtab,
1957 void (*invalidate_cache)(struct ctl_context *))
1960 ctl_context_init_command(ctx, command);
1964 ctx->symtab = symtab;
1965 ctx->invalidate_cache = invalidate_cache;
1968 /* Completes processing of 'command' within 'ctx'. */
1970 ctl_context_done_command(struct ctl_context *ctx,
1971 struct ctl_command *command)
1973 ds_swap(&ctx->output, &command->output);
1974 command->table = ctx->table;
1977 /* Finishes up with 'ctx'.
1979 * If command is nonnull, first calls ctl_context_done_command() to complete
1980 * processing that command within 'ctx'. */
1982 ctl_context_done(struct ctl_context *ctx,
1983 struct ctl_command *command)
1986 ctl_context_done_command(ctx, command);
1988 invalidate_cache(ctx);
1991 /* Finds and returns the "struct ctl_table_class *" with 'table_name' by
1992 * searching the 'tables'. */
1993 const struct ctl_table_class *
1994 get_table(const char *table_name)
1996 const struct ctl_table_class *table;
1997 const struct ctl_table_class *best_match = NULL;
1998 unsigned int best_score = 0;
2000 for (table = tables; table->class; table++) {
2001 unsigned int score = score_partial_match(table->class->name,
2003 if (score > best_score) {
2006 } else if (score == best_score) {
2012 } else if (best_score) {
2013 ctl_fatal("multiple table names match \"%s\"", table_name);
2015 ctl_fatal("unknown table \"%s\"", table_name);
2020 /* Sets the column of 'row' in 'table'. */
2022 set_column(const struct ctl_table_class *table,
2023 const struct ovsdb_idl_row *row, const char *arg,
2024 struct ovsdb_symbol_table *symtab)
2026 const struct ovsdb_idl_column *column;
2027 char *key_string, *value_string;
2030 error = parse_column_key_value(arg, table, &column, &key_string,
2031 NULL, NULL, 0, &value_string);
2032 die_if_error(error);
2033 if (!value_string) {
2034 ctl_fatal("%s: missing value", arg);
2036 check_mutable(row, column);
2039 union ovsdb_atom key, value;
2040 struct ovsdb_datum datum;
2042 if (column->type.value.type == OVSDB_TYPE_VOID) {
2043 ctl_fatal("cannot specify key to set for non-map column %s",
2047 die_if_error(ovsdb_atom_from_string(&key, &column->type.key,
2048 key_string, symtab));
2049 die_if_error(ovsdb_atom_from_string(&value, &column->type.value,
2050 value_string, symtab));
2052 ovsdb_datum_init_empty(&datum);
2053 ovsdb_datum_add_unsafe(&datum, &key, &value, &column->type);
2055 ovsdb_atom_destroy(&key, column->type.key.type);
2056 ovsdb_atom_destroy(&value, column->type.value.type);
2058 ovsdb_datum_union(&datum, ovsdb_idl_read(row, column),
2059 &column->type, false);
2060 ovsdb_idl_txn_verify(row, column);
2061 ovsdb_idl_txn_write(row, column, &datum);
2063 struct ovsdb_datum datum;
2065 die_if_error(ovsdb_datum_from_string(&datum, &column->type,
2066 value_string, symtab));
2067 ovsdb_idl_txn_write(row, column, &datum);