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"
42 VLOG_DEFINE_THIS_MODULE(db_ctl_base
);
44 /* This array defines the 'show' command output format. User can check the
45 * definition in utilities/ovs-vsctl.c as reference.
47 * Particularly, if an element in 'columns[]' represents a reference to
48 * another table, the referred table must also be defined as an entry in
49 * in 'cmd_show_tables[]'.
51 * The definition must end with an all-NULL entry. It is initalized once
52 * when ctl_init() is called.
55 extern struct cmd_show_table cmd_show_tables
[];
57 /* ctl_exit() is called by ctl_fatal(). User can optionally supply an exit
58 * function ctl_exit_func() via ctl_init. If supplied, this function will
59 * be called by ctl_exit()
61 static void (*ctl_exit_func
)(int status
) = NULL
;
62 OVS_NO_RETURN
static void ctl_exit(int status
);
64 /* Represents all tables in the schema. User must define 'tables'
65 * in implementation and supply via clt_init(). The definition must end
66 * with an all-NULL entry. */
67 static const struct ctl_table_class
*tables
;
69 static struct shash all_commands
= SHASH_INITIALIZER(&all_commands
);
70 static const struct ctl_table_class
*get_table(const char *table_name
);
71 static void set_column(const struct ctl_table_class
*,
72 const struct ovsdb_idl_row
*, const char *,
73 struct ovsdb_symbol_table
*);
76 static struct option
*
77 find_option(const char *name
, struct option
*options
, size_t n_options
)
81 for (i
= 0; i
< n_options
; i
++) {
82 if (!strcmp(options
[i
].name
, name
)) {
89 static struct option
*
90 add_option(struct option
**optionsp
, size_t *n_optionsp
,
91 size_t *allocated_optionsp
)
93 if (*n_optionsp
>= *allocated_optionsp
) {
94 *optionsp
= x2nrealloc(*optionsp
, allocated_optionsp
,
97 return &(*optionsp
)[(*n_optionsp
)++];
100 /* Converts the command arguments into format that can be parsed by
101 * bash completion script.
103 * Therein, arguments will be attached with following prefixes:
105 * !argument :: The argument is required
106 * ?argument :: The argument is optional
107 * *argument :: The argument may appear any number (0 or more) times
108 * +argument :: The argument may appear one or more times
112 print_command_arguments(const struct ctl_command_syntax
*command
)
115 * The argument string is parsed in reverse. We use a stack 'oew_stack' to
116 * keep track of nested optionals. Whenever a ']' is encountered, we push
117 * a bit to 'oew_stack'. The bit is set to 1 if the ']' is not nested.
118 * Subsequently, we pop an entry everytime '[' is met.
120 * We use 'whole_word_is_optional' value to decide whether or not a ! or +
121 * should be added on encountering a space: if the optional surrounds the
122 * whole word then it shouldn't be, but if it is only a part of the word
123 * (i.e. [key=]value), it should be.
125 uint32_t oew_stack
= 0;
127 const char *arguments
= command
->arguments
;
128 int length
= strlen(arguments
);
133 /* Output buffer, written backward from end. */
134 char *output
= xmalloc(2 * length
);
135 char *outp
= output
+ 2 * length
;
138 bool in_repeated
= false;
139 bool whole_word_is_optional
= false;
141 for (const char *inp
= arguments
+ length
; inp
> arguments
; ) {
145 if (inp
[1] == '\0' || inp
[1] == ' ' || inp
[1] == '.') {
150 /* Checks if the whole word is optional, and sets the
151 * 'whole_word_is_optional' accordingly. */
152 if ((inp
== arguments
|| inp
[-1] == ' ') && oew_stack
& 1) {
153 *--outp
= in_repeated
? '*' : '?';
154 whole_word_is_optional
= true;
157 whole_word_is_optional
= false;
162 if (!whole_word_is_optional
) {
163 *--outp
= in_repeated
? '+' : '!';
167 whole_word_is_optional
= false;
177 if (arguments
[0] != '[' && outp
!= output
+ 2 * length
- 1) {
178 *--outp
= in_repeated
? '+' : '!';
185 die_if_error(char *error
)
188 ctl_fatal("%s", error
);
193 to_lower_and_underscores(unsigned c
)
195 return c
== '-' ? '_' : tolower(c
);
199 score_partial_match(const char *name
, const char *s
)
203 if (!strcmp(name
, s
)) {
206 for (score
= 0; ; score
++, name
++, s
++) {
207 if (to_lower_and_underscores(*name
) != to_lower_and_underscores(*s
)) {
209 } else if (*name
== '\0') {
213 return *s
== '\0' ? score
: 0;
216 static struct ovsdb_symbol
*
217 create_symbol(struct ovsdb_symbol_table
*symtab
, const char *id
, bool *newp
)
219 struct ovsdb_symbol
*symbol
;
222 ctl_fatal("row id \"%s\" does not begin with \"@\"", id
);
226 *newp
= ovsdb_symbol_table_get(symtab
, id
) == NULL
;
229 symbol
= ovsdb_symbol_table_insert(symtab
, id
);
230 if (symbol
->created
) {
231 ctl_fatal("row id \"%s\" may only be specified on one --id option",
234 symbol
->created
= true;
238 static const struct ovsdb_idl_row
*
239 get_row_by_id(struct ctl_context
*ctx
, const struct ctl_table_class
*table
,
240 const struct ctl_row_id
*id
, const char *record_id
)
242 const struct ovsdb_idl_row
*referrer
, *final
;
248 if (!id
->name_column
) {
249 if (strcmp(record_id
, ".")) {
252 referrer
= ovsdb_idl_first_row(ctx
->idl
, id
->table
);
253 if (!referrer
|| ovsdb_idl_next_row(referrer
)) {
257 const struct ovsdb_idl_row
*row
;
260 for (row
= ovsdb_idl_first_row(ctx
->idl
, id
->table
);
262 row
= ovsdb_idl_next_row(row
))
264 const struct ovsdb_datum
*name
;
266 name
= ovsdb_idl_get(row
, id
->name_column
,
267 OVSDB_TYPE_STRING
, OVSDB_TYPE_VOID
);
268 if (name
->n
== 1 && !strcmp(name
->keys
[0].string
, record_id
)) {
270 ctl_fatal("multiple rows in %s match \"%s\"",
271 table
->class->name
, record_id
);
282 if (id
->uuid_column
) {
283 const struct ovsdb_datum
*uuid
;
285 ovsdb_idl_txn_verify(referrer
, id
->uuid_column
);
286 uuid
= ovsdb_idl_get(referrer
, id
->uuid_column
,
287 OVSDB_TYPE_UUID
, OVSDB_TYPE_VOID
);
289 final
= ovsdb_idl_get_row_for_uuid(ctx
->idl
, table
->class,
290 &uuid
->keys
[0].uuid
);
299 static const struct ovsdb_idl_row
*
300 get_row(struct ctl_context
*ctx
,
301 const struct ctl_table_class
*table
, const char *record_id
,
304 const struct ovsdb_idl_row
*row
;
308 if (uuid_from_string(&uuid
, record_id
)) {
309 row
= ovsdb_idl_get_row_for_uuid(ctx
->idl
, table
->class, &uuid
);
314 for (i
= 0; i
< ARRAY_SIZE(table
->row_ids
); i
++) {
315 row
= get_row_by_id(ctx
, table
, &table
->row_ids
[i
], record_id
);
321 if (must_exist
&& !row
) {
322 ctl_fatal("no row \"%s\" in table %s",
323 record_id
, table
->class->name
);
329 get_column(const struct ctl_table_class
*table
, const char *column_name
,
330 const struct ovsdb_idl_column
**columnp
)
332 const struct ovsdb_idl_column
*best_match
= NULL
;
333 unsigned int best_score
= 0;
336 for (i
= 0; i
< table
->class->n_columns
; i
++) {
337 const struct ovsdb_idl_column
*column
= &table
->class->columns
[i
];
338 unsigned int score
= score_partial_match(column
->name
, column_name
);
339 if (score
> best_score
) {
342 } else if (score
== best_score
) {
347 *columnp
= best_match
;
350 } else if (best_score
) {
351 return xasprintf("%s contains more than one column whose name "
352 "matches \"%s\"", table
->class->name
, column_name
);
354 return xasprintf("%s does not contain a column whose name matches "
355 "\"%s\"", table
->class->name
, column_name
);
360 pre_get_column(struct ctl_context
*ctx
,
361 const struct ctl_table_class
*table
, const char *column_name
,
362 const struct ovsdb_idl_column
**columnp
)
364 die_if_error(get_column(table
, column_name
, columnp
));
365 ovsdb_idl_add_column(ctx
->idl
, *columnp
);
368 static const struct ctl_table_class
*
369 pre_get_table(struct ctl_context
*ctx
, const char *table_name
)
371 const struct ctl_table_class
*table_class
;
374 table_class
= get_table(table_name
);
375 ovsdb_idl_add_table(ctx
->idl
, table_class
->class);
377 for (i
= 0; i
< ARRAY_SIZE(table_class
->row_ids
); i
++) {
378 const struct ctl_row_id
*id
= &table_class
->row_ids
[i
];
380 ovsdb_idl_add_table(ctx
->idl
, id
->table
);
382 if (id
->name_column
) {
383 ovsdb_idl_add_column(ctx
->idl
, id
->name_column
);
385 if (id
->uuid_column
) {
386 ovsdb_idl_add_column(ctx
->idl
, id
->uuid_column
);
394 missing_operator_error(const char *arg
, const char **allowed_operators
,
400 ds_put_format(&s
, "%s: argument does not end in ", arg
);
401 ds_put_format(&s
, "\"%s\"", allowed_operators
[0]);
402 if (n_allowed
== 2) {
403 ds_put_format(&s
, " or \"%s\"", allowed_operators
[1]);
404 } else if (n_allowed
> 2) {
407 for (i
= 1; i
< n_allowed
- 1; i
++) {
408 ds_put_format(&s
, ", \"%s\"", allowed_operators
[i
]);
410 ds_put_format(&s
, ", or \"%s\"", allowed_operators
[i
]);
412 ds_put_format(&s
, " followed by a value.");
414 return ds_steal_cstr(&s
);
417 /* Breaks 'arg' apart into a number of fields in the following order:
419 * - The name of a column in 'table', stored into '*columnp'. The column
420 * name may be abbreviated.
422 * - Optionally ':' followed by a key string. The key is stored as a
423 * malloc()'d string into '*keyp', or NULL if no key is present in
426 * - If 'valuep' is nonnull, an operator followed by a value string. The
427 * allowed operators are the 'n_allowed' string in 'allowed_operators',
428 * or just "=" if 'n_allowed' is 0. If 'operatorp' is nonnull, then the
429 * index of the operator within 'allowed_operators' is stored into
430 * '*operatorp'. The value is stored as a malloc()'d string into
431 * '*valuep', or NULL if no value is present in 'arg'.
433 * On success, returns NULL. On failure, returned a malloc()'d string error
434 * message and stores NULL into all of the nonnull output arguments. */
435 static char * OVS_WARN_UNUSED_RESULT
436 parse_column_key_value(const char *arg
,
437 const struct ctl_table_class
*table
,
438 const struct ovsdb_idl_column
**columnp
, char **keyp
,
440 const char **allowed_operators
, size_t n_allowed
,
447 ovs_assert(!(operatorp
&& !valuep
));
453 /* Parse column name. */
454 error
= ovsdb_token_parse(&p
, &column_name
);
458 if (column_name
[0] == '\0') {
460 error
= xasprintf("%s: missing column name", arg
);
463 error
= get_column(table
, column_name
, columnp
);
469 /* Parse key string. */
472 error
= ovsdb_token_parse(&p
, keyp
);
478 /* Parse value string. */
484 if (!allowed_operators
) {
485 static const char *equals
= "=";
486 allowed_operators
= &equals
;
492 for (i
= 0; i
< n_allowed
; i
++) {
493 const char *op
= allowed_operators
[i
];
494 size_t op_len
= strlen(op
);
496 if (op_len
> best_len
&& !strncmp(op
, p
, op_len
) && p
[op_len
]) {
502 error
= missing_operator_error(arg
, allowed_operators
, n_allowed
);
509 *valuep
= xstrdup(p
+ best_len
);
512 error
= xasprintf("%s: trailing garbage \"%s\" in argument",
533 static const struct ovsdb_idl_column
*
534 pre_parse_column_key_value(struct ctl_context
*ctx
,
536 const struct ctl_table_class
*table
)
538 const struct ovsdb_idl_column
*column
;
543 die_if_error(ovsdb_token_parse(&p
, &column_name
));
544 if (column_name
[0] == '\0') {
545 ctl_fatal("%s: missing column name", arg
);
548 pre_get_column(ctx
, table
, column_name
, &column
);
555 check_mutable(const struct ovsdb_idl_row
*row
,
556 const struct ovsdb_idl_column
*column
)
558 if (!ovsdb_idl_is_mutable(row
, column
)) {
559 ctl_fatal("cannot modify read-only column %s in table %s",
560 column
->name
, row
->table
->class->name
);
565 RELOP(RELOP_EQ, "=") \
566 RELOP(RELOP_NE, "!=") \
567 RELOP(RELOP_LT, "<") \
568 RELOP(RELOP_GT, ">") \
569 RELOP(RELOP_LE, "<=") \
570 RELOP(RELOP_GE, ">=") \
571 RELOP(RELOP_SET_EQ, "{=}") \
572 RELOP(RELOP_SET_NE, "{!=}") \
573 RELOP(RELOP_SET_LT, "{<}") \
574 RELOP(RELOP_SET_GT, "{>}") \
575 RELOP(RELOP_SET_LE, "{<=}") \
576 RELOP(RELOP_SET_GE, "{>=}")
579 #define RELOP(ENUM, STRING) ENUM,
585 is_set_operator(enum relop op
)
587 return (op
== RELOP_SET_EQ
|| op
== RELOP_SET_NE
||
588 op
== RELOP_SET_LT
|| op
== RELOP_SET_GT
||
589 op
== RELOP_SET_LE
|| op
== RELOP_SET_GE
);
593 evaluate_relop(const struct ovsdb_datum
*a
, const struct ovsdb_datum
*b
,
594 const struct ovsdb_type
*type
, enum relop op
)
599 return ovsdb_datum_compare_3way(a
, b
, type
) == 0;
602 return ovsdb_datum_compare_3way(a
, b
, type
) != 0;
604 return ovsdb_datum_compare_3way(a
, b
, type
) < 0;
606 return ovsdb_datum_compare_3way(a
, b
, type
) > 0;
608 return ovsdb_datum_compare_3way(a
, b
, type
) <= 0;
610 return ovsdb_datum_compare_3way(a
, b
, type
) >= 0;
613 return b
->n
> a
->n
&& ovsdb_datum_includes_all(a
, b
, type
);
615 return a
->n
> b
->n
&& ovsdb_datum_includes_all(b
, a
, type
);
617 return ovsdb_datum_includes_all(a
, b
, type
);
619 return ovsdb_datum_includes_all(b
, a
, type
);
627 is_condition_satisfied(const struct ctl_table_class
*table
,
628 const struct ovsdb_idl_row
*row
, const char *arg
,
629 struct ovsdb_symbol_table
*symtab
)
631 static const char *operators
[] = {
632 #define RELOP(ENUM, STRING) STRING,
637 const struct ovsdb_idl_column
*column
;
638 const struct ovsdb_datum
*have_datum
;
639 char *key_string
, *value_string
;
640 struct ovsdb_type type
;
645 error
= parse_column_key_value(arg
, table
, &column
, &key_string
,
646 &operator, operators
, ARRAY_SIZE(operators
),
650 ctl_fatal("%s: missing value", arg
);
654 type
.n_max
= UINT_MAX
;
656 have_datum
= ovsdb_idl_read(row
, column
);
658 union ovsdb_atom want_key
;
659 struct ovsdb_datum b
;
662 if (column
->type
.value
.type
== OVSDB_TYPE_VOID
) {
663 ctl_fatal("cannot specify key to check for non-map column %s",
667 die_if_error(ovsdb_atom_from_string(&want_key
, &column
->type
.key
,
668 key_string
, symtab
));
670 type
.key
= type
.value
;
671 type
.value
.type
= OVSDB_TYPE_VOID
;
672 die_if_error(ovsdb_datum_from_string(&b
, &type
, value_string
, symtab
));
674 idx
= ovsdb_datum_find_key(have_datum
,
675 &want_key
, column
->type
.key
.type
);
676 if (idx
== UINT_MAX
&& !is_set_operator(operator)) {
679 struct ovsdb_datum a
;
681 if (idx
!= UINT_MAX
) {
683 a
.keys
= &have_datum
->values
[idx
];
691 retval
= evaluate_relop(&a
, &b
, &type
, operator);
694 ovsdb_atom_destroy(&want_key
, column
->type
.key
.type
);
695 ovsdb_datum_destroy(&b
, &type
);
697 struct ovsdb_datum want_datum
;
699 die_if_error(ovsdb_datum_from_string(&want_datum
, &column
->type
,
700 value_string
, symtab
));
701 retval
= evaluate_relop(have_datum
, &want_datum
, &type
, operator);
702 ovsdb_datum_destroy(&want_datum
, &column
->type
);
712 invalidate_cache(struct ctl_context
*ctx
)
714 if (ctx
->invalidate_cache
) {
715 (ctx
->invalidate_cache
)(ctx
);
720 pre_cmd_get(struct ctl_context
*ctx
)
722 const char *id
= shash_find_data(&ctx
->options
, "--id");
723 const char *table_name
= ctx
->argv
[1];
724 const struct ctl_table_class
*table
;
727 /* Using "get" without --id or a column name could possibly make sense.
728 * Maybe, for example, a *ctl command run wants to assert that a row
729 * exists. But it is unlikely that an interactive user would want to do
730 * that, so issue a warning if we're running on a terminal. */
731 if (!id
&& ctx
->argc
<= 3 && isatty(STDOUT_FILENO
)) {
732 VLOG_WARN("\"get\" command without row arguments or \"--id\" is "
733 "possibly erroneous");
736 table
= pre_get_table(ctx
, table_name
);
737 for (i
= 3; i
< ctx
->argc
; i
++) {
738 if (!strcasecmp(ctx
->argv
[i
], "_uuid")
739 || !strcasecmp(ctx
->argv
[i
], "-uuid")) {
743 pre_parse_column_key_value(ctx
, ctx
->argv
[i
], table
);
748 cmd_get(struct ctl_context
*ctx
)
750 const char *id
= shash_find_data(&ctx
->options
, "--id");
751 bool must_exist
= !shash_find(&ctx
->options
, "--if-exists");
752 const char *table_name
= ctx
->argv
[1];
753 const char *record_id
= ctx
->argv
[2];
754 const struct ctl_table_class
*table
;
755 const struct ovsdb_idl_row
*row
;
756 struct ds
*out
= &ctx
->output
;
759 if (id
&& !must_exist
) {
760 ctl_fatal("--if-exists and --id may not be specified together");
763 table
= get_table(table_name
);
764 row
= get_row(ctx
, table
, record_id
, must_exist
);
770 struct ovsdb_symbol
*symbol
;
773 symbol
= create_symbol(ctx
->symtab
, id
, &new);
775 ctl_fatal("row id \"%s\" specified on \"get\" command was used "
776 "before it was defined", id
);
778 symbol
->uuid
= row
->uuid
;
780 /* This symbol refers to a row that already exists, so disable warnings
781 * about it being unreferenced. */
782 symbol
->strong_ref
= true;
784 for (i
= 3; i
< ctx
->argc
; i
++) {
785 const struct ovsdb_idl_column
*column
;
786 const struct ovsdb_datum
*datum
;
789 /* Special case for obtaining the UUID of a row. We can't just do this
790 * through parse_column_key_value() below since it returns a "struct
791 * ovsdb_idl_column" and the UUID column doesn't have one. */
792 if (!strcasecmp(ctx
->argv
[i
], "_uuid")
793 || !strcasecmp(ctx
->argv
[i
], "-uuid")) {
794 ds_put_format(out
, UUID_FMT
"\n", UUID_ARGS(&row
->uuid
));
798 die_if_error(parse_column_key_value(ctx
->argv
[i
], table
,
799 &column
, &key_string
,
800 NULL
, NULL
, 0, NULL
));
802 ovsdb_idl_txn_verify(row
, column
);
803 datum
= ovsdb_idl_read(row
, column
);
805 union ovsdb_atom key
;
808 if (column
->type
.value
.type
== OVSDB_TYPE_VOID
) {
809 ctl_fatal("cannot specify key to get for non-map column %s",
813 die_if_error(ovsdb_atom_from_string(&key
,
815 key_string
, ctx
->symtab
));
817 idx
= ovsdb_datum_find_key(datum
, &key
,
818 column
->type
.key
.type
);
819 if (idx
== UINT_MAX
) {
821 ctl_fatal("no key \"%s\" in %s record \"%s\" column %s",
822 key_string
, table
->class->name
, record_id
,
826 ovsdb_atom_to_string(&datum
->values
[idx
],
827 column
->type
.value
.type
, out
);
829 ovsdb_atom_destroy(&key
, column
->type
.key
.type
);
831 ovsdb_datum_to_string(datum
, &column
->type
, out
);
833 ds_put_char(out
, '\n');
840 parse_column_names(const char *column_names
,
841 const struct ctl_table_class
*table
,
842 const struct ovsdb_idl_column
***columnsp
,
845 const struct ovsdb_idl_column
**columns
;
851 n_columns
= table
->class->n_columns
+ 1;
852 columns
= xmalloc(n_columns
* sizeof *columns
);
854 for (i
= 0; i
< table
->class->n_columns
; i
++) {
855 columns
[i
+ 1] = &table
->class->columns
[i
];
858 char *s
= xstrdup(column_names
);
859 size_t allocated_columns
;
860 char *save_ptr
= NULL
;
864 allocated_columns
= n_columns
= 0;
865 for (column_name
= strtok_r(s
, ", ", &save_ptr
); column_name
;
866 column_name
= strtok_r(NULL
, ", ", &save_ptr
)) {
867 const struct ovsdb_idl_column
*column
;
869 if (!strcasecmp(column_name
, "_uuid")) {
872 die_if_error(get_column(table
, column_name
, &column
));
874 if (n_columns
>= allocated_columns
) {
875 columns
= x2nrealloc(columns
, &allocated_columns
,
878 columns
[n_columns
++] = column
;
883 ctl_fatal("must specify at least one column name");
887 *n_columnsp
= n_columns
;
891 pre_list_columns(struct ctl_context
*ctx
,
892 const struct ctl_table_class
*table
,
893 const char *column_names
)
895 const struct ovsdb_idl_column
**columns
;
899 parse_column_names(column_names
, table
, &columns
, &n_columns
);
900 for (i
= 0; i
< n_columns
; i
++) {
902 ovsdb_idl_add_column(ctx
->idl
, columns
[i
]);
909 pre_cmd_list(struct ctl_context
*ctx
)
911 const char *column_names
= shash_find_data(&ctx
->options
, "--columns");
912 const char *table_name
= ctx
->argv
[1];
913 const struct ctl_table_class
*table
;
915 table
= pre_get_table(ctx
, table_name
);
916 pre_list_columns(ctx
, table
, column_names
);
919 static struct table
*
920 list_make_table(const struct ovsdb_idl_column
**columns
, size_t n_columns
)
925 out
= xmalloc(sizeof *out
);
928 for (i
= 0; i
< n_columns
; i
++) {
929 const struct ovsdb_idl_column
*column
= columns
[i
];
930 const char *column_name
= column
? column
->name
: "_uuid";
932 table_add_column(out
, "%s", column_name
);
939 list_record(const struct ovsdb_idl_row
*row
,
940 const struct ovsdb_idl_column
**columns
, size_t n_columns
,
950 for (i
= 0; i
< n_columns
; i
++) {
951 const struct ovsdb_idl_column
*column
= columns
[i
];
952 struct cell
*cell
= table_add_cell(out
);
955 struct ovsdb_datum datum
;
956 union ovsdb_atom atom
;
958 atom
.uuid
= row
->uuid
;
964 cell
->json
= ovsdb_datum_to_json(&datum
, &ovsdb_type_uuid
);
965 cell
->type
= &ovsdb_type_uuid
;
967 const struct ovsdb_datum
*datum
= ovsdb_idl_read(row
, column
);
969 cell
->json
= ovsdb_datum_to_json(datum
, &column
->type
);
970 cell
->type
= &column
->type
;
976 cmd_list(struct ctl_context
*ctx
)
978 const char *column_names
= shash_find_data(&ctx
->options
, "--columns");
979 bool must_exist
= !shash_find(&ctx
->options
, "--if-exists");
980 const struct ovsdb_idl_column
**columns
;
981 const char *table_name
= ctx
->argv
[1];
982 const struct ctl_table_class
*table
;
987 table
= get_table(table_name
);
988 parse_column_names(column_names
, table
, &columns
, &n_columns
);
989 out
= ctx
->table
= list_make_table(columns
, n_columns
);
991 for (i
= 2; i
< ctx
->argc
; i
++) {
992 list_record(get_row(ctx
, table
, ctx
->argv
[i
], must_exist
),
993 columns
, n_columns
, out
);
996 const struct ovsdb_idl_row
*row
;
998 for (row
= ovsdb_idl_first_row(ctx
->idl
, table
->class); row
!= NULL
;
999 row
= ovsdb_idl_next_row(row
)) {
1000 list_record(row
, columns
, n_columns
, out
);
1006 /* Finds and returns the "struct ctl_table_class *" with 'table_name' by
1007 * searching the 'tables'. */
1008 static const struct ctl_table_class
*
1009 get_table(const char *table_name
)
1011 const struct ctl_table_class
*table
;
1012 const struct ctl_table_class
*best_match
= NULL
;
1013 unsigned int best_score
= 0;
1015 for (table
= tables
; table
->class; table
++) {
1016 unsigned int score
= score_partial_match(table
->class->name
,
1018 if (score
> best_score
) {
1021 } else if (score
== best_score
) {
1027 } else if (best_score
) {
1028 ctl_fatal("multiple table names match \"%s\"", table_name
);
1030 ctl_fatal("unknown table \"%s\"", table_name
);
1036 pre_cmd_find(struct ctl_context
*ctx
)
1038 const char *column_names
= shash_find_data(&ctx
->options
, "--columns");
1039 const char *table_name
= ctx
->argv
[1];
1040 const struct ctl_table_class
*table
;
1043 table
= pre_get_table(ctx
, table_name
);
1044 pre_list_columns(ctx
, table
, column_names
);
1045 for (i
= 2; i
< ctx
->argc
; i
++) {
1046 pre_parse_column_key_value(ctx
, ctx
->argv
[i
], table
);
1051 cmd_find(struct ctl_context
*ctx
)
1053 const char *column_names
= shash_find_data(&ctx
->options
, "--columns");
1054 const struct ovsdb_idl_column
**columns
;
1055 const char *table_name
= ctx
->argv
[1];
1056 const struct ctl_table_class
*table
;
1057 const struct ovsdb_idl_row
*row
;
1061 table
= get_table(table_name
);
1062 parse_column_names(column_names
, table
, &columns
, &n_columns
);
1063 out
= ctx
->table
= list_make_table(columns
, n_columns
);
1064 for (row
= ovsdb_idl_first_row(ctx
->idl
, table
->class); row
;
1065 row
= ovsdb_idl_next_row(row
)) {
1068 for (i
= 2; i
< ctx
->argc
; i
++) {
1069 if (!is_condition_satisfied(table
, row
, ctx
->argv
[i
],
1074 list_record(row
, columns
, n_columns
, out
);
1081 /* Sets the column of 'row' in 'table'. */
1083 set_column(const struct ctl_table_class
*table
,
1084 const struct ovsdb_idl_row
*row
, const char *arg
,
1085 struct ovsdb_symbol_table
*symtab
)
1087 const struct ovsdb_idl_column
*column
;
1088 char *key_string
, *value_string
;
1091 error
= parse_column_key_value(arg
, table
, &column
, &key_string
,
1092 NULL
, NULL
, 0, &value_string
);
1093 die_if_error(error
);
1094 if (!value_string
) {
1095 ctl_fatal("%s: missing value", arg
);
1097 check_mutable(row
, column
);
1100 union ovsdb_atom key
, value
;
1101 struct ovsdb_datum datum
;
1103 if (column
->type
.value
.type
== OVSDB_TYPE_VOID
) {
1104 ctl_fatal("cannot specify key to set for non-map column %s",
1108 die_if_error(ovsdb_atom_from_string(&key
, &column
->type
.key
,
1109 key_string
, symtab
));
1110 die_if_error(ovsdb_atom_from_string(&value
, &column
->type
.value
,
1111 value_string
, symtab
));
1113 ovsdb_datum_init_empty(&datum
);
1114 ovsdb_datum_add_unsafe(&datum
, &key
, &value
, &column
->type
);
1116 ovsdb_atom_destroy(&key
, column
->type
.key
.type
);
1117 ovsdb_atom_destroy(&value
, column
->type
.value
.type
);
1119 ovsdb_datum_union(&datum
, ovsdb_idl_read(row
, column
),
1120 &column
->type
, false);
1121 ovsdb_idl_txn_verify(row
, column
);
1122 ovsdb_idl_txn_write(row
, column
, &datum
);
1124 struct ovsdb_datum datum
;
1126 die_if_error(ovsdb_datum_from_string(&datum
, &column
->type
,
1127 value_string
, symtab
));
1128 ovsdb_idl_txn_write(row
, column
, &datum
);
1136 pre_cmd_set(struct ctl_context
*ctx
)
1138 const char *table_name
= ctx
->argv
[1];
1139 const struct ctl_table_class
*table
;
1142 table
= pre_get_table(ctx
, table_name
);
1143 for (i
= 3; i
< ctx
->argc
; i
++) {
1144 pre_parse_column_key_value(ctx
, ctx
->argv
[i
], table
);
1149 cmd_set(struct ctl_context
*ctx
)
1151 bool must_exist
= !shash_find(&ctx
->options
, "--if-exists");
1152 const char *table_name
= ctx
->argv
[1];
1153 const char *record_id
= ctx
->argv
[2];
1154 const struct ctl_table_class
*table
;
1155 const struct ovsdb_idl_row
*row
;
1158 table
= get_table(table_name
);
1159 row
= get_row(ctx
, table
, record_id
, must_exist
);
1164 for (i
= 3; i
< ctx
->argc
; i
++) {
1165 set_column(table
, row
, ctx
->argv
[i
], ctx
->symtab
);
1168 invalidate_cache(ctx
);
1172 pre_cmd_add(struct ctl_context
*ctx
)
1174 const char *table_name
= ctx
->argv
[1];
1175 const char *column_name
= ctx
->argv
[3];
1176 const struct ctl_table_class
*table
;
1177 const struct ovsdb_idl_column
*column
;
1179 table
= pre_get_table(ctx
, table_name
);
1180 pre_get_column(ctx
, table
, column_name
, &column
);
1184 cmd_add(struct ctl_context
*ctx
)
1186 bool must_exist
= !shash_find(&ctx
->options
, "--if-exists");
1187 const char *table_name
= ctx
->argv
[1];
1188 const char *record_id
= ctx
->argv
[2];
1189 const char *column_name
= ctx
->argv
[3];
1190 const struct ctl_table_class
*table
;
1191 const struct ovsdb_idl_column
*column
;
1192 const struct ovsdb_idl_row
*row
;
1193 const struct ovsdb_type
*type
;
1194 struct ovsdb_datum old
;
1197 table
= get_table(table_name
);
1198 die_if_error(get_column(table
, column_name
, &column
));
1199 row
= get_row(ctx
, table
, record_id
, must_exist
);
1203 check_mutable(row
, column
);
1205 type
= &column
->type
;
1206 ovsdb_datum_clone(&old
, ovsdb_idl_read(row
, column
), &column
->type
);
1207 for (i
= 4; i
< ctx
->argc
; i
++) {
1208 struct ovsdb_type add_type
;
1209 struct ovsdb_datum add
;
1213 add_type
.n_max
= UINT_MAX
;
1214 die_if_error(ovsdb_datum_from_string(&add
, &add_type
, ctx
->argv
[i
],
1216 ovsdb_datum_union(&old
, &add
, type
, false);
1217 ovsdb_datum_destroy(&add
, type
);
1219 if (old
.n
> type
->n_max
) {
1220 ctl_fatal("\"add\" operation would put %u %s in column %s of "
1221 "table %s but the maximum number is %u",
1223 type
->value
.type
== OVSDB_TYPE_VOID
? "values" : "pairs",
1224 column
->name
, table
->class->name
, type
->n_max
);
1226 ovsdb_idl_txn_verify(row
, column
);
1227 ovsdb_idl_txn_write(row
, column
, &old
);
1229 invalidate_cache(ctx
);
1233 pre_cmd_remove(struct ctl_context
*ctx
)
1235 const char *table_name
= ctx
->argv
[1];
1236 const char *column_name
= ctx
->argv
[3];
1237 const struct ctl_table_class
*table
;
1238 const struct ovsdb_idl_column
*column
;
1240 table
= pre_get_table(ctx
, table_name
);
1241 pre_get_column(ctx
, table
, column_name
, &column
);
1245 cmd_remove(struct ctl_context
*ctx
)
1247 bool must_exist
= !shash_find(&ctx
->options
, "--if-exists");
1248 const char *table_name
= ctx
->argv
[1];
1249 const char *record_id
= ctx
->argv
[2];
1250 const char *column_name
= ctx
->argv
[3];
1251 const struct ctl_table_class
*table
;
1252 const struct ovsdb_idl_column
*column
;
1253 const struct ovsdb_idl_row
*row
;
1254 const struct ovsdb_type
*type
;
1255 struct ovsdb_datum old
;
1258 table
= get_table(table_name
);
1259 die_if_error(get_column(table
, column_name
, &column
));
1260 row
= get_row(ctx
, table
, record_id
, must_exist
);
1264 check_mutable(row
, column
);
1266 type
= &column
->type
;
1267 ovsdb_datum_clone(&old
, ovsdb_idl_read(row
, column
), &column
->type
);
1268 for (i
= 4; i
< ctx
->argc
; i
++) {
1269 struct ovsdb_type rm_type
;
1270 struct ovsdb_datum rm
;
1275 rm_type
.n_max
= UINT_MAX
;
1276 error
= ovsdb_datum_from_string(&rm
, &rm_type
,
1277 ctx
->argv
[i
], ctx
->symtab
);
1280 if (ovsdb_type_is_map(&rm_type
)) {
1281 rm_type
.value
.type
= OVSDB_TYPE_VOID
;
1283 die_if_error(ovsdb_datum_from_string(
1284 &rm
, &rm_type
, ctx
->argv
[i
], ctx
->symtab
));
1286 ctl_fatal("%s", error
);
1289 ovsdb_datum_subtract(&old
, type
, &rm
, &rm_type
);
1290 ovsdb_datum_destroy(&rm
, &rm_type
);
1292 if (old
.n
< type
->n_min
) {
1293 ctl_fatal("\"remove\" operation would put %u %s in column %s of "
1294 "table %s but the minimum number is %u",
1296 type
->value
.type
== OVSDB_TYPE_VOID
? "values" : "pairs",
1297 column
->name
, table
->class->name
, type
->n_min
);
1299 ovsdb_idl_txn_verify(row
, column
);
1300 ovsdb_idl_txn_write(row
, column
, &old
);
1302 invalidate_cache(ctx
);
1306 pre_cmd_clear(struct ctl_context
*ctx
)
1308 const char *table_name
= ctx
->argv
[1];
1309 const struct ctl_table_class
*table
;
1312 table
= pre_get_table(ctx
, table_name
);
1313 for (i
= 3; i
< ctx
->argc
; i
++) {
1314 const struct ovsdb_idl_column
*column
;
1316 pre_get_column(ctx
, table
, ctx
->argv
[i
], &column
);
1321 cmd_clear(struct ctl_context
*ctx
)
1323 bool must_exist
= !shash_find(&ctx
->options
, "--if-exists");
1324 const char *table_name
= ctx
->argv
[1];
1325 const char *record_id
= ctx
->argv
[2];
1326 const struct ctl_table_class
*table
;
1327 const struct ovsdb_idl_row
*row
;
1330 table
= get_table(table_name
);
1331 row
= get_row(ctx
, table
, record_id
, must_exist
);
1336 for (i
= 3; i
< ctx
->argc
; i
++) {
1337 const struct ovsdb_idl_column
*column
;
1338 const struct ovsdb_type
*type
;
1339 struct ovsdb_datum datum
;
1341 die_if_error(get_column(table
, ctx
->argv
[i
], &column
));
1342 check_mutable(row
, column
);
1344 type
= &column
->type
;
1345 if (type
->n_min
> 0) {
1346 ctl_fatal("\"clear\" operation cannot be applied to column %s "
1347 "of table %s, which is not allowed to be empty",
1348 column
->name
, table
->class->name
);
1351 ovsdb_datum_init_empty(&datum
);
1352 ovsdb_idl_txn_write(row
, column
, &datum
);
1355 invalidate_cache(ctx
);
1359 pre_create(struct ctl_context
*ctx
)
1361 const char *id
= shash_find_data(&ctx
->options
, "--id");
1362 const char *table_name
= ctx
->argv
[1];
1363 const struct ctl_table_class
*table
;
1365 table
= get_table(table_name
);
1366 if (!id
&& !table
->class->is_root
) {
1367 VLOG_WARN("applying \"create\" command to table %s without --id "
1368 "option will have no effect", table
->class->name
);
1373 cmd_create(struct ctl_context
*ctx
)
1375 const char *id
= shash_find_data(&ctx
->options
, "--id");
1376 const char *table_name
= ctx
->argv
[1];
1377 const struct ctl_table_class
*table
= get_table(table_name
);
1378 const struct ovsdb_idl_row
*row
;
1379 const struct uuid
*uuid
;
1383 struct ovsdb_symbol
*symbol
= create_symbol(ctx
->symtab
, id
, NULL
);
1384 if (table
->class->is_root
) {
1385 /* This table is in the root set, meaning that rows created in it
1386 * won't disappear even if they are unreferenced, so disable
1387 * warnings about that by pretending that there is a reference. */
1388 symbol
->strong_ref
= true;
1390 uuid
= &symbol
->uuid
;
1395 row
= ovsdb_idl_txn_insert(ctx
->txn
, table
->class, uuid
);
1396 for (i
= 2; i
< ctx
->argc
; i
++) {
1397 set_column(table
, row
, ctx
->argv
[i
], ctx
->symtab
);
1399 ds_put_format(&ctx
->output
, UUID_FMT
, UUID_ARGS(&row
->uuid
));
1402 /* This function may be used as the 'postprocess' function for commands that
1403 * insert new rows into the database. It expects that the command's 'run'
1404 * function prints the UUID reported by ovsdb_idl_txn_insert() as the command's
1405 * sole output. It replaces that output by the row's permanent UUID assigned
1406 * by the database server and appends a new-line.
1408 * Currently we use this only for "create", because the higher-level commands
1409 * are supposed to be independent of the actual structure of the vswitch
1412 post_create(struct ctl_context
*ctx
)
1414 const struct uuid
*real
;
1417 if (!uuid_from_string(&dummy
, ds_cstr(&ctx
->output
))) {
1420 real
= ovsdb_idl_txn_get_insert_uuid(ctx
->txn
, &dummy
);
1422 ds_clear(&ctx
->output
);
1423 ds_put_format(&ctx
->output
, UUID_FMT
, UUID_ARGS(real
));
1425 ds_put_char(&ctx
->output
, '\n');
1429 pre_cmd_destroy(struct ctl_context
*ctx
)
1431 const char *table_name
= ctx
->argv
[1];
1433 pre_get_table(ctx
, table_name
);
1437 cmd_destroy(struct ctl_context
*ctx
)
1439 bool must_exist
= !shash_find(&ctx
->options
, "--if-exists");
1440 bool delete_all
= shash_find(&ctx
->options
, "--all");
1441 const char *table_name
= ctx
->argv
[1];
1442 const struct ctl_table_class
*table
;
1445 table
= get_table(table_name
);
1447 if (delete_all
&& ctx
->argc
> 2) {
1448 ctl_fatal("--all and records argument should not be specified together");
1451 if (delete_all
&& !must_exist
) {
1452 ctl_fatal("--all and --if-exists should not be specified together");
1456 const struct ovsdb_idl_row
*row
;
1457 const struct ovsdb_idl_row
*next_row
;
1459 for (row
= ovsdb_idl_first_row(ctx
->idl
, table
->class);
1461 next_row
= ovsdb_idl_next_row(row
);
1462 ovsdb_idl_txn_delete(row
);
1466 for (i
= 2; i
< ctx
->argc
; i
++) {
1467 const struct ovsdb_idl_row
*row
;
1469 row
= get_row(ctx
, table
, ctx
->argv
[i
], must_exist
);
1471 ovsdb_idl_txn_delete(row
);
1475 invalidate_cache(ctx
);
1479 pre_cmd_wait_until(struct ctl_context
*ctx
)
1481 const char *table_name
= ctx
->argv
[1];
1482 const struct ctl_table_class
*table
;
1485 table
= pre_get_table(ctx
, table_name
);
1487 for (i
= 3; i
< ctx
->argc
; i
++) {
1488 pre_parse_column_key_value(ctx
, ctx
->argv
[i
], table
);
1493 cmd_wait_until(struct ctl_context
*ctx
)
1495 const char *table_name
= ctx
->argv
[1];
1496 const char *record_id
= ctx
->argv
[2];
1497 const struct ctl_table_class
*table
;
1498 const struct ovsdb_idl_row
*row
;
1501 table
= get_table(table_name
);
1503 row
= get_row(ctx
, table
, record_id
, false);
1505 ctx
->try_again
= true;
1509 for (i
= 3; i
< ctx
->argc
; i
++) {
1510 if (!is_condition_satisfied(table
, row
, ctx
->argv
[i
], ctx
->symtab
)) {
1511 ctx
->try_again
= true;
1517 /* Parses one command. */
1519 parse_command(int argc
, char *argv
[], struct shash
*local_options
,
1520 struct ctl_command
*command
)
1522 const struct ctl_command_syntax
*p
;
1523 struct shash_node
*node
;
1527 shash_init(&command
->options
);
1528 shash_swap(local_options
, &command
->options
);
1529 for (i
= 0; i
< argc
; i
++) {
1530 const char *option
= argv
[i
];
1534 if (option
[0] != '-') {
1538 equals
= strchr(option
, '=');
1540 key
= xmemdup0(option
, equals
- option
);
1541 value
= xstrdup(equals
+ 1);
1543 key
= xstrdup(option
);
1547 if (shash_find(&command
->options
, key
)) {
1548 ctl_fatal("'%s' option specified multiple times", argv
[i
]);
1550 shash_add_nocopy(&command
->options
, key
, value
);
1553 ctl_fatal("missing command name (use --help for help)");
1556 p
= shash_find_data(&all_commands
, argv
[i
]);
1558 ctl_fatal("unknown command '%s'; use --help for help", argv
[i
]);
1561 SHASH_FOR_EACH (node
, &command
->options
) {
1562 const char *s
= strstr(p
->options
, node
->name
);
1563 int end
= s
? s
[strlen(node
->name
)] : EOF
;
1565 if (end
!= '=' && end
!= ',' && end
!= ' ' && end
!= '\0') {
1566 ctl_fatal("'%s' command has no '%s' option",
1567 argv
[i
], node
->name
);
1569 if ((end
== '=') != (node
->data
!= NULL
)) {
1571 ctl_fatal("missing argument to '%s' option on '%s' "
1572 "command", node
->name
, argv
[i
]);
1574 ctl_fatal("'%s' option on '%s' does not accept an "
1575 "argument", node
->name
, argv
[i
]);
1580 n_arg
= argc
- i
- 1;
1581 if (n_arg
< p
->min_args
) {
1582 ctl_fatal("'%s' command requires at least %d arguments",
1583 p
->name
, p
->min_args
);
1584 } else if (n_arg
> p
->max_args
) {
1587 for (j
= i
+ 1; j
< argc
; j
++) {
1588 if (argv
[j
][0] == '-') {
1589 ctl_fatal("'%s' command takes at most %d arguments "
1590 "(note that options must precede command "
1591 "names and follow a \"--\" argument)",
1592 p
->name
, p
->max_args
);
1596 ctl_fatal("'%s' command takes at most %d arguments",
1597 p
->name
, p
->max_args
);
1600 command
->syntax
= p
;
1601 command
->argc
= n_arg
+ 1;
1602 command
->argv
= &argv
[i
];
1606 pre_cmd_show(struct ctl_context
*ctx
)
1608 struct cmd_show_table
*show
;
1610 for (show
= cmd_show_tables
; show
->table
; show
++) {
1613 ovsdb_idl_add_table(ctx
->idl
, show
->table
);
1614 if (show
->name_column
) {
1615 ovsdb_idl_add_column(ctx
->idl
, show
->name_column
);
1617 for (i
= 0; i
< ARRAY_SIZE(show
->columns
); i
++) {
1618 const struct ovsdb_idl_column
*column
= show
->columns
[i
];
1620 ovsdb_idl_add_column(ctx
->idl
, column
);
1626 static struct cmd_show_table
*
1627 cmd_show_find_table_by_row(const struct ovsdb_idl_row
*row
)
1629 struct cmd_show_table
*show
;
1631 for (show
= cmd_show_tables
; show
->table
; show
++) {
1632 if (show
->table
== row
->table
->class) {
1639 static struct cmd_show_table
*
1640 cmd_show_find_table_by_name(const char *name
)
1642 struct cmd_show_table
*show
;
1644 for (show
= cmd_show_tables
; show
->table
; show
++) {
1645 if (!strcmp(show
->table
->name
, name
)) {
1652 /* 'shown' records the tables that has been displayed by the current
1653 * command to avoid duplicated prints.
1656 cmd_show_row(struct ctl_context
*ctx
, const struct ovsdb_idl_row
*row
,
1657 int level
, struct sset
*shown
)
1659 struct cmd_show_table
*show
= cmd_show_find_table_by_row(row
);
1662 ds_put_char_multiple(&ctx
->output
, ' ', level
* 4);
1663 if (show
&& show
->name_column
) {
1664 const struct ovsdb_datum
*datum
;
1666 ds_put_format(&ctx
->output
, "%s ", show
->table
->name
);
1667 datum
= ovsdb_idl_read(row
, show
->name_column
);
1668 ovsdb_datum_to_string(datum
, &show
->name_column
->type
, &ctx
->output
);
1670 ds_put_format(&ctx
->output
, UUID_FMT
, UUID_ARGS(&row
->uuid
));
1672 ds_put_char(&ctx
->output
, '\n');
1674 if (!show
|| sset_find(shown
, show
->table
->name
)) {
1678 sset_add(shown
, show
->table
->name
);
1679 for (i
= 0; i
< ARRAY_SIZE(show
->columns
); i
++) {
1680 const struct ovsdb_idl_column
*column
= show
->columns
[i
];
1681 const struct ovsdb_datum
*datum
;
1687 datum
= ovsdb_idl_read(row
, column
);
1688 if (column
->type
.key
.type
== OVSDB_TYPE_UUID
&&
1689 column
->type
.key
.u
.uuid
.refTableName
) {
1690 struct cmd_show_table
*ref_show
;
1693 ref_show
= cmd_show_find_table_by_name(
1694 column
->type
.key
.u
.uuid
.refTableName
);
1696 for (j
= 0; j
< datum
->n
; j
++) {
1697 const struct ovsdb_idl_row
*ref_row
;
1699 ref_row
= ovsdb_idl_get_row_for_uuid(ctx
->idl
,
1701 &datum
->keys
[j
].uuid
);
1703 cmd_show_row(ctx
, ref_row
, level
+ 1, shown
);
1708 } else if (ovsdb_type_is_map(&column
->type
) &&
1709 column
->type
.value
.type
== OVSDB_TYPE_UUID
&&
1710 column
->type
.value
.u
.uuid
.refTableName
) {
1711 struct cmd_show_table
*ref_show
;
1714 /* Prints the key to ref'ed table name map if the ref'ed table
1715 * is also defined in 'cmd_show_tables'. */
1716 ref_show
= cmd_show_find_table_by_name(
1717 column
->type
.value
.u
.uuid
.refTableName
);
1718 if (ref_show
&& ref_show
->name_column
) {
1719 ds_put_char_multiple(&ctx
->output
, ' ', (level
+ 1) * 4);
1720 ds_put_format(&ctx
->output
, "%s:\n", column
->name
);
1721 for (j
= 0; j
< datum
->n
; j
++) {
1722 const struct ovsdb_idl_row
*ref_row
;
1724 ref_row
= ovsdb_idl_get_row_for_uuid(ctx
->idl
,
1726 &datum
->values
[j
].uuid
);
1728 ds_put_char_multiple(&ctx
->output
, ' ', (level
+ 2) * 4);
1729 ovsdb_atom_to_string(&datum
->keys
[j
], column
->type
.key
.type
,
1731 ds_put_char(&ctx
->output
, '=');
1733 const struct ovsdb_datum
*ref_datum
;
1735 ref_datum
= ovsdb_idl_read(ref_row
,
1736 ref_show
->name_column
);
1737 ovsdb_datum_to_string(ref_datum
,
1738 &ref_show
->name_column
->type
,
1741 ds_put_cstr(&ctx
->output
, "\"<null>\"");
1743 ds_put_char(&ctx
->output
, '\n');
1749 if (!ovsdb_datum_is_default(datum
, &column
->type
)) {
1750 ds_put_char_multiple(&ctx
->output
, ' ', (level
+ 1) * 4);
1751 ds_put_format(&ctx
->output
, "%s: ", column
->name
);
1752 ovsdb_datum_to_string(datum
, &column
->type
, &ctx
->output
);
1753 ds_put_char(&ctx
->output
, '\n');
1756 sset_find_and_delete_assert(shown
, show
->table
->name
);
1760 cmd_show(struct ctl_context
*ctx
)
1762 const struct ovsdb_idl_row
*row
;
1763 struct sset shown
= SSET_INITIALIZER(&shown
);
1765 for (row
= ovsdb_idl_first_row(ctx
->idl
, cmd_show_tables
[0].table
);
1766 row
; row
= ovsdb_idl_next_row(row
)) {
1767 cmd_show_row(ctx
, row
, 0, &shown
);
1770 ovs_assert(sset_is_empty(&shown
));
1771 sset_destroy(&shown
);
1775 /* Given pointer to dynamic array 'options_p', array's current size
1776 * 'allocated_options_p' and number of added options 'n_options_p',
1777 * adds all command options to the array. Enlarges the array if
1780 ctl_add_cmd_options(struct option
**options_p
, size_t *n_options_p
,
1781 size_t *allocated_options_p
, int opt_val
)
1784 const struct shash_node
*node
;
1785 size_t n_existing_options
= *n_options_p
;
1787 SHASH_FOR_EACH (node
, &all_commands
) {
1788 const struct ctl_command_syntax
*p
= node
->data
;
1790 if (p
->options
[0]) {
1791 char *save_ptr
= NULL
;
1795 s
= xstrdup(p
->options
);
1796 for (name
= strtok_r(s
, ",", &save_ptr
); name
!= NULL
;
1797 name
= strtok_r(NULL
, ",", &save_ptr
)) {
1801 ovs_assert(name
[0] == '-' && name
[1] == '-' && name
[2]);
1804 equals
= strchr(name
, '=');
1806 has_arg
= required_argument
;
1809 has_arg
= no_argument
;
1812 o
= find_option(name
, *options_p
, *n_options_p
);
1814 ovs_assert(o
- *options_p
>= n_existing_options
);
1815 ovs_assert(o
->has_arg
== has_arg
);
1817 o
= add_option(options_p
, n_options_p
, allocated_options_p
);
1818 o
->name
= xstrdup(name
);
1819 o
->has_arg
= has_arg
;
1828 o
= add_option(options_p
, n_options_p
, allocated_options_p
);
1829 memset(o
, 0, sizeof *o
);
1832 /* Parses command-line input for commands. */
1833 struct ctl_command
*
1834 ctl_parse_commands(int argc
, char *argv
[], struct shash
*local_options
,
1835 size_t *n_commandsp
)
1837 struct ctl_command
*commands
;
1838 size_t n_commands
, allocated_commands
;
1842 n_commands
= allocated_commands
= 0;
1844 for (start
= i
= 0; i
<= argc
; i
++) {
1845 if (i
== argc
|| !strcmp(argv
[i
], "--")) {
1847 if (n_commands
>= allocated_commands
) {
1848 struct ctl_command
*c
;
1850 commands
= x2nrealloc(commands
, &allocated_commands
,
1852 for (c
= commands
; c
< &commands
[n_commands
]; c
++) {
1853 shash_moved(&c
->options
);
1856 parse_command(i
- start
, &argv
[start
], local_options
,
1857 &commands
[n_commands
++]);
1858 } else if (!shash_is_empty(local_options
)) {
1859 ctl_fatal("missing command name (use --help for help)");
1865 ctl_fatal("missing command name (use --help for help)");
1867 *n_commandsp
= n_commands
;
1871 /* Prints all registered commands. */
1873 ctl_print_commands(void)
1875 const struct shash_node
*node
;
1877 SHASH_FOR_EACH (node
, &all_commands
) {
1878 const struct ctl_command_syntax
*p
= node
->data
;
1879 char *options
= xstrdup(p
->options
);
1880 char *options_begin
= options
;
1883 for (item
= strsep(&options
, ","); item
!= NULL
;
1884 item
= strsep(&options
, ",")) {
1885 if (item
[0] != '\0') {
1886 printf("[%s] ", item
);
1889 printf(",%s,", p
->name
);
1890 print_command_arguments(p
);
1893 free(options_begin
);
1899 /* Given array of options 'options', prints them. */
1901 ctl_print_options(const struct option
*options
)
1903 for (; options
->name
; options
++) {
1904 const struct option
*o
= options
;
1906 printf("--%s%s\n", o
->name
, o
->has_arg
? "=ARG" : "");
1907 if (o
->flag
== NULL
&& o
->val
> 0 && o
->val
<= UCHAR_MAX
) {
1908 printf("-%c%s\n", o
->val
, o
->has_arg
? " ARG" : "");
1915 /* Returns the default local database path. */
1917 ctl_default_db(void)
1921 def
= xasprintf("unix:%s/db.sock", ovs_rundir());
1926 /* Returns true if it looks like this set of arguments might modify the
1927 * database, otherwise false. (Not very smart, so it's prone to false
1930 ctl_might_write_to_db(char **argv
)
1932 for (; *argv
; argv
++) {
1933 const struct ctl_command_syntax
*p
= shash_find_data(&all_commands
,
1935 if (p
&& p
->mode
== RW
) {
1943 ctl_fatal(const char *format
, ...)
1948 va_start(args
, format
);
1949 message
= xvasprintf(format
, args
);
1952 vlog_set_levels(&VLM_db_ctl_base
, VLF_CONSOLE
, VLL_OFF
);
1953 VLOG_ERR("%s", message
);
1954 ovs_error(0, "%s", message
);
1955 ctl_exit(EXIT_FAILURE
);
1958 /* Frees the current transaction and the underlying IDL and then calls
1961 * Freeing the transaction and the IDL is not strictly necessary, but it makes
1962 * for a clean memory leak report from valgrind in the normal case. That makes
1963 * it easier to notice real memory leaks. */
1965 ctl_exit(int status
)
1967 if (ctl_exit_func
) {
1968 ctl_exit_func(status
);
1973 /* Comman database commands to be registered. */
1974 static const struct ctl_command_syntax db_ctl_commands
[] = {
1975 {"comment", 0, INT_MAX
, "[ARG]...", NULL
, NULL
, NULL
, "", RO
},
1976 {"get", 2, INT_MAX
, "TABLE RECORD [COLUMN[:KEY]]...",pre_cmd_get
, cmd_get
,
1977 NULL
, "--if-exists,--id=", RO
},
1978 {"list", 1, INT_MAX
, "TABLE [RECORD]...", pre_cmd_list
, cmd_list
, NULL
,
1979 "--if-exists,--columns=", RO
},
1980 {"find", 1, INT_MAX
, "TABLE [COLUMN[:KEY]=VALUE]...", pre_cmd_find
,
1981 cmd_find
, NULL
, "--columns=", RO
},
1982 {"set", 3, INT_MAX
, "TABLE RECORD COLUMN[:KEY]=VALUE...", pre_cmd_set
,
1983 cmd_set
, NULL
, "--if-exists", RW
},
1984 {"add", 4, INT_MAX
, "TABLE RECORD COLUMN [KEY=]VALUE...", pre_cmd_add
,
1985 cmd_add
, NULL
, "--if-exists", RW
},
1986 {"remove", 4, INT_MAX
, "TABLE RECORD COLUMN KEY|VALUE|KEY=VALUE...",
1987 pre_cmd_remove
, cmd_remove
, NULL
, "--if-exists", RW
},
1988 {"clear", 3, INT_MAX
, "TABLE RECORD COLUMN...", pre_cmd_clear
, cmd_clear
,
1989 NULL
, "--if-exists", RW
},
1990 {"create", 2, INT_MAX
, "TABLE COLUMN[:KEY]=VALUE...", pre_create
,
1991 cmd_create
, post_create
, "--id=", RW
},
1992 {"destroy", 1, INT_MAX
, "TABLE [RECORD]...", pre_cmd_destroy
, cmd_destroy
,
1993 NULL
, "--if-exists,--all", RW
},
1994 {"wait-until", 2, INT_MAX
, "TABLE RECORD [COLUMN[:KEY]=VALUE]...",
1995 pre_cmd_wait_until
, cmd_wait_until
, NULL
, "", RO
},
1996 {"show", 0, 0, "", pre_cmd_show
, cmd_show
, NULL
, "", RO
},
1997 {NULL
, 0, 0, NULL
, NULL
, NULL
, NULL
, NULL
, RO
},
2000 /* Registers commands represented by 'struct ctl_command_syntax's to
2001 * 'all_commands'. The last element of 'commands' must be an all-NULL
2004 ctl_register_commands(const struct ctl_command_syntax
*commands
)
2006 const struct ctl_command_syntax
*p
;
2008 for (p
= commands
; p
->name
; p
++) {
2009 shash_add_assert(&all_commands
, p
->name
, p
);
2013 /* Registers the 'db_ctl_commands' to 'all_commands'. */
2015 ctl_init(const struct ctl_table_class tables_
[],
2016 void (*ctl_exit_func_
)(int status
))
2019 ctl_exit_func
= ctl_exit_func_
;
2020 ctl_register_commands(db_ctl_commands
);
2023 /* Returns the text for the database commands usage. */
2025 ctl_get_db_cmd_usage(void)
2027 return "Database commands:\n\
2028 list TBL [REC] list RECord (or all records) in TBL\n\
2029 find TBL CONDITION... list records satisfying CONDITION in TBL\n\
2030 get TBL REC COL[:KEY] print values of COLumns in RECord in TBL\n\
2031 set TBL REC COL[:KEY]=VALUE set COLumn values in RECord in TBL\n\
2032 add TBL REC COL [KEY=]VALUE add (KEY=)VALUE to COLumn in RECord in TBL\n\
2033 remove TBL REC COL [KEY=]VALUE remove (KEY=)VALUE from COLumn\n\
2034 clear TBL REC COL clear values from COLumn in RECord in TBL\n\
2035 create TBL COL[:KEY]=VALUE create and initialize new record\n\
2036 destroy TBL REC delete RECord from TBL\n\
2037 wait-until TBL REC [COL[:KEY]=VALUE] wait until condition is true\n\
2038 Potentially unsafe database commands require --force option.\n";
2041 /* Initializes 'ctx' from 'command'. */
2043 ctl_context_init_command(struct ctl_context
*ctx
,
2044 struct ctl_command
*command
)
2046 ctx
->argc
= command
->argc
;
2047 ctx
->argv
= command
->argv
;
2048 ctx
->options
= command
->options
;
2050 ds_swap(&ctx
->output
, &command
->output
);
2051 ctx
->table
= command
->table
;
2052 ctx
->try_again
= false;
2055 /* Initializes the entire 'ctx'. */
2057 ctl_context_init(struct ctl_context
*ctx
, struct ctl_command
*command
,
2058 struct ovsdb_idl
*idl
, struct ovsdb_idl_txn
*txn
,
2059 struct ovsdb_symbol_table
*symtab
,
2060 void (*invalidate_cache
)(struct ctl_context
*))
2063 ctl_context_init_command(ctx
, command
);
2067 ctx
->symtab
= symtab
;
2068 ctx
->invalidate_cache
= invalidate_cache
;
2071 /* Completes processing of 'command' within 'ctx'. */
2073 ctl_context_done_command(struct ctl_context
*ctx
,
2074 struct ctl_command
*command
)
2076 ds_swap(&ctx
->output
, &command
->output
);
2077 command
->table
= ctx
->table
;
2080 /* Finishes up with 'ctx'.
2082 * If command is nonnull, first calls ctl_context_done_command() to complete
2083 * processing that command within 'ctx'. */
2085 ctl_context_done(struct ctl_context
*ctx
,
2086 struct ctl_command
*command
)
2089 ctl_context_done_command(ctx
, command
);
2091 invalidate_cache(ctx
);
2094 void ctl_set_column(const char *table_name
,
2095 const struct ovsdb_idl_row
*row
, const char *arg
,
2096 struct ovsdb_symbol_table
*symtab
)
2098 set_column(get_table(table_name
), row
, arg
, symtab
);