db-ctl-base: do not expose get_table() API
[cascardo/ovs.git] / lib / db-ctl-base.c
1 /*
2  * Copyright (c) 2015 Nicira, Inc.
3  *
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:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #include <config.h>
18
19 #include <ctype.h>
20 #include <getopt.h>
21 #include <unistd.h>
22
23 #include "db-ctl-base.h"
24
25 #include "command-line.h"
26 #include "compiler.h"
27 #include "dirs.h"
28 #include "dynamic-string.h"
29 #include "fatal-signal.h"
30 #include "hash.h"
31 #include "json.h"
32 #include "openvswitch/vlog.h"
33 #include "ovsdb-data.h"
34 #include "ovsdb-idl.h"
35 #include "ovsdb-idl-provider.h"
36 #include "shash.h"
37 #include "string.h"
38 #include "table.h"
39 #include "util.h"
40
41 VLOG_DEFINE_THIS_MODULE(db_ctl_base);
42
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;
48
49 static struct shash all_commands = SHASH_INITIALIZER(&all_commands);
50 static const struct ctl_table_class *get_table(const char *table_name);
51 static void set_column(const struct ctl_table_class *,
52                        const struct ovsdb_idl_row *, const char *,
53                        struct ovsdb_symbol_table *);
54
55 \f
56 static struct option *
57 find_option(const char *name, struct option *options, size_t n_options)
58 {
59     size_t i;
60
61     for (i = 0; i < n_options; i++) {
62         if (!strcmp(options[i].name, name)) {
63             return &options[i];
64         }
65     }
66     return NULL;
67 }
68
69 static struct option *
70 add_option(struct option **optionsp, size_t *n_optionsp,
71            size_t *allocated_optionsp)
72 {
73     if (*n_optionsp >= *allocated_optionsp) {
74         *optionsp = x2nrealloc(*optionsp, allocated_optionsp,
75                                sizeof **optionsp);
76     }
77     return &(*optionsp)[(*n_optionsp)++];
78 }
79
80 /* Converts the command arguments into format that can be parsed by
81  * bash completion script.
82  *
83  * Therein, arguments will be attached with following prefixes:
84  *
85  *    !argument :: The argument is required
86  *    ?argument :: The argument is optional
87  *    *argument :: The argument may appear any number (0 or more) times
88  *    +argument :: The argument may appear one or more times
89  *
90  */
91 static void
92 print_command_arguments(const struct ctl_command_syntax *command)
93 {
94     /*
95      * The argument string is parsed in reverse.  We use a stack 'oew_stack' to
96      * keep track of nested optionals.  Whenever a ']' is encountered, we push
97      * a bit to 'oew_stack'.  The bit is set to 1 if the ']' is not nested.
98      * Subsequently, we pop an entry everytime '[' is met.
99      *
100      * We use 'whole_word_is_optional' value to decide whether or not a ! or +
101      * should be added on encountering a space: if the optional surrounds the
102      * whole word then it shouldn't be, but if it is only a part of the word
103      * (i.e. [key=]value), it should be.
104      */
105     uint32_t oew_stack = 0;
106
107     const char *arguments = command->arguments;
108     int length = strlen(arguments);
109     if (!length) {
110         return;
111     }
112
113     /* Output buffer, written backward from end. */
114     char *output = xmalloc(2 * length);
115     char *outp = output + 2 * length;
116     *--outp = '\0';
117
118     bool in_repeated = false;
119     bool whole_word_is_optional = false;
120
121     for (const char *inp = arguments + length; inp > arguments; ) {
122         switch (*--inp) {
123         case ']':
124             oew_stack <<= 1;
125             if (inp[1] == '\0' || inp[1] == ' ' || inp[1] == '.') {
126                 oew_stack |= 1;
127             }
128             break;
129         case '[':
130             /* Checks if the whole word is optional, and sets the
131              * 'whole_word_is_optional' accordingly. */
132             if ((inp == arguments || inp[-1] == ' ') && oew_stack & 1) {
133                 *--outp = in_repeated ? '*' : '?';
134                 whole_word_is_optional = true;
135             } else {
136                 *--outp = '?';
137                 whole_word_is_optional = false;
138             }
139             oew_stack >>= 1;
140             break;
141         case ' ':
142             if (!whole_word_is_optional) {
143                 *--outp = in_repeated ? '+' : '!';
144             }
145             *--outp = ' ';
146             in_repeated = false;
147             whole_word_is_optional = false;
148             break;
149         case '.':
150             in_repeated = true;
151             break;
152         default:
153             *--outp = *inp;
154             break;
155         }
156     }
157     if (arguments[0] != '[' && outp != output + 2 * length - 1) {
158         *--outp = in_repeated ? '+' : '!';
159     }
160     printf("%s", outp);
161     free(output);
162 }
163
164 static void
165 die_if_error(char *error)
166 {
167     if (error) {
168         ctl_fatal("%s", error);
169     }
170 }
171
172 static int
173 to_lower_and_underscores(unsigned c)
174 {
175     return c == '-' ? '_' : tolower(c);
176 }
177
178 static unsigned int
179 score_partial_match(const char *name, const char *s)
180 {
181     int score;
182
183     if (!strcmp(name, s)) {
184         return UINT_MAX;
185     }
186     for (score = 0; ; score++, name++, s++) {
187         if (to_lower_and_underscores(*name) != to_lower_and_underscores(*s)) {
188             break;
189         } else if (*name == '\0') {
190             return UINT_MAX - 1;
191         }
192     }
193     return *s == '\0' ? score : 0;
194 }
195
196 static struct ovsdb_symbol *
197 create_symbol(struct ovsdb_symbol_table *symtab, const char *id, bool *newp)
198 {
199     struct ovsdb_symbol *symbol;
200
201     if (id[0] != '@') {
202         ctl_fatal("row id \"%s\" does not begin with \"@\"", id);
203     }
204
205     if (newp) {
206         *newp = ovsdb_symbol_table_get(symtab, id) == NULL;
207     }
208
209     symbol = ovsdb_symbol_table_insert(symtab, id);
210     if (symbol->created) {
211         ctl_fatal("row id \"%s\" may only be specified on one --id option",
212                   id);
213     }
214     symbol->created = true;
215     return symbol;
216 }
217
218 static const struct ovsdb_idl_row *
219 get_row_by_id(struct ctl_context *ctx, const struct ctl_table_class *table,
220               const struct ctl_row_id *id, const char *record_id)
221 {
222     const struct ovsdb_idl_row *referrer, *final;
223
224     if (!id->table) {
225         return NULL;
226     }
227
228     if (!id->name_column) {
229         if (strcmp(record_id, ".")) {
230             return NULL;
231         }
232         referrer = ovsdb_idl_first_row(ctx->idl, id->table);
233         if (!referrer || ovsdb_idl_next_row(referrer)) {
234             return NULL;
235         }
236     } else {
237         const struct ovsdb_idl_row *row;
238
239         referrer = NULL;
240         for (row = ovsdb_idl_first_row(ctx->idl, id->table);
241              row != NULL;
242              row = ovsdb_idl_next_row(row))
243             {
244                 const struct ovsdb_datum *name;
245
246                 name = ovsdb_idl_get(row, id->name_column,
247                                      OVSDB_TYPE_STRING, OVSDB_TYPE_VOID);
248                 if (name->n == 1 && !strcmp(name->keys[0].string, record_id)) {
249                     if (referrer) {
250                         ctl_fatal("multiple rows in %s match \"%s\"",
251                                   table->class->name, record_id);
252                     }
253                     referrer = row;
254                 }
255             }
256     }
257     if (!referrer) {
258         return NULL;
259     }
260
261     final = NULL;
262     if (id->uuid_column) {
263         const struct ovsdb_datum *uuid;
264
265         ovsdb_idl_txn_verify(referrer, id->uuid_column);
266         uuid = ovsdb_idl_get(referrer, id->uuid_column,
267                              OVSDB_TYPE_UUID, OVSDB_TYPE_VOID);
268         if (uuid->n == 1) {
269             final = ovsdb_idl_get_row_for_uuid(ctx->idl, table->class,
270                                                &uuid->keys[0].uuid);
271         }
272     } else {
273         final = referrer;
274     }
275
276     return final;
277 }
278
279 static const struct ovsdb_idl_row *
280 get_row(struct ctl_context *ctx,
281         const struct ctl_table_class *table, const char *record_id,
282         bool must_exist)
283 {
284     const struct ovsdb_idl_row *row;
285     struct uuid uuid;
286
287     row = NULL;
288     if (uuid_from_string(&uuid, record_id)) {
289         row = ovsdb_idl_get_row_for_uuid(ctx->idl, table->class, &uuid);
290     }
291     if (!row) {
292         int i;
293
294         for (i = 0; i < ARRAY_SIZE(table->row_ids); i++) {
295             row = get_row_by_id(ctx, table, &table->row_ids[i], record_id);
296             if (row) {
297                 break;
298             }
299         }
300     }
301     if (must_exist && !row) {
302         ctl_fatal("no row \"%s\" in table %s",
303                   record_id, table->class->name);
304     }
305     return row;
306 }
307
308 static char *
309 get_column(const struct ctl_table_class *table, const char *column_name,
310            const struct ovsdb_idl_column **columnp)
311 {
312     const struct ovsdb_idl_column *best_match = NULL;
313     unsigned int best_score = 0;
314     size_t i;
315
316     for (i = 0; i < table->class->n_columns; i++) {
317         const struct ovsdb_idl_column *column = &table->class->columns[i];
318         unsigned int score = score_partial_match(column->name, column_name);
319         if (score > best_score) {
320             best_match = column;
321             best_score = score;
322         } else if (score == best_score) {
323             best_match = NULL;
324         }
325     }
326
327     *columnp = best_match;
328     if (best_match) {
329         return NULL;
330     } else if (best_score) {
331         return xasprintf("%s contains more than one column whose name "
332                          "matches \"%s\"", table->class->name, column_name);
333     } else {
334         return xasprintf("%s does not contain a column whose name matches "
335                          "\"%s\"", table->class->name, column_name);
336     }
337 }
338
339 static void
340 pre_get_column(struct ctl_context *ctx,
341                const struct ctl_table_class *table, const char *column_name,
342                const struct ovsdb_idl_column **columnp)
343 {
344     die_if_error(get_column(table, column_name, columnp));
345     ovsdb_idl_add_column(ctx->idl, *columnp);
346 }
347
348 static const struct ctl_table_class *
349 pre_get_table(struct ctl_context *ctx, const char *table_name)
350 {
351     const struct ctl_table_class *table_class;
352     int i;
353
354     table_class = get_table(table_name);
355     ovsdb_idl_add_table(ctx->idl, table_class->class);
356
357     for (i = 0; i < ARRAY_SIZE(table_class->row_ids); i++) {
358         const struct ctl_row_id *id = &table_class->row_ids[i];
359         if (id->table) {
360             ovsdb_idl_add_table(ctx->idl, id->table);
361         }
362         if (id->name_column) {
363             ovsdb_idl_add_column(ctx->idl, id->name_column);
364         }
365         if (id->uuid_column) {
366             ovsdb_idl_add_column(ctx->idl, id->uuid_column);
367         }
368     }
369
370     return table_class;
371 }
372
373 static char *
374 missing_operator_error(const char *arg, const char **allowed_operators,
375                        size_t n_allowed)
376 {
377     struct ds s;
378
379     ds_init(&s);
380     ds_put_format(&s, "%s: argument does not end in ", arg);
381     ds_put_format(&s, "\"%s\"", allowed_operators[0]);
382     if (n_allowed == 2) {
383         ds_put_format(&s, " or \"%s\"", allowed_operators[1]);
384     } else if (n_allowed > 2) {
385         size_t i;
386
387         for (i = 1; i < n_allowed - 1; i++) {
388             ds_put_format(&s, ", \"%s\"", allowed_operators[i]);
389         }
390         ds_put_format(&s, ", or \"%s\"", allowed_operators[i]);
391     }
392     ds_put_format(&s, " followed by a value.");
393
394     return ds_steal_cstr(&s);
395 }
396
397 /* Breaks 'arg' apart into a number of fields in the following order:
398  *
399  *      - The name of a column in 'table', stored into '*columnp'.  The column
400  *        name may be abbreviated.
401  *
402  *      - Optionally ':' followed by a key string.  The key is stored as a
403  *        malloc()'d string into '*keyp', or NULL if no key is present in
404  *        'arg'.
405  *
406  *      - If 'valuep' is nonnull, an operator followed by a value string.  The
407  *        allowed operators are the 'n_allowed' string in 'allowed_operators',
408  *        or just "=" if 'n_allowed' is 0.  If 'operatorp' is nonnull, then the
409  *        index of the operator within 'allowed_operators' is stored into
410  *        '*operatorp'.  The value is stored as a malloc()'d string into
411  *        '*valuep', or NULL if no value is present in 'arg'.
412  *
413  * On success, returns NULL.  On failure, returned a malloc()'d string error
414  * message and stores NULL into all of the nonnull output arguments. */
415 static char * OVS_WARN_UNUSED_RESULT
416 parse_column_key_value(const char *arg,
417                        const struct ctl_table_class *table,
418                        const struct ovsdb_idl_column **columnp, char **keyp,
419                        int *operatorp,
420                        const char **allowed_operators, size_t n_allowed,
421                        char **valuep)
422 {
423     const char *p = arg;
424     char *column_name;
425     char *error;
426
427     ovs_assert(!(operatorp && !valuep));
428     *keyp = NULL;
429     if (valuep) {
430         *valuep = NULL;
431     }
432
433     /* Parse column name. */
434     error = ovsdb_token_parse(&p, &column_name);
435     if (error) {
436         goto error;
437     }
438     if (column_name[0] == '\0') {
439         free(column_name);
440         error = xasprintf("%s: missing column name", arg);
441         goto error;
442     }
443     error = get_column(table, column_name, columnp);
444     free(column_name);
445     if (error) {
446         goto error;
447     }
448
449     /* Parse key string. */
450     if (*p == ':') {
451         p++;
452         error = ovsdb_token_parse(&p, keyp);
453         if (error) {
454             goto error;
455         }
456     }
457
458     /* Parse value string. */
459     if (valuep) {
460         size_t best_len;
461         size_t i;
462         int best;
463
464         if (!allowed_operators) {
465             static const char *equals = "=";
466             allowed_operators = &equals;
467             n_allowed = 1;
468         }
469
470         best = -1;
471         best_len = 0;
472         for (i = 0; i < n_allowed; i++) {
473             const char *op = allowed_operators[i];
474             size_t op_len = strlen(op);
475
476             if (op_len > best_len && !strncmp(op, p, op_len) && p[op_len]) {
477                 best_len = op_len;
478                 best = i;
479             }
480         }
481         if (best < 0) {
482             error = missing_operator_error(arg, allowed_operators, n_allowed);
483             goto error;
484         }
485
486         if (operatorp) {
487             *operatorp = best;
488         }
489         *valuep = xstrdup(p + best_len);
490     } else {
491         if (*p != '\0') {
492             error = xasprintf("%s: trailing garbage \"%s\" in argument",
493                               arg, p);
494             goto error;
495         }
496     }
497     return NULL;
498
499  error:
500     *columnp = NULL;
501     free(*keyp);
502     *keyp = NULL;
503     if (valuep) {
504         free(*valuep);
505         *valuep = NULL;
506         if (operatorp) {
507             *operatorp = -1;
508         }
509     }
510     return error;
511 }
512
513 static const struct ovsdb_idl_column *
514 pre_parse_column_key_value(struct ctl_context *ctx,
515                            const char *arg,
516                            const struct ctl_table_class *table)
517 {
518     const struct ovsdb_idl_column *column;
519     const char *p;
520     char *column_name;
521
522     p = arg;
523     die_if_error(ovsdb_token_parse(&p, &column_name));
524     if (column_name[0] == '\0') {
525         ctl_fatal("%s: missing column name", arg);
526     }
527
528     pre_get_column(ctx, table, column_name, &column);
529     free(column_name);
530
531     return column;
532 }
533
534 static void
535 check_mutable(const struct ovsdb_idl_row *row,
536               const struct ovsdb_idl_column *column)
537 {
538     if (!ovsdb_idl_is_mutable(row, column)) {
539         ctl_fatal("cannot modify read-only column %s in table %s",
540                   column->name, row->table->class->name);
541     }
542 }
543
544 #define RELOPS                                  \
545     RELOP(RELOP_EQ,     "=")                    \
546     RELOP(RELOP_NE,     "!=")                   \
547     RELOP(RELOP_LT,     "<")                    \
548     RELOP(RELOP_GT,     ">")                    \
549     RELOP(RELOP_LE,     "<=")                   \
550     RELOP(RELOP_GE,     ">=")                   \
551     RELOP(RELOP_SET_EQ, "{=}")                  \
552     RELOP(RELOP_SET_NE, "{!=}")                 \
553     RELOP(RELOP_SET_LT, "{<}")                  \
554     RELOP(RELOP_SET_GT, "{>}")                  \
555     RELOP(RELOP_SET_LE, "{<=}")                 \
556     RELOP(RELOP_SET_GE, "{>=}")
557
558 enum relop {
559 #define RELOP(ENUM, STRING) ENUM,
560     RELOPS
561 #undef RELOP
562 };
563
564 static bool
565 is_set_operator(enum relop op)
566 {
567     return (op == RELOP_SET_EQ || op == RELOP_SET_NE ||
568             op == RELOP_SET_LT || op == RELOP_SET_GT ||
569             op == RELOP_SET_LE || op == RELOP_SET_GE);
570 }
571
572 static bool
573 evaluate_relop(const struct ovsdb_datum *a, const struct ovsdb_datum *b,
574                const struct ovsdb_type *type, enum relop op)
575 {
576     switch (op) {
577     case RELOP_EQ:
578     case RELOP_SET_EQ:
579         return ovsdb_datum_compare_3way(a, b, type) == 0;
580     case RELOP_NE:
581     case RELOP_SET_NE:
582         return ovsdb_datum_compare_3way(a, b, type) != 0;
583     case RELOP_LT:
584         return ovsdb_datum_compare_3way(a, b, type) < 0;
585     case RELOP_GT:
586         return ovsdb_datum_compare_3way(a, b, type) > 0;
587     case RELOP_LE:
588         return ovsdb_datum_compare_3way(a, b, type) <= 0;
589     case RELOP_GE:
590         return ovsdb_datum_compare_3way(a, b, type) >= 0;
591
592     case RELOP_SET_LT:
593         return b->n > a->n && ovsdb_datum_includes_all(a, b, type);
594     case RELOP_SET_GT:
595         return a->n > b->n && ovsdb_datum_includes_all(b, a, type);
596     case RELOP_SET_LE:
597         return ovsdb_datum_includes_all(a, b, type);
598     case RELOP_SET_GE:
599         return ovsdb_datum_includes_all(b, a, type);
600
601     default:
602         OVS_NOT_REACHED();
603     }
604 }
605
606 static bool
607 is_condition_satisfied(const struct ctl_table_class *table,
608                        const struct ovsdb_idl_row *row, const char *arg,
609                        struct ovsdb_symbol_table *symtab)
610 {
611     static const char *operators[] = {
612 #define RELOP(ENUM, STRING) STRING,
613         RELOPS
614 #undef RELOP
615     };
616
617     const struct ovsdb_idl_column *column;
618     const struct ovsdb_datum *have_datum;
619     char *key_string, *value_string;
620     struct ovsdb_type type;
621     int operator;
622     bool retval;
623     char *error;
624
625     error = parse_column_key_value(arg, table, &column, &key_string,
626                                    &operator, operators, ARRAY_SIZE(operators),
627                                    &value_string);
628     die_if_error(error);
629     if (!value_string) {
630         ctl_fatal("%s: missing value", arg);
631     }
632
633     type = column->type;
634     type.n_max = UINT_MAX;
635
636     have_datum = ovsdb_idl_read(row, column);
637     if (key_string) {
638         union ovsdb_atom want_key;
639         struct ovsdb_datum b;
640         unsigned int idx;
641
642         if (column->type.value.type == OVSDB_TYPE_VOID) {
643             ctl_fatal("cannot specify key to check for non-map column %s",
644                       column->name);
645         }
646
647         die_if_error(ovsdb_atom_from_string(&want_key, &column->type.key,
648                                             key_string, symtab));
649
650         type.key = type.value;
651         type.value.type = OVSDB_TYPE_VOID;
652         die_if_error(ovsdb_datum_from_string(&b, &type, value_string, symtab));
653
654         idx = ovsdb_datum_find_key(have_datum,
655                                    &want_key, column->type.key.type);
656         if (idx == UINT_MAX && !is_set_operator(operator)) {
657             retval = false;
658         } else {
659             struct ovsdb_datum a;
660
661             if (idx != UINT_MAX) {
662                 a.n = 1;
663                 a.keys = &have_datum->values[idx];
664                 a.values = NULL;
665             } else {
666                 a.n = 0;
667                 a.keys = NULL;
668                 a.values = NULL;
669             }
670
671             retval = evaluate_relop(&a, &b, &type, operator);
672         }
673
674         ovsdb_atom_destroy(&want_key, column->type.key.type);
675         ovsdb_datum_destroy(&b, &type);
676     } else {
677         struct ovsdb_datum want_datum;
678
679         die_if_error(ovsdb_datum_from_string(&want_datum, &column->type,
680                                              value_string, symtab));
681         retval = evaluate_relop(have_datum, &want_datum, &type, operator);
682         ovsdb_datum_destroy(&want_datum, &column->type);
683     }
684
685     free(key_string);
686     free(value_string);
687
688     return retval;
689 }
690
691 static void
692 invalidate_cache(struct ctl_context *ctx)
693 {
694     if (ctx->invalidate_cache) {
695         (ctx->invalidate_cache)(ctx);
696     }
697 }
698 \f
699 static void
700 pre_cmd_get(struct ctl_context *ctx)
701 {
702     const char *id = shash_find_data(&ctx->options, "--id");
703     const char *table_name = ctx->argv[1];
704     const struct ctl_table_class *table;
705     int i;
706
707     /* Using "get" without --id or a column name could possibly make sense.
708      * Maybe, for example, a *ctl command run wants to assert that a row
709      * exists.  But it is unlikely that an interactive user would want to do
710      * that, so issue a warning if we're running on a terminal. */
711     if (!id && ctx->argc <= 3 && isatty(STDOUT_FILENO)) {
712         VLOG_WARN("\"get\" command without row arguments or \"--id\" is "
713                   "possibly erroneous");
714     }
715
716     table = pre_get_table(ctx, table_name);
717     for (i = 3; i < ctx->argc; i++) {
718         if (!strcasecmp(ctx->argv[i], "_uuid")
719             || !strcasecmp(ctx->argv[i], "-uuid")) {
720             continue;
721         }
722
723         pre_parse_column_key_value(ctx, ctx->argv[i], table);
724     }
725 }
726
727 static void
728 cmd_get(struct ctl_context *ctx)
729 {
730     const char *id = shash_find_data(&ctx->options, "--id");
731     bool must_exist = !shash_find(&ctx->options, "--if-exists");
732     const char *table_name = ctx->argv[1];
733     const char *record_id = ctx->argv[2];
734     const struct ctl_table_class *table;
735     const struct ovsdb_idl_row *row;
736     struct ds *out = &ctx->output;
737     int i;
738
739     if (id && !must_exist) {
740         ctl_fatal("--if-exists and --id may not be specified together");
741     }
742
743     table = get_table(table_name);
744     row = get_row(ctx, table, record_id, must_exist);
745     if (!row) {
746         return;
747     }
748
749     if (id) {
750         struct ovsdb_symbol *symbol;
751         bool new;
752
753         symbol = create_symbol(ctx->symtab, id, &new);
754         if (!new) {
755             ctl_fatal("row id \"%s\" specified on \"get\" command was used "
756                       "before it was defined", id);
757         }
758         symbol->uuid = row->uuid;
759
760         /* This symbol refers to a row that already exists, so disable warnings
761          * about it being unreferenced. */
762         symbol->strong_ref = true;
763     }
764     for (i = 3; i < ctx->argc; i++) {
765         const struct ovsdb_idl_column *column;
766         const struct ovsdb_datum *datum;
767         char *key_string;
768
769         /* Special case for obtaining the UUID of a row.  We can't just do this
770          * through parse_column_key_value() below since it returns a "struct
771          * ovsdb_idl_column" and the UUID column doesn't have one. */
772         if (!strcasecmp(ctx->argv[i], "_uuid")
773             || !strcasecmp(ctx->argv[i], "-uuid")) {
774             ds_put_format(out, UUID_FMT"\n", UUID_ARGS(&row->uuid));
775             continue;
776         }
777
778         die_if_error(parse_column_key_value(ctx->argv[i], table,
779                                             &column, &key_string,
780                                             NULL, NULL, 0, NULL));
781
782         ovsdb_idl_txn_verify(row, column);
783         datum = ovsdb_idl_read(row, column);
784         if (key_string) {
785             union ovsdb_atom key;
786             unsigned int idx;
787
788             if (column->type.value.type == OVSDB_TYPE_VOID) {
789                 ctl_fatal("cannot specify key to get for non-map column %s",
790                           column->name);
791             }
792
793             die_if_error(ovsdb_atom_from_string(&key,
794                                                 &column->type.key,
795                                                 key_string, ctx->symtab));
796
797             idx = ovsdb_datum_find_key(datum, &key,
798                                        column->type.key.type);
799             if (idx == UINT_MAX) {
800                 if (must_exist) {
801                     ctl_fatal("no key \"%s\" in %s record \"%s\" column %s",
802                               key_string, table->class->name, record_id,
803                               column->name);
804                 }
805             } else {
806                 ovsdb_atom_to_string(&datum->values[idx],
807                                      column->type.value.type, out);
808             }
809             ovsdb_atom_destroy(&key, column->type.key.type);
810         } else {
811             ovsdb_datum_to_string(datum, &column->type, out);
812         }
813         ds_put_char(out, '\n');
814
815         free(key_string);
816     }
817 }
818
819 static void
820 parse_column_names(const char *column_names,
821                    const struct ctl_table_class *table,
822                    const struct ovsdb_idl_column ***columnsp,
823                    size_t *n_columnsp)
824 {
825     const struct ovsdb_idl_column **columns;
826     size_t n_columns;
827
828     if (!column_names) {
829         size_t i;
830
831         n_columns = table->class->n_columns + 1;
832         columns = xmalloc(n_columns * sizeof *columns);
833         columns[0] = NULL;
834         for (i = 0; i < table->class->n_columns; i++) {
835             columns[i + 1] = &table->class->columns[i];
836         }
837     } else {
838         char *s = xstrdup(column_names);
839         size_t allocated_columns;
840         char *save_ptr = NULL;
841         char *column_name;
842
843         columns = NULL;
844         allocated_columns = n_columns = 0;
845         for (column_name = strtok_r(s, ", ", &save_ptr); column_name;
846              column_name = strtok_r(NULL, ", ", &save_ptr)) {
847             const struct ovsdb_idl_column *column;
848
849             if (!strcasecmp(column_name, "_uuid")) {
850                 column = NULL;
851             } else {
852                 die_if_error(get_column(table, column_name, &column));
853             }
854             if (n_columns >= allocated_columns) {
855                 columns = x2nrealloc(columns, &allocated_columns,
856                                      sizeof *columns);
857             }
858             columns[n_columns++] = column;
859         }
860         free(s);
861
862         if (!n_columns) {
863             ctl_fatal("must specify at least one column name");
864         }
865     }
866     *columnsp = columns;
867     *n_columnsp = n_columns;
868 }
869
870 static void
871 pre_list_columns(struct ctl_context *ctx,
872                  const struct ctl_table_class *table,
873                  const char *column_names)
874 {
875     const struct ovsdb_idl_column **columns;
876     size_t n_columns;
877     size_t i;
878
879     parse_column_names(column_names, table, &columns, &n_columns);
880     for (i = 0; i < n_columns; i++) {
881         if (columns[i]) {
882             ovsdb_idl_add_column(ctx->idl, columns[i]);
883         }
884     }
885     free(columns);
886 }
887
888 static void
889 pre_cmd_list(struct ctl_context *ctx)
890 {
891     const char *column_names = shash_find_data(&ctx->options, "--columns");
892     const char *table_name = ctx->argv[1];
893     const struct ctl_table_class *table;
894
895     table = pre_get_table(ctx, table_name);
896     pre_list_columns(ctx, table, column_names);
897 }
898
899 static struct table *
900 list_make_table(const struct ovsdb_idl_column **columns, size_t n_columns)
901 {
902     struct table *out;
903     size_t i;
904
905     out = xmalloc(sizeof *out);
906     table_init(out);
907
908     for (i = 0; i < n_columns; i++) {
909         const struct ovsdb_idl_column *column = columns[i];
910         const char *column_name = column ? column->name : "_uuid";
911
912         table_add_column(out, "%s", column_name);
913     }
914
915     return out;
916 }
917
918 static void
919 list_record(const struct ovsdb_idl_row *row,
920             const struct ovsdb_idl_column **columns, size_t n_columns,
921             struct table *out)
922 {
923     size_t i;
924
925     if (!row) {
926         return;
927     }
928
929     table_add_row(out);
930     for (i = 0; i < n_columns; i++) {
931         const struct ovsdb_idl_column *column = columns[i];
932         struct cell *cell = table_add_cell(out);
933
934         if (!column) {
935             struct ovsdb_datum datum;
936             union ovsdb_atom atom;
937
938             atom.uuid = row->uuid;
939
940             datum.keys = &atom;
941             datum.values = NULL;
942             datum.n = 1;
943
944             cell->json = ovsdb_datum_to_json(&datum, &ovsdb_type_uuid);
945             cell->type = &ovsdb_type_uuid;
946         } else {
947             const struct ovsdb_datum *datum = ovsdb_idl_read(row, column);
948
949             cell->json = ovsdb_datum_to_json(datum, &column->type);
950             cell->type = &column->type;
951         }
952     }
953 }
954
955 static void
956 cmd_list(struct ctl_context *ctx)
957 {
958     const char *column_names = shash_find_data(&ctx->options, "--columns");
959     bool must_exist = !shash_find(&ctx->options, "--if-exists");
960     const struct ovsdb_idl_column **columns;
961     const char *table_name = ctx->argv[1];
962     const struct ctl_table_class *table;
963     struct table *out;
964     size_t n_columns;
965     int i;
966
967     table = get_table(table_name);
968     parse_column_names(column_names, table, &columns, &n_columns);
969     out = ctx->table = list_make_table(columns, n_columns);
970     if (ctx->argc > 2) {
971         for (i = 2; i < ctx->argc; i++) {
972             list_record(get_row(ctx, table, ctx->argv[i], must_exist),
973                         columns, n_columns, out);
974         }
975     } else {
976         const struct ovsdb_idl_row *row;
977
978         for (row = ovsdb_idl_first_row(ctx->idl, table->class); row != NULL;
979              row = ovsdb_idl_next_row(row)) {
980             list_record(row, columns, n_columns, out);
981         }
982     }
983     free(columns);
984 }
985
986 static void
987 pre_cmd_find(struct ctl_context *ctx)
988 {
989     const char *column_names = shash_find_data(&ctx->options, "--columns");
990     const char *table_name = ctx->argv[1];
991     const struct ctl_table_class *table;
992     int i;
993
994     table = pre_get_table(ctx, table_name);
995     pre_list_columns(ctx, table, column_names);
996     for (i = 2; i < ctx->argc; i++) {
997         pre_parse_column_key_value(ctx, ctx->argv[i], table);
998     }
999 }
1000
1001 static void
1002 cmd_find(struct ctl_context *ctx)
1003 {
1004     const char *column_names = shash_find_data(&ctx->options, "--columns");
1005     const struct ovsdb_idl_column **columns;
1006     const char *table_name = ctx->argv[1];
1007     const struct ctl_table_class *table;
1008     const struct ovsdb_idl_row *row;
1009     struct table *out;
1010     size_t n_columns;
1011
1012     table = get_table(table_name);
1013     parse_column_names(column_names, table, &columns, &n_columns);
1014     out = ctx->table = list_make_table(columns, n_columns);
1015     for (row = ovsdb_idl_first_row(ctx->idl, table->class); row;
1016          row = ovsdb_idl_next_row(row)) {
1017         int i;
1018
1019         for (i = 2; i < ctx->argc; i++) {
1020             if (!is_condition_satisfied(table, row, ctx->argv[i],
1021                                         ctx->symtab)) {
1022                 goto next_row;
1023             }
1024         }
1025         list_record(row, columns, n_columns, out);
1026
1027     next_row: ;
1028     }
1029     free(columns);
1030 }
1031
1032 static void
1033 pre_cmd_set(struct ctl_context *ctx)
1034 {
1035     const char *table_name = ctx->argv[1];
1036     const struct ctl_table_class *table;
1037     int i;
1038
1039     table = pre_get_table(ctx, table_name);
1040     for (i = 3; i < ctx->argc; i++) {
1041         pre_parse_column_key_value(ctx, ctx->argv[i], table);
1042     }
1043 }
1044
1045 static void
1046 cmd_set(struct ctl_context *ctx)
1047 {
1048     bool must_exist = !shash_find(&ctx->options, "--if-exists");
1049     const char *table_name = ctx->argv[1];
1050     const char *record_id = ctx->argv[2];
1051     const struct ctl_table_class*table;
1052     const struct ovsdb_idl_row *row;
1053     int i;
1054
1055     table = get_table(table_name);
1056     row = get_row(ctx, table, record_id, must_exist);
1057     if (!row) {
1058         return;
1059     }
1060
1061     for (i = 3; i < ctx->argc; i++) {
1062         set_column(table, row, ctx->argv[i], ctx->symtab);
1063     }
1064
1065     invalidate_cache(ctx);
1066 }
1067
1068 static void
1069 pre_cmd_add(struct ctl_context *ctx)
1070 {
1071     const char *table_name = ctx->argv[1];
1072     const char *column_name = ctx->argv[3];
1073     const struct ctl_table_class *table;
1074     const struct ovsdb_idl_column *column;
1075
1076     table = pre_get_table(ctx, table_name);
1077     pre_get_column(ctx, table, column_name, &column);
1078 }
1079
1080 static void
1081 cmd_add(struct ctl_context *ctx)
1082 {
1083     bool must_exist = !shash_find(&ctx->options, "--if-exists");
1084     const char *table_name = ctx->argv[1];
1085     const char *record_id = ctx->argv[2];
1086     const char *column_name = ctx->argv[3];
1087     const struct ctl_table_class *table;
1088     const struct ovsdb_idl_column *column;
1089     const struct ovsdb_idl_row *row;
1090     const struct ovsdb_type *type;
1091     struct ovsdb_datum old;
1092     int i;
1093
1094     table = get_table(table_name);
1095     die_if_error(get_column(table, column_name, &column));
1096     row = get_row(ctx, table, record_id, must_exist);
1097     if (!row) {
1098         return;
1099     }
1100     check_mutable(row, column);
1101
1102     type = &column->type;
1103     ovsdb_datum_clone(&old, ovsdb_idl_read(row, column), &column->type);
1104     for (i = 4; i < ctx->argc; i++) {
1105         struct ovsdb_type add_type;
1106         struct ovsdb_datum add;
1107
1108         add_type = *type;
1109         add_type.n_min = 1;
1110         add_type.n_max = UINT_MAX;
1111         die_if_error(ovsdb_datum_from_string(&add, &add_type, ctx->argv[i],
1112                                              ctx->symtab));
1113         ovsdb_datum_union(&old, &add, type, false);
1114         ovsdb_datum_destroy(&add, type);
1115     }
1116     if (old.n > type->n_max) {
1117         ctl_fatal("\"add\" operation would put %u %s in column %s of "
1118                   "table %s but the maximum number is %u",
1119                   old.n,
1120                   type->value.type == OVSDB_TYPE_VOID ? "values" : "pairs",
1121                   column->name, table->class->name, type->n_max);
1122     }
1123     ovsdb_idl_txn_verify(row, column);
1124     ovsdb_idl_txn_write(row, column, &old);
1125
1126     invalidate_cache(ctx);
1127 }
1128
1129 static void
1130 pre_cmd_remove(struct ctl_context *ctx)
1131 {
1132     const char *table_name = ctx->argv[1];
1133     const char *column_name = ctx->argv[3];
1134     const struct ctl_table_class *table;
1135     const struct ovsdb_idl_column *column;
1136
1137     table = pre_get_table(ctx, table_name);
1138     pre_get_column(ctx, table, column_name, &column);
1139 }
1140
1141 static void
1142 cmd_remove(struct ctl_context *ctx)
1143 {
1144     bool must_exist = !shash_find(&ctx->options, "--if-exists");
1145     const char *table_name = ctx->argv[1];
1146     const char *record_id = ctx->argv[2];
1147     const char *column_name = ctx->argv[3];
1148     const struct ctl_table_class *table;
1149     const struct ovsdb_idl_column *column;
1150     const struct ovsdb_idl_row *row;
1151     const struct ovsdb_type *type;
1152     struct ovsdb_datum old;
1153     int i;
1154
1155     table = get_table(table_name);
1156     die_if_error(get_column(table, column_name, &column));
1157     row = get_row(ctx, table, record_id, must_exist);
1158     if (!row) {
1159         return;
1160     }
1161     check_mutable(row, column);
1162
1163     type = &column->type;
1164     ovsdb_datum_clone(&old, ovsdb_idl_read(row, column), &column->type);
1165     for (i = 4; i < ctx->argc; i++) {
1166         struct ovsdb_type rm_type;
1167         struct ovsdb_datum rm;
1168         char *error;
1169
1170         rm_type = *type;
1171         rm_type.n_min = 1;
1172         rm_type.n_max = UINT_MAX;
1173         error = ovsdb_datum_from_string(&rm, &rm_type,
1174                                         ctx->argv[i], ctx->symtab);
1175
1176         if (error) {
1177             if (ovsdb_type_is_map(&rm_type)) {
1178                 rm_type.value.type = OVSDB_TYPE_VOID;
1179                 free(error);
1180                 die_if_error(ovsdb_datum_from_string(
1181                                                      &rm, &rm_type, ctx->argv[i], ctx->symtab));
1182             } else {
1183                 ctl_fatal("%s", error);
1184             }
1185         }
1186         ovsdb_datum_subtract(&old, type, &rm, &rm_type);
1187         ovsdb_datum_destroy(&rm, &rm_type);
1188     }
1189     if (old.n < type->n_min) {
1190         ctl_fatal("\"remove\" operation would put %u %s in column %s of "
1191                   "table %s but the minimum number is %u",
1192                   old.n,
1193                   type->value.type == OVSDB_TYPE_VOID ? "values" : "pairs",
1194                   column->name, table->class->name, type->n_min);
1195     }
1196     ovsdb_idl_txn_verify(row, column);
1197     ovsdb_idl_txn_write(row, column, &old);
1198
1199     invalidate_cache(ctx);
1200 }
1201
1202 static void
1203 pre_cmd_clear(struct ctl_context *ctx)
1204 {
1205     const char *table_name = ctx->argv[1];
1206     const struct ctl_table_class *table;
1207     int i;
1208
1209     table = pre_get_table(ctx, table_name);
1210     for (i = 3; i < ctx->argc; i++) {
1211         const struct ovsdb_idl_column *column;
1212
1213         pre_get_column(ctx, table, ctx->argv[i], &column);
1214     }
1215 }
1216
1217 static void
1218 cmd_clear(struct ctl_context *ctx)
1219 {
1220     bool must_exist = !shash_find(&ctx->options, "--if-exists");
1221     const char *table_name = ctx->argv[1];
1222     const char *record_id = ctx->argv[2];
1223     const struct ctl_table_class *table;
1224     const struct ovsdb_idl_row *row;
1225     int i;
1226
1227     table = get_table(table_name);
1228     row = get_row(ctx, table, record_id, must_exist);
1229     if (!row) {
1230         return;
1231     }
1232
1233     for (i = 3; i < ctx->argc; i++) {
1234         const struct ovsdb_idl_column *column;
1235         const struct ovsdb_type *type;
1236         struct ovsdb_datum datum;
1237
1238         die_if_error(get_column(table, ctx->argv[i], &column));
1239         check_mutable(row, column);
1240
1241         type = &column->type;
1242         if (type->n_min > 0) {
1243             ctl_fatal("\"clear\" operation cannot be applied to column %s "
1244                       "of table %s, which is not allowed to be empty",
1245                       column->name, table->class->name);
1246         }
1247
1248         ovsdb_datum_init_empty(&datum);
1249         ovsdb_idl_txn_write(row, column, &datum);
1250     }
1251
1252     invalidate_cache(ctx);
1253 }
1254
1255 static void
1256 pre_create(struct ctl_context *ctx)
1257 {
1258     const char *id = shash_find_data(&ctx->options, "--id");
1259     const char *table_name = ctx->argv[1];
1260     const struct ctl_table_class *table;
1261
1262     table = get_table(table_name);
1263     if (!id && !table->class->is_root) {
1264         VLOG_WARN("applying \"create\" command to table %s without --id "
1265                   "option will have no effect", table->class->name);
1266     }
1267 }
1268
1269 static void
1270 cmd_create(struct ctl_context *ctx)
1271 {
1272     const char *id = shash_find_data(&ctx->options, "--id");
1273     const char *table_name = ctx->argv[1];
1274     const struct ctl_table_class *table = get_table(table_name);
1275     const struct ovsdb_idl_row *row;
1276     const struct uuid *uuid;
1277     int i;
1278
1279     if (id) {
1280         struct ovsdb_symbol *symbol = create_symbol(ctx->symtab, id, NULL);
1281         if (table->class->is_root) {
1282             /* This table is in the root set, meaning that rows created in it
1283              * won't disappear even if they are unreferenced, so disable
1284              * warnings about that by pretending that there is a reference. */
1285             symbol->strong_ref = true;
1286         }
1287         uuid = &symbol->uuid;
1288     } else {
1289         uuid = NULL;
1290     }
1291
1292     row = ovsdb_idl_txn_insert(ctx->txn, table->class, uuid);
1293     for (i = 2; i < ctx->argc; i++) {
1294         set_column(table, row, ctx->argv[i], ctx->symtab);
1295     }
1296     ds_put_format(&ctx->output, UUID_FMT, UUID_ARGS(&row->uuid));
1297 }
1298
1299 /* This function may be used as the 'postprocess' function for commands that
1300  * insert new rows into the database.  It expects that the command's 'run'
1301  * function prints the UUID reported by ovsdb_idl_txn_insert() as the command's
1302  * sole output.  It replaces that output by the row's permanent UUID assigned
1303  * by the database server and appends a new-line.
1304  *
1305  * Currently we use this only for "create", because the higher-level commands
1306  * are supposed to be independent of the actual structure of the vswitch
1307  * configuration. */
1308 static void
1309 post_create(struct ctl_context *ctx)
1310 {
1311     const struct uuid *real;
1312     struct uuid dummy;
1313
1314     if (!uuid_from_string(&dummy, ds_cstr(&ctx->output))) {
1315         OVS_NOT_REACHED();
1316     }
1317     real = ovsdb_idl_txn_get_insert_uuid(ctx->txn, &dummy);
1318     if (real) {
1319         ds_clear(&ctx->output);
1320         ds_put_format(&ctx->output, UUID_FMT, UUID_ARGS(real));
1321     }
1322     ds_put_char(&ctx->output, '\n');
1323 }
1324
1325 static void
1326 pre_cmd_destroy(struct ctl_context *ctx)
1327 {
1328     const char *table_name = ctx->argv[1];
1329
1330     pre_get_table(ctx, table_name);
1331 }
1332
1333 static void
1334 cmd_destroy(struct ctl_context *ctx)
1335 {
1336     bool must_exist = !shash_find(&ctx->options, "--if-exists");
1337     bool delete_all = shash_find(&ctx->options, "--all");
1338     const char *table_name = ctx->argv[1];
1339     const struct ctl_table_class *table;
1340     int i;
1341
1342     table = get_table(table_name);
1343
1344     if (delete_all && ctx->argc > 2) {
1345         ctl_fatal("--all and records argument should not be specified together");
1346     }
1347
1348     if (delete_all && !must_exist) {
1349         ctl_fatal("--all and --if-exists should not be specified together");
1350     }
1351
1352     if (delete_all) {
1353         const struct ovsdb_idl_row *row;
1354         const struct ovsdb_idl_row *next_row;
1355
1356         for (row = ovsdb_idl_first_row(ctx->idl, table->class);
1357              row;) {
1358             next_row = ovsdb_idl_next_row(row);
1359             ovsdb_idl_txn_delete(row);
1360             row = next_row;
1361         }
1362     } else {
1363         for (i = 2; i < ctx->argc; i++) {
1364             const struct ovsdb_idl_row *row;
1365
1366             row = get_row(ctx, table, ctx->argv[i], must_exist);
1367             if (row) {
1368                 ovsdb_idl_txn_delete(row);
1369             }
1370         }
1371     }
1372     invalidate_cache(ctx);
1373 }
1374
1375 static void
1376 pre_cmd_wait_until(struct ctl_context *ctx)
1377 {
1378     const char *table_name = ctx->argv[1];
1379     const struct ctl_table_class *table;
1380     int i;
1381
1382     table = pre_get_table(ctx, table_name);
1383
1384     for (i = 3; i < ctx->argc; i++) {
1385         pre_parse_column_key_value(ctx, ctx->argv[i], table);
1386     }
1387 }
1388
1389 static void
1390 cmd_wait_until(struct ctl_context *ctx)
1391 {
1392     const char *table_name = ctx->argv[1];
1393     const char *record_id = ctx->argv[2];
1394     const struct ctl_table_class *table;
1395     const struct ovsdb_idl_row *row;
1396     int i;
1397
1398     table = get_table(table_name);
1399
1400     row = get_row(ctx, table, record_id, false);
1401     if (!row) {
1402         ctx->try_again = true;
1403         return;
1404     }
1405
1406     for (i = 3; i < ctx->argc; i++) {
1407         if (!is_condition_satisfied(table, row, ctx->argv[i], ctx->symtab)) {
1408             ctx->try_again = true;
1409             return;
1410         }
1411     }
1412 }
1413
1414 /* Parses one command. */
1415 static void
1416 parse_command(int argc, char *argv[], struct shash *local_options,
1417               struct ctl_command *command)
1418 {
1419     const struct ctl_command_syntax *p;
1420     struct shash_node *node;
1421     int n_arg;
1422     int i;
1423
1424     shash_init(&command->options);
1425     shash_swap(local_options, &command->options);
1426     for (i = 0; i < argc; i++) {
1427         const char *option = argv[i];
1428         const char *equals;
1429         char *key, *value;
1430
1431         if (option[0] != '-') {
1432             break;
1433         }
1434
1435         equals = strchr(option, '=');
1436         if (equals) {
1437             key = xmemdup0(option, equals - option);
1438             value = xstrdup(equals + 1);
1439         } else {
1440             key = xstrdup(option);
1441             value = NULL;
1442         }
1443
1444         if (shash_find(&command->options, key)) {
1445             ctl_fatal("'%s' option specified multiple times", argv[i]);
1446         }
1447         shash_add_nocopy(&command->options, key, value);
1448     }
1449     if (i == argc) {
1450         ctl_fatal("missing command name (use --help for help)");
1451     }
1452
1453     p = shash_find_data(&all_commands, argv[i]);
1454     if (!p) {
1455         ctl_fatal("unknown command '%s'; use --help for help", argv[i]);
1456     }
1457
1458     SHASH_FOR_EACH (node, &command->options) {
1459         const char *s = strstr(p->options, node->name);
1460         int end = s ? s[strlen(node->name)] : EOF;
1461
1462         if (end != '=' && end != ',' && end != ' ' && end != '\0') {
1463             ctl_fatal("'%s' command has no '%s' option",
1464                       argv[i], node->name);
1465         }
1466         if ((end == '=') != (node->data != NULL)) {
1467             if (end == '=') {
1468                 ctl_fatal("missing argument to '%s' option on '%s' "
1469                           "command", node->name, argv[i]);
1470             } else {
1471                 ctl_fatal("'%s' option on '%s' does not accept an "
1472                           "argument", node->name, argv[i]);
1473             }
1474         }
1475     }
1476
1477     n_arg = argc - i - 1;
1478     if (n_arg < p->min_args) {
1479         ctl_fatal("'%s' command requires at least %d arguments",
1480                   p->name, p->min_args);
1481     } else if (n_arg > p->max_args) {
1482         int j;
1483
1484         for (j = i + 1; j < argc; j++) {
1485             if (argv[j][0] == '-') {
1486                 ctl_fatal("'%s' command takes at most %d arguments "
1487                           "(note that options must precede command "
1488                           "names and follow a \"--\" argument)",
1489                           p->name, p->max_args);
1490             }
1491         }
1492
1493         ctl_fatal("'%s' command takes at most %d arguments",
1494                   p->name, p->max_args);
1495     }
1496
1497     command->syntax = p;
1498     command->argc = n_arg + 1;
1499     command->argv = &argv[i];
1500 }
1501
1502 static void
1503 pre_cmd_show(struct ctl_context *ctx)
1504 {
1505     struct cmd_show_table *show;
1506
1507     for (show = cmd_show_tables; show->table; show++) {
1508         size_t i;
1509
1510         ovsdb_idl_add_table(ctx->idl, show->table);
1511         if (show->name_column) {
1512             ovsdb_idl_add_column(ctx->idl, show->name_column);
1513         }
1514         for (i = 0; i < ARRAY_SIZE(show->columns); i++) {
1515             const struct ovsdb_idl_column *column = show->columns[i];
1516             if (column) {
1517                 ovsdb_idl_add_column(ctx->idl, column);
1518             }
1519         }
1520     }
1521 }
1522
1523 static struct cmd_show_table *
1524 cmd_show_find_table_by_row(const struct ovsdb_idl_row *row)
1525 {
1526     struct cmd_show_table *show;
1527
1528     for (show = cmd_show_tables; show->table; show++) {
1529         if (show->table == row->table->class) {
1530             return show;
1531         }
1532     }
1533     return NULL;
1534 }
1535
1536 static struct cmd_show_table *
1537 cmd_show_find_table_by_name(const char *name)
1538 {
1539     struct cmd_show_table *show;
1540
1541     for (show = cmd_show_tables; show->table; show++) {
1542         if (!strcmp(show->table->name, name)) {
1543             return show;
1544         }
1545     }
1546     return NULL;
1547 }
1548
1549 static void
1550 cmd_show_row(struct ctl_context *ctx, const struct ovsdb_idl_row *row,
1551              int level)
1552 {
1553     struct cmd_show_table *show = cmd_show_find_table_by_row(row);
1554     size_t i;
1555
1556     ds_put_char_multiple(&ctx->output, ' ', level * 4);
1557     if (show && show->name_column) {
1558         const struct ovsdb_datum *datum;
1559
1560         ds_put_format(&ctx->output, "%s ", show->table->name);
1561         datum = ovsdb_idl_read(row, show->name_column);
1562         ovsdb_datum_to_string(datum, &show->name_column->type, &ctx->output);
1563     } else {
1564         ds_put_format(&ctx->output, UUID_FMT, UUID_ARGS(&row->uuid));
1565     }
1566     ds_put_char(&ctx->output, '\n');
1567
1568     if (!show || show->recurse) {
1569         return;
1570     }
1571
1572     show->recurse = true;
1573     for (i = 0; i < ARRAY_SIZE(show->columns); i++) {
1574         const struct ovsdb_idl_column *column = show->columns[i];
1575         const struct ovsdb_datum *datum;
1576
1577         if (!column) {
1578             break;
1579         }
1580
1581         datum = ovsdb_idl_read(row, column);
1582         if (column->type.key.type == OVSDB_TYPE_UUID &&
1583             column->type.key.u.uuid.refTableName) {
1584             struct cmd_show_table *ref_show;
1585             size_t j;
1586
1587             ref_show = cmd_show_find_table_by_name(
1588                 column->type.key.u.uuid.refTableName);
1589             if (ref_show) {
1590                 for (j = 0; j < datum->n; j++) {
1591                     const struct ovsdb_idl_row *ref_row;
1592
1593                     ref_row = ovsdb_idl_get_row_for_uuid(ctx->idl,
1594                                                          ref_show->table,
1595                                                          &datum->keys[j].uuid);
1596                     if (ref_row) {
1597                         cmd_show_row(ctx, ref_row, level + 1);
1598                     }
1599                 }
1600                 continue;
1601             }
1602         } else if (ovsdb_type_is_map(&column->type) &&
1603                    column->type.value.type == OVSDB_TYPE_UUID &&
1604                    column->type.value.u.uuid.refTableName) {
1605             struct cmd_show_table *ref_show;
1606             size_t j;
1607
1608             /* Prints the key to ref'ed table name map if the ref'ed table
1609              * is also defined in 'cmd_show_tables'.  */
1610             ref_show = cmd_show_find_table_by_name(
1611                 column->type.value.u.uuid.refTableName);
1612             if (ref_show && ref_show->name_column) {
1613                 ds_put_char_multiple(&ctx->output, ' ', (level + 1) * 4);
1614                 ds_put_format(&ctx->output, "%s:\n", column->name);
1615                 for (j = 0; j < datum->n; j++) {
1616                     const struct ovsdb_idl_row *ref_row;
1617
1618                     ref_row = ovsdb_idl_get_row_for_uuid(ctx->idl,
1619                                                          ref_show->table,
1620                                                          &datum->values[j].uuid);
1621
1622                     ds_put_char_multiple(&ctx->output, ' ', (level + 2) * 4);
1623                     ovsdb_atom_to_string(&datum->keys[j], column->type.key.type,
1624                                          &ctx->output);
1625                     ds_put_char(&ctx->output, '=');
1626                     if (ref_row) {
1627                         const struct ovsdb_datum *ref_datum;
1628
1629                         ref_datum = ovsdb_idl_read(ref_row,
1630                                                    ref_show->name_column);
1631                         ovsdb_datum_to_string(ref_datum,
1632                                               &ref_show->name_column->type,
1633                                               &ctx->output);
1634                     } else {
1635                         ds_put_cstr(&ctx->output, "\"<null>\"");
1636                     }
1637                     ds_put_char(&ctx->output, '\n');
1638                 }
1639                 continue;
1640             }
1641         }
1642
1643         if (!ovsdb_datum_is_default(datum, &column->type)) {
1644             ds_put_char_multiple(&ctx->output, ' ', (level + 1) * 4);
1645             ds_put_format(&ctx->output, "%s: ", column->name);
1646             ovsdb_datum_to_string(datum, &column->type, &ctx->output);
1647             ds_put_char(&ctx->output, '\n');
1648         }
1649     }
1650     show->recurse = false;
1651 }
1652
1653 static void
1654 cmd_show(struct ctl_context *ctx)
1655 {
1656     const struct ovsdb_idl_row *row;
1657
1658     for (row = ovsdb_idl_first_row(ctx->idl, cmd_show_tables[0].table);
1659          row; row = ovsdb_idl_next_row(row)) {
1660         cmd_show_row(ctx, row, 0);
1661     }
1662 }
1663
1664 \f
1665 /* Given pointer to dynamic array 'options_p',  array's current size
1666  * 'allocated_options_p' and number of added options 'n_options_p',
1667  * adds all command options to the array.  Enlarges the array if
1668  * necessary. */
1669 void
1670 ctl_add_cmd_options(struct option **options_p, size_t *n_options_p,
1671                     size_t *allocated_options_p, int opt_val)
1672 {
1673     struct option *o;
1674     const struct shash_node *node;
1675     size_t n_existing_options = *n_options_p;
1676
1677     SHASH_FOR_EACH (node, ctl_get_all_commands()) {
1678         const struct ctl_command_syntax *p = node->data;
1679
1680         if (p->options[0]) {
1681             char *save_ptr = NULL;
1682             char *name;
1683             char *s;
1684
1685             s = xstrdup(p->options);
1686             for (name = strtok_r(s, ",", &save_ptr); name != NULL;
1687                  name = strtok_r(NULL, ",", &save_ptr)) {
1688                 char *equals;
1689                 int has_arg;
1690
1691                 ovs_assert(name[0] == '-' && name[1] == '-' && name[2]);
1692                 name += 2;
1693
1694                 equals = strchr(name, '=');
1695                 if (equals) {
1696                     has_arg = required_argument;
1697                     *equals = '\0';
1698                 } else {
1699                     has_arg = no_argument;
1700                 }
1701
1702                 o = find_option(name, *options_p, *n_options_p);
1703                 if (o) {
1704                     ovs_assert(o - *options_p >= n_existing_options);
1705                     ovs_assert(o->has_arg == has_arg);
1706                 } else {
1707                     o = add_option(options_p, n_options_p, allocated_options_p);
1708                     o->name = xstrdup(name);
1709                     o->has_arg = has_arg;
1710                     o->flag = NULL;
1711                     o->val = opt_val;
1712                 }
1713             }
1714
1715             free(s);
1716         }
1717     }
1718     o = add_option(options_p, n_options_p, allocated_options_p);
1719     memset(o, 0, sizeof *o);
1720 }
1721
1722 /* Parses command-line input for commands. */
1723 struct ctl_command *
1724 ctl_parse_commands(int argc, char *argv[], struct shash *local_options,
1725                    size_t *n_commandsp)
1726 {
1727     struct ctl_command *commands;
1728     size_t n_commands, allocated_commands;
1729     int i, start;
1730
1731     commands = NULL;
1732     n_commands = allocated_commands = 0;
1733
1734     for (start = i = 0; i <= argc; i++) {
1735         if (i == argc || !strcmp(argv[i], "--")) {
1736             if (i > start) {
1737                 if (n_commands >= allocated_commands) {
1738                     struct ctl_command *c;
1739
1740                     commands = x2nrealloc(commands, &allocated_commands,
1741                                           sizeof *commands);
1742                     for (c = commands; c < &commands[n_commands]; c++) {
1743                         shash_moved(&c->options);
1744                     }
1745                 }
1746                 parse_command(i - start, &argv[start], local_options,
1747                               &commands[n_commands++]);
1748             } else if (!shash_is_empty(local_options)) {
1749                 ctl_fatal("missing command name (use --help for help)");
1750             }
1751             start = i + 1;
1752         }
1753     }
1754     if (!n_commands) {
1755         ctl_fatal("missing command name (use --help for help)");
1756     }
1757     *n_commandsp = n_commands;
1758     return commands;
1759 }
1760
1761 /* Prints all registered commands. */
1762 void
1763 ctl_print_commands(void)
1764 {
1765     const struct shash_node *node;
1766
1767     SHASH_FOR_EACH (node, ctl_get_all_commands()) {
1768         const struct ctl_command_syntax *p = node->data;
1769         char *options = xstrdup(p->options);
1770         char *options_begin = options;
1771         char *item;
1772
1773         for (item = strsep(&options, ","); item != NULL;
1774              item = strsep(&options, ",")) {
1775             if (item[0] != '\0') {
1776                 printf("[%s] ", item);
1777             }
1778         }
1779         printf(",%s,", p->name);
1780         print_command_arguments(p);
1781         printf("\n");
1782
1783         free(options_begin);
1784     }
1785
1786     exit(EXIT_SUCCESS);
1787 }
1788
1789 /* Given array of options 'options', prints them. */
1790 void
1791 ctl_print_options(const struct option *options)
1792 {
1793     for (; options->name; options++) {
1794         const struct option *o = options;
1795
1796         printf("--%s%s\n", o->name, o->has_arg ? "=ARG" : "");
1797         if (o->flag == NULL && o->val > 0 && o->val <= UCHAR_MAX) {
1798             printf("-%c%s\n", o->val, o->has_arg ? " ARG" : "");
1799         }
1800     }
1801
1802     exit(EXIT_SUCCESS);
1803 }
1804
1805 /* Returns the default local database path. */
1806 char *
1807 ctl_default_db(void)
1808 {
1809     static char *def;
1810     if (!def) {
1811         def = xasprintf("unix:%s/db.sock", ovs_rundir());
1812     }
1813     return def;
1814 }
1815
1816 /* Returns true if it looks like this set of arguments might modify the
1817  * database, otherwise false.  (Not very smart, so it's prone to false
1818  * positives.) */
1819 bool
1820 ctl_might_write_to_db(char **argv)
1821 {
1822     for (; *argv; argv++) {
1823         const struct ctl_command_syntax *p = shash_find_data(&all_commands, *argv);
1824         if (p && p->mode == RW) {
1825             return true;
1826         }
1827     }
1828     return false;
1829 }
1830
1831 void
1832 ctl_fatal(const char *format, ...)
1833 {
1834     char *message;
1835     va_list args;
1836
1837     va_start(args, format);
1838     message = xvasprintf(format, args);
1839     va_end(args);
1840
1841     vlog_set_levels(&VLM_db_ctl_base, VLF_CONSOLE, VLL_OFF);
1842     VLOG_ERR("%s", message);
1843     ovs_error(0, "%s", message);
1844     ctl_exit(EXIT_FAILURE);
1845 }
1846
1847 /* Frees the current transaction and the underlying IDL and then calls
1848  * exit(status).
1849  *
1850  * Freeing the transaction and the IDL is not strictly necessary, but it makes
1851  * for a clean memory leak report from valgrind in the normal case.  That makes
1852  * it easier to notice real memory leaks. */
1853 void
1854 ctl_exit(int status)
1855 {
1856     if (the_idl_txn) {
1857         ovsdb_idl_txn_abort(the_idl_txn);
1858         ovsdb_idl_txn_destroy(the_idl_txn);
1859     }
1860     ovsdb_idl_destroy(the_idl);
1861     exit(status);
1862 }
1863
1864 /* Command for showing overview of database contents. */
1865 static const struct ctl_command_syntax db_ctl_show_command[] = {
1866     {"show", 0, 0, "", pre_cmd_show, cmd_show, NULL, "", RO},
1867     {NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, RO},
1868 };
1869
1870 /* Comman database commands to be registered. */
1871 static const struct ctl_command_syntax db_ctl_commands[] = {
1872     {"comment", 0, INT_MAX, "[ARG]...", NULL, NULL, NULL, "", RO},
1873     {"get", 2, INT_MAX, "TABLE RECORD [COLUMN[:KEY]]...",pre_cmd_get, cmd_get,
1874      NULL, "--if-exists,--id=", RO},
1875     {"list", 1, INT_MAX, "TABLE [RECORD]...", pre_cmd_list, cmd_list, NULL,
1876      "--if-exists,--columns=", RO},
1877     {"find", 1, INT_MAX, "TABLE [COLUMN[:KEY]=VALUE]...", pre_cmd_find,
1878      cmd_find, NULL, "--columns=", RO},
1879     {"set", 3, INT_MAX, "TABLE RECORD COLUMN[:KEY]=VALUE...", pre_cmd_set,
1880      cmd_set, NULL, "--if-exists", RW},
1881     {"add", 4, INT_MAX, "TABLE RECORD COLUMN [KEY=]VALUE...", pre_cmd_add,
1882      cmd_add, NULL, "--if-exists", RW},
1883     {"remove", 4, INT_MAX, "TABLE RECORD COLUMN KEY|VALUE|KEY=VALUE...",
1884      pre_cmd_remove, cmd_remove, NULL, "--if-exists", RW},
1885     {"clear", 3, INT_MAX, "TABLE RECORD COLUMN...", pre_cmd_clear, cmd_clear,
1886      NULL, "--if-exists", RW},
1887     {"create", 2, INT_MAX, "TABLE COLUMN[:KEY]=VALUE...", pre_create,
1888      cmd_create, post_create, "--id=", RW},
1889     {"destroy", 1, INT_MAX, "TABLE [RECORD]...", pre_cmd_destroy, cmd_destroy,
1890      NULL, "--if-exists,--all", RW},
1891     {"wait-until", 2, INT_MAX, "TABLE RECORD [COLUMN[:KEY]=VALUE]...",
1892      pre_cmd_wait_until, cmd_wait_until, NULL, "", RO},
1893     {NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, RO},
1894 };
1895
1896 /* Registers commands represented by 'struct ctl_command_syntax's to
1897  * 'all_commands'.  The last element of 'commands' must be an all-NULL
1898  * element. */
1899 void
1900 ctl_register_commands(const struct ctl_command_syntax *commands)
1901 {
1902     const struct ctl_command_syntax *p;
1903
1904     for (p = commands; p->name; p++) {
1905         shash_add_assert(&all_commands, p->name, p);
1906     }
1907 }
1908
1909 /* Registers the 'db_ctl_commands' to 'all_commands'. */
1910 void
1911 ctl_init(void)
1912 {
1913     ctl_register_commands(db_ctl_commands);
1914     ctl_register_commands(db_ctl_show_command);
1915 }
1916
1917 /* Returns 'all_commands'. */
1918 const struct shash *
1919 ctl_get_all_commands(void)
1920 {
1921     return &all_commands;
1922 }
1923
1924 /* Returns the text for the database commands usage.  */
1925 const char *
1926 ctl_get_db_cmd_usage(void)
1927 {
1928     return "Database commands:\n\
1929   list TBL [REC]              list RECord (or all records) in TBL\n\
1930   find TBL CONDITION...       list records satisfying CONDITION in TBL\n\
1931   get TBL REC COL[:KEY]       print values of COLumns in RECord in TBL\n\
1932   set TBL REC COL[:KEY]=VALUE set COLumn values in RECord in TBL\n\
1933   add TBL REC COL [KEY=]VALUE add (KEY=)VALUE to COLumn in RECord in TBL\n\
1934   remove TBL REC COL [KEY=]VALUE  remove (KEY=)VALUE from COLumn\n\
1935   clear TBL REC COL           clear values from COLumn in RECord in TBL\n\
1936   create TBL COL[:KEY]=VALUE  create and initialize new record\n\
1937   destroy TBL REC             delete RECord from TBL\n\
1938   wait-until TBL REC [COL[:KEY]=VALUE]  wait until condition is true\n\
1939 Potentially unsafe database commands require --force option.\n";
1940 }
1941
1942 /* Initializes 'ctx' from 'command'. */
1943 void
1944 ctl_context_init_command(struct ctl_context *ctx,
1945                          struct ctl_command *command)
1946 {
1947     ctx->argc = command->argc;
1948     ctx->argv = command->argv;
1949     ctx->options = command->options;
1950
1951     ds_swap(&ctx->output, &command->output);
1952     ctx->table = command->table;
1953     ctx->try_again = false;
1954 }
1955
1956 /* Initializes the entire 'ctx'. */
1957 void
1958 ctl_context_init(struct ctl_context *ctx, struct ctl_command *command,
1959                  struct ovsdb_idl *idl, struct ovsdb_idl_txn *txn,
1960                  struct ovsdb_symbol_table *symtab,
1961                  void (*invalidate_cache)(struct ctl_context *))
1962 {
1963     if (command) {
1964         ctl_context_init_command(ctx, command);
1965     }
1966     ctx->idl = idl;
1967     ctx->txn = txn;
1968     ctx->symtab = symtab;
1969     ctx->invalidate_cache = invalidate_cache;
1970 }
1971
1972 /* Completes processing of 'command' within 'ctx'. */
1973 void
1974 ctl_context_done_command(struct ctl_context *ctx,
1975                          struct ctl_command *command)
1976 {
1977     ds_swap(&ctx->output, &command->output);
1978     command->table = ctx->table;
1979 }
1980
1981 /* Finishes up with 'ctx'.
1982  *
1983  * If command is nonnull, first calls ctl_context_done_command() to complete
1984  * processing that command within 'ctx'. */
1985 void
1986 ctl_context_done(struct ctl_context *ctx,
1987                  struct ctl_command *command)
1988 {
1989     if (command) {
1990         ctl_context_done_command(ctx, command);
1991     }
1992     invalidate_cache(ctx);
1993 }
1994
1995 /* Finds and returns the "struct ctl_table_class *" with 'table_name' by
1996  * searching the 'tables'. */
1997 static const struct ctl_table_class *
1998 get_table(const char *table_name)
1999 {
2000     const struct ctl_table_class *table;
2001     const struct ctl_table_class *best_match = NULL;
2002     unsigned int best_score = 0;
2003
2004     for (table = tables; table->class; table++) {
2005         unsigned int score = score_partial_match(table->class->name,
2006                                                  table_name);
2007         if (score > best_score) {
2008             best_match = table;
2009             best_score = score;
2010         } else if (score == best_score) {
2011             best_match = NULL;
2012         }
2013     }
2014     if (best_match) {
2015         return best_match;
2016     } else if (best_score) {
2017         ctl_fatal("multiple table names match \"%s\"", table_name);
2018     } else {
2019         ctl_fatal("unknown table \"%s\"", table_name);
2020     }
2021     return NULL;
2022 }
2023
2024 /* Sets the column of 'row' in 'table'. */
2025 static void
2026 set_column(const struct ctl_table_class *table,
2027            const struct ovsdb_idl_row *row, const char *arg,
2028            struct ovsdb_symbol_table *symtab)
2029 {
2030     const struct ovsdb_idl_column *column;
2031     char *key_string, *value_string;
2032     char *error;
2033
2034     error = parse_column_key_value(arg, table, &column, &key_string,
2035                                    NULL, NULL, 0, &value_string);
2036     die_if_error(error);
2037     if (!value_string) {
2038         ctl_fatal("%s: missing value", arg);
2039     }
2040     check_mutable(row, column);
2041
2042     if (key_string) {
2043         union ovsdb_atom key, value;
2044         struct ovsdb_datum datum;
2045
2046         if (column->type.value.type == OVSDB_TYPE_VOID) {
2047             ctl_fatal("cannot specify key to set for non-map column %s",
2048                       column->name);
2049         }
2050
2051         die_if_error(ovsdb_atom_from_string(&key, &column->type.key,
2052                                             key_string, symtab));
2053         die_if_error(ovsdb_atom_from_string(&value, &column->type.value,
2054                                             value_string, symtab));
2055
2056         ovsdb_datum_init_empty(&datum);
2057         ovsdb_datum_add_unsafe(&datum, &key, &value, &column->type);
2058
2059         ovsdb_atom_destroy(&key, column->type.key.type);
2060         ovsdb_atom_destroy(&value, column->type.value.type);
2061
2062         ovsdb_datum_union(&datum, ovsdb_idl_read(row, column),
2063                           &column->type, false);
2064         ovsdb_idl_txn_verify(row, column);
2065         ovsdb_idl_txn_write(row, column, &datum);
2066     } else {
2067         struct ovsdb_datum datum;
2068
2069         die_if_error(ovsdb_datum_from_string(&datum, &column->type,
2070                                              value_string, symtab));
2071         ovsdb_idl_txn_write(row, column, &datum);
2072     }
2073
2074     free(key_string);
2075     free(value_string);
2076 }
2077
2078 void ctl_set_column(const char *table_name,
2079                     const struct ovsdb_idl_row *row, const char *arg,
2080                     struct ovsdb_symbol_table *symtab)
2081 {
2082     set_column(get_table(table_name), row, arg, symtab);
2083 }