ovsdb-server: fix monitor counters reported by memory/show
[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         VLOG_FATAL("invalid syntax for '%s' (use --help for help)",
149                     command->name);
150     }
151
152     command->handler(rpc, database, argc - optind, argv + optind);
153
154     free(database);
155     jsonrpc_close(rpc);
156
157     if (ferror(stdout)) {
158         VLOG_FATAL("write to stdout failed");
159     }
160     if (ferror(stderr)) {
161         VLOG_FATAL("write to stderr failed");
162     }
163
164     return 0;
165 }
166
167 static void
168 parse_options(int argc, char *argv[])
169 {
170     enum {
171         OPT_BOOTSTRAP_CA_CERT = UCHAR_MAX + 1,
172         OPT_TIMESTAMP,
173         VLOG_OPTION_ENUMS,
174         DAEMON_OPTION_ENUMS,
175         TABLE_OPTION_ENUMS
176     };
177     static const struct option long_options[] = {
178         {"help", no_argument, NULL, 'h'},
179         {"version", no_argument, NULL, 'V'},
180         {"timestamp", no_argument, NULL, OPT_TIMESTAMP},
181         VLOG_LONG_OPTIONS,
182         DAEMON_LONG_OPTIONS,
183 #ifdef HAVE_OPENSSL
184         {"bootstrap-ca-cert", required_argument, NULL, OPT_BOOTSTRAP_CA_CERT},
185         STREAM_SSL_LONG_OPTIONS,
186 #endif
187         TABLE_LONG_OPTIONS,
188         {NULL, 0, NULL, 0},
189     };
190     char *short_options = ovs_cmdl_long_options_to_short_options(long_options);
191
192     for (;;) {
193         int c;
194
195         c = getopt_long(argc, argv, short_options, long_options, NULL);
196         if (c == -1) {
197             break;
198         }
199
200         switch (c) {
201         case 'h':
202             usage();
203
204         case 'V':
205             ovs_print_version(0, 0);
206             exit(EXIT_SUCCESS);
207
208         VLOG_OPTION_HANDLERS
209         DAEMON_OPTION_HANDLERS
210         TABLE_OPTION_HANDLERS(&table_style)
211         STREAM_SSL_OPTION_HANDLERS
212
213         case OPT_BOOTSTRAP_CA_CERT:
214             stream_ssl_set_ca_cert_file(optarg, true);
215             break;
216
217         case OPT_TIMESTAMP:
218             timestamp = true;
219             break;
220
221         case '?':
222             exit(EXIT_FAILURE);
223
224         case 0:
225             /* getopt_long() already set the value for us. */
226             break;
227
228         default:
229             abort();
230         }
231     }
232     free(short_options);
233 }
234
235 static void
236 usage(void)
237 {
238     printf("%s: Open vSwitch database JSON-RPC client\n"
239            "usage: %s [OPTIONS] COMMAND [ARG...]\n"
240            "\nValid commands are:\n"
241            "\n  list-dbs [SERVER]\n"
242            "    list databases available on SERVER\n"
243            "\n  get-schema [SERVER] [DATABASE]\n"
244            "    retrieve schema for DATABASE from SERVER\n"
245            "\n  get-schema-version [SERVER] [DATABASE]\n"
246            "    retrieve schema for DATABASE from SERVER and report only its\n"
247            "    version number on stdout\n"
248            "\n  list-tables [SERVER] [DATABASE]\n"
249            "    list tables for DATABASE on SERVER\n"
250            "\n  list-columns [SERVER] [DATABASE] [TABLE]\n"
251            "    list columns in TABLE (or all tables) in DATABASE on SERVER\n"
252            "\n  transact [SERVER] TRANSACTION\n"
253            "    run TRANSACTION (a JSON array of operations) on SERVER\n"
254            "    and print the results as JSON on stdout\n"
255            "\n  monitor [SERVER] [DATABASE] TABLE [COLUMN,...]...\n"
256            "    monitor contents of COLUMNs in TABLE in DATABASE on SERVER.\n"
257            "    COLUMNs may include !initial, !insert, !delete, !modify\n"
258            "    to avoid seeing the specified kinds of changes.\n"
259            "\n  monitor [SERVER] [DATABASE] ALL\n"
260            "    monitor all changes to all columns in all tables\n"
261            "    in DATBASE on SERVER.\n"
262            "\n  monitor2 [SERVER] [DATABASE] ALL\n"
263            "    same usage as monitor, but uses \"monitor2\" method over"
264            "    the wire."
265            "\n  dump [SERVER] [DATABASE]\n"
266            "    dump contents of DATABASE on SERVER to stdout\n"
267            "\nThe default SERVER is unix:%s/db.sock.\n"
268            "The default DATABASE is Open_vSwitch.\n",
269            program_name, program_name, ovs_rundir());
270     stream_usage("SERVER", true, true, true);
271     printf("\nOutput formatting options:\n"
272            "  -f, --format=FORMAT         set output formatting to FORMAT\n"
273            "                              (\"table\", \"html\", \"csv\", "
274            "or \"json\")\n"
275            "  --no-headings               omit table heading row\n"
276            "  --pretty                    pretty-print JSON in output\n"
277            "  --timestamp                 timestamp \"monitor\" output");
278     daemon_usage();
279     vlog_usage();
280     printf("\nOther options:\n"
281            "  -h, --help                  display this help message\n"
282            "  -V, --version               display version information\n");
283     exit(EXIT_SUCCESS);
284 }
285 \f
286 static void
287 check_txn(int error, struct jsonrpc_msg **reply_)
288 {
289     struct jsonrpc_msg *reply = *reply_;
290
291     if (error) {
292         ovs_fatal(error, "transaction failed");
293     }
294
295     if (reply->error) {
296         ovs_fatal(error, "transaction returned error: %s",
297                   json_to_string(reply->error, table_style.json_flags));
298     }
299 }
300
301 static struct json *
302 parse_json(const char *s)
303 {
304     struct json *json = json_from_string(s);
305     if (json->type == JSON_STRING) {
306         ovs_fatal(0, "\"%s\": %s", s, json->u.string);
307     }
308     return json;
309 }
310
311 static struct jsonrpc *
312 open_jsonrpc(const char *server)
313 {
314     struct stream *stream;
315     int error;
316
317     error = stream_open_block(jsonrpc_stream_open(server, &stream,
318                               DSCP_DEFAULT), &stream);
319     if (error == EAFNOSUPPORT) {
320         struct pstream *pstream;
321
322         error = jsonrpc_pstream_open(server, &pstream, DSCP_DEFAULT);
323         if (error) {
324             ovs_fatal(error, "failed to connect or listen to \"%s\"", server);
325         }
326
327         VLOG_INFO("%s: waiting for connection...", server);
328         error = pstream_accept_block(pstream, &stream);
329         if (error) {
330             ovs_fatal(error, "failed to accept connection on \"%s\"", server);
331         }
332
333         pstream_close(pstream);
334     } else if (error) {
335         ovs_fatal(error, "failed to connect to \"%s\"", server);
336     }
337
338     return jsonrpc_open(stream);
339 }
340
341 static void
342 print_json(struct json *json)
343 {
344     char *string = json_to_string(json, table_style.json_flags);
345     fputs(string, stdout);
346     free(string);
347 }
348
349 static void
350 print_and_free_json(struct json *json)
351 {
352     print_json(json);
353     json_destroy(json);
354 }
355
356 static void
357 check_ovsdb_error(struct ovsdb_error *error)
358 {
359     if (error) {
360         ovs_fatal(0, "%s", ovsdb_error_to_string(error));
361     }
362 }
363
364 static struct ovsdb_schema *
365 fetch_schema(struct jsonrpc *rpc, const char *database)
366 {
367     struct jsonrpc_msg *request, *reply;
368     struct ovsdb_schema *schema;
369
370     request = jsonrpc_create_request("get_schema",
371                                      json_array_create_1(
372                                          json_string_create(database)),
373                                      NULL);
374     check_txn(jsonrpc_transact_block(rpc, request, &reply), &reply);
375     check_ovsdb_error(ovsdb_schema_from_json(reply->result, &schema));
376     jsonrpc_msg_destroy(reply);
377
378     return schema;
379 }
380
381 static void
382 fetch_dbs(struct jsonrpc *rpc, struct svec *dbs)
383 {
384     struct jsonrpc_msg *request, *reply;
385     size_t i;
386
387     request = jsonrpc_create_request("list_dbs", json_array_create_empty(),
388                                      NULL);
389
390     check_txn(jsonrpc_transact_block(rpc, request, &reply), &reply);
391     if (reply->result->type != JSON_ARRAY) {
392         ovs_fatal(0, "list_dbs response is not array");
393     }
394
395     for (i = 0; i < reply->result->u.array.n; i++) {
396         const struct json *name = reply->result->u.array.elems[i];
397
398         if (name->type != JSON_STRING) {
399             ovs_fatal(0, "list_dbs response %"PRIuSIZE" is not string", i);
400         }
401         svec_add(dbs, name->u.string);
402     }
403     jsonrpc_msg_destroy(reply);
404     svec_sort(dbs);
405 }
406 \f
407 static void
408 do_list_dbs(struct jsonrpc *rpc, const char *database OVS_UNUSED,
409             int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
410 {
411     const char *db_name;
412     struct svec dbs;
413     size_t i;
414
415     svec_init(&dbs);
416     fetch_dbs(rpc, &dbs);
417     SVEC_FOR_EACH (i, db_name, &dbs) {
418         puts(db_name);
419     }
420     svec_destroy(&dbs);
421 }
422
423 static void
424 do_get_schema(struct jsonrpc *rpc, const char *database,
425               int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
426 {
427     struct ovsdb_schema *schema = fetch_schema(rpc, database);
428     print_and_free_json(ovsdb_schema_to_json(schema));
429     ovsdb_schema_destroy(schema);
430 }
431
432 static void
433 do_get_schema_version(struct jsonrpc *rpc, const char *database,
434                       int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
435 {
436     struct ovsdb_schema *schema = fetch_schema(rpc, database);
437     puts(schema->version);
438     ovsdb_schema_destroy(schema);
439 }
440
441 static void
442 do_list_tables(struct jsonrpc *rpc, const char *database,
443                int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
444 {
445     struct ovsdb_schema *schema;
446     struct shash_node *node;
447     struct table t;
448
449     schema = fetch_schema(rpc, database);
450     table_init(&t);
451     table_add_column(&t, "Table");
452     SHASH_FOR_EACH (node, &schema->tables) {
453         struct ovsdb_table_schema *ts = node->data;
454
455         table_add_row(&t);
456         table_add_cell(&t)->text = xstrdup(ts->name);
457     }
458     ovsdb_schema_destroy(schema);
459     table_print(&t, &table_style);
460     table_destroy(&t);
461 }
462
463 static void
464 do_list_columns(struct jsonrpc *rpc, const char *database,
465                 int argc OVS_UNUSED, char *argv[])
466 {
467     const char *table_name = argv[0];
468     struct ovsdb_schema *schema;
469     struct shash_node *table_node;
470     struct table t;
471
472     schema = fetch_schema(rpc, database);
473     table_init(&t);
474     if (!table_name) {
475         table_add_column(&t, "Table");
476     }
477     table_add_column(&t, "Column");
478     table_add_column(&t, "Type");
479     SHASH_FOR_EACH (table_node, &schema->tables) {
480         struct ovsdb_table_schema *ts = table_node->data;
481
482         if (!table_name || !strcmp(table_name, ts->name)) {
483             struct shash_node *column_node;
484
485             SHASH_FOR_EACH (column_node, &ts->columns) {
486                 const struct ovsdb_column *column = column_node->data;
487
488                 table_add_row(&t);
489                 if (!table_name) {
490                     table_add_cell(&t)->text = xstrdup(ts->name);
491                 }
492                 table_add_cell(&t)->text = xstrdup(column->name);
493                 table_add_cell(&t)->json = ovsdb_type_to_json(&column->type);
494             }
495         }
496     }
497     ovsdb_schema_destroy(schema);
498     table_print(&t, &table_style);
499     table_destroy(&t);
500 }
501
502 static void
503 do_transact(struct jsonrpc *rpc, const char *database OVS_UNUSED,
504             int argc OVS_UNUSED, char *argv[])
505 {
506     struct jsonrpc_msg *request, *reply;
507     struct json *transaction;
508
509     transaction = parse_json(argv[0]);
510
511     request = jsonrpc_create_request("transact", transaction, NULL);
512     check_txn(jsonrpc_transact_block(rpc, request, &reply), &reply);
513     print_json(reply->result);
514     putchar('\n');
515     jsonrpc_msg_destroy(reply);
516 }
517 \f
518 /* "monitor" command. */
519
520 struct monitored_table {
521     struct ovsdb_table_schema *table;
522     struct ovsdb_column_set columns;
523 };
524
525 static void
526 monitor_print_row(struct json *row, const char *type, const char *uuid,
527                   const struct ovsdb_column_set *columns, struct table *t)
528 {
529     size_t i;
530
531     if (!row) {
532         ovs_error(0, "missing %s row", type);
533         return;
534     } else if (row->type != JSON_OBJECT) {
535         ovs_error(0, "<row> is not object");
536         return;
537     }
538
539     table_add_row(t);
540     table_add_cell(t)->text = xstrdup(uuid);
541     table_add_cell(t)->text = xstrdup(type);
542     for (i = 0; i < columns->n_columns; i++) {
543         const struct ovsdb_column *column = columns->columns[i];
544         struct json *value = shash_find_data(json_object(row), column->name);
545         struct cell *cell = table_add_cell(t);
546         if (value) {
547             cell->json = json_clone(value);
548             cell->type = &column->type;
549         }
550     }
551 }
552
553 static void
554 monitor_print_table(struct json *table_update,
555                     const struct monitored_table *mt, char *caption,
556                     bool initial)
557 {
558     const struct ovsdb_table_schema *table = mt->table;
559     const struct ovsdb_column_set *columns = &mt->columns;
560     struct shash_node *node;
561     struct table t;
562     size_t i;
563
564     if (table_update->type != JSON_OBJECT) {
565         ovs_error(0, "<table-update> for table %s is not object", table->name);
566         return;
567     }
568
569     table_init(&t);
570     table_set_timestamp(&t, timestamp);
571     table_set_caption(&t, caption);
572
573     table_add_column(&t, "row");
574     table_add_column(&t, "action");
575     for (i = 0; i < columns->n_columns; i++) {
576         table_add_column(&t, "%s", columns->columns[i]->name);
577     }
578     SHASH_FOR_EACH (node, json_object(table_update)) {
579         struct json *row_update = node->data;
580         struct json *old, *new;
581
582         if (row_update->type != JSON_OBJECT) {
583             ovs_error(0, "<row-update> is not object");
584             continue;
585         }
586         old = shash_find_data(json_object(row_update), "old");
587         new = shash_find_data(json_object(row_update), "new");
588         if (initial) {
589             monitor_print_row(new, "initial", node->name, columns, &t);
590         } else if (!old) {
591             monitor_print_row(new, "insert", node->name, columns, &t);
592         } else if (!new) {
593             monitor_print_row(old, "delete", node->name, columns, &t);
594         } else {
595             monitor_print_row(old, "old", node->name, columns, &t);
596             monitor_print_row(new, "new", "", columns, &t);
597         }
598     }
599     table_print(&t, &table_style);
600     table_destroy(&t);
601 }
602
603 static void
604 monitor_print(struct json *table_updates,
605               const struct monitored_table *mts, size_t n_mts,
606               bool initial)
607 {
608     size_t i;
609
610     if (table_updates->type != JSON_OBJECT) {
611         ovs_error(0, "<table-updates> is not object");
612         return;
613     }
614
615     for (i = 0; i < n_mts; i++) {
616         const struct monitored_table *mt = &mts[i];
617         struct json *table_update = shash_find_data(json_object(table_updates),
618                                                     mt->table->name);
619         if (table_update) {
620             monitor_print_table(table_update, mt,
621                                 n_mts > 1 ? xstrdup(mt->table->name) : NULL,
622                                 initial);
623         }
624     }
625 }
626
627 static void
628 monitor2_print_row(struct json *row, const char *type, const char *uuid,
629                    const struct ovsdb_column_set *columns, struct table *t)
630 {
631     if (!strcmp(type, "delete")) {
632         if (row->type != JSON_NULL) {
633             ovs_error(0, "delete method does not expect <row>");
634             return;
635         }
636
637         table_add_row(t);
638         table_add_cell(t)->text = xstrdup(uuid);
639         table_add_cell(t)->text = xstrdup(type);
640     } else {
641         if (!row || row->type != JSON_OBJECT) {
642             ovs_error(0, "<row> is not object");
643             return;
644         }
645         monitor_print_row(row, type, uuid, columns, t);
646     }
647 }
648
649 static void
650 monitor2_print_table(struct json *table_update2,
651                     const struct monitored_table *mt, char *caption)
652 {
653     const struct ovsdb_table_schema *table = mt->table;
654     const struct ovsdb_column_set *columns = &mt->columns;
655     struct shash_node *node;
656     struct table t;
657     size_t i;
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 (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 }