Merge "master" into "next".
[cascardo/ovs.git] / ovsdb / ovsdb-client.c
1 /*
2  * Copyright (c) 2009, 2010 Nicira Networks.
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 <assert.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 "dynamic-string.h"
33 #include "json.h"
34 #include "jsonrpc.h"
35 #include "ovsdb.h"
36 #include "ovsdb-error.h"
37 #include "stream.h"
38 #include "stream-ssl.h"
39 #include "table.h"
40 #include "timeval.h"
41 #include "util.h"
42
43 #include "vlog.h"
44 #define THIS_MODULE VLM_ovsdb_client
45
46 /* --format: Output formatting. */
47 static enum {
48     FMT_TABLE,                  /* Textual table. */
49     FMT_HTML,                   /* HTML table. */
50     FMT_CSV                     /* Comma-separated lines. */
51 } output_format;
52
53 /* --wide: For --format=table, the maximum output width. */
54 static int output_width;
55
56 /* --no-headings: Whether table output should include headings. */
57 static int output_headings = true;
58
59 /* --pretty: Flags to pass to json_to_string(). */
60 static int json_flags = JSSF_SORT;
61
62 static const struct command all_commands[];
63
64 static void usage(void) NO_RETURN;
65 static void parse_options(int argc, char *argv[]);
66
67 int
68 main(int argc, char *argv[])
69 {
70     proctitle_init(argc, argv);
71     set_program_name(argv[0]);
72     time_init();
73     vlog_init();
74     parse_options(argc, argv);
75     signal(SIGPIPE, SIG_IGN);
76     run_command(argc - optind, argv + optind, all_commands);
77     return 0;
78 }
79
80 static void
81 parse_options(int argc, char *argv[])
82 {
83     enum {
84         OPT_BOOTSTRAP_CA_CERT = UCHAR_MAX + 1
85     };
86     static struct option long_options[] = {
87         {"wide", no_argument, &output_width, INT_MAX},
88         {"format", required_argument, 0, 'f'},
89             {"no-headings", no_argument, &output_headings, 0},
90         {"pretty", no_argument, &json_flags, JSSF_PRETTY | JSSF_SORT},
91         {"verbose", optional_argument, 0, 'v'},
92         {"help", no_argument, 0, 'h'},
93         {"version", no_argument, 0, 'V'},
94         DAEMON_LONG_OPTIONS,
95 #ifdef HAVE_OPENSSL
96         {"bootstrap-ca-cert", required_argument, 0, OPT_BOOTSTRAP_CA_CERT},
97         STREAM_SSL_LONG_OPTIONS
98 #endif
99         {0, 0, 0, 0},
100     };
101     char *short_options = long_options_to_short_options(long_options);
102
103     output_width = isatty(fileno(stdout)) ? 79 : INT_MAX;
104     for (;;) {
105         int c;
106
107         c = getopt_long(argc, argv, short_options, long_options, NULL);
108         if (c == -1) {
109             break;
110         }
111
112         switch (c) {
113         case 'f':
114             if (!strcmp(optarg, "table")) {
115                 output_format = FMT_TABLE;
116             } else if (!strcmp(optarg, "html")) {
117                 output_format = FMT_HTML;
118             } else if (!strcmp(optarg, "csv")) {
119                 output_format = FMT_CSV;
120             } else {
121                 ovs_fatal(0, "unknown output format \"%s\"", optarg);
122             }
123             break;
124
125         case 'w':
126             output_width = INT_MAX;
127             break;
128
129         case 'h':
130             usage();
131
132         case 'V':
133             OVS_PRINT_VERSION(0, 0);
134             exit(EXIT_SUCCESS);
135
136         case 'v':
137             vlog_set_verbosity(optarg);
138             break;
139
140         DAEMON_OPTION_HANDLERS
141
142 #ifdef HAVE_OPENSSL
143         STREAM_SSL_OPTION_HANDLERS
144
145         case OPT_BOOTSTRAP_CA_CERT:
146             stream_ssl_set_ca_cert_file(optarg, true);
147             break;
148 #endif
149
150         case '?':
151             exit(EXIT_FAILURE);
152
153         case 0:
154             /* getopt_long() already set the value for us. */
155             break;
156
157         default:
158             abort();
159         }
160     }
161     free(short_options);
162 }
163
164 static void
165 usage(void)
166 {
167     printf("%s: Open vSwitch database JSON-RPC client\n"
168            "usage: %s [OPTIONS] COMMAND [ARG...]\n"
169            "\nValid commands are:\n"
170            "\n  list-dbs SERVER\n"
171            "    list databases available on SERVER\n"
172            "\n  get-schema SERVER DATABASE\n"
173            "    retrieve schema for DATABASE from SERVER\n"
174            "\n  list-tables SERVER DATABSE\n"
175            "    list tables for DATABSAE on SERVER\n"
176            "\n  list-columns SERVER DATABASE [TABLE]\n"
177            "    list columns in TABLE (or all tables) in DATABASE on SERVER\n"
178            "\n  transact SERVER TRANSACTION\n"
179            "    run TRANSACTION (a JSON array of operations) on SERVER\n"
180            "    and print the results as JSON on stdout\n"
181            "\n  monitor SERVER DATABASE TABLE [COLUMN,...] [SELECT,...]\n"
182            "    monitor contents of (COLUMNs in) TABLE in DATABASE on SERVER\n"
183            "    Valid SELECTs are: initial, insert, delete, modify\n",
184            program_name, program_name);
185     stream_usage("SERVER", true, true, true);
186     printf("\nOutput formatting options:\n"
187            "  -f, --format=FORMAT         set output formatting to FORMAT\n"
188            "                              (\"table\", \"html\", or \"csv\"\n"
189            "  --wide                      don't limit TTY lines to 79 bytes\n"
190            "  --no-headings               omit table heading row\n"
191            "  --pretty                    pretty-print JSON in output");
192     daemon_usage();
193     vlog_usage();
194     printf("\nOther options:\n"
195            "  -h, --help                  display this help message\n"
196            "  -V, --version               display version information\n");
197     exit(EXIT_SUCCESS);
198 }
199 \f
200 static struct json *
201 parse_json(const char *s)
202 {
203     struct json *json = json_from_string(s);
204     if (json->type == JSON_STRING) {
205         ovs_fatal(0, "\"%s\": %s", s, json->u.string);
206     }
207     return json;
208 }
209
210 static struct jsonrpc *
211 open_jsonrpc(const char *server)
212 {
213     struct stream *stream;
214     int error;
215
216     error = stream_open_block(server, &stream);
217     if (error == EAFNOSUPPORT) {
218         struct pstream *pstream;
219
220         error = pstream_open(server, &pstream);
221         if (error) {
222             ovs_fatal(error, "failed to connect or listen to \"%s\"", server);
223         }
224
225         VLOG_INFO("%s: waiting for connection...", server);
226         error = pstream_accept_block(pstream, &stream);
227         if (error) {
228             ovs_fatal(error, "failed to accept connection on \"%s\"", server);
229         }
230
231         pstream_close(pstream);
232     } else if (error) {
233         ovs_fatal(error, "failed to connect to \"%s\"", server);
234     }
235
236     return jsonrpc_open(stream);
237 }
238
239 static void
240 print_json(struct json *json)
241 {
242     char *string = json_to_string(json, json_flags);
243     fputs(string, stdout);
244     free(string);
245 }
246
247 static void
248 print_and_free_json(struct json *json)
249 {
250     print_json(json);
251     json_destroy(json);
252 }
253
254 static void
255 check_ovsdb_error(struct ovsdb_error *error)
256 {
257     if (error) {
258         ovs_fatal(0, "%s", ovsdb_error_to_string(error));
259     }
260 }
261
262 static struct ovsdb_schema *
263 fetch_schema_from_rpc(struct jsonrpc *rpc, const char *database)
264 {
265     struct jsonrpc_msg *request, *reply;
266     struct ovsdb_schema *schema;
267     int error;
268
269     request = jsonrpc_create_request("get_schema",
270                                      json_array_create_1(
271                                          json_string_create(database)),
272                                      NULL);
273     error = jsonrpc_transact_block(rpc, request, &reply);
274     if (error) {
275         ovs_fatal(error, "transaction failed");
276     }
277     check_ovsdb_error(ovsdb_schema_from_json(reply->result, &schema));
278     jsonrpc_msg_destroy(reply);
279
280     return schema;
281 }
282
283 static struct ovsdb_schema *
284 fetch_schema(const char *server, const char *database)
285 {
286     struct ovsdb_schema *schema;
287     struct jsonrpc *rpc;
288
289     rpc = open_jsonrpc(server);
290     schema = fetch_schema_from_rpc(rpc, database);
291     jsonrpc_close(rpc);
292
293     return schema;
294 }
295 \f
296 struct column {
297     char *heading;
298     int width;
299 };
300
301 struct table {
302     char **cells;
303     struct column *columns;
304     size_t n_columns, allocated_columns;
305     size_t n_rows, allocated_rows;
306     size_t current_column;
307 };
308
309 static void
310 table_init(struct table *table)
311 {
312     memset(table, 0, sizeof *table);
313 }
314
315 static void
316 table_destroy(struct table *table)
317 {
318     size_t i;
319
320     for (i = 0; i < table->n_columns; i++) {
321         free(table->columns[i].heading);
322     }
323     free(table->columns);
324
325     for (i = 0; i < table->n_columns * table->n_rows; i++) {
326         free(table->cells[i]);
327     }
328     free(table->cells);
329 }
330
331 static void
332 table_add_column(struct table *table, const char *heading, ...)
333     PRINTF_FORMAT(2, 3);
334
335 static void
336 table_add_column(struct table *table, const char *heading, ...)
337 {
338     struct column *column;
339     va_list args;
340
341     assert(!table->n_rows);
342     if (table->n_columns >= table->allocated_columns) {
343         table->columns = x2nrealloc(table->columns, &table->allocated_columns,
344                                     sizeof *table->columns);
345     }
346     column = &table->columns[table->n_columns++];
347
348     va_start(args, heading);
349     column->heading = xvasprintf(heading, args);
350     column->width = strlen(column->heading);
351     va_end(args);
352 }
353
354 static char **
355 table_cell__(const struct table *table, size_t row, size_t column)
356 {
357     return &table->cells[column + row * table->n_columns];
358 }
359
360 static void
361 table_add_row(struct table *table)
362 {
363     size_t x, y;
364
365     if (table->n_rows >= table->allocated_rows) {
366         table->cells = x2nrealloc(table->cells, &table->allocated_rows,
367                                   table->n_columns * sizeof *table->cells);
368     }
369
370     y = table->n_rows++;
371     table->current_column = 0;
372     for (x = 0; x < table->n_columns; x++) {
373         *table_cell__(table, y, x) = NULL;
374     }
375 }
376
377 static void
378 table_add_cell_nocopy(struct table *table, char *s)
379 {
380     size_t x, y;
381     int length;
382
383     assert(table->n_rows > 0);
384     assert(table->current_column < table->n_columns);
385
386     x = table->current_column++;
387     y = table->n_rows - 1;
388     *table_cell__(table, y, x) = s;
389
390     length = strlen(s);
391     if (length > table->columns[x].width) {
392         table->columns[x].width = length;
393     }
394 }
395
396 static void
397 table_add_cell(struct table *table, const char *format, ...)
398 {
399     va_list args;
400
401     va_start(args, format);
402     table_add_cell_nocopy(table, xvasprintf(format, args));
403     va_end(args);
404 }
405
406 static void
407 table_print_table_line__(struct ds *line, size_t max_width)
408 {
409     ds_truncate(line, max_width);
410     puts(ds_cstr(line));
411     ds_clear(line);
412 }
413
414 static void
415 table_print_table__(const struct table *table)
416 {
417     struct ds line = DS_EMPTY_INITIALIZER;
418     size_t x, y;
419
420     if (output_headings) {
421         for (x = 0; x < table->n_columns; x++) {
422             const struct column *column = &table->columns[x];
423             if (x) {
424                 ds_put_char(&line, ' ');
425             }
426             ds_put_format(&line, "%-*s", column->width, column->heading);
427         }
428         table_print_table_line__(&line, output_width);
429
430         for (x = 0; x < table->n_columns; x++) {
431             const struct column *column = &table->columns[x];
432             int i;
433
434             if (x) {
435                 ds_put_char(&line, ' ');
436             }
437             for (i = 0; i < column->width; i++) {
438                 ds_put_char(&line, '-');
439             }
440         }
441         table_print_table_line__(&line, output_width);
442     }
443
444     for (y = 0; y < table->n_rows; y++) {
445         for (x = 0; x < table->n_columns; x++) {
446             const char *cell = *table_cell__(table, y, x);
447             if (x) {
448                 ds_put_char(&line, ' ');
449             }
450             ds_put_format(&line, "%-*s", table->columns[x].width, cell);
451         }
452         table_print_table_line__(&line, output_width);
453     }
454
455     ds_destroy(&line);
456 }
457
458 static void
459 table_print_html_cell__(const char *element, const char *content)
460 {
461     const char *p;
462
463     printf("    <%s>", element);
464     for (p = content; *p != '\0'; p++) {
465         switch (*p) {
466         case '&':
467             fputs("&amp;", stdout);
468             break;
469         case '<':
470             fputs("&lt;", stdout);
471             break;
472         case '>':
473             fputs("&gt;", stdout);
474             break;
475         default:
476             putchar(*p);
477             break;
478         }
479     }
480     printf("</%s>\n", element);
481 }
482
483 static void
484 table_print_html__(const struct table *table)
485 {
486     size_t x, y;
487
488     fputs("<table>\n", stdout);
489
490     if (output_headings) {
491         fputs("  <tr>\n", stdout);
492         for (x = 0; x < table->n_columns; x++) {
493             const struct column *column = &table->columns[x];
494             table_print_html_cell__("th", column->heading);
495         }
496         fputs("  </tr>\n", stdout);
497     }
498
499     for (y = 0; y < table->n_rows; y++) {
500         fputs("  <tr>\n", stdout);
501         for (x = 0; x < table->n_columns; x++) {
502             table_print_html_cell__("td", *table_cell__(table, y, x));
503         }
504         fputs("  </tr>\n", stdout);
505     }
506
507     fputs("</table>\n", stdout);
508 }
509
510 static void
511 table_print_csv_cell__(const char *content)
512 {
513     const char *p;
514
515     if (!strpbrk(content, "\n\",")) {
516         fputs(content, stdout);
517     } else {
518         putchar('"');
519         for (p = content; *p != '\0'; p++) {
520             switch (*p) {
521             case '"':
522                 fputs("\"\"", stdout);
523                 break;
524             default:
525                 putchar(*p);
526                 break;
527             }
528         }
529         putchar('"');
530     }
531 }
532
533 static void
534 table_print_csv__(const struct table *table)
535 {
536     size_t x, y;
537
538     if (output_headings) {
539         for (x = 0; x < table->n_columns; x++) {
540             const struct column *column = &table->columns[x];
541             if (x) {
542                 putchar(',');
543             }
544             table_print_csv_cell__(column->heading);
545         }
546         putchar('\n');
547     }
548
549     for (y = 0; y < table->n_rows; y++) {
550         for (x = 0; x < table->n_columns; x++) {
551             if (x) {
552                 putchar(',');
553             }
554             table_print_csv_cell__(*table_cell__(table, y, x));
555         }
556         putchar('\n');
557     }
558 }
559
560 static void
561 table_print(const struct table *table)
562 {
563     switch (output_format) {
564     case FMT_TABLE:
565         table_print_table__(table);
566         break;
567
568     case FMT_HTML:
569         table_print_html__(table);
570         break;
571
572     case FMT_CSV:
573         table_print_csv__(table);
574         break;
575     }
576 }
577 \f
578 static void
579 do_list_dbs(int argc OVS_UNUSED, char *argv[])
580 {
581     struct jsonrpc_msg *request, *reply;
582     struct jsonrpc *rpc;
583     int error;
584     size_t i;
585
586     rpc = open_jsonrpc(argv[1]);
587     request = jsonrpc_create_request("list_dbs", json_array_create_empty(),
588                                      NULL);
589     error = jsonrpc_transact_block(rpc, request, &reply);
590     if (error) {
591         ovs_fatal(error, "transaction failed");
592     }
593
594     if (reply->result->type != JSON_ARRAY) {
595         ovs_fatal(0, "list_dbs response is not array");
596     }
597
598     for (i = 0; i < reply->result->u.array.n; i++) {
599         const struct json *name = reply->result->u.array.elems[i];
600
601         if (name->type != JSON_STRING) {
602             ovs_fatal(0, "list_dbs response %zu is not string", i);
603         }
604         puts(name->u.string);
605     }
606     jsonrpc_msg_destroy(reply);
607 }
608
609 static void
610 do_get_schema(int argc OVS_UNUSED, char *argv[])
611 {
612     struct ovsdb_schema *schema = fetch_schema(argv[1], argv[2]);
613     print_and_free_json(ovsdb_schema_to_json(schema));
614     ovsdb_schema_destroy(schema);
615 }
616
617 static void
618 do_list_tables(int argc OVS_UNUSED, char *argv[])
619 {
620     struct ovsdb_schema *schema;
621     struct shash_node *node;
622     struct table t;
623
624     schema = fetch_schema(argv[1], argv[2]);
625     table_init(&t);
626     table_add_column(&t, "Table");
627     table_add_column(&t, "Comment");
628     SHASH_FOR_EACH (node, &schema->tables) {
629         struct ovsdb_table_schema *ts = node->data;
630
631         table_add_row(&t);
632         table_add_cell(&t, ts->name);
633         if (ts->comment) {
634             table_add_cell(&t, ts->comment);
635         }
636     }
637     ovsdb_schema_destroy(schema);
638     table_print(&t);
639 }
640
641 static void
642 do_list_columns(int argc OVS_UNUSED, char *argv[])
643 {
644     const char *table_name = argv[3];
645     struct ovsdb_schema *schema;
646     struct shash_node *table_node;
647     struct table t;
648
649     schema = fetch_schema(argv[1], argv[2]);
650     table_init(&t);
651     if (!table_name) {
652         table_add_column(&t, "Table");
653     }
654     table_add_column(&t, "Column");
655     table_add_column(&t, "Type");
656     table_add_column(&t, "Comment");
657     SHASH_FOR_EACH (table_node, &schema->tables) {
658         struct ovsdb_table_schema *ts = table_node->data;
659
660         if (!table_name || !strcmp(table_name, ts->name)) {
661             struct shash_node *column_node;
662
663             SHASH_FOR_EACH (column_node, &ts->columns) {
664                 const struct ovsdb_column *column = column_node->data;
665                 struct json *type = ovsdb_type_to_json(&column->type);
666
667                 table_add_row(&t);
668                 if (!table_name) {
669                     table_add_cell(&t, ts->name);
670                 }
671                 table_add_cell(&t, column->name);
672                 table_add_cell_nocopy(&t, json_to_string(type, JSSF_SORT));
673                 if (column->comment) {
674                     table_add_cell(&t, column->comment);
675                 }
676
677                 json_destroy(type);
678             }
679         }
680     }
681     ovsdb_schema_destroy(schema);
682     table_print(&t);
683 }
684
685 static void
686 do_transact(int argc OVS_UNUSED, char *argv[])
687 {
688     struct jsonrpc_msg *request, *reply;
689     struct json *transaction;
690     struct jsonrpc *rpc;
691     int error;
692
693     transaction = parse_json(argv[2]);
694
695     rpc = open_jsonrpc(argv[1]);
696     request = jsonrpc_create_request("transact", transaction, NULL);
697     error = jsonrpc_transact_block(rpc, request, &reply);
698     if (error) {
699         ovs_fatal(error, "transaction failed");
700     }
701     if (reply->error) {
702         ovs_fatal(error, "transaction returned error: %s",
703                   json_to_string(reply->error, json_flags));
704     }
705     print_json(reply->result);
706     putchar('\n');
707     jsonrpc_msg_destroy(reply);
708     jsonrpc_close(rpc);
709 }
710
711 static void
712 monitor_print_row(struct json *row, const char *type, const char *uuid,
713                   const struct ovsdb_column_set *columns, struct table *t)
714 {
715     size_t i;
716
717     if (!row) {
718         ovs_error(0, "missing %s row", type);
719         return;
720     } else if (row->type != JSON_OBJECT) {
721         ovs_error(0, "<row> is not object");
722         return;
723     }
724
725     table_add_row(t);
726     table_add_cell(t, uuid);
727     table_add_cell(t, type);
728     for (i = 0; i < columns->n_columns; i++) {
729         const struct ovsdb_column *column = columns->columns[i];
730         struct json *value = shash_find_data(json_object(row), column->name);
731         if (value) {
732             table_add_cell_nocopy(t, json_to_string(value, JSSF_SORT));
733         } else {
734             table_add_cell(t, "");
735         }
736     }
737 }
738
739 static void
740 monitor_print(struct json *table_updates,
741               const struct ovsdb_table_schema *table,
742               const struct ovsdb_column_set *columns, bool initial)
743 {
744     struct json *table_update;
745     struct shash_node *node;
746     struct table t;
747     size_t i;
748
749     table_init(&t);
750
751     if (table_updates->type != JSON_OBJECT) {
752         ovs_error(0, "<table-updates> is not object");
753         return;
754     }
755     table_update = shash_find_data(json_object(table_updates), table->name);
756     if (!table_update) {
757         return;
758     }
759     if (table_update->type != JSON_OBJECT) {
760         ovs_error(0, "<table-update> is not object");
761         return;
762     }
763
764     table_add_column(&t, "row");
765     table_add_column(&t, "action");
766     for (i = 0; i < columns->n_columns; i++) {
767         table_add_column(&t, "%s", columns->columns[i]->name);
768     }
769     SHASH_FOR_EACH (node, json_object(table_update)) {
770         struct json *row_update = node->data;
771         struct json *old, *new;
772
773         if (row_update->type != JSON_OBJECT) {
774             ovs_error(0, "<row-update> is not object");
775             continue;
776         }
777         old = shash_find_data(json_object(row_update), "old");
778         new = shash_find_data(json_object(row_update), "new");
779         if (initial) {
780             monitor_print_row(new, "initial", node->name, columns, &t);
781         } else if (!old) {
782             monitor_print_row(new, "insert", node->name, columns, &t);
783         } else if (!new) {
784             monitor_print_row(old, "delete", node->name, columns, &t);
785         } else {
786             monitor_print_row(old, "old", node->name, columns, &t);
787             monitor_print_row(new, "new", "", columns, &t);
788         }
789     }
790     table_print(&t);
791     table_destroy(&t);
792 }
793
794 static void
795 do_monitor(int argc, char *argv[])
796 {
797     const char *server = argv[1];
798     const char *database = argv[2];
799     const char *table_name = argv[3];
800     struct ovsdb_column_set columns = OVSDB_COLUMN_SET_INITIALIZER;
801     struct ovsdb_table_schema *table;
802     struct ovsdb_schema *schema;
803     struct jsonrpc_msg *request;
804     struct jsonrpc *rpc;
805     struct json *select, *monitor, *monitor_request, *monitor_requests,
806         *request_id;
807
808     rpc = open_jsonrpc(server);
809
810     schema = fetch_schema_from_rpc(rpc, database);
811     table = shash_find_data(&schema->tables, table_name);
812     if (!table) {
813         ovs_fatal(0, "%s: %s does not have a table named \"%s\"",
814                   server, database, table_name);
815     }
816
817     if (argc >= 5 && *argv[4] != '\0') {
818         char *save_ptr = NULL;
819         char *token;
820
821         for (token = strtok_r(argv[4], ",", &save_ptr); token != NULL;
822              token = strtok_r(NULL, ",", &save_ptr)) {
823             const struct ovsdb_column *column;
824             column = ovsdb_table_schema_get_column(table, token);
825             if (!column) {
826                 ovs_fatal(0, "%s: table \"%s\" in %s does not have a "
827                           "column named \"%s\"",
828                           server, table_name, database, token);
829             }
830             ovsdb_column_set_add(&columns, column);
831         }
832     } else {
833         struct shash_node *node;
834
835         SHASH_FOR_EACH (node, &table->columns) {
836             const struct ovsdb_column *column = node->data;
837             if (column->index != OVSDB_COL_UUID) {
838                 ovsdb_column_set_add(&columns, column);
839             }
840         }
841     }
842
843     if (argc >= 6 && *argv[5] != '\0') {
844         char *save_ptr = NULL;
845         char *token;
846
847         select = json_object_create();
848         for (token = strtok_r(argv[5], ",", &save_ptr); token != NULL;
849              token = strtok_r(NULL, ",", &save_ptr)) {
850             json_object_put(select, token, json_boolean_create(true));
851         }
852     } else {
853         select = NULL;
854     }
855
856     monitor_request = json_object_create();
857     json_object_put(monitor_request,
858                     "columns", ovsdb_column_set_to_json(&columns));
859     if (select) {
860         json_object_put(monitor_request, "select", select);
861     }
862
863     monitor_requests = json_object_create();
864     json_object_put(monitor_requests, table_name, monitor_request);
865
866     monitor = json_array_create_3(json_string_create(database),
867                                   json_null_create(), monitor_requests);
868     request = jsonrpc_create_request("monitor", monitor, NULL);
869     request_id = json_clone(request->id);
870     jsonrpc_send(rpc, request);
871     for (;;) {
872         struct jsonrpc_msg *msg;
873         int error;
874
875         error = jsonrpc_recv_block(rpc, &msg);
876         if (error) {
877             ovsdb_schema_destroy(schema);
878             ovs_fatal(error, "%s: receive failed", server);
879         }
880
881         if (msg->type == JSONRPC_REQUEST && !strcmp(msg->method, "echo")) {
882             jsonrpc_send(rpc, jsonrpc_create_reply(json_clone(msg->params),
883                                                    msg->id));
884         } else if (msg->type == JSONRPC_REPLY
885                    && json_equal(msg->id, request_id)) {
886             monitor_print(msg->result, table, &columns, true);
887             fflush(stdout);
888             if (get_detach()) {
889                 /* daemonize() closes the standard file descriptors.  We output
890                  * to stdout, so we need to save and restore STDOUT_FILENO. */
891                 int fd = dup(STDOUT_FILENO);
892                 daemonize();
893                 dup2(fd, STDOUT_FILENO);
894                 close(fd);
895             }
896         } else if (msg->type == JSONRPC_NOTIFY
897                    && !strcmp(msg->method, "update")) {
898             struct json *params = msg->params;
899             if (params->type == JSON_ARRAY
900                 && params->u.array.n == 2
901                 && params->u.array.elems[0]->type == JSON_NULL) {
902                 monitor_print(params->u.array.elems[1],
903                               table, &columns, false);
904                 fflush(stdout);
905             }
906         }
907         jsonrpc_msg_destroy(msg);
908     }
909 }
910
911 static void
912 do_help(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
913 {
914     usage();
915 }
916
917 static const struct command all_commands[] = {
918     { "list-dbs", 1, 1, do_list_dbs },
919     { "get-schema", 2, 2, do_get_schema },
920     { "list-tables", 2, 2, do_list_tables },
921     { "list-columns", 2, 3, do_list_columns },
922     { "transact", 2, 2, do_transact },
923     { "monitor", 3, 5, do_monitor },
924     { "help", 0, INT_MAX, do_help },
925     { NULL, 0, 0, NULL },
926 };