2 * Copyright (c) 2015, 2016 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"
33 #include "command-line.h"
35 #include "openvswitch/dynamic-string.h"
36 #include "fatal-signal.h"
38 #include "ovsdb-data.h"
39 #include "ovsdb-idl.h"
40 #include "poll-loop.h"
44 #include "stream-ssl.h"
49 #include "openvswitch/vlog.h"
50 #include "ovn/lib/ovn-sb-idl.h"
52 VLOG_DEFINE_THIS_MODULE(sbctl
);
56 /* --db: The database server to contact. */
57 static const char *db
;
59 /* --oneline: Write each command's output as a single line? */
62 /* --dry-run: Do not commit any changes. */
65 /* --timeout: Time to wait for a connection to 'db'. */
68 /* Format for table output. */
69 static struct table_style table_style
= TABLE_STYLE_DEFAULT
;
71 /* The IDL we're using and the current transaction, if any.
72 * This is for use by sbctl_exit() only, to allow it to clean up.
73 * Other code should use its context arguments. */
74 static struct ovsdb_idl
*the_idl
;
75 static struct ovsdb_idl_txn
*the_idl_txn
;
76 OVS_NO_RETURN
static void sbctl_exit(int status
);
78 static void sbctl_cmd_init(void);
79 OVS_NO_RETURN
static void usage(void);
80 static void parse_options(int argc
, char *argv
[], struct shash
*local_options
);
81 static const char *sbctl_default_db(void);
82 static void run_prerequisites(struct ctl_command
[], size_t n_commands
,
84 static bool do_sbctl(const char *args
, struct ctl_command
*, size_t n
,
88 main(int argc
, char *argv
[])
90 struct ovsdb_idl
*idl
;
91 struct ctl_command
*commands
;
92 struct shash local_options
;
97 set_program_name(argv
[0]);
98 fatal_ignore_sigpipe();
99 vlog_set_levels(NULL
, VLF_CONSOLE
, VLL_WARN
);
100 vlog_set_levels_from_string_assert("reconnect:warn");
105 /* Log our arguments. This is often valuable for debugging systems. */
106 args
= process_escape_args(argv
);
107 VLOG(ctl_might_write_to_db(argv
) ? VLL_INFO
: VLL_DBG
, "Called as %s", args
);
109 /* Parse command line. */
110 shash_init(&local_options
);
111 parse_options(argc
, argv
, &local_options
);
112 commands
= ctl_parse_commands(argc
- optind
, argv
+ optind
, &local_options
,
119 /* Initialize IDL. */
120 idl
= the_idl
= ovsdb_idl_create(db
, &sbrec_idl_class
, false, false);
121 run_prerequisites(commands
, n_commands
, idl
);
123 /* Execute the commands.
125 * 'seqno' is the database sequence number for which we last tried to
126 * execute our transaction. There's no point in trying to commit more than
127 * once for any given sequence number, because if the transaction fails
128 * it's because the database changed and we need to obtain an up-to-date
129 * view of the database before we try the transaction again. */
130 seqno
= ovsdb_idl_get_seqno(idl
);
133 if (!ovsdb_idl_is_alive(idl
)) {
134 int retval
= ovsdb_idl_get_last_error(idl
);
135 ctl_fatal("%s: database connection failed (%s)",
136 db
, ovs_retval_to_string(retval
));
139 if (seqno
!= ovsdb_idl_get_seqno(idl
)) {
140 seqno
= ovsdb_idl_get_seqno(idl
);
141 if (do_sbctl(args
, commands
, n_commands
, idl
)) {
147 if (seqno
== ovsdb_idl_get_seqno(idl
)) {
155 sbctl_default_db(void)
159 def
= getenv("OVN_SB_DB");
161 def
= xasprintf("unix:%s/ovnsb_db.sock", ovs_rundir());
168 parse_options(int argc
, char *argv
[], struct shash
*local_options
)
171 OPT_DB
= UCHAR_MAX
+ 1,
182 static const struct option global_long_options
[] = {
183 {"db", required_argument
, NULL
, OPT_DB
},
184 {"no-syslog", no_argument
, NULL
, OPT_NO_SYSLOG
},
185 {"dry-run", no_argument
, NULL
, OPT_DRY_RUN
},
186 {"oneline", no_argument
, NULL
, OPT_ONELINE
},
187 {"timeout", required_argument
, NULL
, 't'},
188 {"help", no_argument
, NULL
, 'h'},
189 {"commands", no_argument
, NULL
, OPT_COMMANDS
},
190 {"options", no_argument
, NULL
, OPT_OPTIONS
},
191 {"version", no_argument
, NULL
, 'V'},
193 STREAM_SSL_LONG_OPTIONS
,
197 const int n_global_long_options
= ARRAY_SIZE(global_long_options
) - 1;
198 char *tmp
, *short_options
;
200 struct option
*options
;
201 size_t allocated_options
;
205 tmp
= ovs_cmdl_long_options_to_short_options(global_long_options
);
206 short_options
= xasprintf("+%s", tmp
);
209 /* We want to parse both global and command-specific options here, but
210 * getopt_long() isn't too convenient for the job. We copy our global
211 * options into a dynamic array, then append all of the command-specific
213 options
= xmemdup(global_long_options
, sizeof global_long_options
);
214 allocated_options
= ARRAY_SIZE(global_long_options
);
215 n_options
= n_global_long_options
;
216 ctl_add_cmd_options(&options
, &n_options
, &allocated_options
, OPT_LOCAL
);
217 table_style
.format
= TF_LIST
;
223 c
= getopt_long(argc
, argv
, short_options
, options
, &idx
);
238 vlog_set_levels(&this_module
, VLF_SYSLOG
, VLL_WARN
);
246 if (shash_find(local_options
, options
[idx
].name
)) {
247 ctl_fatal("'%s' option specified multiple times",
250 shash_add_nocopy(local_options
,
251 xasprintf("--%s", options
[idx
].name
),
252 nullable_xstrdup(optarg
));
259 ctl_print_commands();
262 ctl_print_options(global_long_options
);
265 ovs_print_version(0, 0);
266 printf("DB Schema %s\n", sbrec_get_db_version());
270 timeout
= strtoul(optarg
, NULL
, 10);
272 ctl_fatal("value %s on -t or --timeout is invalid", optarg
);
277 TABLE_OPTION_HANDLERS(&table_style
)
278 STREAM_SSL_OPTION_HANDLERS
290 db
= sbctl_default_db();
293 for (i
= n_global_long_options
; options
[i
].name
; i
++) {
294 free(CONST_CAST(char *, options
[i
].name
));
303 %s: OVN southbound DB management utility\n\
305 For debugging and testing only, not for use in production.\n\
307 usage: %s [OPTIONS] COMMAND [ARG...]\n\
310 show print overview of database contents\n\
313 chassis-add CHASSIS ENCAP-TYPE ENCAP-IP create a new chassis named\n\
314 CHASSIS with ENCAP-TYPE tunnels\n\
316 chassis-del CHASSIS delete CHASSIS and all of its encaps\n\
319 Port binding commands:\n\
320 lport-bind LPORT CHASSIS bind logical port LPORT to CHASSIS\n\
321 lport-unbind LPORT reset the port binding of logical port LPORT\n\
323 Logical flow commands:\n\
324 lflow-list [DATAPATH] List logical flows for all or a single datapath\n\
325 dump-flows [DATAPATH] Alias for lflow-list\n\
330 --db=DATABASE connect to DATABASE\n\
332 -t, --timeout=SECS wait at most SECS seconds\n\
333 --dry-run do not commit changes to database\n\
334 --oneline print exactly one line of output per command\n",
335 program_name
, program_name
, ctl_get_db_cmd_usage(), sbctl_default_db());
338 --no-syslog equivalent to --verbose=sbctl:syslog:warn\n");
341 -h, --help display this help message\n\
342 -V, --version display version information\n");
343 stream_usage("database", true, true, false);
348 /* ovs-sbctl specific context. Inherits the 'struct ctl_context' as base. */
349 struct sbctl_context
{
350 struct ctl_context base
;
352 /* A cache of the contents of the database.
354 * A command that needs to use any of this information must first call
355 * sbctl_context_populate_cache(). A command that changes anything that
356 * could invalidate the cache must either call
357 * sbctl_context_invalidate_cache() or manually update the cache to
358 * maintain its correctness. */
360 /* Maps from chassis name to struct sbctl_chassis. */
361 struct shash chassis
;
362 /* Maps from lport name to struct sbctl_port_binding. */
363 struct shash port_bindings
;
366 /* Casts 'base' into 'struct sbctl_context'. */
367 static struct sbctl_context
*
368 sbctl_context_cast(struct ctl_context
*base
)
370 return CONTAINER_OF(base
, struct sbctl_context
, base
);
373 struct sbctl_chassis
{
374 const struct sbrec_chassis
*ch_cfg
;
377 struct sbctl_port_binding
{
378 const struct sbrec_port_binding
*bd_cfg
;
382 sbctl_context_invalidate_cache(struct ctl_context
*ctx
)
384 struct sbctl_context
*sbctl_ctx
= sbctl_context_cast(ctx
);
386 if (!sbctl_ctx
->cache_valid
) {
389 sbctl_ctx
->cache_valid
= false;
390 shash_destroy_free_data(&sbctl_ctx
->chassis
);
391 shash_destroy_free_data(&sbctl_ctx
->port_bindings
);
395 sbctl_context_populate_cache(struct ctl_context
*ctx
)
397 struct sbctl_context
*sbctl_ctx
= sbctl_context_cast(ctx
);
398 const struct sbrec_chassis
*chassis_rec
;
399 const struct sbrec_port_binding
*port_binding_rec
;
400 struct sset chassis
, port_bindings
;
402 if (sbctl_ctx
->cache_valid
) {
403 /* Cache is already populated. */
406 sbctl_ctx
->cache_valid
= true;
407 shash_init(&sbctl_ctx
->chassis
);
408 shash_init(&sbctl_ctx
->port_bindings
);
410 SBREC_CHASSIS_FOR_EACH(chassis_rec
, ctx
->idl
) {
411 struct sbctl_chassis
*ch
;
413 if (!sset_add(&chassis
, chassis_rec
->name
)) {
414 VLOG_WARN("database contains duplicate chassis name (%s)",
419 ch
= xmalloc(sizeof *ch
);
420 ch
->ch_cfg
= chassis_rec
;
421 shash_add(&sbctl_ctx
->chassis
, chassis_rec
->name
, ch
);
423 sset_destroy(&chassis
);
425 sset_init(&port_bindings
);
426 SBREC_PORT_BINDING_FOR_EACH(port_binding_rec
, ctx
->idl
) {
427 struct sbctl_port_binding
*bd
;
429 if (!sset_add(&port_bindings
, port_binding_rec
->logical_port
)) {
430 VLOG_WARN("database contains duplicate port binding for logical "
432 port_binding_rec
->logical_port
);
436 bd
= xmalloc(sizeof *bd
);
437 bd
->bd_cfg
= port_binding_rec
;
438 shash_add(&sbctl_ctx
->port_bindings
, port_binding_rec
->logical_port
,
441 sset_destroy(&port_bindings
);
445 check_conflicts(struct sbctl_context
*sbctl_ctx
, const char *name
,
448 if (shash_find(&sbctl_ctx
->chassis
, name
)) {
449 ctl_fatal("%s because a chassis named %s already exists",
455 static struct sbctl_chassis
*
456 find_chassis(struct sbctl_context
*sbctl_ctx
, const char *name
,
459 struct sbctl_chassis
*sbctl_ch
;
461 ovs_assert(sbctl_ctx
->cache_valid
);
463 sbctl_ch
= shash_find_data(&sbctl_ctx
->chassis
, name
);
464 if (must_exist
&& !sbctl_ch
) {
465 ctl_fatal("no chassis named %s", name
);
471 static struct sbctl_port_binding
*
472 find_port_binding(struct sbctl_context
*sbctl_ctx
, const char *name
,
475 struct sbctl_port_binding
*bd
;
477 ovs_assert(sbctl_ctx
->cache_valid
);
479 bd
= shash_find_data(&sbctl_ctx
->port_bindings
, name
);
480 if (must_exist
&& !bd
) {
481 ctl_fatal("no port named %s", name
);
488 pre_get_info(struct ctl_context
*ctx
)
490 ovsdb_idl_add_column(ctx
->idl
, &sbrec_chassis_col_name
);
491 ovsdb_idl_add_column(ctx
->idl
, &sbrec_chassis_col_encaps
);
493 ovsdb_idl_add_column(ctx
->idl
, &sbrec_encap_col_type
);
494 ovsdb_idl_add_column(ctx
->idl
, &sbrec_encap_col_ip
);
496 ovsdb_idl_add_column(ctx
->idl
, &sbrec_port_binding_col_logical_port
);
497 ovsdb_idl_add_column(ctx
->idl
, &sbrec_port_binding_col_chassis
);
499 ovsdb_idl_add_column(ctx
->idl
, &sbrec_logical_flow_col_logical_datapath
);
500 ovsdb_idl_add_column(ctx
->idl
, &sbrec_logical_flow_col_pipeline
);
501 ovsdb_idl_add_column(ctx
->idl
, &sbrec_logical_flow_col_actions
);
502 ovsdb_idl_add_column(ctx
->idl
, &sbrec_logical_flow_col_priority
);
503 ovsdb_idl_add_column(ctx
->idl
, &sbrec_logical_flow_col_table_id
);
504 ovsdb_idl_add_column(ctx
->idl
, &sbrec_logical_flow_col_match
);
505 ovsdb_idl_add_column(ctx
->idl
, &sbrec_logical_flow_col_external_ids
);
508 static struct cmd_show_table cmd_show_tables
[] = {
509 {&sbrec_table_chassis
,
510 &sbrec_chassis_col_name
,
511 {&sbrec_chassis_col_hostname
,
512 &sbrec_chassis_col_encaps
,
514 {&sbrec_table_port_binding
,
515 &sbrec_port_binding_col_logical_port
,
516 &sbrec_port_binding_col_chassis
}},
519 &sbrec_encap_col_type
,
520 {&sbrec_encap_col_ip
,
521 &sbrec_encap_col_options
,
525 {NULL
, NULL
, {NULL
, NULL
, NULL
}, {NULL
, NULL
, NULL
}},
529 cmd_chassis_add(struct ctl_context
*ctx
)
531 struct sbctl_context
*sbctl_ctx
= sbctl_context_cast(ctx
);
532 bool may_exist
= shash_find(&ctx
->options
, "--may-exist") != NULL
;
533 const char *ch_name
, *encap_types
, *encap_ip
;
535 ch_name
= ctx
->argv
[1];
536 encap_types
= ctx
->argv
[2];
537 encap_ip
= ctx
->argv
[3];
539 sbctl_context_populate_cache(ctx
);
541 struct sbctl_chassis
*sbctl_ch
;
543 sbctl_ch
= find_chassis(sbctl_ctx
, ch_name
, false);
548 check_conflicts(sbctl_ctx
, ch_name
,
549 xasprintf("cannot create a chassis named %s", ch_name
));
551 char *tokstr
= xstrdup(encap_types
);
552 char *token
, *save_ptr
= NULL
;
553 struct sset encap_set
= SSET_INITIALIZER(&encap_set
);
554 for (token
= strtok_r(tokstr
, ",", &save_ptr
); token
!= NULL
;
555 token
= strtok_r(NULL
, ",", &save_ptr
)) {
556 sset_add(&encap_set
, token
);
560 size_t n_encaps
= sset_count(&encap_set
);
561 struct sbrec_encap
**encaps
= xmalloc(n_encaps
* sizeof *encaps
);
562 const char *encap_type
;
564 SSET_FOR_EACH (encap_type
, &encap_set
){
565 encaps
[i
] = sbrec_encap_insert(ctx
->txn
);
567 sbrec_encap_set_type(encaps
[i
], encap_type
);
568 sbrec_encap_set_ip(encaps
[i
], encap_ip
);
571 sset_destroy(&encap_set
);
573 struct sbrec_chassis
*ch
= sbrec_chassis_insert(ctx
->txn
);
574 sbrec_chassis_set_name(ch
, ch_name
);
575 sbrec_chassis_set_encaps(ch
, encaps
, n_encaps
);
578 sbctl_context_invalidate_cache(ctx
);
582 cmd_chassis_del(struct ctl_context
*ctx
)
584 struct sbctl_context
*sbctl_ctx
= sbctl_context_cast(ctx
);
585 bool must_exist
= !shash_find(&ctx
->options
, "--if-exists");
586 struct sbctl_chassis
*sbctl_ch
;
588 sbctl_context_populate_cache(ctx
);
589 sbctl_ch
= find_chassis(sbctl_ctx
, ctx
->argv
[1], must_exist
);
591 if (sbctl_ch
->ch_cfg
) {
594 for (i
= 0; i
< sbctl_ch
->ch_cfg
->n_encaps
; i
++) {
595 sbrec_encap_delete(sbctl_ch
->ch_cfg
->encaps
[i
]);
597 sbrec_chassis_delete(sbctl_ch
->ch_cfg
);
599 shash_find_and_delete(&sbctl_ctx
->chassis
, ctx
->argv
[1]);
605 cmd_lport_bind(struct ctl_context
*ctx
)
607 struct sbctl_context
*sbctl_ctx
= sbctl_context_cast(ctx
);
608 bool may_exist
= shash_find(&ctx
->options
, "--may-exist") != NULL
;
609 struct sbctl_chassis
*sbctl_ch
;
610 struct sbctl_port_binding
*sbctl_bd
;
611 char *lport_name
, *ch_name
;
613 /* port_binding must exist, chassis must exist! */
614 lport_name
= ctx
->argv
[1];
615 ch_name
= ctx
->argv
[2];
617 sbctl_context_populate_cache(ctx
);
618 sbctl_bd
= find_port_binding(sbctl_ctx
, lport_name
, true);
619 sbctl_ch
= find_chassis(sbctl_ctx
, ch_name
, true);
621 if (sbctl_bd
->bd_cfg
->chassis
) {
622 if (may_exist
&& sbctl_bd
->bd_cfg
->chassis
== sbctl_ch
->ch_cfg
) {
625 ctl_fatal("lport (%s) has already been binded to chassis (%s)",
626 lport_name
, sbctl_bd
->bd_cfg
->chassis
->name
);
629 sbrec_port_binding_set_chassis(sbctl_bd
->bd_cfg
, sbctl_ch
->ch_cfg
);
630 sbctl_context_invalidate_cache(ctx
);
634 cmd_lport_unbind(struct ctl_context
*ctx
)
636 struct sbctl_context
*sbctl_ctx
= sbctl_context_cast(ctx
);
637 bool must_exist
= !shash_find(&ctx
->options
, "--if-exists");
638 struct sbctl_port_binding
*sbctl_bd
;
641 lport_name
= ctx
->argv
[1];
642 sbctl_context_populate_cache(ctx
);
643 sbctl_bd
= find_port_binding(sbctl_ctx
, lport_name
, must_exist
);
645 sbrec_port_binding_set_chassis(sbctl_bd
->bd_cfg
, NULL
);
654 /* Help ensure we catch any future pipeline values */
656 pipeline_encode(const char *pl
)
658 if (!strcmp(pl
, "ingress")) {
660 } else if (!strcmp(pl
, "egress")) {
668 lflow_cmp(const void *lf1_
, const void *lf2_
)
670 const struct sbrec_logical_flow
*const *lf1p
= lf1_
;
671 const struct sbrec_logical_flow
*const *lf2p
= lf2_
;
672 const struct sbrec_logical_flow
*lf1
= *lf1p
;
673 const struct sbrec_logical_flow
*lf2
= *lf2p
;
675 int pl1
= pipeline_encode(lf1
->pipeline
);
676 int pl2
= pipeline_encode(lf2
->pipeline
);
687 CMP(uuid_compare_3way(&lf1
->logical_datapath
->header_
.uuid
,
688 &lf2
->logical_datapath
->header_
.uuid
));
690 CMP(lf1
->table_id
> lf2
->table_id
? 1 :
691 (lf1
->table_id
< lf2
->table_id
? -1 : 0));
692 CMP(lf1
->priority
> lf2
->priority
? -1 :
693 (lf1
->priority
< lf2
->priority
? 1 : 0));
694 CMP(strcmp(lf1
->match
, lf2
->match
));
702 cmd_lflow_list(struct ctl_context
*ctx
)
704 const char *datapath
= ctx
->argc
== 2 ? ctx
->argv
[1] : NULL
;
705 struct uuid datapath_uuid
= { .parts
= { 0, }};
706 const struct sbrec_logical_flow
**lflows
;
707 const struct sbrec_logical_flow
*lflow
;
708 size_t n_flows
= 0, n_capacity
= 64;
710 if (datapath
&& !uuid_from_string(&datapath_uuid
, datapath
)) {
711 VLOG_ERR("Invalid format of datapath UUID");
715 lflows
= xmalloc(sizeof *lflows
* n_capacity
);
716 SBREC_LOGICAL_FLOW_FOR_EACH (lflow
, ctx
->idl
) {
717 if (n_flows
== n_capacity
) {
718 lflows
= x2nrealloc(lflows
, &n_capacity
, sizeof *lflows
);
720 lflows
[n_flows
] = lflow
;
724 qsort(lflows
, n_flows
, sizeof *lflows
, lflow_cmp
);
726 const char *cur_pipeline
= "";
728 for (i
= 0; i
< n_flows
; i
++) {
730 if (datapath
&& !uuid_equals(&datapath_uuid
,
731 &lflow
->logical_datapath
->header_
.uuid
)) {
734 if (strcmp(cur_pipeline
, lflow
->pipeline
)) {
735 printf("Datapath: " UUID_FMT
" Pipeline: %s\n",
736 UUID_ARGS(&lflow
->logical_datapath
->header_
.uuid
),
738 cur_pipeline
= lflow
->pipeline
;
741 const char *table_name
= smap_get(&lflow
->external_ids
, "stage-name");
742 printf(" table=%" PRId64
"(%16s), priority=%5" PRId64
743 ", match=(%s), action=(%s)\n",
744 lflow
->table_id
, table_name
? table_name
: "",
745 lflow
->priority
, lflow
->match
, lflow
->actions
);
752 static const struct ctl_table_class tables
[] = {
753 {&sbrec_table_chassis
,
754 {{&sbrec_table_chassis
, &sbrec_chassis_col_name
, NULL
},
755 {NULL
, NULL
, NULL
}}},
759 {NULL
, NULL
, NULL
}}},
761 {&sbrec_table_logical_flow
,
762 {{&sbrec_table_logical_flow
, NULL
,
763 &sbrec_logical_flow_col_logical_datapath
},
764 {NULL
, NULL
, NULL
}}},
766 {&sbrec_table_multicast_group
,
768 {NULL
, NULL
, NULL
}}},
770 {&sbrec_table_datapath_binding
,
772 {NULL
, NULL
, NULL
}}},
774 {&sbrec_table_port_binding
,
775 {{&sbrec_table_port_binding
, &sbrec_port_binding_col_logical_port
, NULL
},
776 {NULL
, NULL
, NULL
}}},
778 {&sbrec_table_mac_binding
,
779 {{&sbrec_table_mac_binding
, &sbrec_mac_binding_col_logical_port
, NULL
},
780 {NULL
, NULL
, NULL
}}},
782 {NULL
, {{NULL
, NULL
, NULL
}, {NULL
, NULL
, NULL
}}}
787 sbctl_context_init_command(struct sbctl_context
*sbctl_ctx
,
788 struct ctl_command
*command
)
790 ctl_context_init_command(&sbctl_ctx
->base
, command
);
794 sbctl_context_init(struct sbctl_context
*sbctl_ctx
,
795 struct ctl_command
*command
, struct ovsdb_idl
*idl
,
796 struct ovsdb_idl_txn
*txn
,
797 struct ovsdb_symbol_table
*symtab
)
799 ctl_context_init(&sbctl_ctx
->base
, command
, idl
, txn
, symtab
,
800 sbctl_context_invalidate_cache
);
801 sbctl_ctx
->cache_valid
= false;
805 sbctl_context_done_command(struct sbctl_context
*sbctl_ctx
,
806 struct ctl_command
*command
)
808 ctl_context_done_command(&sbctl_ctx
->base
, command
);
812 sbctl_context_done(struct sbctl_context
*sbctl_ctx
,
813 struct ctl_command
*command
)
815 ctl_context_done(&sbctl_ctx
->base
, command
);
819 run_prerequisites(struct ctl_command
*commands
, size_t n_commands
,
820 struct ovsdb_idl
*idl
)
822 struct ctl_command
*c
;
824 for (c
= commands
; c
< &commands
[n_commands
]; c
++) {
825 if (c
->syntax
->prerequisites
) {
826 struct sbctl_context sbctl_ctx
;
831 sbctl_context_init(&sbctl_ctx
, c
, idl
, NULL
, NULL
);
832 (c
->syntax
->prerequisites
)(&sbctl_ctx
.base
);
833 sbctl_context_done(&sbctl_ctx
, c
);
835 ovs_assert(!c
->output
.string
);
836 ovs_assert(!c
->table
);
842 do_sbctl(const char *args
, struct ctl_command
*commands
, size_t n_commands
,
843 struct ovsdb_idl
*idl
)
845 struct ovsdb_idl_txn
*txn
;
846 enum ovsdb_idl_txn_status status
;
847 struct ovsdb_symbol_table
*symtab
;
848 struct sbctl_context sbctl_ctx
;
849 struct ctl_command
*c
;
850 struct shash_node
*node
;
853 txn
= the_idl_txn
= ovsdb_idl_txn_create(idl
);
855 ovsdb_idl_txn_set_dry_run(txn
);
858 ovsdb_idl_txn_add_comment(txn
, "ovs-sbctl: %s", args
);
860 symtab
= ovsdb_symbol_table_create();
861 for (c
= commands
; c
< &commands
[n_commands
]; c
++) {
865 sbctl_context_init(&sbctl_ctx
, NULL
, idl
, txn
, symtab
);
866 for (c
= commands
; c
< &commands
[n_commands
]; c
++) {
867 sbctl_context_init_command(&sbctl_ctx
, c
);
868 if (c
->syntax
->run
) {
869 (c
->syntax
->run
)(&sbctl_ctx
.base
);
871 sbctl_context_done_command(&sbctl_ctx
, c
);
873 if (sbctl_ctx
.base
.try_again
) {
874 sbctl_context_done(&sbctl_ctx
, NULL
);
878 sbctl_context_done(&sbctl_ctx
, NULL
);
880 SHASH_FOR_EACH (node
, &symtab
->sh
) {
881 struct ovsdb_symbol
*symbol
= node
->data
;
882 if (!symbol
->created
) {
883 ctl_fatal("row id \"%s\" is referenced but never created (e.g. "
884 "with \"-- --id=%s create ...\")",
885 node
->name
, node
->name
);
887 if (!symbol
->strong_ref
) {
888 if (!symbol
->weak_ref
) {
889 VLOG_WARN("row id \"%s\" was created but no reference to it "
890 "was inserted, so it will not actually appear in "
891 "the database", node
->name
);
893 VLOG_WARN("row id \"%s\" was created but only a weak "
894 "reference to it was inserted, so it will not "
895 "actually appear in the database", node
->name
);
900 status
= ovsdb_idl_txn_commit_block(txn
);
901 if (status
== TXN_UNCHANGED
|| status
== TXN_SUCCESS
) {
902 for (c
= commands
; c
< &commands
[n_commands
]; c
++) {
903 if (c
->syntax
->postprocess
) {
904 sbctl_context_init(&sbctl_ctx
, c
, idl
, txn
, symtab
);
905 (c
->syntax
->postprocess
)(&sbctl_ctx
.base
);
906 sbctl_context_done(&sbctl_ctx
, c
);
910 error
= xstrdup(ovsdb_idl_txn_get_error(txn
));
913 case TXN_UNCOMMITTED
:
918 /* Should not happen--we never call ovsdb_idl_txn_abort(). */
919 ctl_fatal("transaction aborted");
929 ctl_fatal("transaction error: %s", error
);
932 /* Should not happen--we never call ovsdb_idl_set_lock(). */
933 ctl_fatal("database not locked");
940 ovsdb_symbol_table_destroy(symtab
);
942 for (c
= commands
; c
< &commands
[n_commands
]; c
++) {
943 struct ds
*ds
= &c
->output
;
946 table_print(c
->table
, &table_style
);
947 } else if (oneline
) {
951 for (j
= 0; j
< ds
->length
; j
++) {
952 int ch
= ds
->string
[j
];
955 fputs("\\n", stdout
);
959 fputs("\\\\", stdout
);
968 fputs(ds_cstr(ds
), stdout
);
970 ds_destroy(&c
->output
);
971 table_destroy(c
->table
);
974 shash_destroy_free_data(&c
->options
);
977 ovsdb_idl_txn_destroy(txn
);
978 ovsdb_idl_destroy(idl
);
983 /* Our transaction needs to be rerun, or a prerequisite was not met. Free
984 * resources and return so that the caller can try again. */
986 ovsdb_idl_txn_abort(txn
);
987 ovsdb_idl_txn_destroy(txn
);
990 ovsdb_symbol_table_destroy(symtab
);
991 for (c
= commands
; c
< &commands
[n_commands
]; c
++) {
992 ds_destroy(&c
->output
);
993 table_destroy(c
->table
);
1000 /* Frees the current transaction and the underlying IDL and then calls
1003 * Freeing the transaction and the IDL is not strictly necessary, but it makes
1004 * for a clean memory leak report from valgrind in the normal case. That makes
1005 * it easier to notice real memory leaks. */
1007 sbctl_exit(int status
)
1010 ovsdb_idl_txn_abort(the_idl_txn
);
1011 ovsdb_idl_txn_destroy(the_idl_txn
);
1013 ovsdb_idl_destroy(the_idl
);
1017 static const struct ctl_command_syntax sbctl_commands
[] = {
1018 /* Chassis commands. */
1019 {"chassis-add", 3, 3, "CHASSIS ENCAP-TYPE ENCAP-IP", pre_get_info
,
1020 cmd_chassis_add
, NULL
, "--may-exist", RW
},
1021 {"chassis-del", 1, 1, "CHASSIS", pre_get_info
, cmd_chassis_del
, NULL
,
1024 /* Port binding commands. */
1025 {"lport-bind", 2, 2, "LPORT CHASSIS", pre_get_info
, cmd_lport_bind
, NULL
,
1027 {"lport-unbind", 1, 1, "LPORT", pre_get_info
, cmd_lport_unbind
, NULL
,
1030 /* Logical flow commands */
1031 {"lflow-list", 0, 1, "[DATAPATH]", pre_get_info
, cmd_lflow_list
, NULL
,
1033 {"dump-flows", 0, 1, "[DATAPATH]", pre_get_info
, cmd_lflow_list
, NULL
,
1034 "", RO
}, /* Friendly alias for lflow-list */
1036 /* SSL commands (To Be Added). */
1038 {NULL
, 0, 0, NULL
, NULL
, NULL
, NULL
, NULL
, RO
},
1041 /* Registers sbctl and common db commands. */
1043 sbctl_cmd_init(void)
1045 ctl_init(tables
, cmd_show_tables
, sbctl_exit
);
1046 ctl_register_commands(sbctl_commands
);