25fe9037739a6315ee139151735309d9f73fa5a9
[cascardo/ovs.git] / ovsdb / ovsdb-client.c
1 /*
2  * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 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 <errno.h>
21 #include <getopt.h>
22 #include <limits.h>
23 #include <signal.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <unistd.h>
27
28 #include "command-line.h"
29 #include "column.h"
30 #include "compiler.h"
31 #include "daemon.h"
32 #include "dirs.h"
33 #include "openvswitch/dynamic-string.h"
34 #include "fatal-signal.h"
35 #include "json.h"
36 #include "jsonrpc.h"
37 #include "lib/table.h"
38 #include "ovsdb.h"
39 #include "ovsdb-data.h"
40 #include "ovsdb-error.h"
41 #include "poll-loop.h"
42 #include "sort.h"
43 #include "svec.h"
44 #include "stream.h"
45 #include "stream-ssl.h"
46 #include "table.h"
47 #include "monitor.h"
48 #include "timeval.h"
49 #include "unixctl.h"
50 #include "util.h"
51 #include "openvswitch/vlog.h"
52
53 VLOG_DEFINE_THIS_MODULE(ovsdb_client);
54
55 enum args_needed {
56     NEED_NONE,            /* No JSON-RPC connection or database name needed. */
57     NEED_RPC,             /* JSON-RPC connection needed. */
58     NEED_DATABASE         /* JSON-RPC connection and database name needed. */
59 };
60
61 struct ovsdb_client_command {
62     const char *name;
63     enum args_needed need;
64     int min_args;
65     int max_args;
66     void (*handler)(struct jsonrpc *rpc, const char *database,
67                     int argc, char *argv[]);
68 };
69
70 /* --timestamp: Print a timestamp before each update on "monitor" command? */
71 static bool timestamp;
72
73 /* Format for table output. */
74 static struct table_style table_style = TABLE_STYLE_DEFAULT;
75
76 static const struct ovsdb_client_command *get_all_commands(void);
77
78 OVS_NO_RETURN static void usage(void);
79 static void parse_options(int argc, char *argv[]);
80 static struct jsonrpc *open_jsonrpc(const char *server);
81 static void fetch_dbs(struct jsonrpc *, struct svec *dbs);
82
83 int
84 main(int argc, char *argv[])
85 {
86     const struct ovsdb_client_command *command;
87     char *database;
88     struct jsonrpc *rpc;
89
90     ovs_cmdl_proctitle_init(argc, argv);
91     set_program_name(argv[0]);
92     parse_options(argc, argv);
93     fatal_ignore_sigpipe();
94
95     daemon_become_new_user(false);
96     if (optind >= argc) {
97         ovs_fatal(0, "missing command name; use --help for help");
98     }
99
100     for (command = get_all_commands(); ; command++) {
101         if (!command->name) {
102             VLOG_FATAL("unknown command '%s'; use --help for help",
103                        argv[optind]);
104         } else if (!strcmp(command->name, argv[optind])) {
105             break;
106         }
107     }
108     optind++;
109
110     if (command->need != NEED_NONE) {
111         if (argc - optind > command->min_args
112             && (isalpha((unsigned char) argv[optind][0])
113                 && strchr(argv[optind], ':'))) {
114             rpc = open_jsonrpc(argv[optind++]);
115         } else {
116             char *sock = xasprintf("unix:%s/db.sock", ovs_rundir());
117             rpc = open_jsonrpc(sock);
118             free(sock);
119         }
120     } else {
121         rpc = NULL;
122     }
123
124     if (command->need == NEED_DATABASE) {
125         struct svec dbs;
126
127         svec_init(&dbs);
128         fetch_dbs(rpc, &dbs);
129         if (argc - optind > command->min_args
130             && svec_contains(&dbs, argv[optind])) {
131             database = xstrdup(argv[optind++]);
132         } else if (dbs.n == 1) {
133             database = xstrdup(dbs.names[0]);
134         } else if (svec_contains(&dbs, "Open_vSwitch")) {
135             database = xstrdup("Open_vSwitch");
136         } else {
137             jsonrpc_close(rpc);
138             ovs_fatal(0, "no default database for `%s' command, please "
139                       "specify a database name", command->name);
140         }
141         svec_destroy(&dbs);
142     } else {
143         database = NULL;
144     }
145
146     if (argc - optind < command->min_args ||
147         argc - optind > command->max_args) {
148         free(database);
149         VLOG_FATAL("invalid syntax for '%s' (use --help for help)",
150                     command->name);
151     }
152
153     command->handler(rpc, database, argc - optind, argv + optind);
154
155     free(database);
156     jsonrpc_close(rpc);
157
158     if (ferror(stdout)) {
159         VLOG_FATAL("write to stdout failed");
160     }
161     if (ferror(stderr)) {
162         VLOG_FATAL("write to stderr failed");
163     }
164
165     return 0;
166 }
167
168 static void
169 parse_options(int argc, char *argv[])
170 {
171     enum {
172         OPT_BOOTSTRAP_CA_CERT = UCHAR_MAX + 1,
173         OPT_TIMESTAMP,
174         VLOG_OPTION_ENUMS,
175         DAEMON_OPTION_ENUMS,
176         TABLE_OPTION_ENUMS
177     };
178     static const struct option long_options[] = {
179         {"help", no_argument, NULL, 'h'},
180         {"version", no_argument, NULL, 'V'},
181         {"timestamp", no_argument, NULL, OPT_TIMESTAMP},
182         VLOG_LONG_OPTIONS,
183         DAEMON_LONG_OPTIONS,
184 #ifdef HAVE_OPENSSL
185         {"bootstrap-ca-cert", required_argument, NULL, OPT_BOOTSTRAP_CA_CERT},
186         STREAM_SSL_LONG_OPTIONS,
187 #endif
188         TABLE_LONG_OPTIONS,
189         {NULL, 0, NULL, 0},
190     };
191     char *short_options = ovs_cmdl_long_options_to_short_options(long_options);
192
193     for (;;) {
194         int c;
195
196         c = getopt_long(argc, argv, short_options, long_options, NULL);
197         if (c == -1) {
198             break;
199         }
200
201         switch (c) {
202         case 'h':
203             usage();
204
205         case 'V':
206             ovs_print_version(0, 0);
207             exit(EXIT_SUCCESS);
208
209         VLOG_OPTION_HANDLERS
210         DAEMON_OPTION_HANDLERS
211         TABLE_OPTION_HANDLERS(&table_style)
212         STREAM_SSL_OPTION_HANDLERS
213
214         case OPT_BOOTSTRAP_CA_CERT:
215             stream_ssl_set_ca_cert_file(optarg, true);
216             break;
217
218         case OPT_TIMESTAMP:
219             timestamp = true;
220             break;
221
222         case '?':
223             exit(EXIT_FAILURE);
224
225         case 0:
226             /* getopt_long() already set the value for us. */
227             break;
228
229         default:
230             abort();
231         }
232     }
233     free(short_options);
234 }
235
236 static void
237 usage(void)
238 {
239     printf("%s: Open vSwitch database JSON-RPC client\n"
240            "usage: %s [OPTIONS] COMMAND [ARG...]\n"
241            "\nValid commands are:\n"
242            "\n  list-dbs [SERVER]\n"
243            "    list databases available on SERVER\n"
244            "\n  get-schema [SERVER] [DATABASE]\n"
245            "    retrieve schema for DATABASE from SERVER\n"
246            "\n  get-schema-version [SERVER] [DATABASE]\n"
247            "    retrieve schema for DATABASE from SERVER and report only its\n"
248            "    version number on stdout\n"
249            "\n  list-tables [SERVER] [DATABASE]\n"
250            "    list tables for DATABASE on SERVER\n"
251            "\n  list-columns [SERVER] [DATABASE] [TABLE]\n"
252            "    list columns in TABLE (or all tables) in DATABASE on SERVER\n"
253            "\n  transact [SERVER] TRANSACTION\n"
254            "    run TRANSACTION (a JSON array of operations) on SERVER\n"
255            "    and print the results as JSON on stdout\n"
256            "\n  monitor [SERVER] [DATABASE] TABLE [COLUMN,...]...\n"
257            "    monitor contents of COLUMNs in TABLE in DATABASE on SERVER.\n"
258            "    COLUMNs may include !initial, !insert, !delete, !modify\n"
259            "    to avoid seeing the specified kinds of changes.\n"
260            "\n  monitor [SERVER] [DATABASE] ALL\n"
261            "    monitor all changes to all columns in all tables\n"
262            "    in DATBASE on SERVER.\n"
263            "\n  monitor2 [SERVER] [DATABASE] ALL\n"
264            "    same usage as monitor, but uses \"monitor2\" method over"
265            "    the wire."
266            "\n  dump [SERVER] [DATABASE]\n"
267            "    dump contents of DATABASE on SERVER to stdout\n"
268            "\nThe default SERVER is unix:%s/db.sock.\n"
269            "The default DATABASE is Open_vSwitch.\n",
270            program_name, program_name, ovs_rundir());
271     stream_usage("SERVER", true, true, true);
272     printf("\nOutput formatting options:\n"
273            "  -f, --format=FORMAT         set output formatting to FORMAT\n"
274            "                              (\"table\", \"html\", \"csv\", "
275            "or \"json\")\n"
276            "  --no-headings               omit table heading row\n"
277            "  --pretty                    pretty-print JSON in output\n"
278            "  --timestamp                 timestamp \"monitor\" output");
279     daemon_usage();
280     vlog_usage();
281     printf("\nOther options:\n"
282            "  -h, --help                  display this help message\n"
283            "  -V, --version               display version information\n");
284     exit(EXIT_SUCCESS);
285 }
286 \f
287 static void
288 check_txn(int error, struct jsonrpc_msg **reply_)
289 {
290     struct jsonrpc_msg *reply = *reply_;
291
292     if (error) {
293         ovs_fatal(error, "transaction failed");
294     }
295
296     if (reply->error) {
297         ovs_fatal(error, "transaction returned error: %s",
298                   json_to_string(reply->error, table_style.json_flags));
299     }
300 }
301
302 static struct json *
303 parse_json(const char *s)
304 {
305     struct json *json = json_from_string(s);
306     if (json->type == JSON_STRING) {
307         ovs_fatal(0, "\"%s\": %s", s, json->u.string);
308     }
309     return json;
310 }
311
312 static struct jsonrpc *
313 open_jsonrpc(const char *server)
314 {
315     struct stream *stream;
316     int error;
317
318     error = stream_open_block(jsonrpc_stream_open(server, &stream,
319                               DSCP_DEFAULT), &stream);
320     if (error == EAFNOSUPPORT) {
321         struct pstream *pstream;
322
323         error = jsonrpc_pstream_open(server, &pstream, DSCP_DEFAULT);
324         if (error) {
325             ovs_fatal(error, "failed to connect or listen to \"%s\"", server);
326         }
327
328         VLOG_INFO("%s: waiting for connection...", server);
329         error = pstream_accept_block(pstream, &stream);
330         if (error) {
331             ovs_fatal(error, "failed to accept connection on \"%s\"", server);
332         }
333
334         pstream_close(pstream);
335     } else if (error) {
336         ovs_fatal(error, "failed to connect to \"%s\"", server);
337     }
338
339     return jsonrpc_open(stream);
340 }
341
342 static void
343 print_json(struct json *json)
344 {
345     char *string = json_to_string(json, table_style.json_flags);
346     fputs(string, stdout);
347     free(string);
348 }
349
350 static void
351 print_and_free_json(struct json *json)
352 {
353     print_json(json);
354     json_destroy(json);
355 }
356
357 static void
358 check_ovsdb_error(struct ovsdb_error *error)
359 {
360     if (error) {
361         ovs_fatal(0, "%s", ovsdb_error_to_string(error));
362     }
363 }
364
365 static struct ovsdb_schema *
366 fetch_schema(struct jsonrpc *rpc, const char *database)
367 {
368     struct jsonrpc_msg *request, *reply;
369     struct ovsdb_schema *schema;
370
371     request = jsonrpc_create_request("get_schema",
372                                      json_array_create_1(
373                                          json_string_create(database)),
374                                      NULL);
375     check_txn(jsonrpc_transact_block(rpc, request, &reply), &reply);
376     check_ovsdb_error(ovsdb_schema_from_json(reply->result, &schema));
377     jsonrpc_msg_destroy(reply);
378
379     return schema;
380 }
381
382 static void
383 fetch_dbs(struct jsonrpc *rpc, struct svec *dbs)
384 {
385     struct jsonrpc_msg *request, *reply;
386     size_t i;
387
388     request = jsonrpc_create_request("list_dbs", json_array_create_empty(),
389                                      NULL);
390
391     check_txn(jsonrpc_transact_block(rpc, request, &reply), &reply);
392     if (reply->result->type != JSON_ARRAY) {
393         ovs_fatal(0, "list_dbs response is not array");
394     }
395
396     for (i = 0; i < reply->result->u.array.n; i++) {
397         const struct json *name = reply->result->u.array.elems[i];
398
399         if (name->type != JSON_STRING) {
400             ovs_fatal(0, "list_dbs response %"PRIuSIZE" is not string", i);
401         }
402         svec_add(dbs, name->u.string);
403     }
404     jsonrpc_msg_destroy(reply);
405     svec_sort(dbs);
406 }
407 \f
408 static void
409 do_list_dbs(struct jsonrpc *rpc, const char *database OVS_UNUSED,
410             int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
411 {
412     const char *db_name;
413     struct svec dbs;
414     size_t i;
415
416     svec_init(&dbs);
417     fetch_dbs(rpc, &dbs);
418     SVEC_FOR_EACH (i, db_name, &dbs) {
419         puts(db_name);
420     }
421     svec_destroy(&dbs);
422 }
423
424 static void
425 do_get_schema(struct jsonrpc *rpc, const char *database,
426               int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
427 {
428     struct ovsdb_schema *schema = fetch_schema(rpc, database);
429     print_and_free_json(ovsdb_schema_to_json(schema));
430     ovsdb_schema_destroy(schema);
431 }
432
433 static void
434 do_get_schema_version(struct jsonrpc *rpc, const char *database,
435                       int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
436 {
437     struct ovsdb_schema *schema = fetch_schema(rpc, database);
438     puts(schema->version);
439     ovsdb_schema_destroy(schema);
440 }
441
442 static void
443 do_list_tables(struct jsonrpc *rpc, const char *database,
444                int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
445 {
446     struct ovsdb_schema *schema;
447     struct shash_node *node;
448     struct table t;
449
450     schema = fetch_schema(rpc, database);
451     table_init(&t);
452     table_add_column(&t, "Table");
453     SHASH_FOR_EACH (node, &schema->tables) {
454         struct ovsdb_table_schema *ts = node->data;
455
456         table_add_row(&t);
457         table_add_cell(&t)->text = xstrdup(ts->name);
458     }
459     ovsdb_schema_destroy(schema);
460     table_print(&t, &table_style);
461     table_destroy(&t);
462 }
463
464 static void
465 do_list_columns(struct jsonrpc *rpc, const char *database,
466                 int argc OVS_UNUSED, char *argv[])
467 {
468     const char *table_name = argv[0];
469     struct ovsdb_schema *schema;
470     struct shash_node *table_node;
471     struct table t;
472
473     schema = fetch_schema(rpc, database);
474     table_init(&t);
475     if (!table_name) {
476         table_add_column(&t, "Table");
477     }
478     table_add_column(&t, "Column");
479     table_add_column(&t, "Type");
480     SHASH_FOR_EACH (table_node, &schema->tables) {
481         struct ovsdb_table_schema *ts = table_node->data;
482
483         if (!table_name || !strcmp(table_name, ts->name)) {
484             struct shash_node *column_node;
485
486             SHASH_FOR_EACH (column_node, &ts->columns) {
487                 const struct ovsdb_column *column = column_node->data;
488
489                 table_add_row(&t);
490                 if (!table_name) {
491                     table_add_cell(&t)->text = xstrdup(ts->name);
492                 }
493                 table_add_cell(&t)->text = xstrdup(column->name);
494                 table_add_cell(&t)->json = ovsdb_type_to_json(&column->type);
495             }
496         }
497     }
498     ovsdb_schema_destroy(schema);
499     table_print(&t, &table_style);
500     table_destroy(&t);
501 }
502
503 static void
504 do_transact(struct jsonrpc *rpc, const char *database OVS_UNUSED,
505             int argc OVS_UNUSED, char *argv[])
506 {
507     struct jsonrpc_msg *request, *reply;
508     struct json *transaction;
509
510     transaction = parse_json(argv[0]);
511
512     request = jsonrpc_create_request("transact", transaction, NULL);
513     check_txn(jsonrpc_transact_block(rpc, request, &reply), &reply);
514     print_json(reply->result);
515     putchar('\n');
516     jsonrpc_msg_destroy(reply);
517 }
518 \f
519 /* "monitor" command. */
520
521 struct monitored_table {
522     struct ovsdb_table_schema *table;
523     struct ovsdb_column_set columns;
524 };
525
526 static void
527 monitor_print_row(struct json *row, const char *type, const char *uuid,
528                   const struct ovsdb_column_set *columns, struct table *t)
529 {
530     size_t i;
531
532     if (!row) {
533         ovs_error(0, "missing %s row", type);
534         return;
535     } else if (row->type != JSON_OBJECT) {
536         ovs_error(0, "<row> is not object");
537         return;
538     }
539
540     table_add_row(t);
541     table_add_cell(t)->text = xstrdup(uuid);
542     table_add_cell(t)->text = xstrdup(type);
543     for (i = 0; i < columns->n_columns; i++) {
544         const struct ovsdb_column *column = columns->columns[i];
545         struct json *value = shash_find_data(json_object(row), column->name);
546         struct cell *cell = table_add_cell(t);
547         if (value) {
548             cell->json = json_clone(value);
549             cell->type = &column->type;
550         }
551     }
552 }
553
554 static void
555 monitor_print_table(struct json *table_update,
556                     const struct monitored_table *mt, char *caption,
557                     bool initial)
558 {
559     const struct ovsdb_table_schema *table = mt->table;
560     const struct ovsdb_column_set *columns = &mt->columns;
561     struct shash_node *node;
562     struct table t;
563     size_t i;
564
565     if (table_update->type != JSON_OBJECT) {
566         ovs_error(0, "<table-update> for table %s is not object", table->name);
567         return;
568     }
569
570     table_init(&t);
571     table_set_timestamp(&t, timestamp);
572     table_set_caption(&t, caption);
573
574     table_add_column(&t, "row");
575     table_add_column(&t, "action");
576     for (i = 0; i < columns->n_columns; i++) {
577         table_add_column(&t, "%s", columns->columns[i]->name);
578     }
579     SHASH_FOR_EACH (node, json_object(table_update)) {
580         struct json *row_update = node->data;
581         struct json *old, *new;
582
583         if (row_update->type != JSON_OBJECT) {
584             ovs_error(0, "<row-update> is not object");
585             continue;
586         }
587         old = shash_find_data(json_object(row_update), "old");
588         new = shash_find_data(json_object(row_update), "new");
589         if (initial) {
590             monitor_print_row(new, "initial", node->name, columns, &t);
591         } else if (!old) {
592             monitor_print_row(new, "insert", node->name, columns, &t);
593         } else if (!new) {
594             monitor_print_row(old, "delete", node->name, columns, &t);
595         } else {
596             monitor_print_row(old, "old", node->name, columns, &t);
597             monitor_print_row(new, "new", "", columns, &t);
598         }
599     }
600     table_print(&t, &table_style);
601     table_destroy(&t);
602 }
603
604 static void
605 monitor_print(struct json *table_updates,
606               const struct monitored_table *mts, size_t n_mts,
607               bool initial)
608 {
609     size_t i;
610
611     if (table_updates->type != JSON_OBJECT) {
612         ovs_error(0, "<table-updates> is not object");
613         return;
614     }
615
616     for (i = 0; i < n_mts; i++) {
617         const struct monitored_table *mt = &mts[i];
618         struct json *table_update = shash_find_data(json_object(table_updates),
619                                                     mt->table->name);
620         if (table_update) {
621             monitor_print_table(table_update, mt,
622                                 n_mts > 1 ? xstrdup(mt->table->name) : NULL,
623                                 initial);
624         }
625     }
626 }
627
628 static void
629 monitor2_print_row(struct json *row, const char *type, const char *uuid,
630                    const struct ovsdb_column_set *columns, struct table *t)
631 {
632     if (!strcmp(type, "delete")) {
633         if (row->type != JSON_NULL) {
634             ovs_error(0, "delete method does not expect <row>");
635             return;
636         }
637
638         table_add_row(t);
639         table_add_cell(t)->text = xstrdup(uuid);
640         table_add_cell(t)->text = xstrdup(type);
641     } else {
642         if (!row || row->type != JSON_OBJECT) {
643             ovs_error(0, "<row> is not object");
644             return;
645         }
646         monitor_print_row(row, type, uuid, columns, t);
647     }
648 }
649
650 static void
651 monitor2_print_table(struct json *table_update2,
652                     const struct monitored_table *mt, char *caption)
653 {
654     const struct ovsdb_table_schema *table = mt->table;
655     const struct ovsdb_column_set *columns = &mt->columns;
656     struct shash_node *node;
657     struct table t;
658
659     if (table_update2->type != JSON_OBJECT) {
660         ovs_error(0, "<table-update> for table %s is not object", table->name);
661         return;
662     }
663
664     table_init(&t);
665     table_set_timestamp(&t, timestamp);
666     table_set_caption(&t, caption);
667
668     table_add_column(&t, "row");
669     table_add_column(&t, "action");
670     for (size_t i = 0; i < columns->n_columns; i++) {
671         table_add_column(&t, "%s", columns->columns[i]->name);
672     }
673     SHASH_FOR_EACH (node, json_object(table_update2)) {
674         struct json *row_update2 = node->data;
675         const char *operation;
676         struct json *row;
677         const char *ops[] = {"delete", "initial", "modify", "insert"};
678
679         if (row_update2->type != JSON_OBJECT) {
680             ovs_error(0, "<row-update2> is not object");
681             continue;
682         }
683
684         /* row_update2 contains one of objects indexed by ops[] */
685         for (int i = 0; i < ARRAY_SIZE(ops); i++) {
686             operation = ops[i];
687             row = shash_find_data(json_object(row_update2), operation);
688
689             if (row) {
690                 monitor2_print_row(row, operation, node->name, columns, &t);
691                 break;
692             }
693         }
694     }
695     table_print(&t, &table_style);
696     table_destroy(&t);
697 }
698
699 static void
700 monitor2_print(struct json *table_updates2,
701                const struct monitored_table *mts, size_t n_mts)
702 {
703     size_t i;
704
705     if (table_updates2->type != JSON_OBJECT) {
706         ovs_error(0, "<table-updates2> is not object");
707         return;
708     }
709
710     for (i = 0; i < n_mts; i++) {
711         const struct monitored_table *mt = &mts[i];
712         struct json *table_update = shash_find_data(
713                                         json_object(table_updates2),
714                                         mt->table->name);
715         if (table_update) {
716             monitor2_print_table(table_update, mt,
717                                 n_mts > 1 ? xstrdup(mt->table->name) : NULL);
718         }
719     }
720 }
721
722 static void
723 add_column(const char *server, const struct ovsdb_column *column,
724            struct ovsdb_column_set *columns, struct json *columns_json)
725 {
726     if (ovsdb_column_set_contains(columns, column->index)) {
727         ovs_fatal(0, "%s: column \"%s\" mentioned multiple times",
728                   server, column->name);
729     }
730     ovsdb_column_set_add(columns, column);
731     json_array_add(columns_json, json_string_create(column->name));
732 }
733
734 static struct json *
735 parse_monitor_columns(char *arg, const char *server, const char *database,
736                       const struct ovsdb_table_schema *table,
737                       struct ovsdb_column_set *columns)
738 {
739     bool initial, insert, delete, modify;
740     struct json *mr, *columns_json;
741     char *save_ptr = NULL;
742     char *token;
743
744     mr = json_object_create();
745     columns_json = json_array_create_empty();
746     json_object_put(mr, "columns", columns_json);
747
748     initial = insert = delete = modify = true;
749     for (token = strtok_r(arg, ",", &save_ptr); token != NULL;
750          token = strtok_r(NULL, ",", &save_ptr)) {
751         if (!strcmp(token, "!initial")) {
752             initial = false;
753         } else if (!strcmp(token, "!insert")) {
754             insert = false;
755         } else if (!strcmp(token, "!delete")) {
756             delete = false;
757         } else if (!strcmp(token, "!modify")) {
758             modify = false;
759         } else {
760             const struct ovsdb_column *column;
761
762             column = ovsdb_table_schema_get_column(table, token);
763             if (!column) {
764                 ovs_fatal(0, "%s: table \"%s\" in %s does not have a "
765                           "column named \"%s\"",
766                           server, table->name, database, token);
767             }
768             add_column(server, column, columns, columns_json);
769         }
770     }
771
772     if (columns_json->u.array.n == 0) {
773         const struct shash_node **nodes;
774         size_t i, n;
775
776         n = shash_count(&table->columns);
777         nodes = shash_sort(&table->columns);
778         for (i = 0; i < n; i++) {
779             const struct ovsdb_column *column = nodes[i]->data;
780             if (column->index != OVSDB_COL_UUID
781                 && column->index != OVSDB_COL_VERSION) {
782                 add_column(server, column, columns, columns_json);
783             }
784         }
785         free(nodes);
786
787         add_column(server, ovsdb_table_schema_get_column(table, "_version"),
788                    columns, columns_json);
789     }
790
791     if (!initial || !insert || !delete || !modify) {
792         struct json *select = json_object_create();
793         json_object_put(select, "initial", json_boolean_create(initial));
794         json_object_put(select, "insert", json_boolean_create(insert));
795         json_object_put(select, "delete", json_boolean_create(delete));
796         json_object_put(select, "modify", json_boolean_create(modify));
797         json_object_put(mr, "select", select);
798     }
799
800     return mr;
801 }
802
803 static void
804 ovsdb_client_exit(struct unixctl_conn *conn, int argc OVS_UNUSED,
805                   const char *argv[] OVS_UNUSED, void *exiting_)
806 {
807     bool *exiting = exiting_;
808     *exiting = true;
809     unixctl_command_reply(conn, NULL);
810 }
811
812 static void
813 ovsdb_client_block(struct unixctl_conn *conn, int argc OVS_UNUSED,
814                    const char *argv[] OVS_UNUSED, void *blocked_)
815 {
816     bool *blocked = blocked_;
817
818     if (!*blocked) {
819         *blocked = true;
820         unixctl_command_reply(conn, NULL);
821     } else {
822         unixctl_command_reply(conn, "already blocking");
823     }
824 }
825
826 static void
827 ovsdb_client_unblock(struct unixctl_conn *conn, int argc OVS_UNUSED,
828                      const char *argv[] OVS_UNUSED, void *blocked_)
829 {
830     bool *blocked = blocked_;
831
832     if (*blocked) {
833         *blocked = false;
834         unixctl_command_reply(conn, NULL);
835     } else {
836         unixctl_command_reply(conn, "already unblocked");
837     }
838 }
839
840 static void
841 add_monitored_table(int argc, char *argv[],
842                     const char *server, const char *database,
843                     struct ovsdb_table_schema *table,
844                     struct json *monitor_requests,
845                     struct monitored_table **mts,
846                     size_t *n_mts, size_t *allocated_mts)
847 {
848     struct json *monitor_request_array;
849     struct monitored_table *mt;
850
851     if (*n_mts >= *allocated_mts) {
852         *mts = x2nrealloc(*mts, allocated_mts, sizeof **mts);
853     }
854     mt = &(*mts)[(*n_mts)++];
855     mt->table = table;
856     ovsdb_column_set_init(&mt->columns);
857
858     monitor_request_array = json_array_create_empty();
859     if (argc > 1) {
860         int i;
861
862         for (i = 1; i < argc; i++) {
863             json_array_add(
864                 monitor_request_array,
865                 parse_monitor_columns(argv[i], server, database, table,
866                                       &mt->columns));
867         }
868     } else {
869         /* Allocate a writable empty string since parse_monitor_columns()
870          * is going to strtok() it and that's risky with literal "". */
871         char empty[] = "";
872         json_array_add(
873             monitor_request_array,
874             parse_monitor_columns(empty, server, database,
875                                   table, &mt->columns));
876     }
877
878     json_object_put(monitor_requests, table->name, monitor_request_array);
879 }
880
881 static void
882 destroy_monitored_table(struct monitored_table *mts, size_t n)
883 {
884     int i;
885
886     for (i = 0; i < n; i++) {
887         struct monitored_table *mt = &mts[i];
888         ovsdb_column_set_destroy(&mt->columns);
889     }
890
891     free(mts);
892 }
893
894 static void
895 do_monitor__(struct jsonrpc *rpc, const char *database,
896              enum ovsdb_monitor_version version,
897              int argc, char *argv[])
898 {
899     const char *server = jsonrpc_get_name(rpc);
900     const char *table_name = argv[0];
901     struct unixctl_server *unixctl;
902     struct ovsdb_schema *schema;
903     struct jsonrpc_msg *request;
904     struct json *monitor, *monitor_requests, *request_id;
905     bool exiting = false;
906     bool blocked = false;
907
908     struct monitored_table *mts;
909     size_t n_mts, allocated_mts;
910
911     ovs_assert(version < OVSDB_MONITOR_VERSION_MAX);
912
913     daemon_save_fd(STDOUT_FILENO);
914     daemonize_start(false);
915     if (get_detach()) {
916         int error;
917
918         error = unixctl_server_create(NULL, &unixctl);
919         if (error) {
920             ovs_fatal(error, "failed to create unixctl server");
921         }
922
923         unixctl_command_register("exit", "", 0, 0,
924                                  ovsdb_client_exit, &exiting);
925         unixctl_command_register("ovsdb-client/block", "", 0, 0,
926                                  ovsdb_client_block, &blocked);
927         unixctl_command_register("ovsdb-client/unblock", "", 0, 0,
928                                  ovsdb_client_unblock, &blocked);
929     } else {
930         unixctl = NULL;
931     }
932
933     schema = fetch_schema(rpc, database);
934
935     monitor_requests = json_object_create();
936
937     mts = NULL;
938     n_mts = allocated_mts = 0;
939     if (strcmp(table_name, "ALL")) {
940         struct ovsdb_table_schema *table;
941
942         table = shash_find_data(&schema->tables, table_name);
943         if (!table) {
944             ovs_fatal(0, "%s: %s does not have a table named \"%s\"",
945                       server, database, table_name);
946         }
947
948         add_monitored_table(argc, argv, server, database, table,
949                             monitor_requests, &mts, &n_mts, &allocated_mts);
950     } else {
951         size_t n = shash_count(&schema->tables);
952         const struct shash_node **nodes = shash_sort(&schema->tables);
953         size_t i;
954
955         for (i = 0; i < n; i++) {
956             struct ovsdb_table_schema *table = nodes[i]->data;
957
958             add_monitored_table(argc, argv, server, database, table,
959                                 monitor_requests,
960                                 &mts, &n_mts, &allocated_mts);
961         }
962         free(nodes);
963     }
964
965     monitor = json_array_create_3(json_string_create(database),
966                                   json_null_create(), monitor_requests);
967     const char *method = version == OVSDB_MONITOR_V2 ? "monitor2"
968                                                      : "monitor";
969
970     request = jsonrpc_create_request(method, monitor, NULL);
971     request_id = json_clone(request->id);
972     jsonrpc_send(rpc, request);
973
974     for (;;) {
975         unixctl_server_run(unixctl);
976         while (!blocked) {
977             struct jsonrpc_msg *msg;
978             int error;
979
980             error = jsonrpc_recv(rpc, &msg);
981             if (error == EAGAIN) {
982                 break;
983             } else if (error) {
984                 ovs_fatal(error, "%s: receive failed", server);
985             }
986
987             if (msg->type == JSONRPC_REQUEST && !strcmp(msg->method, "echo")) {
988                 jsonrpc_send(rpc, jsonrpc_create_reply(json_clone(msg->params),
989                                                        msg->id));
990             } else if (msg->type == JSONRPC_REPLY
991                        && json_equal(msg->id, request_id)) {
992                 switch(version) {
993                 case OVSDB_MONITOR_V1:
994                     monitor_print(msg->result, mts, n_mts, true);
995                     break;
996                 case OVSDB_MONITOR_V2:
997                     monitor2_print(msg->result, mts, n_mts);
998                     break;
999                 case OVSDB_MONITOR_VERSION_MAX:
1000                 default:
1001                     OVS_NOT_REACHED();
1002                 }
1003                 fflush(stdout);
1004                 daemonize_complete();
1005             } else if (msg->type == JSONRPC_NOTIFY
1006                        && !strcmp(msg->method, "update")) {
1007                 struct json *params = msg->params;
1008                 if (params->type == JSON_ARRAY
1009                     && params->u.array.n == 2
1010                     && params->u.array.elems[0]->type == JSON_NULL) {
1011                     monitor_print(params->u.array.elems[1], mts, n_mts, false);
1012                     fflush(stdout);
1013                 }
1014             } else if (msg->type == JSONRPC_NOTIFY
1015                        && version == OVSDB_MONITOR_V2
1016                        && !strcmp(msg->method, "update2")) {
1017                 struct json *params = msg->params;
1018                 if (params->type == JSON_ARRAY
1019                     && params->u.array.n == 2
1020                     && params->u.array.elems[0]->type == JSON_NULL) {
1021                     monitor2_print(params->u.array.elems[1], mts, n_mts);
1022                     fflush(stdout);
1023                 }
1024             }
1025             jsonrpc_msg_destroy(msg);
1026         }
1027
1028         if (exiting) {
1029             break;
1030         }
1031
1032         jsonrpc_run(rpc);
1033         jsonrpc_wait(rpc);
1034         if (!blocked) {
1035             jsonrpc_recv_wait(rpc);
1036         }
1037         unixctl_server_wait(unixctl);
1038         poll_block();
1039     }
1040
1041     json_destroy(request_id);
1042     unixctl_server_destroy(unixctl);
1043     ovsdb_schema_destroy(schema);
1044     destroy_monitored_table(mts, n_mts);
1045 }
1046
1047 static void
1048 do_monitor(struct jsonrpc *rpc, const char *database,
1049            int argc, char *argv[])
1050 {
1051     do_monitor__(rpc, database, OVSDB_MONITOR_V1, argc, argv);
1052 }
1053
1054 static void
1055 do_monitor2(struct jsonrpc *rpc, const char *database,
1056            int argc, char *argv[])
1057 {
1058     do_monitor__(rpc, database, OVSDB_MONITOR_V2, argc, argv);
1059 }
1060
1061 struct dump_table_aux {
1062     struct ovsdb_datum **data;
1063     const struct ovsdb_column **columns;
1064     size_t n_columns;
1065 };
1066
1067 static int
1068 compare_data(size_t a_y, size_t b_y, size_t x,
1069              const struct dump_table_aux *aux)
1070 {
1071     return ovsdb_datum_compare_3way(&aux->data[a_y][x],
1072                                     &aux->data[b_y][x],
1073                                     &aux->columns[x]->type);
1074 }
1075
1076 static int
1077 compare_rows(size_t a_y, size_t b_y, void *aux_)
1078 {
1079     struct dump_table_aux *aux = aux_;
1080     size_t x;
1081
1082     /* Skip UUID columns on the first pass, since their values tend to be
1083      * random and make our results less reproducible. */
1084     for (x = 0; x < aux->n_columns; x++) {
1085         if (aux->columns[x]->type.key.type != OVSDB_TYPE_UUID) {
1086             int cmp = compare_data(a_y, b_y, x, aux);
1087             if (cmp) {
1088                 return cmp;
1089             }
1090         }
1091     }
1092
1093     /* Use UUID columns as tie-breakers. */
1094     for (x = 0; x < aux->n_columns; x++) {
1095         if (aux->columns[x]->type.key.type == OVSDB_TYPE_UUID) {
1096             int cmp = compare_data(a_y, b_y, x, aux);
1097             if (cmp) {
1098                 return cmp;
1099             }
1100         }
1101     }
1102
1103     return 0;
1104 }
1105
1106 static void
1107 swap_rows(size_t a_y, size_t b_y, void *aux_)
1108 {
1109     struct dump_table_aux *aux = aux_;
1110     struct ovsdb_datum *tmp = aux->data[a_y];
1111     aux->data[a_y] = aux->data[b_y];
1112     aux->data[b_y] = tmp;
1113 }
1114
1115 static int
1116 compare_columns(const void *a_, const void *b_)
1117 {
1118     const struct ovsdb_column *const *ap = a_;
1119     const struct ovsdb_column *const *bp = b_;
1120     const struct ovsdb_column *a = *ap;
1121     const struct ovsdb_column *b = *bp;
1122
1123     return strcmp(a->name, b->name);
1124 }
1125
1126 static void
1127 dump_table(const char *table_name, const struct shash *cols,
1128            struct json_array *rows)
1129 {
1130     const struct ovsdb_column **columns;
1131     size_t n_columns;
1132
1133     struct ovsdb_datum **data;
1134
1135     struct dump_table_aux aux;
1136     struct shash_node *node;
1137     struct table t;
1138     size_t x, y;
1139
1140     /* Sort columns by name, for reproducibility. */
1141     columns = xmalloc(shash_count(cols) * sizeof *columns);
1142     n_columns = 0;
1143     SHASH_FOR_EACH (node, cols) {
1144         struct ovsdb_column *column = node->data;
1145         if (strcmp(column->name, "_version")) {
1146             columns[n_columns++] = column;
1147         }
1148     }
1149     qsort(columns, n_columns, sizeof *columns, compare_columns);
1150
1151     /* Extract data from table. */
1152     data = xmalloc(rows->n * sizeof *data);
1153     for (y = 0; y < rows->n; y++) {
1154         struct shash *row;
1155
1156         if (rows->elems[y]->type != JSON_OBJECT) {
1157             ovs_fatal(0,  "row %"PRIuSIZE" in table %s response is not a JSON object: "
1158                       "%s", y, table_name, json_to_string(rows->elems[y], 0));
1159         }
1160         row = json_object(rows->elems[y]);
1161
1162         data[y] = xmalloc(n_columns * sizeof **data);
1163         for (x = 0; x < n_columns; x++) {
1164             const struct json *json = shash_find_data(row, columns[x]->name);
1165             if (!json) {
1166                 ovs_fatal(0, "row %"PRIuSIZE" in table %s response lacks %s column",
1167                           y, table_name, columns[x]->name);
1168             }
1169
1170             check_ovsdb_error(ovsdb_datum_from_json(&data[y][x],
1171                                                     &columns[x]->type,
1172                                                     json, NULL));
1173         }
1174     }
1175
1176     /* Sort rows by column values, for reproducibility. */
1177     aux.data = data;
1178     aux.columns = columns;
1179     aux.n_columns = n_columns;
1180     sort(rows->n, compare_rows, swap_rows, &aux);
1181
1182     /* Add column headings. */
1183     table_init(&t);
1184     table_set_caption(&t, xasprintf("%s table", table_name));
1185     for (x = 0; x < n_columns; x++) {
1186         table_add_column(&t, "%s", columns[x]->name);
1187     }
1188
1189     /* Print rows. */
1190     for (y = 0; y < rows->n; y++) {
1191         table_add_row(&t);
1192         for (x = 0; x < n_columns; x++) {
1193             struct cell *cell = table_add_cell(&t);
1194             cell->json = ovsdb_datum_to_json(&data[y][x], &columns[x]->type);
1195             cell->type = &columns[x]->type;
1196             ovsdb_datum_destroy(&data[y][x], &columns[x]->type);
1197         }
1198         free(data[y]);
1199     }
1200     table_print(&t, &table_style);
1201     table_destroy(&t);
1202
1203     free(data);
1204     free(columns);
1205 }
1206
1207 static void
1208 do_dump(struct jsonrpc *rpc, const char *database,
1209         int argc, char *argv[])
1210 {
1211     struct jsonrpc_msg *request, *reply;
1212     struct ovsdb_schema *schema;
1213     struct json *transaction;
1214
1215     const struct shash_node *node, **tables;
1216     size_t n_tables;
1217     struct ovsdb_table_schema *tschema;
1218     const struct shash *columns;
1219     struct shash custom_columns;
1220
1221     size_t i;
1222
1223     shash_init(&custom_columns);
1224     schema = fetch_schema(rpc, database);
1225     if (argc) {
1226         node = shash_find(&schema->tables, argv[0]);
1227         if (!node) {
1228             ovs_fatal(0, "No table \"%s\" found.", argv[0]);
1229         }
1230         tables = xmemdup(&node, sizeof(&node));
1231         n_tables = 1;
1232         tschema = tables[0]->data;
1233         for (i = 1; i < argc; i++) {
1234             node = shash_find(&tschema->columns, argv[i]);
1235             if (!node) {
1236                 ovs_fatal(0, "Table \"%s\" has no column %s.", argv[0], argv[1]);
1237             }
1238             shash_add(&custom_columns, argv[1], node->data);
1239         }
1240     } else {
1241         tables = shash_sort(&schema->tables);
1242         n_tables = shash_count(&schema->tables);
1243     }
1244
1245     /* Construct transaction to retrieve entire database. */
1246     transaction = json_array_create_1(json_string_create(database));
1247     for (i = 0; i < n_tables; i++) {
1248         const struct ovsdb_table_schema *ts = tables[i]->data;
1249         struct json *op, *jcolumns;
1250
1251         if (argc > 1) {
1252             columns = &custom_columns;
1253         } else {
1254             columns = &ts->columns;
1255         }
1256         jcolumns = json_array_create_empty();
1257         SHASH_FOR_EACH (node, columns) {
1258             const struct ovsdb_column *column = node->data;
1259
1260             if (strcmp(column->name, "_version")) {
1261                 json_array_add(jcolumns, json_string_create(column->name));
1262             }
1263         }
1264
1265         op = json_object_create();
1266         json_object_put_string(op, "op", "select");
1267         json_object_put_string(op, "table", tables[i]->name);
1268         json_object_put(op, "where", json_array_create_empty());
1269         json_object_put(op, "columns", jcolumns);
1270         json_array_add(transaction, op);
1271     }
1272
1273     /* Send request, get reply. */
1274     request = jsonrpc_create_request("transact", transaction, NULL);
1275     check_txn(jsonrpc_transact_block(rpc, request, &reply), &reply);
1276
1277     /* Print database contents. */
1278     if (reply->result->type != JSON_ARRAY
1279         || reply->result->u.array.n != n_tables) {
1280         ovs_fatal(0, "reply is not array of %"PRIuSIZE" elements: %s",
1281                   n_tables, json_to_string(reply->result, 0));
1282     }
1283     for (i = 0; i < n_tables; i++) {
1284         const struct ovsdb_table_schema *ts = tables[i]->data;
1285         const struct json *op_result = reply->result->u.array.elems[i];
1286         struct json *rows;
1287
1288         if (op_result->type != JSON_OBJECT
1289             || !(rows = shash_find_data(json_object(op_result), "rows"))
1290             || rows->type != JSON_ARRAY) {
1291             ovs_fatal(0, "%s table reply is not an object with a \"rows\" "
1292                       "member array: %s",
1293                       ts->name, json_to_string(op_result, 0));
1294         }
1295
1296         if (argc > 1) {
1297             dump_table(tables[i]->name, &custom_columns, &rows->u.array);
1298         } else {
1299             dump_table(tables[i]->name, &ts->columns, &rows->u.array);
1300         }
1301     }
1302
1303     jsonrpc_msg_destroy(reply);
1304     shash_destroy(&custom_columns);
1305     free(tables);
1306     ovsdb_schema_destroy(schema);
1307 }
1308
1309 static void
1310 do_help(struct jsonrpc *rpc OVS_UNUSED, const char *database OVS_UNUSED,
1311         int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
1312 {
1313     usage();
1314 }
1315
1316 /* All command handlers (except for "help") are expected to take an optional
1317  * server socket name (e.g. "unix:...") as their first argument.  The socket
1318  * name argument must be included in max_args (but left out of min_args).  The
1319  * command name and socket name are not included in the arguments passed to the
1320  * handler: the argv[0] passed to the handler is the first argument after the
1321  * optional server socket name.  The connection to the server is available as
1322  * global variable 'rpc'. */
1323 static const struct ovsdb_client_command all_commands[] = {
1324     { "list-dbs",           NEED_RPC,      0, 0,       do_list_dbs },
1325     { "get-schema",         NEED_DATABASE, 0, 0,       do_get_schema },
1326     { "get-schema-version", NEED_DATABASE, 0, 0,       do_get_schema_version },
1327     { "list-tables",        NEED_DATABASE, 0, 0,       do_list_tables },
1328     { "list-columns",       NEED_DATABASE, 0, 1,       do_list_columns },
1329     { "transact",           NEED_RPC,      1, 1,       do_transact },
1330     { "monitor",            NEED_DATABASE, 1, INT_MAX, do_monitor },
1331     { "monitor2",           NEED_DATABASE, 1, INT_MAX, do_monitor2 },
1332     { "dump",               NEED_DATABASE, 0, INT_MAX, do_dump },
1333     { "help",               NEED_NONE,     0, INT_MAX, do_help },
1334
1335     { NULL,                 0,             0, 0,       NULL },
1336 };
1337
1338 static const struct ovsdb_client_command *get_all_commands(void)
1339 {
1340     return all_commands;
1341 }