netdev-dpdk: fix mbuf leaks
[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 "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     size_t i;
659
660     if (table_update2->type != JSON_OBJECT) {
661         ovs_error(0, "<table-update> for table %s is not object", table->name);
662         return;
663     }
664
665     table_init(&t);
666     table_set_timestamp(&t, timestamp);
667     table_set_caption(&t, caption);
668
669     table_add_column(&t, "row");
670     table_add_column(&t, "action");
671     for (i = 0; i < columns->n_columns; i++) {
672         table_add_column(&t, "%s", columns->columns[i]->name);
673     }
674     SHASH_FOR_EACH (node, json_object(table_update2)) {
675         struct json *row_update2 = node->data;
676         const char *operation;
677         struct json *row;
678         const char *ops[] = {"delete", "initial", "modify", "insert"};
679
680         if (row_update2->type != JSON_OBJECT) {
681             ovs_error(0, "<row-update2> is not object");
682             continue;
683         }
684
685         /* row_update2 contains one of objects indexed by ops[] */
686         for (int i = 0; i < ARRAY_SIZE(ops); i++) {
687             operation = ops[i];
688             row = shash_find_data(json_object(row_update2), operation);
689
690             if (row) {
691                 monitor2_print_row(row, operation, node->name, columns, &t);
692                 break;
693             }
694         }
695     }
696     table_print(&t, &table_style);
697     table_destroy(&t);
698 }
699
700 static void
701 monitor2_print(struct json *table_updates2,
702                const struct monitored_table *mts, size_t n_mts)
703 {
704     size_t i;
705
706     if (table_updates2->type != JSON_OBJECT) {
707         ovs_error(0, "<table-updates2> is not object");
708         return;
709     }
710
711     for (i = 0; i < n_mts; i++) {
712         const struct monitored_table *mt = &mts[i];
713         struct json *table_update = shash_find_data(
714                                         json_object(table_updates2),
715                                         mt->table->name);
716         if (table_update) {
717             monitor2_print_table(table_update, mt,
718                                 n_mts > 1 ? xstrdup(mt->table->name) : NULL);
719         }
720     }
721 }
722
723 static void
724 add_column(const char *server, const struct ovsdb_column *column,
725            struct ovsdb_column_set *columns, struct json *columns_json)
726 {
727     if (ovsdb_column_set_contains(columns, column->index)) {
728         ovs_fatal(0, "%s: column \"%s\" mentioned multiple times",
729                   server, column->name);
730     }
731     ovsdb_column_set_add(columns, column);
732     json_array_add(columns_json, json_string_create(column->name));
733 }
734
735 static struct json *
736 parse_monitor_columns(char *arg, const char *server, const char *database,
737                       const struct ovsdb_table_schema *table,
738                       struct ovsdb_column_set *columns)
739 {
740     bool initial, insert, delete, modify;
741     struct json *mr, *columns_json;
742     char *save_ptr = NULL;
743     char *token;
744
745     mr = json_object_create();
746     columns_json = json_array_create_empty();
747     json_object_put(mr, "columns", columns_json);
748
749     initial = insert = delete = modify = true;
750     for (token = strtok_r(arg, ",", &save_ptr); token != NULL;
751          token = strtok_r(NULL, ",", &save_ptr)) {
752         if (!strcmp(token, "!initial")) {
753             initial = false;
754         } else if (!strcmp(token, "!insert")) {
755             insert = false;
756         } else if (!strcmp(token, "!delete")) {
757             delete = false;
758         } else if (!strcmp(token, "!modify")) {
759             modify = false;
760         } else {
761             const struct ovsdb_column *column;
762
763             column = ovsdb_table_schema_get_column(table, token);
764             if (!column) {
765                 ovs_fatal(0, "%s: table \"%s\" in %s does not have a "
766                           "column named \"%s\"",
767                           server, table->name, database, token);
768             }
769             add_column(server, column, columns, columns_json);
770         }
771     }
772
773     if (columns_json->u.array.n == 0) {
774         const struct shash_node **nodes;
775         size_t i, n;
776
777         n = shash_count(&table->columns);
778         nodes = shash_sort(&table->columns);
779         for (i = 0; i < n; i++) {
780             const struct ovsdb_column *column = nodes[i]->data;
781             if (column->index != OVSDB_COL_UUID
782                 && column->index != OVSDB_COL_VERSION) {
783                 add_column(server, column, columns, columns_json);
784             }
785         }
786         free(nodes);
787
788         add_column(server, ovsdb_table_schema_get_column(table, "_version"),
789                    columns, columns_json);
790     }
791
792     if (!initial || !insert || !delete || !modify) {
793         struct json *select = json_object_create();
794         json_object_put(select, "initial", json_boolean_create(initial));
795         json_object_put(select, "insert", json_boolean_create(insert));
796         json_object_put(select, "delete", json_boolean_create(delete));
797         json_object_put(select, "modify", json_boolean_create(modify));
798         json_object_put(mr, "select", select);
799     }
800
801     return mr;
802 }
803
804 static void
805 ovsdb_client_exit(struct unixctl_conn *conn, int argc OVS_UNUSED,
806                   const char *argv[] OVS_UNUSED, void *exiting_)
807 {
808     bool *exiting = exiting_;
809     *exiting = true;
810     unixctl_command_reply(conn, NULL);
811 }
812
813 static void
814 ovsdb_client_block(struct unixctl_conn *conn, int argc OVS_UNUSED,
815                    const char *argv[] OVS_UNUSED, void *blocked_)
816 {
817     bool *blocked = blocked_;
818
819     if (!*blocked) {
820         *blocked = true;
821         unixctl_command_reply(conn, NULL);
822     } else {
823         unixctl_command_reply(conn, "already blocking");
824     }
825 }
826
827 static void
828 ovsdb_client_unblock(struct unixctl_conn *conn, int argc OVS_UNUSED,
829                      const char *argv[] OVS_UNUSED, void *blocked_)
830 {
831     bool *blocked = blocked_;
832
833     if (*blocked) {
834         *blocked = false;
835         unixctl_command_reply(conn, NULL);
836     } else {
837         unixctl_command_reply(conn, "already unblocked");
838     }
839 }
840
841 static void
842 add_monitored_table(int argc, char *argv[],
843                     const char *server, const char *database,
844                     struct ovsdb_table_schema *table,
845                     struct json *monitor_requests,
846                     struct monitored_table **mts,
847                     size_t *n_mts, size_t *allocated_mts)
848 {
849     struct json *monitor_request_array;
850     struct monitored_table *mt;
851
852     if (*n_mts >= *allocated_mts) {
853         *mts = x2nrealloc(*mts, allocated_mts, sizeof **mts);
854     }
855     mt = &(*mts)[(*n_mts)++];
856     mt->table = table;
857     ovsdb_column_set_init(&mt->columns);
858
859     monitor_request_array = json_array_create_empty();
860     if (argc > 1) {
861         int i;
862
863         for (i = 1; i < argc; i++) {
864             json_array_add(
865                 monitor_request_array,
866                 parse_monitor_columns(argv[i], server, database, table,
867                                       &mt->columns));
868         }
869     } else {
870         /* Allocate a writable empty string since parse_monitor_columns()
871          * is going to strtok() it and that's risky with literal "". */
872         char empty[] = "";
873         json_array_add(
874             monitor_request_array,
875             parse_monitor_columns(empty, server, database,
876                                   table, &mt->columns));
877     }
878
879     json_object_put(monitor_requests, table->name, monitor_request_array);
880 }
881
882 static void
883 destroy_monitored_table(struct monitored_table *mts, size_t n)
884 {
885     int i;
886
887     for (i = 0; i < n; i++) {
888         struct monitored_table *mt = &mts[i];
889         ovsdb_column_set_destroy(&mt->columns);
890     }
891
892     free(mts);
893 }
894
895 static void
896 do_monitor__(struct jsonrpc *rpc, const char *database,
897              enum ovsdb_monitor_version version,
898              int argc, char *argv[])
899 {
900     const char *server = jsonrpc_get_name(rpc);
901     const char *table_name = argv[0];
902     struct unixctl_server *unixctl;
903     struct ovsdb_schema *schema;
904     struct jsonrpc_msg *request;
905     struct json *monitor, *monitor_requests, *request_id;
906     bool exiting = false;
907     bool blocked = false;
908
909     struct monitored_table *mts;
910     size_t n_mts, allocated_mts;
911
912     ovs_assert(version < OVSDB_MONITOR_VERSION_MAX);
913
914     daemon_save_fd(STDOUT_FILENO);
915     daemonize_start(false);
916     if (get_detach()) {
917         int error;
918
919         error = unixctl_server_create(NULL, &unixctl);
920         if (error) {
921             ovs_fatal(error, "failed to create unixctl server");
922         }
923
924         unixctl_command_register("exit", "", 0, 0,
925                                  ovsdb_client_exit, &exiting);
926         unixctl_command_register("ovsdb-client/block", "", 0, 0,
927                                  ovsdb_client_block, &blocked);
928         unixctl_command_register("ovsdb-client/unblock", "", 0, 0,
929                                  ovsdb_client_unblock, &blocked);
930     } else {
931         unixctl = NULL;
932     }
933
934     schema = fetch_schema(rpc, database);
935
936     monitor_requests = json_object_create();
937
938     mts = NULL;
939     n_mts = allocated_mts = 0;
940     if (strcmp(table_name, "ALL")) {
941         struct ovsdb_table_schema *table;
942
943         table = shash_find_data(&schema->tables, table_name);
944         if (!table) {
945             ovs_fatal(0, "%s: %s does not have a table named \"%s\"",
946                       server, database, table_name);
947         }
948
949         add_monitored_table(argc, argv, server, database, table,
950                             monitor_requests, &mts, &n_mts, &allocated_mts);
951     } else {
952         size_t n = shash_count(&schema->tables);
953         const struct shash_node **nodes = shash_sort(&schema->tables);
954         size_t i;
955
956         for (i = 0; i < n; i++) {
957             struct ovsdb_table_schema *table = nodes[i]->data;
958
959             add_monitored_table(argc, argv, server, database, table,
960                                 monitor_requests,
961                                 &mts, &n_mts, &allocated_mts);
962         }
963         free(nodes);
964     }
965
966     monitor = json_array_create_3(json_string_create(database),
967                                   json_null_create(), monitor_requests);
968     const char *method = version == OVSDB_MONITOR_V2 ? "monitor2"
969                                                      : "monitor";
970
971     request = jsonrpc_create_request(method, monitor, NULL);
972     request_id = json_clone(request->id);
973     jsonrpc_send(rpc, request);
974
975     for (;;) {
976         unixctl_server_run(unixctl);
977         while (!blocked) {
978             struct jsonrpc_msg *msg;
979             int error;
980
981             error = jsonrpc_recv(rpc, &msg);
982             if (error == EAGAIN) {
983                 break;
984             } else if (error) {
985                 ovs_fatal(error, "%s: receive failed", server);
986             }
987
988             if (msg->type == JSONRPC_REQUEST && !strcmp(msg->method, "echo")) {
989                 jsonrpc_send(rpc, jsonrpc_create_reply(json_clone(msg->params),
990                                                        msg->id));
991             } else if (msg->type == JSONRPC_REPLY
992                        && json_equal(msg->id, request_id)) {
993                 switch(version) {
994                 case OVSDB_MONITOR_V1:
995                     monitor_print(msg->result, mts, n_mts, true);
996                     break;
997                 case OVSDB_MONITOR_V2:
998                     monitor2_print(msg->result, mts, n_mts);
999                     break;
1000                 case OVSDB_MONITOR_VERSION_MAX:
1001                 default:
1002                     OVS_NOT_REACHED();
1003                 }
1004                 fflush(stdout);
1005                 daemonize_complete();
1006             } else if (msg->type == JSONRPC_NOTIFY
1007                        && !strcmp(msg->method, "update")) {
1008                 struct json *params = msg->params;
1009                 if (params->type == JSON_ARRAY
1010                     && params->u.array.n == 2
1011                     && params->u.array.elems[0]->type == JSON_NULL) {
1012                     monitor_print(params->u.array.elems[1], mts, n_mts, false);
1013                     fflush(stdout);
1014                 }
1015             } else if (msg->type == JSONRPC_NOTIFY
1016                        && version == OVSDB_MONITOR_V2
1017                        && !strcmp(msg->method, "update2")) {
1018                 struct json *params = msg->params;
1019                 if (params->type == JSON_ARRAY
1020                     && params->u.array.n == 2
1021                     && params->u.array.elems[0]->type == JSON_NULL) {
1022                     monitor2_print(params->u.array.elems[1], mts, n_mts);
1023                     fflush(stdout);
1024                 }
1025             }
1026             jsonrpc_msg_destroy(msg);
1027         }
1028
1029         if (exiting) {
1030             break;
1031         }
1032
1033         jsonrpc_run(rpc);
1034         jsonrpc_wait(rpc);
1035         if (!blocked) {
1036             jsonrpc_recv_wait(rpc);
1037         }
1038         unixctl_server_wait(unixctl);
1039         poll_block();
1040     }
1041
1042     json_destroy(request_id);
1043     unixctl_server_destroy(unixctl);
1044     ovsdb_schema_destroy(schema);
1045     destroy_monitored_table(mts, n_mts);
1046 }
1047
1048 static void
1049 do_monitor(struct jsonrpc *rpc, const char *database,
1050            int argc, char *argv[])
1051 {
1052     do_monitor__(rpc, database, OVSDB_MONITOR_V1, argc, argv);
1053 }
1054
1055 static void
1056 do_monitor2(struct jsonrpc *rpc, const char *database,
1057            int argc, char *argv[])
1058 {
1059     do_monitor__(rpc, database, OVSDB_MONITOR_V2, argc, argv);
1060 }
1061
1062 struct dump_table_aux {
1063     struct ovsdb_datum **data;
1064     const struct ovsdb_column **columns;
1065     size_t n_columns;
1066 };
1067
1068 static int
1069 compare_data(size_t a_y, size_t b_y, size_t x,
1070              const struct dump_table_aux *aux)
1071 {
1072     return ovsdb_datum_compare_3way(&aux->data[a_y][x],
1073                                     &aux->data[b_y][x],
1074                                     &aux->columns[x]->type);
1075 }
1076
1077 static int
1078 compare_rows(size_t a_y, size_t b_y, void *aux_)
1079 {
1080     struct dump_table_aux *aux = aux_;
1081     size_t x;
1082
1083     /* Skip UUID columns on the first pass, since their values tend to be
1084      * random and make our results less reproducible. */
1085     for (x = 0; x < aux->n_columns; x++) {
1086         if (aux->columns[x]->type.key.type != OVSDB_TYPE_UUID) {
1087             int cmp = compare_data(a_y, b_y, x, aux);
1088             if (cmp) {
1089                 return cmp;
1090             }
1091         }
1092     }
1093
1094     /* Use UUID columns as tie-breakers. */
1095     for (x = 0; x < aux->n_columns; x++) {
1096         if (aux->columns[x]->type.key.type == OVSDB_TYPE_UUID) {
1097             int cmp = compare_data(a_y, b_y, x, aux);
1098             if (cmp) {
1099                 return cmp;
1100             }
1101         }
1102     }
1103
1104     return 0;
1105 }
1106
1107 static void
1108 swap_rows(size_t a_y, size_t b_y, void *aux_)
1109 {
1110     struct dump_table_aux *aux = aux_;
1111     struct ovsdb_datum *tmp = aux->data[a_y];
1112     aux->data[a_y] = aux->data[b_y];
1113     aux->data[b_y] = tmp;
1114 }
1115
1116 static int
1117 compare_columns(const void *a_, const void *b_)
1118 {
1119     const struct ovsdb_column *const *ap = a_;
1120     const struct ovsdb_column *const *bp = b_;
1121     const struct ovsdb_column *a = *ap;
1122     const struct ovsdb_column *b = *bp;
1123
1124     return strcmp(a->name, b->name);
1125 }
1126
1127 static void
1128 dump_table(const char *table_name, const struct shash *cols,
1129            struct json_array *rows)
1130 {
1131     const struct ovsdb_column **columns;
1132     size_t n_columns;
1133
1134     struct ovsdb_datum **data;
1135
1136     struct dump_table_aux aux;
1137     struct shash_node *node;
1138     struct table t;
1139     size_t x, y;
1140
1141     /* Sort columns by name, for reproducibility. */
1142     columns = xmalloc(shash_count(cols) * sizeof *columns);
1143     n_columns = 0;
1144     SHASH_FOR_EACH (node, cols) {
1145         struct ovsdb_column *column = node->data;
1146         if (strcmp(column->name, "_version")) {
1147             columns[n_columns++] = column;
1148         }
1149     }
1150     qsort(columns, n_columns, sizeof *columns, compare_columns);
1151
1152     /* Extract data from table. */
1153     data = xmalloc(rows->n * sizeof *data);
1154     for (y = 0; y < rows->n; y++) {
1155         struct shash *row;
1156
1157         if (rows->elems[y]->type != JSON_OBJECT) {
1158             ovs_fatal(0,  "row %"PRIuSIZE" in table %s response is not a JSON object: "
1159                       "%s", y, table_name, json_to_string(rows->elems[y], 0));
1160         }
1161         row = json_object(rows->elems[y]);
1162
1163         data[y] = xmalloc(n_columns * sizeof **data);
1164         for (x = 0; x < n_columns; x++) {
1165             const struct json *json = shash_find_data(row, columns[x]->name);
1166             if (!json) {
1167                 ovs_fatal(0, "row %"PRIuSIZE" in table %s response lacks %s column",
1168                           y, table_name, columns[x]->name);
1169             }
1170
1171             check_ovsdb_error(ovsdb_datum_from_json(&data[y][x],
1172                                                     &columns[x]->type,
1173                                                     json, NULL));
1174         }
1175     }
1176
1177     /* Sort rows by column values, for reproducibility. */
1178     aux.data = data;
1179     aux.columns = columns;
1180     aux.n_columns = n_columns;
1181     sort(rows->n, compare_rows, swap_rows, &aux);
1182
1183     /* Add column headings. */
1184     table_init(&t);
1185     table_set_caption(&t, xasprintf("%s table", table_name));
1186     for (x = 0; x < n_columns; x++) {
1187         table_add_column(&t, "%s", columns[x]->name);
1188     }
1189
1190     /* Print rows. */
1191     for (y = 0; y < rows->n; y++) {
1192         table_add_row(&t);
1193         for (x = 0; x < n_columns; x++) {
1194             struct cell *cell = table_add_cell(&t);
1195             cell->json = ovsdb_datum_to_json(&data[y][x], &columns[x]->type);
1196             cell->type = &columns[x]->type;
1197             ovsdb_datum_destroy(&data[y][x], &columns[x]->type);
1198         }
1199         free(data[y]);
1200     }
1201     table_print(&t, &table_style);
1202     table_destroy(&t);
1203
1204     free(data);
1205     free(columns);
1206 }
1207
1208 static void
1209 do_dump(struct jsonrpc *rpc, const char *database,
1210         int argc, char *argv[])
1211 {
1212     struct jsonrpc_msg *request, *reply;
1213     struct ovsdb_schema *schema;
1214     struct json *transaction;
1215
1216     const struct shash_node *node, **tables;
1217     size_t n_tables;
1218     struct ovsdb_table_schema *tschema;
1219     const struct shash *columns;
1220     struct shash custom_columns;
1221
1222     size_t i;
1223
1224     shash_init(&custom_columns);
1225     schema = fetch_schema(rpc, database);
1226     if (argc) {
1227         node = shash_find(&schema->tables, argv[0]);
1228         if (!node) {
1229             ovs_fatal(0, "No table \"%s\" found.", argv[0]);
1230         }
1231         tables = xmemdup(&node, sizeof(&node));
1232         n_tables = 1;
1233         tschema = tables[0]->data;
1234         for (i = 1; i < argc; i++) {
1235             node = shash_find(&tschema->columns, argv[i]);
1236             if (!node) {
1237                 ovs_fatal(0, "Table \"%s\" has no column %s.", argv[0], argv[1]);
1238             }
1239             shash_add(&custom_columns, argv[1], node->data);
1240         }
1241     } else {
1242         tables = shash_sort(&schema->tables);
1243         n_tables = shash_count(&schema->tables);
1244     }
1245
1246     /* Construct transaction to retrieve entire database. */
1247     transaction = json_array_create_1(json_string_create(database));
1248     for (i = 0; i < n_tables; i++) {
1249         const struct ovsdb_table_schema *ts = tables[i]->data;
1250         struct json *op, *jcolumns;
1251
1252         if (argc > 1) {
1253             columns = &custom_columns;
1254         } else {
1255             columns = &ts->columns;
1256         }
1257         jcolumns = json_array_create_empty();
1258         SHASH_FOR_EACH (node, columns) {
1259             const struct ovsdb_column *column = node->data;
1260
1261             if (strcmp(column->name, "_version")) {
1262                 json_array_add(jcolumns, json_string_create(column->name));
1263             }
1264         }
1265
1266         op = json_object_create();
1267         json_object_put_string(op, "op", "select");
1268         json_object_put_string(op, "table", tables[i]->name);
1269         json_object_put(op, "where", json_array_create_empty());
1270         json_object_put(op, "columns", jcolumns);
1271         json_array_add(transaction, op);
1272     }
1273
1274     /* Send request, get reply. */
1275     request = jsonrpc_create_request("transact", transaction, NULL);
1276     check_txn(jsonrpc_transact_block(rpc, request, &reply), &reply);
1277
1278     /* Print database contents. */
1279     if (reply->result->type != JSON_ARRAY
1280         || reply->result->u.array.n != n_tables) {
1281         ovs_fatal(0, "reply is not array of %"PRIuSIZE" elements: %s",
1282                   n_tables, json_to_string(reply->result, 0));
1283     }
1284     for (i = 0; i < n_tables; i++) {
1285         const struct ovsdb_table_schema *ts = tables[i]->data;
1286         const struct json *op_result = reply->result->u.array.elems[i];
1287         struct json *rows;
1288
1289         if (op_result->type != JSON_OBJECT
1290             || !(rows = shash_find_data(json_object(op_result), "rows"))
1291             || rows->type != JSON_ARRAY) {
1292             ovs_fatal(0, "%s table reply is not an object with a \"rows\" "
1293                       "member array: %s",
1294                       ts->name, json_to_string(op_result, 0));
1295         }
1296
1297         if (argc > 1) {
1298             dump_table(tables[i]->name, &custom_columns, &rows->u.array);
1299         } else {
1300             dump_table(tables[i]->name, &ts->columns, &rows->u.array);
1301         }
1302     }
1303
1304     jsonrpc_msg_destroy(reply);
1305     shash_destroy(&custom_columns);
1306     free(tables);
1307     ovsdb_schema_destroy(schema);
1308 }
1309
1310 static void
1311 do_help(struct jsonrpc *rpc OVS_UNUSED, const char *database OVS_UNUSED,
1312         int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
1313 {
1314     usage();
1315 }
1316
1317 /* All command handlers (except for "help") are expected to take an optional
1318  * server socket name (e.g. "unix:...") as their first argument.  The socket
1319  * name argument must be included in max_args (but left out of min_args).  The
1320  * command name and socket name are not included in the arguments passed to the
1321  * handler: the argv[0] passed to the handler is the first argument after the
1322  * optional server socket name.  The connection to the server is available as
1323  * global variable 'rpc'. */
1324 static const struct ovsdb_client_command all_commands[] = {
1325     { "list-dbs",           NEED_RPC,      0, 0,       do_list_dbs },
1326     { "get-schema",         NEED_DATABASE, 0, 0,       do_get_schema },
1327     { "get-schema-version", NEED_DATABASE, 0, 0,       do_get_schema_version },
1328     { "list-tables",        NEED_DATABASE, 0, 0,       do_list_tables },
1329     { "list-columns",       NEED_DATABASE, 0, 1,       do_list_columns },
1330     { "transact",           NEED_RPC,      1, 1,       do_transact },
1331     { "monitor",            NEED_DATABASE, 1, INT_MAX, do_monitor },
1332     { "monitor2",           NEED_DATABASE, 1, INT_MAX, do_monitor2 },
1333     { "dump",               NEED_DATABASE, 0, INT_MAX, do_dump },
1334     { "help",               NEED_NONE,     0, INT_MAX, do_help },
1335
1336     { NULL,                 0,             0, 0,       NULL },
1337 };
1338
1339 static const struct ovsdb_client_command *get_all_commands(void)
1340 {
1341     return all_commands;
1342 }