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
= &equals
;
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 /* Given pointer to dynamic array 'options_p', array's current size
1500 * 'allocated_options_p' and number of added options 'n_options_p',
1501 * adds all command options to the array. Enlarges the array if
1504 ctl_add_cmd_options(struct option
**options_p
, size_t *n_options_p
,
1505 size_t *allocated_options_p
, int opt_val
)
1508 const struct shash_node
*node
;
1509 size_t n_existing_options
= *n_options_p
;
1511 SHASH_FOR_EACH (node
, ctl_get_all_commands()) {
1512 const struct ctl_command_syntax
*p
= node
->data
;
1514 if (p
->options
[0]) {
1515 char *save_ptr
= NULL
;
1519 s
= xstrdup(p
->options
);
1520 for (name
= strtok_r(s
, ",", &save_ptr
); name
!= NULL
;
1521 name
= strtok_r(NULL
, ",", &save_ptr
)) {
1525 ovs_assert(name
[0] == '-' && name
[1] == '-' && name
[2]);
1528 equals
= strchr(name
, '=');
1530 has_arg
= required_argument
;
1533 has_arg
= no_argument
;
1536 o
= find_option(name
, *options_p
, *n_options_p
);
1538 ovs_assert(o
- *options_p
>= n_existing_options
);
1539 ovs_assert(o
->has_arg
== has_arg
);
1541 o
= add_option(options_p
, n_options_p
, allocated_options_p
);
1542 o
->name
= xstrdup(name
);
1543 o
->has_arg
= has_arg
;
1552 o
= add_option(options_p
, n_options_p
, allocated_options_p
);
1553 memset(o
, 0, sizeof *o
);
1556 /* Parses command-line input for commands. */
1557 struct ctl_command
*
1558 ctl_parse_commands(int argc
, char *argv
[], struct shash
*local_options
,
1559 size_t *n_commandsp
)
1561 struct ctl_command
*commands
;
1562 size_t n_commands
, allocated_commands
;
1566 n_commands
= allocated_commands
= 0;
1568 for (start
= i
= 0; i
<= argc
; i
++) {
1569 if (i
== argc
|| !strcmp(argv
[i
], "--")) {
1571 if (n_commands
>= allocated_commands
) {
1572 struct ctl_command
*c
;
1574 commands
= x2nrealloc(commands
, &allocated_commands
,
1576 for (c
= commands
; c
< &commands
[n_commands
]; c
++) {
1577 shash_moved(&c
->options
);
1580 parse_command(i
- start
, &argv
[start
], local_options
,
1581 &commands
[n_commands
++]);
1582 } else if (!shash_is_empty(local_options
)) {
1583 ctl_fatal("missing command name (use --help for help)");
1589 ctl_fatal("missing command name (use --help for help)");
1591 *n_commandsp
= n_commands
;
1595 /* Prints all registered commands. */
1597 ctl_print_commands(void)
1599 const struct shash_node
*node
;
1601 SHASH_FOR_EACH (node
, ctl_get_all_commands()) {
1602 const struct ctl_command_syntax
*p
= node
->data
;
1603 char *options
= xstrdup(p
->options
);
1604 char *options_begin
= options
;
1607 for (item
= strsep(&options
, ","); item
!= NULL
;
1608 item
= strsep(&options
, ",")) {
1609 if (item
[0] != '\0') {
1610 printf("[%s] ", item
);
1613 printf(",%s,", p
->name
);
1614 print_command_arguments(p
);
1617 free(options_begin
);
1623 /* Given array of options 'options', prints them. */
1625 ctl_print_options(const struct option
*options
)
1627 for (; options
->name
; options
++) {
1628 const struct option
*o
= options
;
1630 printf("--%s%s\n", o
->name
, o
->has_arg
? "=ARG" : "");
1631 if (o
->flag
== NULL
&& o
->val
> 0 && o
->val
<= UCHAR_MAX
) {
1632 printf("-%c%s\n", o
->val
, o
->has_arg
? " ARG" : "");
1639 /* Returns the default local database path. */
1641 ctl_default_db(void)
1645 def
= xasprintf("unix:%s/db.sock", ovs_rundir());
1650 /* Returns true if it looks like this set of arguments might modify the
1651 * database, otherwise false. (Not very smart, so it's prone to false
1654 ctl_might_write_to_db(char **argv
)
1656 for (; *argv
; argv
++) {
1657 const struct ctl_command_syntax
*p
= shash_find_data(&all_commands
, *argv
);
1658 if (p
&& p
->mode
== RW
) {
1666 ctl_fatal(const char *format
, ...)
1671 va_start(args
, format
);
1672 message
= xvasprintf(format
, args
);
1675 vlog_set_levels(&VLM_db_ctl_base
, VLF_CONSOLE
, VLL_OFF
);
1676 VLOG_ERR("%s", message
);
1677 ovs_error(0, "%s", message
);
1678 ctl_exit(EXIT_FAILURE
);
1681 /* Frees the current transaction and the underlying IDL and then calls
1684 * Freeing the transaction and the IDL is not strictly necessary, but it makes
1685 * for a clean memory leak report from valgrind in the normal case. That makes
1686 * it easier to notice real memory leaks. */
1688 ctl_exit(int status
)
1691 ovsdb_idl_txn_abort(the_idl_txn
);
1692 ovsdb_idl_txn_destroy(the_idl_txn
);
1694 ovsdb_idl_destroy(the_idl
);
1698 /* Comman database commands to be registered. */
1699 static const struct ctl_command_syntax db_ctl_commands
[] = {
1700 {"comment", 0, INT_MAX
, "[ARG]...", NULL
, NULL
, NULL
, "", RO
},
1701 {"get", 2, INT_MAX
, "TABLE RECORD [COLUMN[:KEY]]...",pre_cmd_get
, cmd_get
,
1702 NULL
, "--if-exists,--id=", RO
},
1703 {"list", 1, INT_MAX
, "TABLE [RECORD]...", pre_cmd_list
, cmd_list
, NULL
,
1704 "--if-exists,--columns=", RO
},
1705 {"find", 1, INT_MAX
, "TABLE [COLUMN[:KEY]=VALUE]...", pre_cmd_find
,
1706 cmd_find
, NULL
, "--columns=", RO
},
1707 {"set", 3, INT_MAX
, "TABLE RECORD COLUMN[:KEY]=VALUE...", pre_cmd_set
,
1708 cmd_set
, NULL
, "--if-exists", RW
},
1709 {"add", 4, INT_MAX
, "TABLE RECORD COLUMN [KEY=]VALUE...", pre_cmd_add
,
1710 cmd_add
, NULL
, "--if-exists", RW
},
1711 {"remove", 4, INT_MAX
, "TABLE RECORD COLUMN KEY|VALUE|KEY=VALUE...",
1712 pre_cmd_remove
, cmd_remove
, NULL
, "--if-exists", RW
},
1713 {"clear", 3, INT_MAX
, "TABLE RECORD COLUMN...", pre_cmd_clear
, cmd_clear
,
1714 NULL
, "--if-exists", RW
},
1715 {"create", 2, INT_MAX
, "TABLE COLUMN[:KEY]=VALUE...", pre_create
,
1716 cmd_create
, post_create
, "--id=", RW
},
1717 {"destroy", 1, INT_MAX
, "TABLE [RECORD]...", pre_cmd_destroy
, cmd_destroy
,
1718 NULL
, "--if-exists,--all", RW
},
1719 {"wait-until", 2, INT_MAX
, "TABLE RECORD [COLUMN[:KEY]=VALUE]...",
1720 pre_cmd_wait_until
, cmd_wait_until
, NULL
, "", RO
},
1721 {NULL
, 0, 0, NULL
, NULL
, NULL
, NULL
, NULL
, RO
},
1724 /* Registers commands represented by 'struct ctl_command_syntax's to
1725 * 'all_commands'. The last element of 'commands' must be an all-NULL
1728 ctl_register_commands(const struct ctl_command_syntax
*commands
)
1730 const struct ctl_command_syntax
*p
;
1732 for (p
= commands
; p
->name
; p
++) {
1733 shash_add_assert(&all_commands
, p
->name
, p
);
1737 /* Registers the 'db_ctl_commands' to 'all_commands'. */
1741 ctl_register_commands(db_ctl_commands
);
1744 /* Returns 'all_commands'. */
1745 const struct shash
*
1746 ctl_get_all_commands(void)
1748 return &all_commands
;
1751 /* Returns the text for the database commands usage. */
1753 ctl_get_db_cmd_usage(void)
1755 return "Database commands:\n\
1756 list TBL [REC] list RECord (or all records) in TBL\n\
1757 find TBL CONDITION... list records satisfying CONDITION in TBL\n\
1758 get TBL REC COL[:KEY] print values of COLumns in RECord in TBL\n\
1759 set TBL REC COL[:KEY]=VALUE set COLumn values in RECord in TBL\n\
1760 add TBL REC COL [KEY=]VALUE add (KEY=)VALUE to COLumn in RECord in TBL\n\
1761 remove TBL REC COL [KEY=]VALUE remove (KEY=)VALUE from COLumn\n\
1762 clear TBL REC COL clear values from COLumn in RECord in TBL\n\
1763 create TBL COL[:KEY]=VALUE create and initialize new record\n\
1764 destroy TBL REC delete RECord from TBL\n\
1765 wait-until TBL REC [COL[:KEY]=VALUE] wait until condition is true\n\
1766 Potentially unsafe database commands require --force option.\n";
1769 /* Initializes 'ctx' from 'command'. */
1771 ctl_context_init_command(struct ctl_context
*ctx
,
1772 struct ctl_command
*command
)
1774 ctx
->argc
= command
->argc
;
1775 ctx
->argv
= command
->argv
;
1776 ctx
->options
= command
->options
;
1778 ds_swap(&ctx
->output
, &command
->output
);
1779 ctx
->table
= command
->table
;
1780 ctx
->try_again
= false;
1783 /* Initializes the entire 'ctx'. */
1785 ctl_context_init(struct ctl_context
*ctx
, struct ctl_command
*command
,
1786 struct ovsdb_idl
*idl
, struct ovsdb_idl_txn
*txn
,
1787 struct ovsdb_symbol_table
*symtab
,
1788 void (*invalidate_cache
)(struct ctl_context
*))
1791 ctl_context_init_command(ctx
, command
);
1795 ctx
->symtab
= symtab
;
1796 ctx
->invalidate_cache
= invalidate_cache
;
1799 /* Completes processing of 'command' within 'ctx'. */
1801 ctl_context_done_command(struct ctl_context
*ctx
,
1802 struct ctl_command
*command
)
1804 ds_swap(&ctx
->output
, &command
->output
);
1805 command
->table
= ctx
->table
;
1808 /* Finishes up with 'ctx'.
1810 * If command is nonnull, first calls ctl_context_done_command() to complete
1811 * processing that command within 'ctx'. */
1813 ctl_context_done(struct ctl_context
*ctx
,
1814 struct ctl_command
*command
)
1817 ctl_context_done_command(ctx
, command
);
1819 invalidate_cache(ctx
);
1822 /* Finds and returns the "struct ctl_table_class *" with 'table_name' by
1823 * searching the 'tables'. */
1824 const struct ctl_table_class
*
1825 get_table(const char *table_name
)
1827 const struct ctl_table_class
*table
;
1828 const struct ctl_table_class
*best_match
= NULL
;
1829 unsigned int best_score
= 0;
1831 for (table
= tables
; table
->class; table
++) {
1832 unsigned int score
= score_partial_match(table
->class->name
,
1834 if (score
> best_score
) {
1837 } else if (score
== best_score
) {
1843 } else if (best_score
) {
1844 ctl_fatal("multiple table names match \"%s\"", table_name
);
1846 ctl_fatal("unknown table \"%s\"", table_name
);
1851 /* Sets the column of 'row' in 'table'. */
1853 set_column(const struct ctl_table_class
*table
,
1854 const struct ovsdb_idl_row
*row
, const char *arg
,
1855 struct ovsdb_symbol_table
*symtab
)
1857 const struct ovsdb_idl_column
*column
;
1858 char *key_string
, *value_string
;
1861 error
= parse_column_key_value(arg
, table
, &column
, &key_string
,
1862 NULL
, NULL
, 0, &value_string
);
1863 die_if_error(error
);
1864 if (!value_string
) {
1865 ctl_fatal("%s: missing value", arg
);
1867 check_mutable(row
, column
);
1870 union ovsdb_atom key
, value
;
1871 struct ovsdb_datum datum
;
1873 if (column
->type
.value
.type
== OVSDB_TYPE_VOID
) {
1874 ctl_fatal("cannot specify key to set for non-map column %s",
1878 die_if_error(ovsdb_atom_from_string(&key
, &column
->type
.key
,
1879 key_string
, symtab
));
1880 die_if_error(ovsdb_atom_from_string(&value
, &column
->type
.value
,
1881 value_string
, symtab
));
1883 ovsdb_datum_init_empty(&datum
);
1884 ovsdb_datum_add_unsafe(&datum
, &key
, &value
, &column
->type
);
1886 ovsdb_atom_destroy(&key
, column
->type
.key
.type
);
1887 ovsdb_atom_destroy(&value
, column
->type
.value
.type
);
1889 ovsdb_datum_union(&datum
, ovsdb_idl_read(row
, column
),
1890 &column
->type
, false);
1891 ovsdb_idl_txn_verify(row
, column
);
1892 ovsdb_idl_txn_write(row
, column
, &datum
);
1894 struct ovsdb_datum datum
;
1896 die_if_error(ovsdb_datum_from_string(&datum
, &column
->type
,
1897 value_string
, symtab
));
1898 ovsdb_idl_txn_write(row
, column
, &datum
);