2 * Licensed under the Apache License, Version 2.0 (the "License");
3 * you may not use this file except in compliance with the License.
4 * You may obtain a copy of the License at:
6 * http://www.apache.org/licenses/LICENSE-2.0
8 * Unless required by applicable law or agreed to in writing, software
9 * distributed under the License is distributed on an "AS IS" BASIS,
10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 * See the License for the specific language governing permissions and
12 * limitations under the License.
22 #include "command-line.h"
24 #include "fatal-signal.h"
25 #include "ovn/lib/ovn-nb-idl.h"
26 #include "poll-loop.h"
30 #include "stream-ssl.h"
33 #include "openvswitch/vlog.h"
35 VLOG_DEFINE_THIS_MODULE(ovn_nbctl);
37 struct nbctl_context {
38 struct ovsdb_idl *idl;
39 struct ovsdb_idl_txn *txn;
42 static const char *db;
44 static const char *default_db(void);
50 %s: OVN northbound DB management utility\n\
51 usage: %s [OPTIONS] COMMAND [ARG...]\n\
54 show print overview of database contents\n\
55 show LSWITCH print overview of database contents for LSWITCH\n\
57 Logical switch commands:\n\
58 lswitch-add [LSWITCH] create a logical switch named LSWITCH\n\
59 lswitch-del LSWITCH delete LSWITCH and all its ports\n\
60 lswitch-list print the names of all logical switches\n\
61 lswitch-set-external-id LSWITCH KEY [VALUE]\n\
62 set or delete an external-id on LSWITCH\n\
63 lswitch-get-external-id LSWITCH [KEY]\n\
64 list one or all external-ids on LSWITCH\n\
66 Logical port commands:\n\
67 lport-add LSWITCH LPORT add logical port LPORT on LSWITCH\n\
68 lport-add LSWITCH LPORT PARENT TAG\n\
69 add logical port LPORT on LSWITCH with PARENT\n\
71 lport-del LPORT delete LPORT from its attached switch\n\
72 lport-list LSWITCH print the names of all logical ports on LSWITCH\n\
73 lport-get-parent LPORT get the parent of LPORT if set\n\
74 lport-get-tag LPORT get the LPORT's tag if set\n\
75 lport-set-external-id LPORT KEY [VALUE]\n\
76 set or delete an external-id on LPORT\n\
77 lport-get-external-id LPORT [KEY]\n\
78 list one or all external-ids on LPORT\n\
79 lport-set-macs LPORT [MAC]...\n\
80 set MAC addresses for LPORT.\n\
81 lport-get-macs LPORT get a list of MAC addresses on LPORT\n\
82 lport-set-port-security LPORT [ADDRS]...\n\
83 set port security addresses for LPORT.\n\
84 lport-get-port-security LPORT get LPORT's port security addresses\n\
85 lport-get-up LPORT get state of LPORT ('up' or 'down')\n\
86 lport-set-enabled LPORT STATE\n\
87 set administrative state LPORT\n\
88 ('enabled' or 'disabled')\n\
89 lport-get-enabled LPORT get administrative state LPORT\n\
90 ('enabled' or 'disabled')\n\
91 lport-set-type LPORT TYPE Set the type for LPORT\n\
92 lport-get-type LPORT Get the type for LPORT\n\
93 lport-set-options LPORT KEY=VALUE [KEY=VALUE]...\n\
94 Set options related to the type of LPORT\n\
95 lport-get-options LPORT Get the type specific options for LPORT\n\
98 --db=DATABASE connect to DATABASE\n\
100 -h, --help display this help message\n\
101 -o, --options list available options\n\
102 -V, --version display version information\n\
103 ", program_name, program_name, default_db());
105 stream_usage("database", true, true, false);
108 static const struct nbrec_logical_switch *
109 lswitch_by_name_or_uuid(struct nbctl_context *nb_ctx, const char *id)
111 const struct nbrec_logical_switch *lswitch = NULL;
112 bool is_uuid = false;
113 bool duplicate = false;
114 struct uuid lswitch_uuid;
116 if (uuid_from_string(&lswitch_uuid, id)) {
118 lswitch = nbrec_logical_switch_get_for_uuid(nb_ctx->idl,
123 const struct nbrec_logical_switch *iter;
125 NBREC_LOGICAL_SWITCH_FOR_EACH(iter, nb_ctx->idl) {
126 if (strcmp(iter->name, id)) {
130 VLOG_WARN("There is more than one logical switch named '%s'. "
140 if (!lswitch && !duplicate) {
141 VLOG_WARN("lswitch not found for %s: '%s'",
142 is_uuid ? "UUID" : "name", id);
149 print_lswitch(const struct nbrec_logical_switch *lswitch)
151 printf(" lswitch "UUID_FMT" (%s)\n",
152 UUID_ARGS(&lswitch->header_.uuid), lswitch->name);
154 for (size_t i = 0; i < lswitch->n_ports; i++) {
155 const struct nbrec_logical_port *lport = lswitch->ports[i];
157 printf(" lport %s\n", lport->name);
158 if (lport->parent_name && lport->n_tag) {
159 printf(" parent: %s, tag:%"PRIu64"\n",
160 lport->parent_name, lport->tag[0]);
164 for (size_t j = 0; j < lport->n_macs; j++) {
165 printf(" %s", lport->macs[j]);
173 do_show(struct ovs_cmdl_context *ctx)
175 struct nbctl_context *nb_ctx = ctx->pvt;
176 const struct nbrec_logical_switch *lswitch;
178 if (ctx->argc == 2) {
179 lswitch = lswitch_by_name_or_uuid(nb_ctx, ctx->argv[1]);
181 print_lswitch(lswitch);
184 NBREC_LOGICAL_SWITCH_FOR_EACH(lswitch, nb_ctx->idl) {
185 print_lswitch(lswitch);
191 do_lswitch_add(struct ovs_cmdl_context *ctx)
193 struct nbctl_context *nb_ctx = ctx->pvt;
194 struct nbrec_logical_switch *lswitch;
196 lswitch = nbrec_logical_switch_insert(nb_ctx->txn);
197 if (ctx->argc == 2) {
198 nbrec_logical_switch_set_name(lswitch, ctx->argv[1]);
203 do_lswitch_del(struct ovs_cmdl_context *ctx)
205 struct nbctl_context *nb_ctx = ctx->pvt;
206 const char *id = ctx->argv[1];
207 const struct nbrec_logical_switch *lswitch;
209 lswitch = lswitch_by_name_or_uuid(nb_ctx, id);
214 nbrec_logical_switch_delete(lswitch);
218 do_lswitch_list(struct ovs_cmdl_context *ctx)
220 struct nbctl_context *nb_ctx = ctx->pvt;
221 const struct nbrec_logical_switch *lswitch;
222 struct smap lswitches;
224 smap_init(&lswitches);
225 NBREC_LOGICAL_SWITCH_FOR_EACH(lswitch, nb_ctx->idl) {
226 smap_add_format(&lswitches, lswitch->name, UUID_FMT " (%s)",
227 UUID_ARGS(&lswitch->header_.uuid), lswitch->name);
229 const struct smap_node **nodes = smap_sort(&lswitches);
230 for (size_t i = 0; i < smap_count(&lswitches); i++) {
231 const struct smap_node *node = nodes[i];
232 printf("%s\n", node->value);
234 smap_destroy(&lswitches);
239 do_lswitch_set_external_id(struct ovs_cmdl_context *ctx)
241 struct nbctl_context *nb_ctx = ctx->pvt;
242 const char *id = ctx->argv[1];
243 const struct nbrec_logical_switch *lswitch;
244 struct smap new_external_ids;
246 lswitch = lswitch_by_name_or_uuid(nb_ctx, id);
251 smap_init(&new_external_ids);
252 smap_clone(&new_external_ids, &lswitch->external_ids);
253 if (ctx->argc == 4) {
254 smap_replace(&new_external_ids, ctx->argv[2], ctx->argv[3]);
256 smap_remove(&new_external_ids, ctx->argv[2]);
258 nbrec_logical_switch_set_external_ids(lswitch, &new_external_ids);
259 smap_destroy(&new_external_ids);
263 do_lswitch_get_external_id(struct ovs_cmdl_context *ctx)
265 struct nbctl_context *nb_ctx = ctx->pvt;
266 const char *id = ctx->argv[1];
267 const struct nbrec_logical_switch *lswitch;
269 lswitch = lswitch_by_name_or_uuid(nb_ctx, id);
274 if (ctx->argc == 3) {
275 const char *key = ctx->argv[2];
278 /* List one external ID */
280 value = smap_get(&lswitch->external_ids, key);
282 printf("%s\n", value);
285 struct smap_node *node;
287 /* List all external IDs */
289 SMAP_FOR_EACH(node, &lswitch->external_ids) {
290 printf("%s=%s\n", node->key, node->value);
295 static const struct nbrec_logical_port *
296 lport_by_name_or_uuid(struct nbctl_context *nb_ctx, const char *id)
298 const struct nbrec_logical_port *lport = NULL;
299 bool is_uuid = false;
300 struct uuid lport_uuid;
302 if (uuid_from_string(&lport_uuid, id)) {
304 lport = nbrec_logical_port_get_for_uuid(nb_ctx->idl, &lport_uuid);
308 NBREC_LOGICAL_PORT_FOR_EACH(lport, nb_ctx->idl) {
309 if (!strcmp(lport->name, id)) {
316 VLOG_WARN("lport not found for %s: '%s'",
317 is_uuid ? "UUID" : "name", id);
324 do_lport_add(struct ovs_cmdl_context *ctx)
326 struct nbctl_context *nb_ctx = ctx->pvt;
327 struct nbrec_logical_port *lport;
328 const struct nbrec_logical_switch *lswitch;
331 lswitch = lswitch_by_name_or_uuid(nb_ctx, ctx->argv[1]);
336 if (ctx->argc != 3 && ctx->argc != 5) {
337 /* If a parent_name is specified, a tag must be specified as well. */
338 VLOG_WARN("Invalid arguments to lport-add.");
342 if (ctx->argc == 5) {
344 if (!ovs_scan(ctx->argv[4], "%"SCNd64, &tag) || tag < 0 || tag > 4095) {
345 VLOG_WARN("Invalid tag '%s'", ctx->argv[4]);
350 /* Create the logical port. */
351 lport = nbrec_logical_port_insert(nb_ctx->txn);
352 nbrec_logical_port_set_name(lport, ctx->argv[2]);
353 if (ctx->argc == 5) {
354 nbrec_logical_port_set_parent_name(lport, ctx->argv[3]);
355 nbrec_logical_port_set_tag(lport, &tag, 1);
358 /* Insert the logical port into the logical switch. */
359 nbrec_logical_switch_verify_ports(lswitch);
360 struct nbrec_logical_port **new_ports = xmalloc(sizeof *new_ports *
361 (lswitch->n_ports + 1));
362 memcpy(new_ports, lswitch->ports, sizeof *new_ports * lswitch->n_ports);
363 new_ports[lswitch->n_ports] = lport;
364 nbrec_logical_switch_set_ports(lswitch, new_ports, lswitch->n_ports + 1);
368 /* Removes lport 'lswitch->ports[idx]'. */
370 remove_lport(const struct nbrec_logical_switch *lswitch, size_t idx)
372 const struct nbrec_logical_port *lport = lswitch->ports[idx];
374 /* First remove 'lport' from the array of ports. This is what will
375 * actually cause the logical port to be deleted when the transaction is
376 * sent to the database server (due to garbage collection). */
377 struct nbrec_logical_port **new_ports
378 = xmemdup(lswitch->ports, sizeof *new_ports * lswitch->n_ports);
379 new_ports[idx] = new_ports[lswitch->n_ports - 1];
380 nbrec_logical_switch_verify_ports(lswitch);
381 nbrec_logical_switch_set_ports(lswitch, new_ports, lswitch->n_ports - 1);
384 /* Delete 'lport' from the IDL. This won't have a real effect on the
385 * database server (the IDL will suppress it in fact) but it means that it
386 * won't show up when we iterate with NBREC_LOGICAL_PORT_FOR_EACH later. */
387 nbrec_logical_port_delete(lport);
391 do_lport_del(struct ovs_cmdl_context *ctx)
393 struct nbctl_context *nb_ctx = ctx->pvt;
394 const struct nbrec_logical_port *lport;
396 lport = lport_by_name_or_uuid(nb_ctx, ctx->argv[1]);
401 /* Find the switch that contains 'lport', then delete it. */
402 const struct nbrec_logical_switch *lswitch;
403 NBREC_LOGICAL_SWITCH_FOR_EACH (lswitch, nb_ctx->idl) {
404 for (size_t i = 0; i < lswitch->n_ports; i++) {
405 if (lswitch->ports[i] == lport) {
406 remove_lport(lswitch, i);
412 VLOG_WARN("logical port %s is not part of any logical switch",
417 do_lport_list(struct ovs_cmdl_context *ctx)
419 struct nbctl_context *nb_ctx = ctx->pvt;
420 const char *id = ctx->argv[1];
421 const struct nbrec_logical_switch *lswitch;
425 lswitch = lswitch_by_name_or_uuid(nb_ctx, id);
431 for (i = 0; i < lswitch->n_ports; i++) {
432 const struct nbrec_logical_port *lport = lswitch->ports[i];
433 smap_add_format(&lports, lport->name, UUID_FMT " (%s)",
434 UUID_ARGS(&lport->header_.uuid), lport->name);
436 const struct smap_node **nodes = smap_sort(&lports);
437 for (i = 0; i < smap_count(&lports); i++) {
438 const struct smap_node *node = nodes[i];
439 printf("%s\n", node->value);
441 smap_destroy(&lports);
446 do_lport_get_parent(struct ovs_cmdl_context *ctx)
448 struct nbctl_context *nb_ctx = ctx->pvt;
449 const struct nbrec_logical_port *lport;
451 lport = lport_by_name_or_uuid(nb_ctx, ctx->argv[1]);
456 if (lport->parent_name) {
457 printf("%s\n", lport->parent_name);
462 do_lport_get_tag(struct ovs_cmdl_context *ctx)
464 struct nbctl_context *nb_ctx = ctx->pvt;
465 const struct nbrec_logical_port *lport;
467 lport = lport_by_name_or_uuid(nb_ctx, ctx->argv[1]);
472 if (lport->n_tag > 0) {
473 printf("%"PRId64"\n", lport->tag[0]);
478 do_lport_set_external_id(struct ovs_cmdl_context *ctx)
480 struct nbctl_context *nb_ctx = ctx->pvt;
481 const char *id = ctx->argv[1];
482 const struct nbrec_logical_port *lport;
483 struct smap new_external_ids;
485 lport = lport_by_name_or_uuid(nb_ctx, id);
490 smap_init(&new_external_ids);
491 smap_clone(&new_external_ids, &lport->external_ids);
492 if (ctx->argc == 4) {
493 smap_replace(&new_external_ids, ctx->argv[2], ctx->argv[3]);
495 smap_remove(&new_external_ids, ctx->argv[2]);
497 nbrec_logical_port_set_external_ids(lport, &new_external_ids);
498 smap_destroy(&new_external_ids);
502 do_lport_get_external_id(struct ovs_cmdl_context *ctx)
504 struct nbctl_context *nb_ctx = ctx->pvt;
505 const char *id = ctx->argv[1];
506 const struct nbrec_logical_port *lport;
508 lport = lport_by_name_or_uuid(nb_ctx, id);
513 if (ctx->argc == 3) {
514 const char *key = ctx->argv[2];
517 /* List one external ID */
519 value = smap_get(&lport->external_ids, key);
521 printf("%s\n", value);
524 struct smap_node *node;
526 /* List all external IDs */
528 SMAP_FOR_EACH(node, &lport->external_ids) {
529 printf("%s=%s\n", node->key, node->value);
535 do_lport_set_macs(struct ovs_cmdl_context *ctx)
537 struct nbctl_context *nb_ctx = ctx->pvt;
538 const char *id = ctx->argv[1];
539 const struct nbrec_logical_port *lport;
541 lport = lport_by_name_or_uuid(nb_ctx, id);
546 nbrec_logical_port_set_macs(lport,
547 (const char **) ctx->argv + 2, ctx->argc - 2);
551 do_lport_get_macs(struct ovs_cmdl_context *ctx)
553 struct nbctl_context *nb_ctx = ctx->pvt;
554 const char *id = ctx->argv[1];
555 const struct nbrec_logical_port *lport;
560 lport = lport_by_name_or_uuid(nb_ctx, id);
566 for (i = 0; i < lport->n_macs; i++) {
567 svec_add(&macs, lport->macs[i]);
570 SVEC_FOR_EACH(i, mac, &macs) {
577 do_lport_set_port_security(struct ovs_cmdl_context *ctx)
579 struct nbctl_context *nb_ctx = ctx->pvt;
580 const char *id = ctx->argv[1];
581 const struct nbrec_logical_port *lport;
583 lport = lport_by_name_or_uuid(nb_ctx, id);
588 nbrec_logical_port_set_port_security(lport,
589 (const char **) ctx->argv + 2, ctx->argc - 2);
593 do_lport_get_port_security(struct ovs_cmdl_context *ctx)
595 struct nbctl_context *nb_ctx = ctx->pvt;
596 const char *id = ctx->argv[1];
597 const struct nbrec_logical_port *lport;
602 lport = lport_by_name_or_uuid(nb_ctx, id);
608 for (i = 0; i < lport->n_port_security; i++) {
609 svec_add(&addrs, lport->port_security[i]);
612 SVEC_FOR_EACH(i, addr, &addrs) {
613 printf("%s\n", addr);
615 svec_destroy(&addrs);
619 do_lport_get_up(struct ovs_cmdl_context *ctx)
621 struct nbctl_context *nb_ctx = ctx->pvt;
622 const char *id = ctx->argv[1];
623 const struct nbrec_logical_port *lport;
625 lport = lport_by_name_or_uuid(nb_ctx, id);
630 printf("%s\n", (lport->up && *lport->up) ? "up" : "down");
634 do_lport_set_enabled(struct ovs_cmdl_context *ctx)
636 struct nbctl_context *nb_ctx = ctx->pvt;
637 const char *id = ctx->argv[1];
638 const char *state = ctx->argv[2];
639 const struct nbrec_logical_port *lport;
641 lport = lport_by_name_or_uuid(nb_ctx, id);
646 if (!strcasecmp(state, "enabled")) {
648 nbrec_logical_port_set_enabled(lport, &enabled, 1);
649 } else if (!strcasecmp(state, "disabled")) {
650 bool enabled = false;
651 nbrec_logical_port_set_enabled(lport, &enabled, 1);
653 VLOG_ERR("Invalid state '%s' provided to lport-set-enabled", state);
658 do_lport_get_enabled(struct ovs_cmdl_context *ctx)
660 struct nbctl_context *nb_ctx = ctx->pvt;
661 const char *id = ctx->argv[1];
662 const struct nbrec_logical_port *lport;
664 lport = lport_by_name_or_uuid(nb_ctx, id);
670 (!lport->enabled || *lport->enabled) ? "enabled" : "disabled");
674 do_lport_set_type(struct ovs_cmdl_context *ctx)
676 struct nbctl_context *nb_ctx = ctx->pvt;
677 const char *id = ctx->argv[1];
678 const char *type = ctx->argv[2];
679 const struct nbrec_logical_port *lport;
681 lport = lport_by_name_or_uuid(nb_ctx, id);
686 nbrec_logical_port_set_type(lport, type);
690 do_lport_get_type(struct ovs_cmdl_context *ctx)
692 struct nbctl_context *nb_ctx = ctx->pvt;
693 const char *id = ctx->argv[1];
694 const struct nbrec_logical_port *lport;
696 lport = lport_by_name_or_uuid(nb_ctx, id);
701 printf("%s\n", lport->type);
705 do_lport_set_options(struct ovs_cmdl_context *ctx)
707 struct nbctl_context *nb_ctx = ctx->pvt;
708 const char *id = ctx->argv[1];
709 const struct nbrec_logical_port *lport;
711 struct smap options = SMAP_INITIALIZER(&options);
713 lport = lport_by_name_or_uuid(nb_ctx, id);
718 for (i = 2; i < ctx->argc; i++) {
720 value = xstrdup(ctx->argv[i]);
721 key = strsep(&value, "=");
723 smap_add(&options, key, value);
728 nbrec_logical_port_set_options(lport, &options);
730 smap_destroy(&options);
734 do_lport_get_options(struct ovs_cmdl_context *ctx)
736 struct nbctl_context *nb_ctx = ctx->pvt;
737 const char *id = ctx->argv[1];
738 const struct nbrec_logical_port *lport;
739 struct smap_node *node;
741 lport = lport_by_name_or_uuid(nb_ctx, id);
746 SMAP_FOR_EACH(node, &lport->options) {
747 printf("%s=%s\n", node->key, node->value);
752 parse_options(int argc, char *argv[])
757 static const struct option long_options[] = {
758 {"db", required_argument, NULL, 'd'},
759 {"help", no_argument, NULL, 'h'},
760 {"options", no_argument, NULL, 'o'},
761 {"version", no_argument, NULL, 'V'},
763 STREAM_SSL_LONG_OPTIONS,
766 char *short_options = ovs_cmdl_long_options_to_short_options(long_options);
771 c = getopt_long(argc, argv, short_options, long_options, NULL);
777 VLOG_OPTION_HANDLERS;
778 STREAM_SSL_OPTION_HANDLERS;
789 ovs_cmdl_print_options(long_options);
793 ovs_print_version(0, 0);
808 static const struct ovs_cmdl_command all_commands[] = {
811 .usage = "[LSWITCH]",
817 .name = "lswitch-add",
818 .usage = "[LSWITCH]",
821 .handler = do_lswitch_add,
824 .name = "lswitch-del",
828 .handler = do_lswitch_del,
831 .name = "lswitch-list",
835 .handler = do_lswitch_list,
838 .name = "lswitch-set-external-id",
839 .usage = "LSWITCH KEY [VALUE]",
842 .handler = do_lswitch_set_external_id,
845 .name = "lswitch-get-external-id",
846 .usage = "LSWITCH [KEY]",
849 .handler = do_lswitch_get_external_id,
853 .usage = "LSWITCH LPORT [PARENT] [TAG]",
856 .handler = do_lport_add,
863 .handler = do_lport_del,
866 .name = "lport-list",
870 .handler = do_lport_list,
873 .name = "lport-get-parent",
877 .handler = do_lport_get_parent,
880 .name = "lport-get-tag",
884 .handler = do_lport_get_tag,
887 .name = "lport-set-external-id",
888 .usage = "LPORT KEY [VALUE]",
891 .handler = do_lport_set_external_id,
894 .name = "lport-get-external-id",
895 .usage = "LPORT [KEY]",
898 .handler = do_lport_get_external_id,
901 .name = "lport-set-macs",
902 .usage = "LPORT [MAC]...",
904 /* Accept however many arguments the system will allow. */
906 .handler = do_lport_set_macs,
909 .name = "lport-get-macs",
913 .handler = do_lport_get_macs,
916 .name = "lport-set-port-security",
917 .usage = "LPORT [ADDRS]...",
919 /* Accept however many arguments the system will allow. */
921 .handler = do_lport_set_port_security,
924 .name = "lport-get-port-security",
928 .handler = do_lport_get_port_security,
931 .name = "lport-get-up",
935 .handler = do_lport_get_up,
938 .name = "lport-set-enabled",
939 .usage = "LPORT STATE",
942 .handler = do_lport_set_enabled,
945 .name = "lport-get-enabled",
949 .handler = do_lport_get_enabled,
952 .name = "lport-set-type",
953 .usage = "LPORT TYPE",
956 .handler = do_lport_set_type,
959 .name = "lport-get-type",
963 .handler = do_lport_get_type,
966 .name = "lport-set-options",
967 .usage = "LPORT KEY=VALUE [KEY=VALUE]...",
970 .handler = do_lport_set_options
973 .name = "lport-get-options",
977 .handler = do_lport_get_options,
986 static const struct ovs_cmdl_command *
987 get_all_commands(void)
997 def = getenv("OVN_NB_DB");
999 def = xasprintf("unix:%s/db.sock", ovs_rundir());
1006 main(int argc, char *argv[])
1008 extern struct vlog_module VLM_reconnect;
1009 struct ovs_cmdl_context ctx;
1010 struct nbctl_context nb_ctx = { .idl = NULL, };
1011 enum ovsdb_idl_txn_status txn_status;
1016 fatal_ignore_sigpipe();
1017 set_program_name(argv[0]);
1018 vlog_set_levels(NULL, VLF_CONSOLE, VLL_WARN);
1019 vlog_set_levels(&VLM_reconnect, VLF_ANY_DESTINATION, VLL_WARN);
1020 parse_options(argc, argv);
1023 args = process_escape_args(argv);
1025 nb_ctx.idl = ovsdb_idl_create(db, &nbrec_idl_class, true, false);
1027 ctx.argc = argc - optind;
1028 ctx.argv = argv + optind;
1030 seqno = ovsdb_idl_get_seqno(nb_ctx.idl);
1032 ovsdb_idl_run(nb_ctx.idl);
1034 if (!ovsdb_idl_is_alive(nb_ctx.idl)) {
1035 int retval = ovsdb_idl_get_last_error(nb_ctx.idl);
1036 VLOG_ERR("%s: database connection failed (%s)",
1037 db, ovs_retval_to_string(retval));
1042 if (seqno != ovsdb_idl_get_seqno(nb_ctx.idl)) {
1043 nb_ctx.txn = ovsdb_idl_txn_create(nb_ctx.idl);
1044 ovsdb_idl_txn_add_comment(nb_ctx.txn, "ovn-nbctl: %s", args);
1045 ovs_cmdl_run_command(&ctx, get_all_commands());
1046 txn_status = ovsdb_idl_txn_commit_block(nb_ctx.txn);
1047 if (txn_status == TXN_TRY_AGAIN) {
1048 ovsdb_idl_txn_destroy(nb_ctx.txn);
1056 if (seqno == ovsdb_idl_get_seqno(nb_ctx.idl)) {
1057 ovsdb_idl_wait(nb_ctx.idl);
1063 ovsdb_idl_txn_destroy(nb_ctx.txn);
1065 ovsdb_idl_destroy(nb_ctx.idl);