ovsdb-monitor: stores jsonrpc-monitor in a linked-list
[cascardo/ovs.git] / ovsdb / ovsdb-server.c
1 /* Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc.
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #include <config.h>
17
18 #include <errno.h>
19 #include <getopt.h>
20 #include <inttypes.h>
21 #include <signal.h>
22 #include <sys/stat.h>
23 #include <unistd.h>
24
25 #include "column.h"
26 #include "command-line.h"
27 #include "daemon.h"
28 #include "dirs.h"
29 #include "dynamic-string.h"
30 #include "fatal-signal.h"
31 #include "file.h"
32 #include "hash.h"
33 #include "json.h"
34 #include "jsonrpc.h"
35 #include "jsonrpc-server.h"
36 #include "list.h"
37 #include "memory.h"
38 #include "ovsdb.h"
39 #include "ovsdb-data.h"
40 #include "ovsdb-types.h"
41 #include "ovsdb-error.h"
42 #include "poll-loop.h"
43 #include "process.h"
44 #include "row.h"
45 #include "simap.h"
46 #include "shash.h"
47 #include "stream-ssl.h"
48 #include "stream.h"
49 #include "sset.h"
50 #include "table.h"
51 #include "timeval.h"
52 #include "transaction.h"
53 #include "trigger.h"
54 #include "util.h"
55 #include "unixctl.h"
56 #include "perf-counter.h"
57 #include "openvswitch/vlog.h"
58
59 VLOG_DEFINE_THIS_MODULE(ovsdb_server);
60
61 struct db {
62     /* Initialized in main(). */
63     char *filename;
64     struct ovsdb_file *file;
65     struct ovsdb *db;
66
67     /* Only used by update_remote_status(). */
68     struct ovsdb_txn *txn;
69 };
70
71 /* SSL configuration. */
72 static char *private_key_file;
73 static char *certificate_file;
74 static char *ca_cert_file;
75 static bool bootstrap_ca_cert;
76
77 static unixctl_cb_func ovsdb_server_exit;
78 static unixctl_cb_func ovsdb_server_compact;
79 static unixctl_cb_func ovsdb_server_reconnect;
80 static unixctl_cb_func ovsdb_server_perf_counters_clear;
81 static unixctl_cb_func ovsdb_server_perf_counters_show;
82
83 struct server_config {
84     struct sset *remotes;
85     struct shash *all_dbs;
86     FILE *config_tmpfile;
87     struct ovsdb_jsonrpc_server *jsonrpc;
88 };
89 static unixctl_cb_func ovsdb_server_add_remote;
90 static unixctl_cb_func ovsdb_server_remove_remote;
91 static unixctl_cb_func ovsdb_server_list_remotes;
92
93 static unixctl_cb_func ovsdb_server_add_database;
94 static unixctl_cb_func ovsdb_server_remove_database;
95 static unixctl_cb_func ovsdb_server_list_databases;
96
97 static char *open_db(struct server_config *config, const char *filename);
98 static void close_db(struct db *db);
99
100 static void parse_options(int *argc, char **argvp[],
101                           struct sset *remotes, char **unixctl_pathp,
102                           char **run_command);
103 OVS_NO_RETURN static void usage(void);
104
105 static char *reconfigure_remotes(struct ovsdb_jsonrpc_server *,
106                                  const struct shash *all_dbs,
107                                  struct sset *remotes);
108 static char *reconfigure_ssl(const struct shash *all_dbs);
109 static void report_error_if_changed(char *error, char **last_errorp);
110
111 static void update_remote_status(const struct ovsdb_jsonrpc_server *jsonrpc,
112                                  const struct sset *remotes,
113                                  struct shash *all_dbs);
114
115 static void save_config__(FILE *config_file, const struct sset *remotes,
116                           const struct sset *db_filenames);
117 static void save_config(struct server_config *);
118 static void load_config(FILE *config_file, struct sset *remotes,
119                         struct sset *db_filenames);
120
121 static void
122 main_loop(struct ovsdb_jsonrpc_server *jsonrpc, struct shash *all_dbs,
123           struct unixctl_server *unixctl, struct sset *remotes,
124           struct process *run_process, bool *exiting)
125 {
126     char *remotes_error, *ssl_error;
127     struct shash_node *node;
128     long long int status_timer = LLONG_MIN;
129
130     *exiting = false;
131     ssl_error = NULL;
132     remotes_error = NULL;
133     while (!*exiting) {
134         memory_run();
135         if (memory_should_report()) {
136             struct simap usage;
137
138             simap_init(&usage);
139             ovsdb_jsonrpc_server_get_memory_usage(jsonrpc, &usage);
140             SHASH_FOR_EACH(node, all_dbs) {
141                 struct db *db = node->data;
142                 ovsdb_get_memory_usage(db->db, &usage);
143             }
144             memory_report(&usage);
145             simap_destroy(&usage);
146         }
147
148         /* Run unixctl_server_run() before reconfigure_remotes() because
149          * ovsdb-server/add-remote and ovsdb-server/remove-remote can change
150          * the set of remotes that reconfigure_remotes() uses. */
151         unixctl_server_run(unixctl);
152
153         report_error_if_changed(
154             reconfigure_remotes(jsonrpc, all_dbs, remotes),
155             &remotes_error);
156         report_error_if_changed(reconfigure_ssl(all_dbs), &ssl_error);
157         ovsdb_jsonrpc_server_run(jsonrpc);
158
159         SHASH_FOR_EACH(node, all_dbs) {
160             struct db *db = node->data;
161             ovsdb_trigger_run(db->db, time_msec());
162         }
163         if (run_process) {
164             process_run();
165             if (process_exited(run_process)) {
166                 *exiting = true;
167             }
168         }
169
170         /* update Manager status(es) every 5 seconds */
171         if (time_msec() >= status_timer) {
172             status_timer = time_msec() + 5000;
173             update_remote_status(jsonrpc, remotes, all_dbs);
174         }
175
176         memory_wait();
177         ovsdb_jsonrpc_server_wait(jsonrpc);
178         unixctl_server_wait(unixctl);
179         SHASH_FOR_EACH(node, all_dbs) {
180             struct db *db = node->data;
181             ovsdb_trigger_wait(db->db, time_msec());
182         }
183         if (run_process) {
184             process_wait(run_process);
185         }
186         if (*exiting) {
187             poll_immediate_wake();
188         }
189         poll_timer_wait_until(status_timer);
190         poll_block();
191         if (should_service_stop()) {
192             *exiting = true;
193         }
194     }
195
196 }
197
198 int
199 main(int argc, char *argv[])
200 {
201     char *unixctl_path = NULL;
202     char *run_command = NULL;
203     struct unixctl_server *unixctl;
204     struct ovsdb_jsonrpc_server *jsonrpc;
205     struct sset remotes, db_filenames;
206     const char *db_filename;
207     struct process *run_process;
208     bool exiting;
209     int retval;
210     FILE *config_tmpfile;
211     struct server_config server_config;
212     struct shash all_dbs;
213     struct shash_node *node, *next;
214     char *error;
215     int i;
216
217     ovs_cmdl_proctitle_init(argc, argv);
218     set_program_name(argv[0]);
219     service_start(&argc, &argv);
220     fatal_ignore_sigpipe();
221     process_init();
222
223     parse_options(&argc, &argv, &remotes, &unixctl_path, &run_command);
224
225     /* Create and initialize 'config_tmpfile' as a temporary file to hold
226      * ovsdb-server's most basic configuration, and then save our initial
227      * configuration to it.  When --monitor is used, this preserves the effects
228      * of ovs-appctl commands such as ovsdb-server/add-remote (which saves the
229      * new configuration) across crashes. */
230     config_tmpfile = tmpfile();
231     if (!config_tmpfile) {
232         ovs_fatal(errno, "failed to create temporary file");
233     }
234
235     sset_init(&db_filenames);
236     if (argc > 0) {
237         for (i = 0; i < argc; i++) {
238             sset_add(&db_filenames, argv[i]);
239          }
240     } else {
241         char *default_db = xasprintf("%s/conf.db", ovs_dbdir());
242         sset_add(&db_filenames, default_db);
243         free(default_db);
244     }
245
246     server_config.remotes = &remotes;
247     server_config.config_tmpfile = config_tmpfile;
248
249     save_config__(config_tmpfile, &remotes, &db_filenames);
250
251     daemonize_start();
252
253     /* Load the saved config. */
254     load_config(config_tmpfile, &remotes, &db_filenames);
255     jsonrpc = ovsdb_jsonrpc_server_create();
256
257     shash_init(&all_dbs);
258     server_config.all_dbs = &all_dbs;
259     server_config.jsonrpc = jsonrpc;
260     SSET_FOR_EACH (db_filename, &db_filenames) {
261         error = open_db(&server_config, db_filename);
262         if (error) {
263             ovs_fatal(0, "%s", error);
264         }
265     }
266
267     error = reconfigure_remotes(jsonrpc, &all_dbs, &remotes);
268     if (!error) {
269         error = reconfigure_ssl(&all_dbs);
270     }
271     if (error) {
272         ovs_fatal(0, "%s", error);
273     }
274
275     retval = unixctl_server_create(unixctl_path, &unixctl);
276     if (retval) {
277         exit(EXIT_FAILURE);
278     }
279
280     if (run_command) {
281         char *run_argv[4];
282
283         run_argv[0] = "/bin/sh";
284         run_argv[1] = "-c";
285         run_argv[2] = run_command;
286         run_argv[3] = NULL;
287
288         retval = process_start(run_argv, &run_process);
289         if (retval) {
290             ovs_fatal(retval, "%s: process failed to start", run_command);
291         }
292     } else {
293         run_process = NULL;
294     }
295
296     daemonize_complete();
297
298     perf_counters_init();
299
300     if (!run_command) {
301         /* ovsdb-server is usually a long-running process, in which case it
302          * makes plenty of sense to log the version, but --run makes
303          * ovsdb-server more like a command-line tool, so skip it.  */
304         VLOG_INFO("%s (Open vSwitch) %s", program_name, VERSION);
305     }
306
307     unixctl_command_register("exit", "", 0, 0, ovsdb_server_exit, &exiting);
308     unixctl_command_register("ovsdb-server/compact", "", 0, 1,
309                              ovsdb_server_compact, &all_dbs);
310     unixctl_command_register("ovsdb-server/reconnect", "", 0, 0,
311                              ovsdb_server_reconnect, jsonrpc);
312
313     unixctl_command_register("ovsdb-server/add-remote", "REMOTE", 1, 1,
314                              ovsdb_server_add_remote, &server_config);
315     unixctl_command_register("ovsdb-server/remove-remote", "REMOTE", 1, 1,
316                              ovsdb_server_remove_remote, &server_config);
317     unixctl_command_register("ovsdb-server/list-remotes", "", 0, 0,
318                              ovsdb_server_list_remotes, &remotes);
319
320     unixctl_command_register("ovsdb-server/add-db", "DB", 1, 1,
321                              ovsdb_server_add_database, &server_config);
322     unixctl_command_register("ovsdb-server/remove-db", "DB", 1, 1,
323                              ovsdb_server_remove_database, &server_config);
324     unixctl_command_register("ovsdb-server/list-dbs", "", 0, 0,
325                              ovsdb_server_list_databases, &all_dbs);
326     unixctl_command_register("ovsdb-server/perf-counters-show", "", 0, 0,
327                              ovsdb_server_perf_counters_show, NULL);
328     unixctl_command_register("ovsdb-server/perf-counters-clear", "", 0, 0,
329                              ovsdb_server_perf_counters_clear, NULL);
330
331     main_loop(jsonrpc, &all_dbs, unixctl, &remotes, run_process, &exiting);
332
333     ovsdb_jsonrpc_server_destroy(jsonrpc);
334     SHASH_FOR_EACH_SAFE(node, next, &all_dbs) {
335         struct db *db = node->data;
336         close_db(db);
337         shash_delete(&all_dbs, node);
338     }
339     sset_destroy(&remotes);
340     sset_destroy(&db_filenames);
341     unixctl_server_destroy(unixctl);
342
343     if (run_process && process_exited(run_process)) {
344         int status = process_status(run_process);
345         if (status) {
346             ovs_fatal(0, "%s: child exited, %s",
347                       run_command, process_status_msg(status));
348         }
349     }
350     perf_counters_destroy();
351     service_stop();
352     return 0;
353 }
354
355 /* Returns true if 'filename' is known to be already open as a database,
356  * false if not.
357  *
358  * "False negatives" are possible. */
359 static bool
360 is_already_open(struct server_config *config OVS_UNUSED,
361                 const char *filename OVS_UNUSED)
362 {
363 #ifndef _WIN32
364     struct stat s;
365
366     if (!stat(filename, &s)) {
367         struct shash_node *node;
368
369         SHASH_FOR_EACH (node, config->all_dbs) {
370             struct db *db = node->data;
371             struct stat s2;
372
373             if (!stat(db->filename, &s2)
374                 && s.st_dev == s2.st_dev
375                 && s.st_ino == s2.st_ino) {
376                 return true;
377             }
378         }
379     }
380 #endif  /* !_WIN32 */
381
382     return false;
383 }
384
385 static void
386 close_db(struct db *db)
387 {
388     ovsdb_destroy(db->db);
389     free(db->filename);
390     free(db);
391 }
392
393 static char *
394 open_db(struct server_config *config, const char *filename)
395 {
396     struct ovsdb_error *db_error;
397     struct db *db;
398     char *error;
399
400     /* If we know that the file is already open, return a good error message.
401      * Otherwise, if the file is open, we'll fail later on with a harder to
402      * interpret file locking error. */
403     if (is_already_open(config, filename)) {
404         return xasprintf("%s: already open", filename);
405     }
406
407     db = xzalloc(sizeof *db);
408     db->filename = xstrdup(filename);
409
410     db_error = ovsdb_file_open(db->filename, false, &db->db, &db->file);
411     if (db_error) {
412         error = ovsdb_error_to_string(db_error);
413     } else if (!ovsdb_jsonrpc_server_add_db(config->jsonrpc, db->db)) {
414         error = xasprintf("%s: duplicate database name", db->db->schema->name);
415     } else {
416         shash_add_assert(config->all_dbs, db->db->schema->name, db);
417         return NULL;
418     }
419
420     ovsdb_error_destroy(db_error);
421     close_db(db);
422     return error;
423 }
424
425 static const struct db *
426 find_db(const struct shash *all_dbs, const char *db_name)
427 {
428     struct shash_node *node;
429
430     SHASH_FOR_EACH(node, all_dbs) {
431         struct db *db = node->data;
432         if (!strcmp(db->db->schema->name, db_name)) {
433             return db;
434         }
435     }
436
437     return NULL;
438 }
439
440 static char * OVS_WARN_UNUSED_RESULT
441 parse_db_column__(const struct shash *all_dbs,
442                   const char *name_, char *name,
443                   const struct db **dbp,
444                   const struct ovsdb_table **tablep,
445                   const struct ovsdb_column **columnp)
446 {
447     const char *db_name, *table_name, *column_name;
448     const struct ovsdb_column *column;
449     const struct ovsdb_table *table;
450     const char *tokens[3];
451     char *save_ptr = NULL;
452     const struct db *db;
453
454     *dbp = NULL;
455     *tablep = NULL;
456     *columnp = NULL;
457
458     strtok_r(name, ":", &save_ptr); /* "db:" */
459     tokens[0] = strtok_r(NULL, ",", &save_ptr);
460     tokens[1] = strtok_r(NULL, ",", &save_ptr);
461     tokens[2] = strtok_r(NULL, ",", &save_ptr);
462     if (!tokens[0] || !tokens[1] || !tokens[2]) {
463         return xasprintf("\"%s\": invalid syntax", name_);
464     }
465
466     db_name = tokens[0];
467     table_name = tokens[1];
468     column_name = tokens[2];
469
470     db = find_db(all_dbs, tokens[0]);
471     if (!db) {
472         return xasprintf("\"%s\": no database named %s", name_, db_name);
473     }
474
475     table = ovsdb_get_table(db->db, table_name);
476     if (!table) {
477         return xasprintf("\"%s\": no table named %s", name_, table_name);
478     }
479
480     column = ovsdb_table_schema_get_column(table->schema, column_name);
481     if (!column) {
482         return xasprintf("\"%s\": table \"%s\" has no column \"%s\"",
483                          name_, table_name, column_name);
484     }
485
486     *dbp = db;
487     *columnp = column;
488     *tablep = table;
489     return NULL;
490 }
491
492 /* Returns NULL if successful, otherwise a malloc()'d string describing the
493  * error. */
494 static char * OVS_WARN_UNUSED_RESULT
495 parse_db_column(const struct shash *all_dbs,
496                 const char *name_,
497                 const struct db **dbp,
498                 const struct ovsdb_table **tablep,
499                 const struct ovsdb_column **columnp)
500 {
501     char *name = xstrdup(name_);
502     char *retval = parse_db_column__(all_dbs, name_, name,
503                                      dbp, tablep, columnp);
504     free(name);
505     return retval;
506 }
507
508 /* Returns NULL if successful, otherwise a malloc()'d string describing the
509  * error. */
510 static char * OVS_WARN_UNUSED_RESULT
511 parse_db_string_column(const struct shash *all_dbs,
512                        const char *name,
513                        const struct db **dbp,
514                        const struct ovsdb_table **tablep,
515                        const struct ovsdb_column **columnp)
516 {
517     char *retval;
518
519     retval = parse_db_column(all_dbs, name, dbp, tablep, columnp);
520     if (retval) {
521         return retval;
522     }
523
524     if ((*columnp)->type.key.type != OVSDB_TYPE_STRING
525         || (*columnp)->type.value.type != OVSDB_TYPE_VOID) {
526         return xasprintf("\"%s\": table \"%s\" column \"%s\" is "
527                          "not string or set of strings",
528                          name, (*tablep)->schema->name, (*columnp)->name);
529     }
530
531     return NULL;
532 }
533
534 static const char *
535 query_db_string(const struct shash *all_dbs, const char *name,
536                 struct ds *errors)
537 {
538     if (!name || strncmp(name, "db:", 3)) {
539         return name;
540     } else {
541         const struct ovsdb_column *column;
542         const struct ovsdb_table *table;
543         const struct ovsdb_row *row;
544         const struct db *db;
545         char *retval;
546
547         retval = parse_db_string_column(all_dbs, name,
548                                         &db, &table, &column);
549         if (retval) {
550             ds_put_format(errors, "%s\n", retval);
551             free(retval);
552             return NULL;
553         }
554
555         HMAP_FOR_EACH (row, hmap_node, &table->rows) {
556             const struct ovsdb_datum *datum;
557             size_t i;
558
559             datum = &row->fields[column->index];
560             for (i = 0; i < datum->n; i++) {
561                 if (datum->keys[i].string[0]) {
562                     return datum->keys[i].string;
563                 }
564             }
565         }
566         return NULL;
567     }
568 }
569
570 static struct ovsdb_jsonrpc_options *
571 add_remote(struct shash *remotes, const char *target)
572 {
573     struct ovsdb_jsonrpc_options *options;
574
575     options = shash_find_data(remotes, target);
576     if (!options) {
577         options = ovsdb_jsonrpc_default_options(target);
578         shash_add(remotes, target, options);
579     }
580
581     return options;
582 }
583
584 static struct ovsdb_datum *
585 get_datum(struct ovsdb_row *row, const char *column_name,
586           const enum ovsdb_atomic_type key_type,
587           const enum ovsdb_atomic_type value_type,
588           const size_t n_max)
589 {
590     static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
591     const struct ovsdb_table_schema *schema = row->table->schema;
592     const struct ovsdb_column *column;
593
594     column = ovsdb_table_schema_get_column(schema, column_name);
595     if (!column) {
596         VLOG_DBG_RL(&rl, "Table `%s' has no `%s' column",
597                     schema->name, column_name);
598         return NULL;
599     }
600
601     if (column->type.key.type != key_type
602         || column->type.value.type != value_type
603         || column->type.n_max != n_max) {
604         if (!VLOG_DROP_DBG(&rl)) {
605             char *type_name = ovsdb_type_to_english(&column->type);
606             VLOG_DBG("Table `%s' column `%s' has type %s, not expected "
607                      "key type %s, value type %s, max elements %"PRIuSIZE".",
608                      schema->name, column_name, type_name,
609                      ovsdb_atomic_type_to_string(key_type),
610                      ovsdb_atomic_type_to_string(value_type),
611                      n_max);
612             free(type_name);
613         }
614         return NULL;
615     }
616
617     return &row->fields[column->index];
618 }
619
620 /* Read string-string key-values from a map.  Returns the value associated with
621  * 'key', if found, or NULL */
622 static const char *
623 read_map_string_column(const struct ovsdb_row *row, const char *column_name,
624                        const char *key)
625 {
626     const struct ovsdb_datum *datum;
627     union ovsdb_atom *atom_key = NULL, *atom_value = NULL;
628     size_t i;
629
630     datum = get_datum(CONST_CAST(struct ovsdb_row *, row), column_name,
631                       OVSDB_TYPE_STRING, OVSDB_TYPE_STRING, UINT_MAX);
632
633     if (!datum) {
634         return NULL;
635     }
636
637     for (i = 0; i < datum->n; i++) {
638         atom_key = &datum->keys[i];
639         if (!strcmp(atom_key->string, key)){
640             atom_value = &datum->values[i];
641             break;
642         }
643     }
644
645     return atom_value ? atom_value->string : NULL;
646 }
647
648 static const union ovsdb_atom *
649 read_column(const struct ovsdb_row *row, const char *column_name,
650             enum ovsdb_atomic_type type)
651 {
652     const struct ovsdb_datum *datum;
653
654     datum = get_datum(CONST_CAST(struct ovsdb_row *, row), column_name, type,
655                       OVSDB_TYPE_VOID, 1);
656     return datum && datum->n ? datum->keys : NULL;
657 }
658
659 static bool
660 read_integer_column(const struct ovsdb_row *row, const char *column_name,
661                     long long int *integerp)
662 {
663     const union ovsdb_atom *atom;
664
665     atom = read_column(row, column_name, OVSDB_TYPE_INTEGER);
666     *integerp = atom ? atom->integer : 0;
667     return atom != NULL;
668 }
669
670 static bool
671 read_string_column(const struct ovsdb_row *row, const char *column_name,
672                    const char **stringp)
673 {
674     const union ovsdb_atom *atom;
675
676     atom = read_column(row, column_name, OVSDB_TYPE_STRING);
677     *stringp = atom ? atom->string : NULL;
678     return atom != NULL;
679 }
680
681 static void
682 write_bool_column(struct ovsdb_row *row, const char *column_name, bool value)
683 {
684     const struct ovsdb_column *column;
685     struct ovsdb_datum *datum;
686
687     column = ovsdb_table_schema_get_column(row->table->schema, column_name);
688     datum = get_datum(row, column_name, OVSDB_TYPE_BOOLEAN,
689                       OVSDB_TYPE_VOID, 1);
690     if (!datum) {
691         return;
692     }
693
694     if (datum->n != 1) {
695         ovsdb_datum_destroy(datum, &column->type);
696
697         datum->n = 1;
698         datum->keys = xmalloc(sizeof *datum->keys);
699         datum->values = NULL;
700     }
701
702     datum->keys[0].boolean = value;
703 }
704
705 static void
706 write_string_string_column(struct ovsdb_row *row, const char *column_name,
707                            char **keys, char **values, size_t n)
708 {
709     const struct ovsdb_column *column;
710     struct ovsdb_datum *datum;
711     size_t i;
712
713     column = ovsdb_table_schema_get_column(row->table->schema, column_name);
714     datum = get_datum(row, column_name, OVSDB_TYPE_STRING, OVSDB_TYPE_STRING,
715                       UINT_MAX);
716     if (!datum) {
717         for (i = 0; i < n; i++) {
718             free(keys[i]);
719             free(values[i]);
720         }
721         return;
722     }
723
724     /* Free existing data. */
725     ovsdb_datum_destroy(datum, &column->type);
726
727     /* Allocate space for new values. */
728     datum->n = n;
729     datum->keys = xmalloc(n * sizeof *datum->keys);
730     datum->values = xmalloc(n * sizeof *datum->values);
731
732     for (i = 0; i < n; ++i) {
733         datum->keys[i].string = keys[i];
734         datum->values[i].string = values[i];
735     }
736
737     /* Sort and check constraints. */
738     ovsdb_datum_sort_assert(datum, column->type.key.type);
739 }
740
741 /* Adds a remote and options to 'remotes', based on the Manager table row in
742  * 'row'. */
743 static void
744 add_manager_options(struct shash *remotes, const struct ovsdb_row *row)
745 {
746     static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
747     struct ovsdb_jsonrpc_options *options;
748     long long int max_backoff, probe_interval;
749     const char *target, *dscp_string;
750
751     if (!read_string_column(row, "target", &target) || !target) {
752         VLOG_INFO_RL(&rl, "Table `%s' has missing or invalid `target' column",
753                      row->table->schema->name);
754         return;
755     }
756
757     options = add_remote(remotes, target);
758     if (read_integer_column(row, "max_backoff", &max_backoff)) {
759         options->max_backoff = max_backoff;
760     }
761     if (read_integer_column(row, "inactivity_probe", &probe_interval)) {
762         options->probe_interval = probe_interval;
763     }
764
765     options->dscp = DSCP_DEFAULT;
766     dscp_string = read_map_string_column(row, "other_config", "dscp");
767     if (dscp_string) {
768         int dscp = atoi(dscp_string);
769         if (dscp >= 0 && dscp <= 63) {
770             options->dscp = dscp;
771         }
772     }
773 }
774
775 static void
776 query_db_remotes(const char *name, const struct shash *all_dbs,
777                  struct shash *remotes, struct ds *errors)
778 {
779     const struct ovsdb_column *column;
780     const struct ovsdb_table *table;
781     const struct ovsdb_row *row;
782     const struct db *db;
783     char *retval;
784
785     retval = parse_db_column(all_dbs, name, &db, &table, &column);
786     if (retval) {
787         ds_put_format(errors, "%s\n", retval);
788         free(retval);
789         return;
790     }
791
792     if (column->type.key.type == OVSDB_TYPE_STRING
793         && column->type.value.type == OVSDB_TYPE_VOID) {
794         HMAP_FOR_EACH (row, hmap_node, &table->rows) {
795             const struct ovsdb_datum *datum;
796             size_t i;
797
798             datum = &row->fields[column->index];
799             for (i = 0; i < datum->n; i++) {
800                 add_remote(remotes, datum->keys[i].string);
801             }
802         }
803     } else if (column->type.key.type == OVSDB_TYPE_UUID
804                && column->type.key.u.uuid.refTable
805                && column->type.value.type == OVSDB_TYPE_VOID) {
806         const struct ovsdb_table *ref_table = column->type.key.u.uuid.refTable;
807         HMAP_FOR_EACH (row, hmap_node, &table->rows) {
808             const struct ovsdb_datum *datum;
809             size_t i;
810
811             datum = &row->fields[column->index];
812             for (i = 0; i < datum->n; i++) {
813                 const struct ovsdb_row *ref_row;
814
815                 ref_row = ovsdb_table_get_row(ref_table, &datum->keys[i].uuid);
816                 if (ref_row) {
817                     add_manager_options(remotes, ref_row);
818                 }
819             }
820         }
821     }
822 }
823
824 static void
825 update_remote_row(const struct ovsdb_row *row, struct ovsdb_txn *txn,
826                   const struct ovsdb_jsonrpc_server *jsonrpc)
827 {
828     struct ovsdb_jsonrpc_remote_status status;
829     struct ovsdb_row *rw_row;
830     const char *target;
831     char *keys[9], *values[9];
832     size_t n = 0;
833
834     /* Get the "target" (protocol/host/port) spec. */
835     if (!read_string_column(row, "target", &target)) {
836         /* Bad remote spec or incorrect schema. */
837         return;
838     }
839     rw_row = ovsdb_txn_row_modify(txn, row);
840     ovsdb_jsonrpc_server_get_remote_status(jsonrpc, target, &status);
841
842     /* Update status information columns. */
843     write_bool_column(rw_row, "is_connected", status.is_connected);
844
845     if (status.state) {
846         keys[n] = xstrdup("state");
847         values[n++] = xstrdup(status.state);
848     }
849     if (status.sec_since_connect != UINT_MAX) {
850         keys[n] = xstrdup("sec_since_connect");
851         values[n++] = xasprintf("%u", status.sec_since_connect);
852     }
853     if (status.sec_since_disconnect != UINT_MAX) {
854         keys[n] = xstrdup("sec_since_disconnect");
855         values[n++] = xasprintf("%u", status.sec_since_disconnect);
856     }
857     if (status.last_error) {
858         keys[n] = xstrdup("last_error");
859         values[n++] =
860             xstrdup(ovs_retval_to_string(status.last_error));
861     }
862     if (status.locks_held && status.locks_held[0]) {
863         keys[n] = xstrdup("locks_held");
864         values[n++] = xstrdup(status.locks_held);
865     }
866     if (status.locks_waiting && status.locks_waiting[0]) {
867         keys[n] = xstrdup("locks_waiting");
868         values[n++] = xstrdup(status.locks_waiting);
869     }
870     if (status.locks_lost && status.locks_lost[0]) {
871         keys[n] = xstrdup("locks_lost");
872         values[n++] = xstrdup(status.locks_lost);
873     }
874     if (status.n_connections > 1) {
875         keys[n] = xstrdup("n_connections");
876         values[n++] = xasprintf("%d", status.n_connections);
877     }
878     if (status.bound_port != htons(0)) {
879         keys[n] = xstrdup("bound_port");
880         values[n++] = xasprintf("%"PRIu16, ntohs(status.bound_port));
881     }
882     write_string_string_column(rw_row, "status", keys, values, n);
883
884     ovsdb_jsonrpc_server_free_remote_status(&status);
885 }
886
887 static void
888 update_remote_rows(const struct shash *all_dbs,
889                    const char *remote_name,
890                    const struct ovsdb_jsonrpc_server *jsonrpc)
891 {
892     const struct ovsdb_table *table, *ref_table;
893     const struct ovsdb_column *column;
894     const struct ovsdb_row *row;
895     const struct db *db;
896     char *retval;
897
898     if (strncmp("db:", remote_name, 3)) {
899         return;
900     }
901
902     retval = parse_db_column(all_dbs, remote_name, &db, &table, &column);
903     if (retval) {
904         free(retval);
905         return;
906     }
907
908     if (column->type.key.type != OVSDB_TYPE_UUID
909         || !column->type.key.u.uuid.refTable
910         || column->type.value.type != OVSDB_TYPE_VOID) {
911         return;
912     }
913
914     ref_table = column->type.key.u.uuid.refTable;
915
916     HMAP_FOR_EACH (row, hmap_node, &table->rows) {
917         const struct ovsdb_datum *datum;
918         size_t i;
919
920         datum = &row->fields[column->index];
921         for (i = 0; i < datum->n; i++) {
922             const struct ovsdb_row *ref_row;
923
924             ref_row = ovsdb_table_get_row(ref_table, &datum->keys[i].uuid);
925             if (ref_row) {
926                 update_remote_row(ref_row, db->txn, jsonrpc);
927             }
928         }
929     }
930 }
931
932 static void
933 update_remote_status(const struct ovsdb_jsonrpc_server *jsonrpc,
934                      const struct sset *remotes,
935                      struct shash *all_dbs)
936 {
937     static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
938     const char *remote;
939     struct db *db;
940     struct shash_node *node;
941
942     SHASH_FOR_EACH(node, all_dbs) {
943         db = node->data;
944         db->txn = ovsdb_txn_create(db->db);
945     }
946
947     /* Iterate over --remote arguments given on command line. */
948     SSET_FOR_EACH (remote, remotes) {
949         update_remote_rows(all_dbs, remote, jsonrpc);
950     }
951
952     SHASH_FOR_EACH(node, all_dbs) {
953         struct ovsdb_error *error;
954         db = node->data;
955         error = ovsdb_txn_commit(db->txn, false);
956         if (error) {
957             VLOG_ERR_RL(&rl, "Failed to update remote status: %s",
958                         ovsdb_error_to_string(error));
959             ovsdb_error_destroy(error);
960         }
961     }
962 }
963
964 /* Reconfigures ovsdb-server's remotes based on information in the database. */
965 static char *
966 reconfigure_remotes(struct ovsdb_jsonrpc_server *jsonrpc,
967                     const struct shash *all_dbs, struct sset *remotes)
968 {
969     struct ds errors = DS_EMPTY_INITIALIZER;
970     struct shash resolved_remotes;
971     const char *name;
972
973     /* Configure remotes. */
974     shash_init(&resolved_remotes);
975     SSET_FOR_EACH (name, remotes) {
976         if (!strncmp(name, "db:", 3)) {
977             query_db_remotes(name, all_dbs, &resolved_remotes, &errors);
978         } else {
979             add_remote(&resolved_remotes, name);
980         }
981     }
982     ovsdb_jsonrpc_server_set_remotes(jsonrpc, &resolved_remotes);
983     shash_destroy_free_data(&resolved_remotes);
984
985     return errors.string;
986 }
987
988 static char *
989 reconfigure_ssl(const struct shash *all_dbs)
990 {
991     struct ds errors = DS_EMPTY_INITIALIZER;
992     const char *resolved_private_key;
993     const char *resolved_certificate;
994     const char *resolved_ca_cert;
995
996     resolved_private_key = query_db_string(all_dbs, private_key_file, &errors);
997     resolved_certificate = query_db_string(all_dbs, certificate_file, &errors);
998     resolved_ca_cert = query_db_string(all_dbs, ca_cert_file, &errors);
999
1000     stream_ssl_set_key_and_cert(resolved_private_key, resolved_certificate);
1001     stream_ssl_set_ca_cert_file(resolved_ca_cert, bootstrap_ca_cert);
1002
1003     return errors.string;
1004 }
1005
1006 static void
1007 report_error_if_changed(char *error, char **last_errorp)
1008 {
1009     if (error) {
1010         if (!*last_errorp || strcmp(error, *last_errorp)) {
1011             VLOG_WARN("%s", error);
1012             free(*last_errorp);
1013             *last_errorp = error;
1014             return;
1015         }
1016         free(error);
1017     } else {
1018         free(*last_errorp);
1019         *last_errorp = NULL;
1020     }
1021 }
1022
1023 static void
1024 ovsdb_server_exit(struct unixctl_conn *conn, int argc OVS_UNUSED,
1025                   const char *argv[] OVS_UNUSED,
1026                   void *exiting_)
1027 {
1028     bool *exiting = exiting_;
1029     *exiting = true;
1030     unixctl_command_reply(conn, NULL);
1031 }
1032
1033 static void
1034 ovsdb_server_perf_counters_show(struct unixctl_conn *conn, int argc OVS_UNUSED,
1035                                 const char *argv[] OVS_UNUSED,
1036                                 void *arg_ OVS_UNUSED)
1037 {
1038     char *s = perf_counters_to_string();
1039
1040     unixctl_command_reply(conn, s);
1041     free(s);
1042 }
1043
1044 static void
1045 ovsdb_server_perf_counters_clear(struct unixctl_conn *conn, int argc OVS_UNUSED,
1046                                  const char *argv[] OVS_UNUSED,
1047                                  void *arg_ OVS_UNUSED)
1048 {
1049     perf_counters_clear();
1050     unixctl_command_reply(conn, NULL);
1051 }
1052
1053 static void
1054 ovsdb_server_compact(struct unixctl_conn *conn, int argc,
1055                      const char *argv[], void *dbs_)
1056 {
1057     struct shash *all_dbs = dbs_;
1058     struct ds reply;
1059     struct db *db;
1060     struct shash_node *node;
1061     int n = 0;
1062
1063     ds_init(&reply);
1064     SHASH_FOR_EACH(node, all_dbs) {
1065         const char *name;
1066
1067         db = node->data;
1068         name = db->db->schema->name;
1069
1070         if (argc < 2 || !strcmp(argv[1], name)) {
1071             struct ovsdb_error *error;
1072
1073             VLOG_INFO("compacting %s database by user request", name);
1074
1075             error = ovsdb_file_compact(db->file);
1076             if (error) {
1077                 char *s = ovsdb_error_to_string(error);
1078                 ds_put_format(&reply, "%s\n", s);
1079                 free(s);
1080                 ovsdb_error_destroy(error);
1081             }
1082
1083             n++;
1084         }
1085     }
1086
1087     if (!n) {
1088         unixctl_command_reply_error(conn, "no database by that name");
1089     } else if (reply.length) {
1090         unixctl_command_reply_error(conn, ds_cstr(&reply));
1091     } else {
1092         unixctl_command_reply(conn, NULL);
1093     }
1094     ds_destroy(&reply);
1095 }
1096
1097 /* "ovsdb-server/reconnect": makes ovsdb-server drop all of its JSON-RPC
1098  * connections and reconnect. */
1099 static void
1100 ovsdb_server_reconnect(struct unixctl_conn *conn, int argc OVS_UNUSED,
1101                        const char *argv[] OVS_UNUSED, void *jsonrpc_)
1102 {
1103     struct ovsdb_jsonrpc_server *jsonrpc = jsonrpc_;
1104
1105     ovsdb_jsonrpc_server_reconnect(jsonrpc);
1106     unixctl_command_reply(conn, NULL);
1107 }
1108
1109 /* "ovsdb-server/add-remote REMOTE": adds REMOTE to the set of remotes that
1110  * ovsdb-server services. */
1111 static void
1112 ovsdb_server_add_remote(struct unixctl_conn *conn, int argc OVS_UNUSED,
1113                         const char *argv[], void *config_)
1114 {
1115     struct server_config *config = config_;
1116     const char *remote = argv[1];
1117
1118     const struct ovsdb_column *column;
1119     const struct ovsdb_table *table;
1120     const struct db *db;
1121     char *retval;
1122
1123     retval = (strncmp("db:", remote, 3)
1124               ? NULL
1125               : parse_db_column(config->all_dbs, remote,
1126                                 &db, &table, &column));
1127     if (!retval) {
1128         if (sset_add(config->remotes, remote)) {
1129             save_config(config);
1130         }
1131         unixctl_command_reply(conn, NULL);
1132     } else {
1133         unixctl_command_reply_error(conn, retval);
1134         free(retval);
1135     }
1136 }
1137
1138 /* "ovsdb-server/remove-remote REMOTE": removes REMOTE frmo the set of remotes
1139  * that ovsdb-server services. */
1140 static void
1141 ovsdb_server_remove_remote(struct unixctl_conn *conn, int argc OVS_UNUSED,
1142                            const char *argv[], void *config_)
1143 {
1144     struct server_config *config = config_;
1145     struct sset_node *node;
1146
1147     node = sset_find(config->remotes, argv[1]);
1148     if (node) {
1149         sset_delete(config->remotes, node);
1150         save_config(config);
1151         unixctl_command_reply(conn, NULL);
1152     } else {
1153         unixctl_command_reply_error(conn, "no such remote");
1154     }
1155 }
1156
1157 /* "ovsdb-server/list-remotes": outputs a list of configured rmeotes. */
1158 static void
1159 ovsdb_server_list_remotes(struct unixctl_conn *conn, int argc OVS_UNUSED,
1160                           const char *argv[] OVS_UNUSED, void *remotes_)
1161 {
1162     struct sset *remotes = remotes_;
1163     const char **list, **p;
1164     struct ds s;
1165
1166     ds_init(&s);
1167
1168     list = sset_sort(remotes);
1169     for (p = list; *p; p++) {
1170         ds_put_format(&s, "%s\n", *p);
1171     }
1172     free(list);
1173
1174     unixctl_command_reply(conn, ds_cstr(&s));
1175     ds_destroy(&s);
1176 }
1177
1178
1179 /* "ovsdb-server/add-db DB": adds the DB to ovsdb-server. */
1180 static void
1181 ovsdb_server_add_database(struct unixctl_conn *conn, int argc OVS_UNUSED,
1182                           const char *argv[], void *config_)
1183 {
1184     struct server_config *config = config_;
1185     const char *filename = argv[1];
1186     char *error;
1187
1188     error = open_db(config, filename);
1189     if (!error) {
1190         save_config(config);
1191         unixctl_command_reply(conn, NULL);
1192     } else {
1193         unixctl_command_reply_error(conn, error);
1194         free(error);
1195     }
1196 }
1197
1198 static void
1199 ovsdb_server_remove_database(struct unixctl_conn *conn, int argc OVS_UNUSED,
1200                              const char *argv[], void *config_)
1201 {
1202     struct server_config *config = config_;
1203     struct shash_node *node;
1204     struct db *db;
1205     bool ok;
1206
1207     node = shash_find(config->all_dbs, argv[1]);
1208     if (!node)  {
1209         unixctl_command_reply_error(conn, "Failed to find the database.");
1210         return;
1211     }
1212     db = node->data;
1213
1214     ok = ovsdb_jsonrpc_server_remove_db(config->jsonrpc, db->db);
1215     ovs_assert(ok);
1216
1217     close_db(db);
1218     shash_delete(config->all_dbs, node);
1219
1220     save_config(config);
1221     unixctl_command_reply(conn, NULL);
1222 }
1223
1224 static void
1225 ovsdb_server_list_databases(struct unixctl_conn *conn, int argc OVS_UNUSED,
1226                             const char *argv[] OVS_UNUSED, void *all_dbs_)
1227 {
1228     struct shash *all_dbs = all_dbs_;
1229     const struct shash_node **nodes;
1230     struct ds s;
1231     size_t i;
1232
1233     ds_init(&s);
1234
1235     nodes = shash_sort(all_dbs);
1236     for (i = 0; i < shash_count(all_dbs); i++) {
1237         struct db *db = nodes[i]->data;
1238         ds_put_format(&s, "%s\n", db->db->schema->name);
1239     }
1240     free(nodes);
1241
1242     unixctl_command_reply(conn, ds_cstr(&s));
1243     ds_destroy(&s);
1244 }
1245
1246 static void
1247 parse_options(int *argcp, char **argvp[],
1248               struct sset *remotes, char **unixctl_pathp, char **run_command)
1249 {
1250     enum {
1251         OPT_REMOTE = UCHAR_MAX + 1,
1252         OPT_UNIXCTL,
1253         OPT_RUN,
1254         OPT_BOOTSTRAP_CA_CERT,
1255         VLOG_OPTION_ENUMS,
1256         DAEMON_OPTION_ENUMS
1257     };
1258     static const struct option long_options[] = {
1259         {"remote",      required_argument, NULL, OPT_REMOTE},
1260         {"unixctl",     required_argument, NULL, OPT_UNIXCTL},
1261 #ifndef _WIN32
1262         {"run",         required_argument, NULL, OPT_RUN},
1263 #endif
1264         {"help",        no_argument, NULL, 'h'},
1265         {"version",     no_argument, NULL, 'V'},
1266         DAEMON_LONG_OPTIONS,
1267         VLOG_LONG_OPTIONS,
1268         {"bootstrap-ca-cert", required_argument, NULL, OPT_BOOTSTRAP_CA_CERT},
1269         {"private-key", required_argument, NULL, 'p'},
1270         {"certificate", required_argument, NULL, 'c'},
1271         {"ca-cert",     required_argument, NULL, 'C'},
1272         {NULL, 0, NULL, 0},
1273     };
1274     char *short_options = ovs_cmdl_long_options_to_short_options(long_options);
1275     int argc = *argcp;
1276     char **argv = *argvp;
1277
1278     sset_init(remotes);
1279     for (;;) {
1280         int c;
1281
1282         c = getopt_long(argc, argv, short_options, long_options, NULL);
1283         if (c == -1) {
1284             break;
1285         }
1286
1287         switch (c) {
1288         case OPT_REMOTE:
1289             sset_add(remotes, optarg);
1290             break;
1291
1292         case OPT_UNIXCTL:
1293             *unixctl_pathp = optarg;
1294             break;
1295
1296         case OPT_RUN:
1297             *run_command = optarg;
1298             break;
1299
1300         case 'h':
1301             usage();
1302
1303         case 'V':
1304             ovs_print_version(0, 0);
1305             exit(EXIT_SUCCESS);
1306
1307         VLOG_OPTION_HANDLERS
1308         DAEMON_OPTION_HANDLERS
1309
1310         case 'p':
1311             private_key_file = optarg;
1312             break;
1313
1314         case 'c':
1315             certificate_file = optarg;
1316             break;
1317
1318         case 'C':
1319             ca_cert_file = optarg;
1320             bootstrap_ca_cert = false;
1321             break;
1322
1323         case OPT_BOOTSTRAP_CA_CERT:
1324             ca_cert_file = optarg;
1325             bootstrap_ca_cert = true;
1326             break;
1327
1328         case '?':
1329             exit(EXIT_FAILURE);
1330
1331         default:
1332             abort();
1333         }
1334     }
1335     free(short_options);
1336
1337     *argcp -= optind;
1338     *argvp += optind;
1339 }
1340
1341 static void
1342 usage(void)
1343 {
1344     printf("%s: Open vSwitch database server\n"
1345            "usage: %s [OPTIONS] [DATABASE...]\n"
1346            "where each DATABASE is a database file in ovsdb format.\n"
1347            "The default DATABASE, if none is given, is\n%s/conf.db.\n",
1348            program_name, program_name, ovs_dbdir());
1349     printf("\nJSON-RPC options (may be specified any number of times):\n"
1350            "  --remote=REMOTE         connect or listen to REMOTE\n");
1351     stream_usage("JSON-RPC", true, true, true);
1352     daemon_usage();
1353     vlog_usage();
1354     printf("\nOther options:\n"
1355            "  --run COMMAND           run COMMAND as subprocess then exit\n"
1356            "  --unixctl=SOCKET        override default control socket name\n"
1357            "  -h, --help              display this help message\n"
1358            "  -V, --version           display version information\n");
1359     exit(EXIT_SUCCESS);
1360 }
1361 \f
1362 static struct json *
1363 sset_to_json(const struct sset *sset)
1364 {
1365     struct json *array;
1366     const char *s;
1367
1368     array = json_array_create_empty();
1369     SSET_FOR_EACH (s, sset) {
1370         json_array_add(array, json_string_create(s));
1371     }
1372     return array;
1373 }
1374
1375 /* Truncates and replaces the contents of 'config_file' by a representation of
1376  * 'remotes' and 'db_filenames'. */
1377 static void
1378 save_config__(FILE *config_file, const struct sset *remotes,
1379               const struct sset *db_filenames)
1380 {
1381     struct json *obj;
1382     char *s;
1383
1384     if (ftruncate(fileno(config_file), 0) == -1) {
1385         VLOG_FATAL("failed to truncate temporary file (%s)",
1386                    ovs_strerror(errno));
1387     }
1388
1389     obj = json_object_create();
1390     json_object_put(obj, "remotes", sset_to_json(remotes));
1391     json_object_put(obj, "db_filenames", sset_to_json(db_filenames));
1392     s = json_to_string(obj, 0);
1393     json_destroy(obj);
1394
1395     if (fseek(config_file, 0, SEEK_SET) != 0
1396         || fputs(s, config_file) == EOF
1397         || fflush(config_file) == EOF) {
1398         VLOG_FATAL("failed to write temporary file (%s)", ovs_strerror(errno));
1399     }
1400     free(s);
1401 }
1402
1403 /* Truncates and replaces the contents of 'config_file' by a representation of
1404  * 'config'. */
1405 static void
1406 save_config(struct server_config *config)
1407 {
1408     struct sset db_filenames;
1409     struct shash_node *node;
1410
1411     sset_init(&db_filenames);
1412     SHASH_FOR_EACH (node, config->all_dbs) {
1413         struct db *db = node->data;
1414         sset_add(&db_filenames, db->filename);
1415     }
1416
1417     save_config__(config->config_tmpfile, config->remotes, &db_filenames);
1418
1419     sset_destroy(&db_filenames);
1420 }
1421
1422 static void
1423 sset_from_json(struct sset *sset, const struct json *array)
1424 {
1425     size_t i;
1426
1427     sset_clear(sset);
1428
1429     ovs_assert(array->type == JSON_ARRAY);
1430     for (i = 0; i < array->u.array.n; i++) {
1431         const struct json *elem = array->u.array.elems[i];
1432         sset_add(sset, json_string(elem));
1433     }
1434 }
1435
1436 /* Clears and replaces 'remotes' and 'dbnames' by a configuration read from
1437  * 'config_file', which must have been previously written by save_config(). */
1438 static void
1439 load_config(FILE *config_file, struct sset *remotes, struct sset *db_filenames)
1440 {
1441     struct json *json;
1442
1443     if (fseek(config_file, 0, SEEK_SET) != 0) {
1444         VLOG_FATAL("seek failed in temporary file (%s)", ovs_strerror(errno));
1445     }
1446     json = json_from_stream(config_file);
1447     if (json->type == JSON_STRING) {
1448         VLOG_FATAL("reading json failed (%s)", json_string(json));
1449     }
1450     ovs_assert(json->type == JSON_OBJECT);
1451
1452     sset_from_json(remotes, shash_find_data(json_object(json), "remotes"));
1453     sset_from_json(db_filenames,
1454                    shash_find_data(json_object(json), "db_filenames"));
1455     json_destroy(json);
1456 }