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);
50 static const struct ctl_table_class *get_table(const char *table_name);
51 static void set_column(const struct ctl_table_class *,
52 const struct ovsdb_idl_row *, const char *,
53 struct ovsdb_symbol_table *);
56 static struct option *
57 find_option(const char *name, struct option *options, size_t n_options)
61 for (i = 0; i < n_options; i++) {
62 if (!strcmp(options[i].name, name)) {
69 static struct option *
70 add_option(struct option **optionsp, size_t *n_optionsp,
71 size_t *allocated_optionsp)
73 if (*n_optionsp >= *allocated_optionsp) {
74 *optionsp = x2nrealloc(*optionsp, allocated_optionsp,
77 return &(*optionsp)[(*n_optionsp)++];
80 /* Converts the command arguments into format that can be parsed by
81 * bash completion script.
83 * Therein, arguments will be attached with following prefixes:
85 * !argument :: The argument is required
86 * ?argument :: The argument is optional
87 * *argument :: The argument may appear any number (0 or more) times
88 * +argument :: The argument may appear one or more times
92 print_command_arguments(const struct ctl_command_syntax *command)
95 * The argument string is parsed in reverse. We use a stack 'oew_stack' to
96 * keep track of nested optionals. Whenever a ']' is encountered, we push
97 * a bit to 'oew_stack'. The bit is set to 1 if the ']' is not nested.
98 * Subsequently, we pop an entry everytime '[' is met.
100 * We use 'whole_word_is_optional' value to decide whether or not a ! or +
101 * should be added on encountering a space: if the optional surrounds the
102 * whole word then it shouldn't be, but if it is only a part of the word
103 * (i.e. [key=]value), it should be.
105 uint32_t oew_stack = 0;
107 const char *arguments = command->arguments;
108 int length = strlen(arguments);
113 /* Output buffer, written backward from end. */
114 char *output = xmalloc(2 * length);
115 char *outp = output + 2 * length;
118 bool in_repeated = false;
119 bool whole_word_is_optional = false;
121 for (const char *inp = arguments + length; inp > arguments; ) {
125 if (inp[1] == '\0' || inp[1] == ' ' || inp[1] == '.') {
130 /* Checks if the whole word is optional, and sets the
131 * 'whole_word_is_optional' accordingly. */
132 if ((inp == arguments || inp[-1] == ' ') && oew_stack & 1) {
133 *--outp = in_repeated ? '*' : '?';
134 whole_word_is_optional = true;
137 whole_word_is_optional = false;
142 if (!whole_word_is_optional) {
143 *--outp = in_repeated ? '+' : '!';
147 whole_word_is_optional = false;
157 if (arguments[0] != '[' && outp != output + 2 * length - 1) {
158 *--outp = in_repeated ? '+' : '!';
165 die_if_error(char *error)
168 ctl_fatal("%s", error);
173 to_lower_and_underscores(unsigned c)
175 return c == '-' ? '_' : tolower(c);
179 score_partial_match(const char *name, const char *s)
183 if (!strcmp(name, s)) {
186 for (score = 0; ; score++, name++, s++) {
187 if (to_lower_and_underscores(*name) != to_lower_and_underscores(*s)) {
189 } else if (*name == '\0') {
193 return *s == '\0' ? score : 0;
196 static struct ovsdb_symbol *
197 create_symbol(struct ovsdb_symbol_table *symtab, const char *id, bool *newp)
199 struct ovsdb_symbol *symbol;
202 ctl_fatal("row id \"%s\" does not begin with \"@\"", id);
206 *newp = ovsdb_symbol_table_get(symtab, id) == NULL;
209 symbol = ovsdb_symbol_table_insert(symtab, id);
210 if (symbol->created) {
211 ctl_fatal("row id \"%s\" may only be specified on one --id option",
214 symbol->created = true;
218 static const struct ovsdb_idl_row *
219 get_row_by_id(struct ctl_context *ctx, const struct ctl_table_class *table,
220 const struct ctl_row_id *id, const char *record_id)
222 const struct ovsdb_idl_row *referrer, *final;
228 if (!id->name_column) {
229 if (strcmp(record_id, ".")) {
232 referrer = ovsdb_idl_first_row(ctx->idl, id->table);
233 if (!referrer || ovsdb_idl_next_row(referrer)) {
237 const struct ovsdb_idl_row *row;
240 for (row = ovsdb_idl_first_row(ctx->idl, id->table);
242 row = ovsdb_idl_next_row(row))
244 const struct ovsdb_datum *name;
246 name = ovsdb_idl_get(row, id->name_column,
247 OVSDB_TYPE_STRING, OVSDB_TYPE_VOID);
248 if (name->n == 1 && !strcmp(name->keys[0].string, record_id)) {
250 ctl_fatal("multiple rows in %s match \"%s\"",
251 table->class->name, record_id);
262 if (id->uuid_column) {
263 const struct ovsdb_datum *uuid;
265 ovsdb_idl_txn_verify(referrer, id->uuid_column);
266 uuid = ovsdb_idl_get(referrer, id->uuid_column,
267 OVSDB_TYPE_UUID, OVSDB_TYPE_VOID);
269 final = ovsdb_idl_get_row_for_uuid(ctx->idl, table->class,
270 &uuid->keys[0].uuid);
279 static const struct ovsdb_idl_row *
280 get_row(struct ctl_context *ctx,
281 const struct ctl_table_class *table, const char *record_id,
284 const struct ovsdb_idl_row *row;
288 if (uuid_from_string(&uuid, record_id)) {
289 row = ovsdb_idl_get_row_for_uuid(ctx->idl, table->class, &uuid);
294 for (i = 0; i < ARRAY_SIZE(table->row_ids); i++) {
295 row = get_row_by_id(ctx, table, &table->row_ids[i], record_id);
301 if (must_exist && !row) {
302 ctl_fatal("no row \"%s\" in table %s",
303 record_id, table->class->name);
309 get_column(const struct ctl_table_class *table, const char *column_name,
310 const struct ovsdb_idl_column **columnp)
312 const struct ovsdb_idl_column *best_match = NULL;
313 unsigned int best_score = 0;
316 for (i = 0; i < table->class->n_columns; i++) {
317 const struct ovsdb_idl_column *column = &table->class->columns[i];
318 unsigned int score = score_partial_match(column->name, column_name);
319 if (score > best_score) {
322 } else if (score == best_score) {
327 *columnp = best_match;
330 } else if (best_score) {
331 return xasprintf("%s contains more than one column whose name "
332 "matches \"%s\"", table->class->name, column_name);
334 return xasprintf("%s does not contain a column whose name matches "
335 "\"%s\"", table->class->name, column_name);
340 pre_get_column(struct ctl_context *ctx,
341 const struct ctl_table_class *table, const char *column_name,
342 const struct ovsdb_idl_column **columnp)
344 die_if_error(get_column(table, column_name, columnp));
345 ovsdb_idl_add_column(ctx->idl, *columnp);
348 static const struct ctl_table_class *
349 pre_get_table(struct ctl_context *ctx, const char *table_name)
351 const struct ctl_table_class *table_class;
354 table_class = get_table(table_name);
355 ovsdb_idl_add_table(ctx->idl, table_class->class);
357 for (i = 0; i < ARRAY_SIZE(table_class->row_ids); i++) {
358 const struct ctl_row_id *id = &table_class->row_ids[i];
360 ovsdb_idl_add_table(ctx->idl, id->table);
362 if (id->name_column) {
363 ovsdb_idl_add_column(ctx->idl, id->name_column);
365 if (id->uuid_column) {
366 ovsdb_idl_add_column(ctx->idl, id->uuid_column);
374 missing_operator_error(const char *arg, const char **allowed_operators,
380 ds_put_format(&s, "%s: argument does not end in ", arg);
381 ds_put_format(&s, "\"%s\"", allowed_operators[0]);
382 if (n_allowed == 2) {
383 ds_put_format(&s, " or \"%s\"", allowed_operators[1]);
384 } else if (n_allowed > 2) {
387 for (i = 1; i < n_allowed - 1; i++) {
388 ds_put_format(&s, ", \"%s\"", allowed_operators[i]);
390 ds_put_format(&s, ", or \"%s\"", allowed_operators[i]);
392 ds_put_format(&s, " followed by a value.");
394 return ds_steal_cstr(&s);
397 /* Breaks 'arg' apart into a number of fields in the following order:
399 * - The name of a column in 'table', stored into '*columnp'. The column
400 * name may be abbreviated.
402 * - Optionally ':' followed by a key string. The key is stored as a
403 * malloc()'d string into '*keyp', or NULL if no key is present in
406 * - If 'valuep' is nonnull, an operator followed by a value string. The
407 * allowed operators are the 'n_allowed' string in 'allowed_operators',
408 * or just "=" if 'n_allowed' is 0. If 'operatorp' is nonnull, then the
409 * index of the operator within 'allowed_operators' is stored into
410 * '*operatorp'. The value is stored as a malloc()'d string into
411 * '*valuep', or NULL if no value is present in 'arg'.
413 * On success, returns NULL. On failure, returned a malloc()'d string error
414 * message and stores NULL into all of the nonnull output arguments. */
415 static char * OVS_WARN_UNUSED_RESULT
416 parse_column_key_value(const char *arg,
417 const struct ctl_table_class *table,
418 const struct ovsdb_idl_column **columnp, char **keyp,
420 const char **allowed_operators, size_t n_allowed,
427 ovs_assert(!(operatorp && !valuep));
433 /* Parse column name. */
434 error = ovsdb_token_parse(&p, &column_name);
438 if (column_name[0] == '\0') {
440 error = xasprintf("%s: missing column name", arg);
443 error = get_column(table, column_name, columnp);
449 /* Parse key string. */
452 error = ovsdb_token_parse(&p, keyp);
458 /* Parse value string. */
464 if (!allowed_operators) {
465 static const char *equals = "=";
466 allowed_operators = =
472 for (i = 0; i < n_allowed; i++) {
473 const char *op = allowed_operators[i];
474 size_t op_len = strlen(op);
476 if (op_len > best_len && !strncmp(op, p, op_len) && p[op_len]) {
482 error = missing_operator_error(arg, allowed_operators, n_allowed);
489 *valuep = xstrdup(p + best_len);
492 error = xasprintf("%s: trailing garbage \"%s\" in argument",
513 static const struct ovsdb_idl_column *
514 pre_parse_column_key_value(struct ctl_context *ctx,
516 const struct ctl_table_class *table)
518 const struct ovsdb_idl_column *column;
523 die_if_error(ovsdb_token_parse(&p, &column_name));
524 if (column_name[0] == '\0') {
525 ctl_fatal("%s: missing column name", arg);
528 pre_get_column(ctx, table, column_name, &column);
535 check_mutable(const struct ovsdb_idl_row *row,
536 const struct ovsdb_idl_column *column)
538 if (!ovsdb_idl_is_mutable(row, column)) {
539 ctl_fatal("cannot modify read-only column %s in table %s",
540 column->name, row->table->class->name);
545 RELOP(RELOP_EQ, "=") \
546 RELOP(RELOP_NE, "!=") \
547 RELOP(RELOP_LT, "<") \
548 RELOP(RELOP_GT, ">") \
549 RELOP(RELOP_LE, "<=") \
550 RELOP(RELOP_GE, ">=") \
551 RELOP(RELOP_SET_EQ, "{=}") \
552 RELOP(RELOP_SET_NE, "{!=}") \
553 RELOP(RELOP_SET_LT, "{<}") \
554 RELOP(RELOP_SET_GT, "{>}") \
555 RELOP(RELOP_SET_LE, "{<=}") \
556 RELOP(RELOP_SET_GE, "{>=}")
559 #define RELOP(ENUM, STRING) ENUM,
565 is_set_operator(enum relop op)
567 return (op == RELOP_SET_EQ || op == RELOP_SET_NE ||
568 op == RELOP_SET_LT || op == RELOP_SET_GT ||
569 op == RELOP_SET_LE || op == RELOP_SET_GE);
573 evaluate_relop(const struct ovsdb_datum *a, const struct ovsdb_datum *b,
574 const struct ovsdb_type *type, enum relop op)
579 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;
588 return ovsdb_datum_compare_3way(a, b, type) <= 0;
590 return ovsdb_datum_compare_3way(a, b, type) >= 0;
593 return b->n > a->n && ovsdb_datum_includes_all(a, b, type);
595 return a->n > b->n && ovsdb_datum_includes_all(b, a, type);
597 return ovsdb_datum_includes_all(a, b, type);
599 return ovsdb_datum_includes_all(b, a, type);
607 is_condition_satisfied(const struct ctl_table_class *table,
608 const struct ovsdb_idl_row *row, const char *arg,
609 struct ovsdb_symbol_table *symtab)
611 static const char *operators[] = {
612 #define RELOP(ENUM, STRING) STRING,
617 const struct ovsdb_idl_column *column;
618 const struct ovsdb_datum *have_datum;
619 char *key_string, *value_string;
620 struct ovsdb_type type;
625 error = parse_column_key_value(arg, table, &column, &key_string,
626 &operator, operators, ARRAY_SIZE(operators),
630 ctl_fatal("%s: missing value", arg);
634 type.n_max = UINT_MAX;
636 have_datum = ovsdb_idl_read(row, column);
638 union ovsdb_atom want_key;
639 struct ovsdb_datum b;
642 if (column->type.value.type == OVSDB_TYPE_VOID) {
643 ctl_fatal("cannot specify key to check for non-map column %s",
647 die_if_error(ovsdb_atom_from_string(&want_key, &column->type.key,
648 key_string, symtab));
650 type.key = type.value;
651 type.value.type = OVSDB_TYPE_VOID;
652 die_if_error(ovsdb_datum_from_string(&b, &type, value_string, symtab));
654 idx = ovsdb_datum_find_key(have_datum,
655 &want_key, column->type.key.type);
656 if (idx == UINT_MAX && !is_set_operator(operator)) {
659 struct ovsdb_datum a;
661 if (idx != UINT_MAX) {
663 a.keys = &have_datum->values[idx];
671 retval = evaluate_relop(&a, &b, &type, operator);
674 ovsdb_atom_destroy(&want_key, column->type.key.type);
675 ovsdb_datum_destroy(&b, &type);
677 struct ovsdb_datum want_datum;
679 die_if_error(ovsdb_datum_from_string(&want_datum, &column->type,
680 value_string, symtab));
681 retval = evaluate_relop(have_datum, &want_datum, &type, operator);
682 ovsdb_datum_destroy(&want_datum, &column->type);
692 invalidate_cache(struct ctl_context *ctx)
694 if (ctx->invalidate_cache) {
695 (ctx->invalidate_cache)(ctx);
700 pre_cmd_get(struct ctl_context *ctx)
702 const char *id = shash_find_data(&ctx->options, "--id");
703 const char *table_name = ctx->argv[1];
704 const struct ctl_table_class *table;
707 /* Using "get" without --id or a column name could possibly make sense.
708 * Maybe, for example, a *ctl command run wants to assert that a row
709 * exists. But it is unlikely that an interactive user would want to do
710 * that, so issue a warning if we're running on a terminal. */
711 if (!id && ctx->argc <= 3 && isatty(STDOUT_FILENO)) {
712 VLOG_WARN("\"get\" command without row arguments or \"--id\" is "
713 "possibly erroneous");
716 table = pre_get_table(ctx, table_name);
717 for (i = 3; i < ctx->argc; i++) {
718 if (!strcasecmp(ctx->argv[i], "_uuid")
719 || !strcasecmp(ctx->argv[i], "-uuid")) {
723 pre_parse_column_key_value(ctx, ctx->argv[i], table);
728 cmd_get(struct ctl_context *ctx)
730 const char *id = shash_find_data(&ctx->options, "--id");
731 bool must_exist = !shash_find(&ctx->options, "--if-exists");
732 const char *table_name = ctx->argv[1];
733 const char *record_id = ctx->argv[2];
734 const struct ctl_table_class *table;
735 const struct ovsdb_idl_row *row;
736 struct ds *out = &ctx->output;
739 if (id && !must_exist) {
740 ctl_fatal("--if-exists and --id may not be specified together");
743 table = get_table(table_name);
744 row = get_row(ctx, table, record_id, must_exist);
750 struct ovsdb_symbol *symbol;
753 symbol = create_symbol(ctx->symtab, id, &new);
755 ctl_fatal("row id \"%s\" specified on \"get\" command was used "
756 "before it was defined", id);
758 symbol->uuid = row->uuid;
760 /* This symbol refers to a row that already exists, so disable warnings
761 * about it being unreferenced. */
762 symbol->strong_ref = true;
764 for (i = 3; i < ctx->argc; i++) {
765 const struct ovsdb_idl_column *column;
766 const struct ovsdb_datum *datum;
769 /* Special case for obtaining the UUID of a row. We can't just do this
770 * through parse_column_key_value() below since it returns a "struct
771 * ovsdb_idl_column" and the UUID column doesn't have one. */
772 if (!strcasecmp(ctx->argv[i], "_uuid")
773 || !strcasecmp(ctx->argv[i], "-uuid")) {
774 ds_put_format(out, UUID_FMT"\n", UUID_ARGS(&row->uuid));
778 die_if_error(parse_column_key_value(ctx->argv[i], table,
779 &column, &key_string,
780 NULL, NULL, 0, NULL));
782 ovsdb_idl_txn_verify(row, column);
783 datum = ovsdb_idl_read(row, column);
785 union ovsdb_atom key;
788 if (column->type.value.type == OVSDB_TYPE_VOID) {
789 ctl_fatal("cannot specify key to get for non-map column %s",
793 die_if_error(ovsdb_atom_from_string(&key,
795 key_string, ctx->symtab));
797 idx = ovsdb_datum_find_key(datum, &key,
798 column->type.key.type);
799 if (idx == UINT_MAX) {
801 ctl_fatal("no key \"%s\" in %s record \"%s\" column %s",
802 key_string, table->class->name, record_id,
806 ovsdb_atom_to_string(&datum->values[idx],
807 column->type.value.type, out);
809 ovsdb_atom_destroy(&key, column->type.key.type);
811 ovsdb_datum_to_string(datum, &column->type, out);
813 ds_put_char(out, '\n');
820 parse_column_names(const char *column_names,
821 const struct ctl_table_class *table,
822 const struct ovsdb_idl_column ***columnsp,
825 const struct ovsdb_idl_column **columns;
831 n_columns = table->class->n_columns + 1;
832 columns = xmalloc(n_columns * sizeof *columns);
834 for (i = 0; i < table->class->n_columns; i++) {
835 columns[i + 1] = &table->class->columns[i];
838 char *s = xstrdup(column_names);
839 size_t allocated_columns;
840 char *save_ptr = NULL;
844 allocated_columns = n_columns = 0;
845 for (column_name = strtok_r(s, ", ", &save_ptr); column_name;
846 column_name = strtok_r(NULL, ", ", &save_ptr)) {
847 const struct ovsdb_idl_column *column;
849 if (!strcasecmp(column_name, "_uuid")) {
852 die_if_error(get_column(table, column_name, &column));
854 if (n_columns >= allocated_columns) {
855 columns = x2nrealloc(columns, &allocated_columns,
858 columns[n_columns++] = column;
863 ctl_fatal("must specify at least one column name");
867 *n_columnsp = n_columns;
871 pre_list_columns(struct ctl_context *ctx,
872 const struct ctl_table_class *table,
873 const char *column_names)
875 const struct ovsdb_idl_column **columns;
879 parse_column_names(column_names, table, &columns, &n_columns);
880 for (i = 0; i < n_columns; i++) {
882 ovsdb_idl_add_column(ctx->idl, columns[i]);
889 pre_cmd_list(struct ctl_context *ctx)
891 const char *column_names = shash_find_data(&ctx->options, "--columns");
892 const char *table_name = ctx->argv[1];
893 const struct ctl_table_class *table;
895 table = pre_get_table(ctx, table_name);
896 pre_list_columns(ctx, table, column_names);
899 static struct table *
900 list_make_table(const struct ovsdb_idl_column **columns, size_t n_columns)
905 out = xmalloc(sizeof *out);
908 for (i = 0; i < n_columns; i++) {
909 const struct ovsdb_idl_column *column = columns[i];
910 const char *column_name = column ? column->name : "_uuid";
912 table_add_column(out, "%s", column_name);
919 list_record(const struct ovsdb_idl_row *row,
920 const struct ovsdb_idl_column **columns, size_t n_columns,
930 for (i = 0; i < n_columns; i++) {
931 const struct ovsdb_idl_column *column = columns[i];
932 struct cell *cell = table_add_cell(out);
935 struct ovsdb_datum datum;
936 union ovsdb_atom atom;
938 atom.uuid = row->uuid;
944 cell->json = ovsdb_datum_to_json(&datum, &ovsdb_type_uuid);
945 cell->type = &ovsdb_type_uuid;
947 const struct ovsdb_datum *datum = ovsdb_idl_read(row, column);
949 cell->json = ovsdb_datum_to_json(datum, &column->type);
950 cell->type = &column->type;
956 cmd_list(struct ctl_context *ctx)
958 const char *column_names = shash_find_data(&ctx->options, "--columns");
959 bool must_exist = !shash_find(&ctx->options, "--if-exists");
960 const struct ovsdb_idl_column **columns;
961 const char *table_name = ctx->argv[1];
962 const struct ctl_table_class *table;
967 table = get_table(table_name);
968 parse_column_names(column_names, table, &columns, &n_columns);
969 out = ctx->table = list_make_table(columns, n_columns);
971 for (i = 2; i < ctx->argc; i++) {
972 list_record(get_row(ctx, table, ctx->argv[i], must_exist),
973 columns, n_columns, out);
976 const struct ovsdb_idl_row *row;
978 for (row = ovsdb_idl_first_row(ctx->idl, table->class); row != NULL;
979 row = ovsdb_idl_next_row(row)) {
980 list_record(row, columns, n_columns, out);
987 pre_cmd_find(struct ctl_context *ctx)
989 const char *column_names = shash_find_data(&ctx->options, "--columns");
990 const char *table_name = ctx->argv[1];
991 const struct ctl_table_class *table;
994 table = pre_get_table(ctx, table_name);
995 pre_list_columns(ctx, table, column_names);
996 for (i = 2; i < ctx->argc; i++) {
997 pre_parse_column_key_value(ctx, ctx->argv[i], table);
1002 cmd_find(struct ctl_context *ctx)
1004 const char *column_names = shash_find_data(&ctx->options, "--columns");
1005 const struct ovsdb_idl_column **columns;
1006 const char *table_name = ctx->argv[1];
1007 const struct ctl_table_class *table;
1008 const struct ovsdb_idl_row *row;
1012 table = get_table(table_name);
1013 parse_column_names(column_names, table, &columns, &n_columns);
1014 out = ctx->table = list_make_table(columns, n_columns);
1015 for (row = ovsdb_idl_first_row(ctx->idl, table->class); row;
1016 row = ovsdb_idl_next_row(row)) {
1019 for (i = 2; i < ctx->argc; i++) {
1020 if (!is_condition_satisfied(table, row, ctx->argv[i],
1025 list_record(row, columns, n_columns, out);
1033 pre_cmd_set(struct ctl_context *ctx)
1035 const char *table_name = ctx->argv[1];
1036 const struct ctl_table_class *table;
1039 table = pre_get_table(ctx, table_name);
1040 for (i = 3; i < ctx->argc; i++) {
1041 pre_parse_column_key_value(ctx, ctx->argv[i], table);
1046 cmd_set(struct ctl_context *ctx)
1048 bool must_exist = !shash_find(&ctx->options, "--if-exists");
1049 const char *table_name = ctx->argv[1];
1050 const char *record_id = ctx->argv[2];
1051 const struct ctl_table_class*table;
1052 const struct ovsdb_idl_row *row;
1055 table = get_table(table_name);
1056 row = get_row(ctx, table, record_id, must_exist);
1061 for (i = 3; i < ctx->argc; i++) {
1062 set_column(table, row, ctx->argv[i], ctx->symtab);
1065 invalidate_cache(ctx);
1069 pre_cmd_add(struct ctl_context *ctx)
1071 const char *table_name = ctx->argv[1];
1072 const char *column_name = ctx->argv[3];
1073 const struct ctl_table_class *table;
1074 const struct ovsdb_idl_column *column;
1076 table = pre_get_table(ctx, table_name);
1077 pre_get_column(ctx, table, column_name, &column);
1081 cmd_add(struct ctl_context *ctx)
1083 bool must_exist = !shash_find(&ctx->options, "--if-exists");
1084 const char *table_name = ctx->argv[1];
1085 const char *record_id = ctx->argv[2];
1086 const char *column_name = ctx->argv[3];
1087 const struct ctl_table_class *table;
1088 const struct ovsdb_idl_column *column;
1089 const struct ovsdb_idl_row *row;
1090 const struct ovsdb_type *type;
1091 struct ovsdb_datum old;
1094 table = get_table(table_name);
1095 die_if_error(get_column(table, column_name, &column));
1096 row = get_row(ctx, table, record_id, must_exist);
1100 check_mutable(row, column);
1102 type = &column->type;
1103 ovsdb_datum_clone(&old, ovsdb_idl_read(row, column), &column->type);
1104 for (i = 4; i < ctx->argc; i++) {
1105 struct ovsdb_type add_type;
1106 struct ovsdb_datum add;
1110 add_type.n_max = UINT_MAX;
1111 die_if_error(ovsdb_datum_from_string(&add, &add_type, ctx->argv[i],
1113 ovsdb_datum_union(&old, &add, type, false);
1114 ovsdb_datum_destroy(&add, type);
1116 if (old.n > type->n_max) {
1117 ctl_fatal("\"add\" operation would put %u %s in column %s of "
1118 "table %s but the maximum number is %u",
1120 type->value.type == OVSDB_TYPE_VOID ? "values" : "pairs",
1121 column->name, table->class->name, type->n_max);
1123 ovsdb_idl_txn_verify(row, column);
1124 ovsdb_idl_txn_write(row, column, &old);
1126 invalidate_cache(ctx);
1130 pre_cmd_remove(struct ctl_context *ctx)
1132 const char *table_name = ctx->argv[1];
1133 const char *column_name = ctx->argv[3];
1134 const struct ctl_table_class *table;
1135 const struct ovsdb_idl_column *column;
1137 table = pre_get_table(ctx, table_name);
1138 pre_get_column(ctx, table, column_name, &column);
1142 cmd_remove(struct ctl_context *ctx)
1144 bool must_exist = !shash_find(&ctx->options, "--if-exists");
1145 const char *table_name = ctx->argv[1];
1146 const char *record_id = ctx->argv[2];
1147 const char *column_name = ctx->argv[3];
1148 const struct ctl_table_class *table;
1149 const struct ovsdb_idl_column *column;
1150 const struct ovsdb_idl_row *row;
1151 const struct ovsdb_type *type;
1152 struct ovsdb_datum old;
1155 table = get_table(table_name);
1156 die_if_error(get_column(table, column_name, &column));
1157 row = get_row(ctx, table, record_id, must_exist);
1161 check_mutable(row, column);
1163 type = &column->type;
1164 ovsdb_datum_clone(&old, ovsdb_idl_read(row, column), &column->type);
1165 for (i = 4; i < ctx->argc; i++) {
1166 struct ovsdb_type rm_type;
1167 struct ovsdb_datum rm;
1172 rm_type.n_max = UINT_MAX;
1173 error = ovsdb_datum_from_string(&rm, &rm_type,
1174 ctx->argv[i], ctx->symtab);
1177 if (ovsdb_type_is_map(&rm_type)) {
1178 rm_type.value.type = OVSDB_TYPE_VOID;
1180 die_if_error(ovsdb_datum_from_string(
1181 &rm, &rm_type, ctx->argv[i], ctx->symtab));
1183 ctl_fatal("%s", error);
1186 ovsdb_datum_subtract(&old, type, &rm, &rm_type);
1187 ovsdb_datum_destroy(&rm, &rm_type);
1189 if (old.n < type->n_min) {
1190 ctl_fatal("\"remove\" operation would put %u %s in column %s of "
1191 "table %s but the minimum number is %u",
1193 type->value.type == OVSDB_TYPE_VOID ? "values" : "pairs",
1194 column->name, table->class->name, type->n_min);
1196 ovsdb_idl_txn_verify(row, column);
1197 ovsdb_idl_txn_write(row, column, &old);
1199 invalidate_cache(ctx);
1203 pre_cmd_clear(struct ctl_context *ctx)
1205 const char *table_name = ctx->argv[1];
1206 const struct ctl_table_class *table;
1209 table = pre_get_table(ctx, table_name);
1210 for (i = 3; i < ctx->argc; i++) {
1211 const struct ovsdb_idl_column *column;
1213 pre_get_column(ctx, table, ctx->argv[i], &column);
1218 cmd_clear(struct ctl_context *ctx)
1220 bool must_exist = !shash_find(&ctx->options, "--if-exists");
1221 const char *table_name = ctx->argv[1];
1222 const char *record_id = ctx->argv[2];
1223 const struct ctl_table_class *table;
1224 const struct ovsdb_idl_row *row;
1227 table = get_table(table_name);
1228 row = get_row(ctx, table, record_id, must_exist);
1233 for (i = 3; i < ctx->argc; i++) {
1234 const struct ovsdb_idl_column *column;
1235 const struct ovsdb_type *type;
1236 struct ovsdb_datum datum;
1238 die_if_error(get_column(table, ctx->argv[i], &column));
1239 check_mutable(row, column);
1241 type = &column->type;
1242 if (type->n_min > 0) {
1243 ctl_fatal("\"clear\" operation cannot be applied to column %s "
1244 "of table %s, which is not allowed to be empty",
1245 column->name, table->class->name);
1248 ovsdb_datum_init_empty(&datum);
1249 ovsdb_idl_txn_write(row, column, &datum);
1252 invalidate_cache(ctx);
1256 pre_create(struct ctl_context *ctx)
1258 const char *id = shash_find_data(&ctx->options, "--id");
1259 const char *table_name = ctx->argv[1];
1260 const struct ctl_table_class *table;
1262 table = get_table(table_name);
1263 if (!id && !table->class->is_root) {
1264 VLOG_WARN("applying \"create\" command to table %s without --id "
1265 "option will have no effect", table->class->name);
1270 cmd_create(struct ctl_context *ctx)
1272 const char *id = shash_find_data(&ctx->options, "--id");
1273 const char *table_name = ctx->argv[1];
1274 const struct ctl_table_class *table = get_table(table_name);
1275 const struct ovsdb_idl_row *row;
1276 const struct uuid *uuid;
1280 struct ovsdb_symbol *symbol = create_symbol(ctx->symtab, id, NULL);
1281 if (table->class->is_root) {
1282 /* This table is in the root set, meaning that rows created in it
1283 * won't disappear even if they are unreferenced, so disable
1284 * warnings about that by pretending that there is a reference. */
1285 symbol->strong_ref = true;
1287 uuid = &symbol->uuid;
1292 row = ovsdb_idl_txn_insert(ctx->txn, table->class, uuid);
1293 for (i = 2; i < ctx->argc; i++) {
1294 set_column(table, row, ctx->argv[i], ctx->symtab);
1296 ds_put_format(&ctx->output, UUID_FMT, UUID_ARGS(&row->uuid));
1299 /* This function may be used as the 'postprocess' function for commands that
1300 * insert new rows into the database. It expects that the command's 'run'
1301 * function prints the UUID reported by ovsdb_idl_txn_insert() as the command's
1302 * sole output. It replaces that output by the row's permanent UUID assigned
1303 * by the database server and appends a new-line.
1305 * Currently we use this only for "create", because the higher-level commands
1306 * are supposed to be independent of the actual structure of the vswitch
1309 post_create(struct ctl_context *ctx)
1311 const struct uuid *real;
1314 if (!uuid_from_string(&dummy, ds_cstr(&ctx->output))) {
1317 real = ovsdb_idl_txn_get_insert_uuid(ctx->txn, &dummy);
1319 ds_clear(&ctx->output);
1320 ds_put_format(&ctx->output, UUID_FMT, UUID_ARGS(real));
1322 ds_put_char(&ctx->output, '\n');
1326 pre_cmd_destroy(struct ctl_context *ctx)
1328 const char *table_name = ctx->argv[1];
1330 pre_get_table(ctx, table_name);
1334 cmd_destroy(struct ctl_context *ctx)
1336 bool must_exist = !shash_find(&ctx->options, "--if-exists");
1337 bool delete_all = shash_find(&ctx->options, "--all");
1338 const char *table_name = ctx->argv[1];
1339 const struct ctl_table_class *table;
1342 table = get_table(table_name);
1344 if (delete_all && ctx->argc > 2) {
1345 ctl_fatal("--all and records argument should not be specified together");
1348 if (delete_all && !must_exist) {
1349 ctl_fatal("--all and --if-exists should not be specified together");
1353 const struct ovsdb_idl_row *row;
1354 const struct ovsdb_idl_row *next_row;
1356 for (row = ovsdb_idl_first_row(ctx->idl, table->class);
1358 next_row = ovsdb_idl_next_row(row);
1359 ovsdb_idl_txn_delete(row);
1363 for (i = 2; i < ctx->argc; i++) {
1364 const struct ovsdb_idl_row *row;
1366 row = get_row(ctx, table, ctx->argv[i], must_exist);
1368 ovsdb_idl_txn_delete(row);
1372 invalidate_cache(ctx);
1376 pre_cmd_wait_until(struct ctl_context *ctx)
1378 const char *table_name = ctx->argv[1];
1379 const struct ctl_table_class *table;
1382 table = pre_get_table(ctx, table_name);
1384 for (i = 3; i < ctx->argc; i++) {
1385 pre_parse_column_key_value(ctx, ctx->argv[i], table);
1390 cmd_wait_until(struct ctl_context *ctx)
1392 const char *table_name = ctx->argv[1];
1393 const char *record_id = ctx->argv[2];
1394 const struct ctl_table_class *table;
1395 const struct ovsdb_idl_row *row;
1398 table = get_table(table_name);
1400 row = get_row(ctx, table, record_id, false);
1402 ctx->try_again = true;
1406 for (i = 3; i < ctx->argc; i++) {
1407 if (!is_condition_satisfied(table, row, ctx->argv[i], ctx->symtab)) {
1408 ctx->try_again = true;
1414 /* Parses one command. */
1416 parse_command(int argc, char *argv[], struct shash *local_options,
1417 struct ctl_command *command)
1419 const struct ctl_command_syntax *p;
1420 struct shash_node *node;
1424 shash_init(&command->options);
1425 shash_swap(local_options, &command->options);
1426 for (i = 0; i < argc; i++) {
1427 const char *option = argv[i];
1431 if (option[0] != '-') {
1435 equals = strchr(option, '=');
1437 key = xmemdup0(option, equals - option);
1438 value = xstrdup(equals + 1);
1440 key = xstrdup(option);
1444 if (shash_find(&command->options, key)) {
1445 ctl_fatal("'%s' option specified multiple times", argv[i]);
1447 shash_add_nocopy(&command->options, key, value);
1450 ctl_fatal("missing command name (use --help for help)");
1453 p = shash_find_data(&all_commands, argv[i]);
1455 ctl_fatal("unknown command '%s'; use --help for help", argv[i]);
1458 SHASH_FOR_EACH (node, &command->options) {
1459 const char *s = strstr(p->options, node->name);
1460 int end = s ? s[strlen(node->name)] : EOF;
1462 if (end != '=' && end != ',' && end != ' ' && end != '\0') {
1463 ctl_fatal("'%s' command has no '%s' option",
1464 argv[i], node->name);
1466 if ((end == '=') != (node->data != NULL)) {
1468 ctl_fatal("missing argument to '%s' option on '%s' "
1469 "command", node->name, argv[i]);
1471 ctl_fatal("'%s' option on '%s' does not accept an "
1472 "argument", node->name, argv[i]);
1477 n_arg = argc - i - 1;
1478 if (n_arg < p->min_args) {
1479 ctl_fatal("'%s' command requires at least %d arguments",
1480 p->name, p->min_args);
1481 } else if (n_arg > p->max_args) {
1484 for (j = i + 1; j < argc; j++) {
1485 if (argv[j][0] == '-') {
1486 ctl_fatal("'%s' command takes at most %d arguments "
1487 "(note that options must precede command "
1488 "names and follow a \"--\" argument)",
1489 p->name, p->max_args);
1493 ctl_fatal("'%s' command takes at most %d arguments",
1494 p->name, p->max_args);
1497 command->syntax = p;
1498 command->argc = n_arg + 1;
1499 command->argv = &argv[i];
1503 pre_cmd_show(struct ctl_context *ctx)
1505 struct cmd_show_table *show;
1507 for (show = cmd_show_tables; show->table; show++) {
1510 ovsdb_idl_add_table(ctx->idl, show->table);
1511 if (show->name_column) {
1512 ovsdb_idl_add_column(ctx->idl, show->name_column);
1514 for (i = 0; i < ARRAY_SIZE(show->columns); i++) {
1515 const struct ovsdb_idl_column *column = show->columns[i];
1517 ovsdb_idl_add_column(ctx->idl, column);
1523 static struct cmd_show_table *
1524 cmd_show_find_table_by_row(const struct ovsdb_idl_row *row)
1526 struct cmd_show_table *show;
1528 for (show = cmd_show_tables; show->table; show++) {
1529 if (show->table == row->table->class) {
1536 static struct cmd_show_table *
1537 cmd_show_find_table_by_name(const char *name)
1539 struct cmd_show_table *show;
1541 for (show = cmd_show_tables; show->table; show++) {
1542 if (!strcmp(show->table->name, name)) {
1550 cmd_show_row(struct ctl_context *ctx, const struct ovsdb_idl_row *row,
1553 struct cmd_show_table *show = cmd_show_find_table_by_row(row);
1556 ds_put_char_multiple(&ctx->output, ' ', level * 4);
1557 if (show && show->name_column) {
1558 const struct ovsdb_datum *datum;
1560 ds_put_format(&ctx->output, "%s ", show->table->name);
1561 datum = ovsdb_idl_read(row, show->name_column);
1562 ovsdb_datum_to_string(datum, &show->name_column->type, &ctx->output);
1564 ds_put_format(&ctx->output, UUID_FMT, UUID_ARGS(&row->uuid));
1566 ds_put_char(&ctx->output, '\n');
1568 if (!show || show->recurse) {
1572 show->recurse = true;
1573 for (i = 0; i < ARRAY_SIZE(show->columns); i++) {
1574 const struct ovsdb_idl_column *column = show->columns[i];
1575 const struct ovsdb_datum *datum;
1581 datum = ovsdb_idl_read(row, column);
1582 if (column->type.key.type == OVSDB_TYPE_UUID &&
1583 column->type.key.u.uuid.refTableName) {
1584 struct cmd_show_table *ref_show;
1587 ref_show = cmd_show_find_table_by_name(
1588 column->type.key.u.uuid.refTableName);
1590 for (j = 0; j < datum->n; j++) {
1591 const struct ovsdb_idl_row *ref_row;
1593 ref_row = ovsdb_idl_get_row_for_uuid(ctx->idl,
1595 &datum->keys[j].uuid);
1597 cmd_show_row(ctx, ref_row, level + 1);
1602 } else if (ovsdb_type_is_map(&column->type) &&
1603 column->type.value.type == OVSDB_TYPE_UUID &&
1604 column->type.value.u.uuid.refTableName) {
1605 struct cmd_show_table *ref_show;
1608 /* Prints the key to ref'ed table name map if the ref'ed table
1609 * is also defined in 'cmd_show_tables'. */
1610 ref_show = cmd_show_find_table_by_name(
1611 column->type.value.u.uuid.refTableName);
1612 if (ref_show && ref_show->name_column) {
1613 ds_put_char_multiple(&ctx->output, ' ', (level + 1) * 4);
1614 ds_put_format(&ctx->output, "%s:\n", column->name);
1615 for (j = 0; j < datum->n; j++) {
1616 const struct ovsdb_idl_row *ref_row;
1618 ref_row = ovsdb_idl_get_row_for_uuid(ctx->idl,
1620 &datum->values[j].uuid);
1622 ds_put_char_multiple(&ctx->output, ' ', (level + 2) * 4);
1623 ovsdb_atom_to_string(&datum->keys[j], column->type.key.type,
1625 ds_put_char(&ctx->output, '=');
1627 const struct ovsdb_datum *ref_datum;
1629 ref_datum = ovsdb_idl_read(ref_row,
1630 ref_show->name_column);
1631 ovsdb_datum_to_string(ref_datum,
1632 &ref_show->name_column->type,
1635 ds_put_cstr(&ctx->output, "\"<null>\"");
1637 ds_put_char(&ctx->output, '\n');
1643 if (!ovsdb_datum_is_default(datum, &column->type)) {
1644 ds_put_char_multiple(&ctx->output, ' ', (level + 1) * 4);
1645 ds_put_format(&ctx->output, "%s: ", column->name);
1646 ovsdb_datum_to_string(datum, &column->type, &ctx->output);
1647 ds_put_char(&ctx->output, '\n');
1650 show->recurse = false;
1654 cmd_show(struct ctl_context *ctx)
1656 const struct ovsdb_idl_row *row;
1658 for (row = ovsdb_idl_first_row(ctx->idl, cmd_show_tables[0].table);
1659 row; row = ovsdb_idl_next_row(row)) {
1660 cmd_show_row(ctx, row, 0);
1665 /* Given pointer to dynamic array 'options_p', array's current size
1666 * 'allocated_options_p' and number of added options 'n_options_p',
1667 * adds all command options to the array. Enlarges the array if
1670 ctl_add_cmd_options(struct option **options_p, size_t *n_options_p,
1671 size_t *allocated_options_p, int opt_val)
1674 const struct shash_node *node;
1675 size_t n_existing_options = *n_options_p;
1677 SHASH_FOR_EACH (node, ctl_get_all_commands()) {
1678 const struct ctl_command_syntax *p = node->data;
1680 if (p->options[0]) {
1681 char *save_ptr = NULL;
1685 s = xstrdup(p->options);
1686 for (name = strtok_r(s, ",", &save_ptr); name != NULL;
1687 name = strtok_r(NULL, ",", &save_ptr)) {
1691 ovs_assert(name[0] == '-' && name[1] == '-' && name[2]);
1694 equals = strchr(name, '=');
1696 has_arg = required_argument;
1699 has_arg = no_argument;
1702 o = find_option(name, *options_p, *n_options_p);
1704 ovs_assert(o - *options_p >= n_existing_options);
1705 ovs_assert(o->has_arg == has_arg);
1707 o = add_option(options_p, n_options_p, allocated_options_p);
1708 o->name = xstrdup(name);
1709 o->has_arg = has_arg;
1718 o = add_option(options_p, n_options_p, allocated_options_p);
1719 memset(o, 0, sizeof *o);
1722 /* Parses command-line input for commands. */
1723 struct ctl_command *
1724 ctl_parse_commands(int argc, char *argv[], struct shash *local_options,
1725 size_t *n_commandsp)
1727 struct ctl_command *commands;
1728 size_t n_commands, allocated_commands;
1732 n_commands = allocated_commands = 0;
1734 for (start = i = 0; i <= argc; i++) {
1735 if (i == argc || !strcmp(argv[i], "--")) {
1737 if (n_commands >= allocated_commands) {
1738 struct ctl_command *c;
1740 commands = x2nrealloc(commands, &allocated_commands,
1742 for (c = commands; c < &commands[n_commands]; c++) {
1743 shash_moved(&c->options);
1746 parse_command(i - start, &argv[start], local_options,
1747 &commands[n_commands++]);
1748 } else if (!shash_is_empty(local_options)) {
1749 ctl_fatal("missing command name (use --help for help)");
1755 ctl_fatal("missing command name (use --help for help)");
1757 *n_commandsp = n_commands;
1761 /* Prints all registered commands. */
1763 ctl_print_commands(void)
1765 const struct shash_node *node;
1767 SHASH_FOR_EACH (node, ctl_get_all_commands()) {
1768 const struct ctl_command_syntax *p = node->data;
1769 char *options = xstrdup(p->options);
1770 char *options_begin = options;
1773 for (item = strsep(&options, ","); item != NULL;
1774 item = strsep(&options, ",")) {
1775 if (item[0] != '\0') {
1776 printf("[%s] ", item);
1779 printf(",%s,", p->name);
1780 print_command_arguments(p);
1783 free(options_begin);
1789 /* Given array of options 'options', prints them. */
1791 ctl_print_options(const struct option *options)
1793 for (; options->name; options++) {
1794 const struct option *o = options;
1796 printf("--%s%s\n", o->name, o->has_arg ? "=ARG" : "");
1797 if (o->flag == NULL && o->val > 0 && o->val <= UCHAR_MAX) {
1798 printf("-%c%s\n", o->val, o->has_arg ? " ARG" : "");
1805 /* Returns the default local database path. */
1807 ctl_default_db(void)
1811 def = xasprintf("unix:%s/db.sock", ovs_rundir());
1816 /* Returns true if it looks like this set of arguments might modify the
1817 * database, otherwise false. (Not very smart, so it's prone to false
1820 ctl_might_write_to_db(char **argv)
1822 for (; *argv; argv++) {
1823 const struct ctl_command_syntax *p = shash_find_data(&all_commands, *argv);
1824 if (p && p->mode == RW) {
1832 ctl_fatal(const char *format, ...)
1837 va_start(args, format);
1838 message = xvasprintf(format, args);
1841 vlog_set_levels(&VLM_db_ctl_base, VLF_CONSOLE, VLL_OFF);
1842 VLOG_ERR("%s", message);
1843 ovs_error(0, "%s", message);
1844 ctl_exit(EXIT_FAILURE);
1847 /* Frees the current transaction and the underlying IDL and then calls
1850 * Freeing the transaction and the IDL is not strictly necessary, but it makes
1851 * for a clean memory leak report from valgrind in the normal case. That makes
1852 * it easier to notice real memory leaks. */
1854 ctl_exit(int status)
1857 ovsdb_idl_txn_abort(the_idl_txn);
1858 ovsdb_idl_txn_destroy(the_idl_txn);
1860 ovsdb_idl_destroy(the_idl);
1864 /* Command for showing overview of database contents. */
1865 static const struct ctl_command_syntax db_ctl_show_command[] = {
1866 {"show", 0, 0, "", pre_cmd_show, cmd_show, NULL, "", RO},
1867 {NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, RO},
1870 /* Comman database commands to be registered. */
1871 static const struct ctl_command_syntax db_ctl_commands[] = {
1872 {"comment", 0, INT_MAX, "[ARG]...", NULL, NULL, NULL, "", RO},
1873 {"get", 2, INT_MAX, "TABLE RECORD [COLUMN[:KEY]]...",pre_cmd_get, cmd_get,
1874 NULL, "--if-exists,--id=", RO},
1875 {"list", 1, INT_MAX, "TABLE [RECORD]...", pre_cmd_list, cmd_list, NULL,
1876 "--if-exists,--columns=", RO},
1877 {"find", 1, INT_MAX, "TABLE [COLUMN[:KEY]=VALUE]...", pre_cmd_find,
1878 cmd_find, NULL, "--columns=", RO},
1879 {"set", 3, INT_MAX, "TABLE RECORD COLUMN[:KEY]=VALUE...", pre_cmd_set,
1880 cmd_set, NULL, "--if-exists", RW},
1881 {"add", 4, INT_MAX, "TABLE RECORD COLUMN [KEY=]VALUE...", pre_cmd_add,
1882 cmd_add, NULL, "--if-exists", RW},
1883 {"remove", 4, INT_MAX, "TABLE RECORD COLUMN KEY|VALUE|KEY=VALUE...",
1884 pre_cmd_remove, cmd_remove, NULL, "--if-exists", RW},
1885 {"clear", 3, INT_MAX, "TABLE RECORD COLUMN...", pre_cmd_clear, cmd_clear,
1886 NULL, "--if-exists", RW},
1887 {"create", 2, INT_MAX, "TABLE COLUMN[:KEY]=VALUE...", pre_create,
1888 cmd_create, post_create, "--id=", RW},
1889 {"destroy", 1, INT_MAX, "TABLE [RECORD]...", pre_cmd_destroy, cmd_destroy,
1890 NULL, "--if-exists,--all", RW},
1891 {"wait-until", 2, INT_MAX, "TABLE RECORD [COLUMN[:KEY]=VALUE]...",
1892 pre_cmd_wait_until, cmd_wait_until, NULL, "", RO},
1893 {NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, RO},
1896 /* Registers commands represented by 'struct ctl_command_syntax's to
1897 * 'all_commands'. The last element of 'commands' must be an all-NULL
1900 ctl_register_commands(const struct ctl_command_syntax *commands)
1902 const struct ctl_command_syntax *p;
1904 for (p = commands; p->name; p++) {
1905 shash_add_assert(&all_commands, p->name, p);
1909 /* Registers the 'db_ctl_commands' to 'all_commands'. */
1913 ctl_register_commands(db_ctl_commands);
1914 ctl_register_commands(db_ctl_show_command);
1917 /* Returns 'all_commands'. */
1918 const struct shash *
1919 ctl_get_all_commands(void)
1921 return &all_commands;
1924 /* Returns the text for the database commands usage. */
1926 ctl_get_db_cmd_usage(void)
1928 return "Database commands:\n\
1929 list TBL [REC] list RECord (or all records) in TBL\n\
1930 find TBL CONDITION... list records satisfying CONDITION in TBL\n\
1931 get TBL REC COL[:KEY] print values of COLumns in RECord in TBL\n\
1932 set TBL REC COL[:KEY]=VALUE set COLumn values in RECord in TBL\n\
1933 add TBL REC COL [KEY=]VALUE add (KEY=)VALUE to COLumn in RECord in TBL\n\
1934 remove TBL REC COL [KEY=]VALUE remove (KEY=)VALUE from COLumn\n\
1935 clear TBL REC COL clear values from COLumn in RECord in TBL\n\
1936 create TBL COL[:KEY]=VALUE create and initialize new record\n\
1937 destroy TBL REC delete RECord from TBL\n\
1938 wait-until TBL REC [COL[:KEY]=VALUE] wait until condition is true\n\
1939 Potentially unsafe database commands require --force option.\n";
1942 /* Initializes 'ctx' from 'command'. */
1944 ctl_context_init_command(struct ctl_context *ctx,
1945 struct ctl_command *command)
1947 ctx->argc = command->argc;
1948 ctx->argv = command->argv;
1949 ctx->options = command->options;
1951 ds_swap(&ctx->output, &command->output);
1952 ctx->table = command->table;
1953 ctx->try_again = false;
1956 /* Initializes the entire 'ctx'. */
1958 ctl_context_init(struct ctl_context *ctx, struct ctl_command *command,
1959 struct ovsdb_idl *idl, struct ovsdb_idl_txn *txn,
1960 struct ovsdb_symbol_table *symtab,
1961 void (*invalidate_cache)(struct ctl_context *))
1964 ctl_context_init_command(ctx, command);
1968 ctx->symtab = symtab;
1969 ctx->invalidate_cache = invalidate_cache;
1972 /* Completes processing of 'command' within 'ctx'. */
1974 ctl_context_done_command(struct ctl_context *ctx,
1975 struct ctl_command *command)
1977 ds_swap(&ctx->output, &command->output);
1978 command->table = ctx->table;
1981 /* Finishes up with 'ctx'.
1983 * If command is nonnull, first calls ctl_context_done_command() to complete
1984 * processing that command within 'ctx'. */
1986 ctl_context_done(struct ctl_context *ctx,
1987 struct ctl_command *command)
1990 ctl_context_done_command(ctx, command);
1992 invalidate_cache(ctx);
1995 /* Finds and returns the "struct ctl_table_class *" with 'table_name' by
1996 * searching the 'tables'. */
1997 static const struct ctl_table_class *
1998 get_table(const char *table_name)
2000 const struct ctl_table_class *table;
2001 const struct ctl_table_class *best_match = NULL;
2002 unsigned int best_score = 0;
2004 for (table = tables; table->class; table++) {
2005 unsigned int score = score_partial_match(table->class->name,
2007 if (score > best_score) {
2010 } else if (score == best_score) {
2016 } else if (best_score) {
2017 ctl_fatal("multiple table names match \"%s\"", table_name);
2019 ctl_fatal("unknown table \"%s\"", table_name);
2024 /* Sets the column of 'row' in 'table'. */
2026 set_column(const struct ctl_table_class *table,
2027 const struct ovsdb_idl_row *row, const char *arg,
2028 struct ovsdb_symbol_table *symtab)
2030 const struct ovsdb_idl_column *column;
2031 char *key_string, *value_string;
2034 error = parse_column_key_value(arg, table, &column, &key_string,
2035 NULL, NULL, 0, &value_string);
2036 die_if_error(error);
2037 if (!value_string) {
2038 ctl_fatal("%s: missing value", arg);
2040 check_mutable(row, column);
2043 union ovsdb_atom key, value;
2044 struct ovsdb_datum datum;
2046 if (column->type.value.type == OVSDB_TYPE_VOID) {
2047 ctl_fatal("cannot specify key to set for non-map column %s",
2051 die_if_error(ovsdb_atom_from_string(&key, &column->type.key,
2052 key_string, symtab));
2053 die_if_error(ovsdb_atom_from_string(&value, &column->type.value,
2054 value_string, symtab));
2056 ovsdb_datum_init_empty(&datum);
2057 ovsdb_datum_add_unsafe(&datum, &key, &value, &column->type);
2059 ovsdb_atom_destroy(&key, column->type.key.type);
2060 ovsdb_atom_destroy(&value, column->type.value.type);
2062 ovsdb_datum_union(&datum, ovsdb_idl_read(row, column),
2063 &column->type, false);
2064 ovsdb_idl_txn_verify(row, column);
2065 ovsdb_idl_txn_write(row, column, &datum);
2067 struct ovsdb_datum datum;
2069 die_if_error(ovsdb_datum_from_string(&datum, &column->type,
2070 value_string, symtab));
2071 ovsdb_idl_txn_write(row, column, &datum);
2078 void ctl_set_column(const char *table_name,
2079 const struct ovsdb_idl_row *row, const char *arg,
2080 struct ovsdb_symbol_table *symtab)
2082 set_column(get_table(table_name), row, arg, symtab);