2 * Copyright (c) 2015 Nicira, Inc.
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:
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
30 #include "db-ctl-base.h"
32 #include "command-line.h"
34 #include "dynamic-string.h"
35 #include "fatal-signal.h"
37 #include "ovsdb-data.h"
38 #include "ovsdb-idl.h"
39 #include "poll-loop.h"
43 #include "stream-ssl.h"
48 #include "openvswitch/vlog.h"
49 #include "ovn/lib/ovn-sb-idl.h"
51 VLOG_DEFINE_THIS_MODULE(sbctl);
55 /* --db: The database server to contact. */
56 static const char *db;
58 /* --oneline: Write each command's output as a single line? */
61 /* --dry-run: Do not commit any changes. */
64 /* --timeout: Time to wait for a connection to 'db'. */
67 /* Format for table output. */
68 static struct table_style table_style = TABLE_STYLE_DEFAULT;
70 /* The IDL we're using and the current transaction, if any.
71 * This is for use by sbctl_exit() only, to allow it to clean up.
72 * Other code should use its context arguments. */
73 static struct ovsdb_idl *the_idl;
74 static struct ovsdb_idl_txn *the_idl_txn;
75 OVS_NO_RETURN static void sbctl_exit(int status);
77 static void sbctl_cmd_init(void);
78 OVS_NO_RETURN static void usage(void);
79 static void parse_options(int argc, char *argv[], struct shash *local_options);
80 static void run_prerequisites(struct ctl_command[], size_t n_commands,
82 static void do_sbctl(const char *args, struct ctl_command *, size_t n,
86 main(int argc, char *argv[])
88 extern struct vlog_module VLM_reconnect;
89 struct ovsdb_idl *idl;
90 struct ctl_command *commands;
91 struct shash local_options;
96 set_program_name(argv[0]);
97 fatal_ignore_sigpipe();
98 vlog_set_levels(NULL, VLF_CONSOLE, VLL_WARN);
99 vlog_set_levels(&VLM_reconnect, VLF_ANY_DESTINATION, VLL_WARN);
104 /* Log our arguments. This is often valuable for debugging systems. */
105 args = process_escape_args(argv);
106 VLOG(ctl_might_write_to_db(argv) ? VLL_INFO : VLL_DBG, "Called as %s", args);
108 /* Parse command line. */
109 shash_init(&local_options);
110 parse_options(argc, argv, &local_options);
111 commands = ctl_parse_commands(argc - optind, argv + optind, &local_options,
118 /* Initialize IDL. */
119 idl = the_idl = ovsdb_idl_create(db, &sbrec_idl_class, false, false);
120 run_prerequisites(commands, n_commands, idl);
122 /* Execute the commands.
124 * 'seqno' is the database sequence number for which we last tried to
125 * execute our transaction. There's no point in trying to commit more than
126 * once for any given sequence number, because if the transaction fails
127 * it's because the database changed and we need to obtain an up-to-date
128 * view of the database before we try the transaction again. */
129 seqno = ovsdb_idl_get_seqno(idl);
132 if (!ovsdb_idl_is_alive(idl)) {
133 int retval = ovsdb_idl_get_last_error(idl);
134 ctl_fatal("%s: database connection failed (%s)",
135 db, ovs_retval_to_string(retval));
138 if (seqno != ovsdb_idl_get_seqno(idl)) {
139 seqno = ovsdb_idl_get_seqno(idl);
140 do_sbctl(args, commands, n_commands, idl);
143 if (seqno == ovsdb_idl_get_seqno(idl)) {
151 parse_options(int argc, char *argv[], struct shash *local_options)
154 OPT_DB = UCHAR_MAX + 1,
165 static const struct option global_long_options[] = {
166 {"db", required_argument, NULL, OPT_DB},
167 {"no-syslog", no_argument, NULL, OPT_NO_SYSLOG},
168 {"dry-run", no_argument, NULL, OPT_DRY_RUN},
169 {"oneline", no_argument, NULL, OPT_ONELINE},
170 {"timeout", required_argument, NULL, 't'},
171 {"help", no_argument, NULL, 'h'},
172 {"commands", no_argument, NULL, OPT_COMMANDS},
173 {"options", no_argument, NULL, OPT_OPTIONS},
174 {"version", no_argument, NULL, 'V'},
176 STREAM_SSL_LONG_OPTIONS,
180 const int n_global_long_options = ARRAY_SIZE(global_long_options) - 1;
181 char *tmp, *short_options;
183 struct option *options;
184 size_t allocated_options;
188 tmp = ovs_cmdl_long_options_to_short_options(global_long_options);
189 short_options = xasprintf("+%s", tmp);
192 /* We want to parse both global and command-specific options here, but
193 * getopt_long() isn't too convenient for the job. We copy our global
194 * options into a dynamic array, then append all of the command-specific
196 options = xmemdup(global_long_options, sizeof global_long_options);
197 allocated_options = ARRAY_SIZE(global_long_options);
198 n_options = n_global_long_options;
199 ctl_add_cmd_options(&options, &n_options, &allocated_options, OPT_LOCAL);
200 table_style.format = TF_LIST;
206 c = getopt_long(argc, argv, short_options, options, &idx);
221 vlog_set_levels(&VLM_sbctl, VLF_SYSLOG, VLL_WARN);
229 if (shash_find(local_options, options[idx].name)) {
230 ctl_fatal("'%s' option specified multiple times",
233 shash_add_nocopy(local_options,
234 xasprintf("--%s", options[idx].name),
235 optarg ? xstrdup(optarg) : NULL);
242 ctl_print_commands();
245 ctl_print_options(global_long_options);
248 ovs_print_version(0, 0);
249 printf("DB Schema %s\n", sbrec_get_db_version());
253 timeout = strtoul(optarg, NULL, 10);
255 ctl_fatal("value %s on -t or --timeout is invalid", optarg);
260 TABLE_OPTION_HANDLERS(&table_style)
261 STREAM_SSL_OPTION_HANDLERS
273 db = ctl_default_db();
276 for (i = n_global_long_options; options[i].name; i++) {
277 free(CONST_CAST(char *, options[i].name));
286 %s: OVN southbound DB management utility\n\
288 For debugging and testing only, not for use in production.\n\
290 usage: %s [OPTIONS] COMMAND [ARG...]\n\
293 show print overview of database contents\n\
296 chassis-add CHASSIS ENCAP-TYPE ENCAP-IP create a new chassis named\n\
297 CHASSIS with one encapsulation\n\
298 entry of ENCAP-TYPE and ENCAP-IP\n\
299 chassis-del CHASSIS delete CHASSIS and all of its encaps,\n\
302 Port binding commands:\n\
303 lport-bind LPORT CHASSIS bind logical port LPORT to CHASSIS\n\
304 lport-unbind LPORT reset the port binding of logical port LPORT\n\
306 Logical flow commands:\n\
307 lflow-list [DATAPATH] List logical flows for all or a single datapath\n\
308 dump-flows [DATAPATH] Alias for lflow-list\n\
313 --db=DATABASE connect to DATABASE\n\
315 -t, --timeout=SECS wait at most SECS seconds\n\
316 --dry-run do not commit changes to database\n\
317 --oneline print exactly one line of output per command\n",
318 program_name, program_name, ctl_get_db_cmd_usage(), ctl_default_db());
321 --no-syslog equivalent to --verbose=sbctl:syslog:warn\n");
324 -h, --help display this help message\n\
325 -V, --version display version information\n");
326 stream_usage("database", true, true, false);
331 /* ovs-sbctl specific context. Inherits the 'struct ctl_context' as base. */
332 struct sbctl_context {
333 struct ctl_context base;
335 /* A cache of the contents of the database.
337 * A command that needs to use any of this information must first call
338 * sbctl_context_populate_cache(). A command that changes anything that
339 * could invalidate the cache must either call
340 * sbctl_context_invalidate_cache() or manually update the cache to
341 * maintain its correctness. */
343 /* Maps from chassis name to struct sbctl_chassis. */
344 struct shash chassis;
345 /* Maps from lport name to struct sbctl_port_binding. */
346 struct shash port_bindings;
349 /* Casts 'base' into 'struct sbctl_context'. */
350 static struct sbctl_context *
351 sbctl_context_cast(struct ctl_context *base)
353 return CONTAINER_OF(base, struct sbctl_context, base);
356 struct sbctl_chassis {
357 const struct sbrec_chassis *ch_cfg;
360 struct sbctl_port_binding {
361 const struct sbrec_port_binding *bd_cfg;
365 sbctl_context_invalidate_cache(struct ctl_context *ctx)
367 struct sbctl_context *sbctl_ctx = sbctl_context_cast(ctx);
369 if (!sbctl_ctx->cache_valid) {
372 sbctl_ctx->cache_valid = false;
373 shash_destroy_free_data(&sbctl_ctx->chassis);
374 shash_destroy_free_data(&sbctl_ctx->port_bindings);
378 sbctl_context_populate_cache(struct ctl_context *ctx)
380 struct sbctl_context *sbctl_ctx = sbctl_context_cast(ctx);
381 const struct sbrec_chassis *chassis_rec;
382 const struct sbrec_port_binding *port_binding_rec;
383 struct sset chassis, port_bindings;
385 if (sbctl_ctx->cache_valid) {
386 /* Cache is already populated. */
389 sbctl_ctx->cache_valid = true;
390 shash_init(&sbctl_ctx->chassis);
391 shash_init(&sbctl_ctx->port_bindings);
393 SBREC_CHASSIS_FOR_EACH(chassis_rec, ctx->idl) {
394 struct sbctl_chassis *ch;
396 if (!sset_add(&chassis, chassis_rec->name)) {
397 VLOG_WARN("database contains duplicate chassis name (%s)",
402 ch = xmalloc(sizeof *ch);
403 ch->ch_cfg = chassis_rec;
404 shash_add(&sbctl_ctx->chassis, chassis_rec->name, ch);
406 sset_destroy(&chassis);
408 sset_init(&port_bindings);
409 SBREC_PORT_BINDING_FOR_EACH(port_binding_rec, ctx->idl) {
410 struct sbctl_port_binding *bd;
412 if (!sset_add(&port_bindings, port_binding_rec->logical_port)) {
413 VLOG_WARN("database contains duplicate port binding for logical "
415 port_binding_rec->logical_port);
419 bd = xmalloc(sizeof *bd);
420 bd->bd_cfg = port_binding_rec;
421 shash_add(&sbctl_ctx->port_bindings, port_binding_rec->logical_port,
424 sset_destroy(&port_bindings);
428 check_conflicts(struct sbctl_context *sbctl_ctx, const char *name,
431 if (shash_find(&sbctl_ctx->chassis, name)) {
432 ctl_fatal("%s because a chassis named %s already exists",
438 static struct sbctl_chassis *
439 find_chassis(struct sbctl_context *sbctl_ctx, const char *name,
442 struct sbctl_chassis *sbctl_ch;
444 ovs_assert(sbctl_ctx->cache_valid);
446 sbctl_ch = shash_find_data(&sbctl_ctx->chassis, name);
447 if (must_exist && !sbctl_ch) {
448 ctl_fatal("no chassis named %s", name);
454 static struct sbctl_port_binding *
455 find_port_binding(struct sbctl_context *sbctl_ctx, const char *name,
458 struct sbctl_port_binding *bd;
460 ovs_assert(sbctl_ctx->cache_valid);
462 bd = shash_find_data(&sbctl_ctx->port_bindings, name);
463 if (must_exist && !bd) {
464 ctl_fatal("no port named %s", name);
471 pre_get_info(struct ctl_context *ctx)
473 ovsdb_idl_add_column(ctx->idl, &sbrec_chassis_col_name);
474 ovsdb_idl_add_column(ctx->idl, &sbrec_chassis_col_encaps);
476 ovsdb_idl_add_column(ctx->idl, &sbrec_encap_col_type);
477 ovsdb_idl_add_column(ctx->idl, &sbrec_encap_col_ip);
479 ovsdb_idl_add_column(ctx->idl, &sbrec_port_binding_col_logical_port);
480 ovsdb_idl_add_column(ctx->idl, &sbrec_port_binding_col_chassis);
482 ovsdb_idl_add_column(ctx->idl, &sbrec_logical_flow_col_logical_datapath);
483 ovsdb_idl_add_column(ctx->idl, &sbrec_logical_flow_col_pipeline);
484 ovsdb_idl_add_column(ctx->idl, &sbrec_logical_flow_col_actions);
485 ovsdb_idl_add_column(ctx->idl, &sbrec_logical_flow_col_priority);
486 ovsdb_idl_add_column(ctx->idl, &sbrec_logical_flow_col_table_id);
487 ovsdb_idl_add_column(ctx->idl, &sbrec_logical_flow_col_match);
488 ovsdb_idl_add_column(ctx->idl, &sbrec_logical_flow_col_external_ids);
491 static struct cmd_show_table cmd_show_tables[] = {
492 {&sbrec_table_chassis,
493 &sbrec_chassis_col_name,
494 {&sbrec_chassis_col_encaps,
497 {&sbrec_table_port_binding,
498 &sbrec_port_binding_col_logical_port,
499 &sbrec_port_binding_col_chassis}},
502 &sbrec_encap_col_type,
503 {&sbrec_encap_col_ip,
504 &sbrec_encap_col_options,
508 {NULL, NULL, {NULL, NULL, NULL}, {NULL, NULL, NULL}},
512 cmd_chassis_add(struct ctl_context *ctx)
514 struct sbctl_context *sbctl_ctx = sbctl_context_cast(ctx);
515 struct sbrec_chassis *ch;
516 struct sbrec_encap *encap;
517 bool may_exist = shash_find(&ctx->options, "--may-exist") != NULL;
518 const char *ch_name, *encap_type, *encap_ip;
520 ch_name = ctx->argv[1];
521 encap_type = ctx->argv[2];
522 encap_ip = ctx->argv[3];
524 sbctl_context_populate_cache(ctx);
526 struct sbctl_chassis *sbctl_ch;
528 sbctl_ch = find_chassis(sbctl_ctx, ch_name, false);
533 check_conflicts(sbctl_ctx, ch_name,
534 xasprintf("cannot create a chassis named %s", ch_name));
535 ch = sbrec_chassis_insert(ctx->txn);
536 sbrec_chassis_set_name(ch, ch_name);
537 encap = sbrec_encap_insert(ctx->txn);
538 sbrec_encap_set_type(encap, encap_type);
539 sbrec_encap_set_ip(encap, encap_ip);
540 sbrec_chassis_set_encaps(ch, &encap, 1);
541 sbctl_context_invalidate_cache(ctx);
545 cmd_chassis_del(struct ctl_context *ctx)
547 struct sbctl_context *sbctl_ctx = sbctl_context_cast(ctx);
548 bool must_exist = !shash_find(&ctx->options, "--if-exists");
549 struct sbctl_chassis *sbctl_ch;
551 sbctl_context_populate_cache(ctx);
552 sbctl_ch = find_chassis(sbctl_ctx, ctx->argv[1], must_exist);
554 if (sbctl_ch->ch_cfg) {
557 for (i = 0; i < sbctl_ch->ch_cfg->n_encaps; i++) {
558 sbrec_encap_delete(sbctl_ch->ch_cfg->encaps[i]);
560 sbrec_chassis_delete(sbctl_ch->ch_cfg);
562 shash_find_and_delete(&sbctl_ctx->chassis, ctx->argv[1]);
568 cmd_lport_bind(struct ctl_context *ctx)
570 struct sbctl_context *sbctl_ctx = sbctl_context_cast(ctx);
571 bool may_exist = shash_find(&ctx->options, "--may-exist") != NULL;
572 struct sbctl_chassis *sbctl_ch;
573 struct sbctl_port_binding *sbctl_bd;
574 char *lport_name, *ch_name;
576 /* port_binding must exist, chassis must exist! */
577 lport_name = ctx->argv[1];
578 ch_name = ctx->argv[2];
580 sbctl_context_populate_cache(ctx);
581 sbctl_bd = find_port_binding(sbctl_ctx, lport_name, true);
582 sbctl_ch = find_chassis(sbctl_ctx, ch_name, true);
584 if (sbctl_bd->bd_cfg->chassis) {
585 if (may_exist && sbctl_bd->bd_cfg->chassis == sbctl_ch->ch_cfg) {
588 ctl_fatal("lport (%s) has already been binded to chassis (%s)",
589 lport_name, sbctl_bd->bd_cfg->chassis->name);
592 sbrec_port_binding_set_chassis(sbctl_bd->bd_cfg, sbctl_ch->ch_cfg);
593 sbctl_context_invalidate_cache(ctx);
597 cmd_lport_unbind(struct ctl_context *ctx)
599 struct sbctl_context *sbctl_ctx = sbctl_context_cast(ctx);
600 bool must_exist = !shash_find(&ctx->options, "--if-exists");
601 struct sbctl_port_binding *sbctl_bd;
604 lport_name = ctx->argv[1];
605 sbctl_context_populate_cache(ctx);
606 sbctl_bd = find_port_binding(sbctl_ctx, lport_name, must_exist);
608 sbrec_port_binding_set_chassis(sbctl_bd->bd_cfg, NULL);
617 /* Help ensure we catch any future pipeline values */
619 pipeline_encode(const char *pl)
621 if (!strcmp(pl, "ingress")) {
623 } else if (!strcmp(pl, "egress")) {
631 lflow_cmp(const void *lf1_, const void *lf2_)
633 const struct sbrec_logical_flow *const *lf1p = lf1_;
634 const struct sbrec_logical_flow *const *lf2p = lf2_;
635 const struct sbrec_logical_flow *lf1 = *lf1p;
636 const struct sbrec_logical_flow *lf2 = *lf2p;
638 int pl1 = pipeline_encode(lf1->pipeline);
639 int pl2 = pipeline_encode(lf2->pipeline);
650 CMP(uuid_compare_3way(&lf1->logical_datapath->header_.uuid,
651 &lf2->logical_datapath->header_.uuid));
653 CMP(lf1->table_id > lf2->table_id ? 1 :
654 (lf1->table_id < lf2->table_id ? -1 : 0));
655 CMP(lf1->priority > lf2->priority ? -1 :
656 (lf1->priority < lf2->priority ? 1 : 0));
657 CMP(strcmp(lf1->match, lf2->match));
665 cmd_lflow_list(struct ctl_context *ctx)
667 const char *datapath = ctx->argc == 2 ? ctx->argv[1] : NULL;
668 struct uuid datapath_uuid = { .parts = { 0, }};
669 const struct sbrec_logical_flow **lflows;
670 const struct sbrec_logical_flow *lflow;
671 size_t n_flows = 0, n_capacity = 64;
673 if (datapath && !uuid_from_string(&datapath_uuid, datapath)) {
674 VLOG_ERR("Invalid format of datapath UUID");
678 lflows = xmalloc(sizeof *lflows * n_capacity);
679 SBREC_LOGICAL_FLOW_FOR_EACH (lflow, ctx->idl) {
680 if (n_flows == n_capacity) {
681 lflows = x2nrealloc(lflows, &n_capacity, sizeof *lflows);
683 lflows[n_flows] = lflow;
687 qsort(lflows, n_flows, sizeof *lflows, lflow_cmp);
689 const char *cur_pipeline = "";
691 for (i = 0; i < n_flows; i++) {
693 if (datapath && !uuid_equals(&datapath_uuid,
694 &lflow->logical_datapath->header_.uuid)) {
697 if (strcmp(cur_pipeline, lflow->pipeline)) {
698 printf("Datapath: " UUID_FMT " Pipeline: %s\n",
699 UUID_ARGS(&lflow->logical_datapath->header_.uuid),
701 cur_pipeline = lflow->pipeline;
704 const char *table_name = smap_get(&lflow->external_ids, "stage-name");
705 printf(" table=%" PRId64 "(%8s), priority=%5" PRId64
706 ", match=(%s), action=(%s)\n",
707 lflow->table_id, table_name ? table_name : "",
708 lflow->priority, lflow->match, lflow->actions);
715 static const struct ctl_table_class tables[] = {
716 {&sbrec_table_chassis,
717 {{&sbrec_table_chassis, &sbrec_chassis_col_name, NULL},
718 {NULL, NULL, NULL}}},
722 {NULL, NULL, NULL}}},
724 {&sbrec_table_logical_flow,
725 {{&sbrec_table_logical_flow, NULL,
726 &sbrec_logical_flow_col_logical_datapath},
727 {NULL, NULL, NULL}}},
729 {&sbrec_table_multicast_group,
731 {NULL, NULL, NULL}}},
733 {&sbrec_table_datapath_binding,
735 {NULL, NULL, NULL}}},
737 {&sbrec_table_port_binding,
738 {{&sbrec_table_port_binding, &sbrec_port_binding_col_logical_port, NULL},
739 {NULL, NULL, NULL}}},
741 {NULL, {{NULL, NULL, NULL}, {NULL, NULL, NULL}}}
746 sbctl_context_init_command(struct sbctl_context *sbctl_ctx,
747 struct ctl_command *command)
749 ctl_context_init_command(&sbctl_ctx->base, command);
753 sbctl_context_init(struct sbctl_context *sbctl_ctx,
754 struct ctl_command *command, struct ovsdb_idl *idl,
755 struct ovsdb_idl_txn *txn,
756 struct ovsdb_symbol_table *symtab)
758 ctl_context_init(&sbctl_ctx->base, command, idl, txn, symtab,
759 sbctl_context_invalidate_cache);
760 sbctl_ctx->cache_valid = false;
764 sbctl_context_done_command(struct sbctl_context *sbctl_ctx,
765 struct ctl_command *command)
767 ctl_context_done_command(&sbctl_ctx->base, command);
771 sbctl_context_done(struct sbctl_context *sbctl_ctx,
772 struct ctl_command *command)
774 ctl_context_done(&sbctl_ctx->base, command);
778 run_prerequisites(struct ctl_command *commands, size_t n_commands,
779 struct ovsdb_idl *idl)
781 struct ctl_command *c;
783 for (c = commands; c < &commands[n_commands]; c++) {
784 if (c->syntax->prerequisites) {
785 struct sbctl_context sbctl_ctx;
790 sbctl_context_init(&sbctl_ctx, c, idl, NULL, NULL);
791 (c->syntax->prerequisites)(&sbctl_ctx.base);
792 sbctl_context_done(&sbctl_ctx, c);
794 ovs_assert(!c->output.string);
795 ovs_assert(!c->table);
801 do_sbctl(const char *args, struct ctl_command *commands, size_t n_commands,
802 struct ovsdb_idl *idl)
804 struct ovsdb_idl_txn *txn;
805 enum ovsdb_idl_txn_status status;
806 struct ovsdb_symbol_table *symtab;
807 struct sbctl_context sbctl_ctx;
808 struct ctl_command *c;
809 struct shash_node *node;
812 txn = the_idl_txn = ovsdb_idl_txn_create(idl);
814 ovsdb_idl_txn_set_dry_run(txn);
817 ovsdb_idl_txn_add_comment(txn, "ovs-sbctl: %s", args);
819 symtab = ovsdb_symbol_table_create();
820 for (c = commands; c < &commands[n_commands]; c++) {
824 sbctl_context_init(&sbctl_ctx, NULL, idl, txn, symtab);
825 for (c = commands; c < &commands[n_commands]; c++) {
826 sbctl_context_init_command(&sbctl_ctx, c);
827 if (c->syntax->run) {
828 (c->syntax->run)(&sbctl_ctx.base);
830 sbctl_context_done_command(&sbctl_ctx, c);
832 if (sbctl_ctx.base.try_again) {
833 sbctl_context_done(&sbctl_ctx, NULL);
837 sbctl_context_done(&sbctl_ctx, NULL);
839 SHASH_FOR_EACH (node, &symtab->sh) {
840 struct ovsdb_symbol *symbol = node->data;
841 if (!symbol->created) {
842 ctl_fatal("row id \"%s\" is referenced but never created (e.g. "
843 "with \"-- --id=%s create ...\")",
844 node->name, node->name);
846 if (!symbol->strong_ref) {
847 if (!symbol->weak_ref) {
848 VLOG_WARN("row id \"%s\" was created but no reference to it "
849 "was inserted, so it will not actually appear in "
850 "the database", node->name);
852 VLOG_WARN("row id \"%s\" was created but only a weak "
853 "reference to it was inserted, so it will not "
854 "actually appear in the database", node->name);
859 status = ovsdb_idl_txn_commit_block(txn);
860 if (status == TXN_UNCHANGED || status == TXN_SUCCESS) {
861 for (c = commands; c < &commands[n_commands]; c++) {
862 if (c->syntax->postprocess) {
863 sbctl_context_init(&sbctl_ctx, c, idl, txn, symtab);
864 (c->syntax->postprocess)(&sbctl_ctx.base);
865 sbctl_context_done(&sbctl_ctx, c);
869 error = xstrdup(ovsdb_idl_txn_get_error(txn));
872 case TXN_UNCOMMITTED:
877 /* Should not happen--we never call ovsdb_idl_txn_abort(). */
878 ctl_fatal("transaction aborted");
888 ctl_fatal("transaction error: %s", error);
891 /* Should not happen--we never call ovsdb_idl_set_lock(). */
892 ctl_fatal("database not locked");
899 ovsdb_symbol_table_destroy(symtab);
901 for (c = commands; c < &commands[n_commands]; c++) {
902 struct ds *ds = &c->output;
905 table_print(c->table, &table_style);
906 } else if (oneline) {
910 for (j = 0; j < ds->length; j++) {
911 int ch = ds->string[j];
914 fputs("\\n", stdout);
918 fputs("\\\\", stdout);
927 fputs(ds_cstr(ds), stdout);
929 ds_destroy(&c->output);
930 table_destroy(c->table);
933 shash_destroy_free_data(&c->options);
936 ovsdb_idl_txn_destroy(txn);
937 ovsdb_idl_destroy(idl);
942 /* Our transaction needs to be rerun, or a prerequisite was not met. Free
943 * resources and return so that the caller can try again. */
945 ovsdb_idl_txn_abort(txn);
946 ovsdb_idl_txn_destroy(txn);
949 ovsdb_symbol_table_destroy(symtab);
950 for (c = commands; c < &commands[n_commands]; c++) {
951 ds_destroy(&c->output);
952 table_destroy(c->table);
958 /* Frees the current transaction and the underlying IDL and then calls
961 * Freeing the transaction and the IDL is not strictly necessary, but it makes
962 * for a clean memory leak report from valgrind in the normal case. That makes
963 * it easier to notice real memory leaks. */
965 sbctl_exit(int status)
968 ovsdb_idl_txn_abort(the_idl_txn);
969 ovsdb_idl_txn_destroy(the_idl_txn);
971 ovsdb_idl_destroy(the_idl);
975 static const struct ctl_command_syntax sbctl_commands[] = {
976 /* Chassis commands. */
977 {"chassis-add", 3, 3, "CHASSIS ENCAP-TYPE ENCAP-IP", pre_get_info,
978 cmd_chassis_add, NULL, "--may-exist", RW},
979 {"chassis-del", 1, 1, "CHASSIS", pre_get_info, cmd_chassis_del, NULL,
982 /* Port binding commands. */
983 {"lport-bind", 2, 2, "LPORT CHASSIS", pre_get_info, cmd_lport_bind, NULL,
985 {"lport-unbind", 1, 1, "LPORT", pre_get_info, cmd_lport_unbind, NULL,
988 /* Logical flow commands */
989 {"lflow-list", 0, 1, "[DATAPATH]", pre_get_info, cmd_lflow_list, NULL,
991 {"dump-flows", 0, 1, "[DATAPATH]", pre_get_info, cmd_lflow_list, NULL,
992 "", RO}, /* Friendly alias for lflow-list */
994 /* SSL commands (To Be Added). */
996 {NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, RO},
999 /* Registers sbctl and common db commands. */
1001 sbctl_cmd_init(void)
1003 ctl_init(tables, cmd_show_tables, sbctl_exit);
1004 ctl_register_commands(sbctl_commands);