]> git.proxmox.com Git - mirror_ovs.git/blob - ovn/utilities/ovn-sbctl.c
vlog: Stop using explicit references to external log modules.
[mirror_ovs.git] / ovn / utilities / ovn-sbctl.c
1 /*
2 * Copyright (c) 2015 Nicira, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <config.h>
18
19 #include <ctype.h>
20 #include <errno.h>
21 #include <float.h>
22 #include <getopt.h>
23 #include <inttypes.h>
24 #include <signal.h>
25 #include <stdarg.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <unistd.h>
29
30 #include "db-ctl-base.h"
31
32 #include "command-line.h"
33 #include "compiler.h"
34 #include "dynamic-string.h"
35 #include "fatal-signal.h"
36 #include "json.h"
37 #include "ovsdb-data.h"
38 #include "ovsdb-idl.h"
39 #include "poll-loop.h"
40 #include "process.h"
41 #include "sset.h"
42 #include "shash.h"
43 #include "stream-ssl.h"
44 #include "stream.h"
45 #include "table.h"
46 #include "timeval.h"
47 #include "util.h"
48 #include "openvswitch/vlog.h"
49 #include "ovn/lib/ovn-sb-idl.h"
50
51 VLOG_DEFINE_THIS_MODULE(sbctl);
52
53 struct sbctl_context;
54
55 /* --db: The database server to contact. */
56 static const char *db;
57
58 /* --oneline: Write each command's output as a single line? */
59 static bool oneline;
60
61 /* --dry-run: Do not commit any changes. */
62 static bool dry_run;
63
64 /* --timeout: Time to wait for a connection to 'db'. */
65 static int timeout;
66
67 /* Format for table output. */
68 static struct table_style table_style = TABLE_STYLE_DEFAULT;
69
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);
76
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 const char *sbctl_default_db(void);
81 static void run_prerequisites(struct ctl_command[], size_t n_commands,
82 struct ovsdb_idl *);
83 static void do_sbctl(const char *args, struct ctl_command *, size_t n,
84 struct ovsdb_idl *);
85
86 int
87 main(int argc, char *argv[])
88 {
89 struct ovsdb_idl *idl;
90 struct ctl_command *commands;
91 struct shash local_options;
92 unsigned int seqno;
93 size_t n_commands;
94 char *args;
95
96 set_program_name(argv[0]);
97 fatal_ignore_sigpipe();
98 vlog_set_levels(NULL, VLF_CONSOLE, VLL_WARN);
99 vlog_set_levels_from_string_assert("reconnect:warn");
100 sbrec_init();
101
102 sbctl_cmd_init();
103
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);
107
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,
112 &n_commands);
113
114 if (timeout) {
115 time_alarm(timeout);
116 }
117
118 /* Initialize IDL. */
119 idl = the_idl = ovsdb_idl_create(db, &sbrec_idl_class, false, false);
120 run_prerequisites(commands, n_commands, idl);
121
122 /* Execute the commands.
123 *
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);
130 for (;;) {
131 ovsdb_idl_run(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));
136 }
137
138 if (seqno != ovsdb_idl_get_seqno(idl)) {
139 seqno = ovsdb_idl_get_seqno(idl);
140 do_sbctl(args, commands, n_commands, idl);
141 }
142
143 if (seqno == ovsdb_idl_get_seqno(idl)) {
144 ovsdb_idl_wait(idl);
145 poll_block();
146 }
147 }
148 }
149
150 static const char *
151 sbctl_default_db(void)
152 {
153 static char *def;
154 if (!def) {
155 def = getenv("OVN_SB_DB");
156 if (!def) {
157 def = ctl_default_db();
158 }
159 }
160 return def;
161 }
162
163 static void
164 parse_options(int argc, char *argv[], struct shash *local_options)
165 {
166 enum {
167 OPT_DB = UCHAR_MAX + 1,
168 OPT_ONELINE,
169 OPT_NO_SYSLOG,
170 OPT_DRY_RUN,
171 OPT_PEER_CA_CERT,
172 OPT_LOCAL,
173 OPT_COMMANDS,
174 OPT_OPTIONS,
175 VLOG_OPTION_ENUMS,
176 TABLE_OPTION_ENUMS
177 };
178 static const struct option global_long_options[] = {
179 {"db", required_argument, NULL, OPT_DB},
180 {"no-syslog", no_argument, NULL, OPT_NO_SYSLOG},
181 {"dry-run", no_argument, NULL, OPT_DRY_RUN},
182 {"oneline", no_argument, NULL, OPT_ONELINE},
183 {"timeout", required_argument, NULL, 't'},
184 {"help", no_argument, NULL, 'h'},
185 {"commands", no_argument, NULL, OPT_COMMANDS},
186 {"options", no_argument, NULL, OPT_OPTIONS},
187 {"version", no_argument, NULL, 'V'},
188 VLOG_LONG_OPTIONS,
189 STREAM_SSL_LONG_OPTIONS,
190 TABLE_LONG_OPTIONS,
191 {NULL, 0, NULL, 0},
192 };
193 const int n_global_long_options = ARRAY_SIZE(global_long_options) - 1;
194 char *tmp, *short_options;
195
196 struct option *options;
197 size_t allocated_options;
198 size_t n_options;
199 size_t i;
200
201 tmp = ovs_cmdl_long_options_to_short_options(global_long_options);
202 short_options = xasprintf("+%s", tmp);
203 free(tmp);
204
205 /* We want to parse both global and command-specific options here, but
206 * getopt_long() isn't too convenient for the job. We copy our global
207 * options into a dynamic array, then append all of the command-specific
208 * options. */
209 options = xmemdup(global_long_options, sizeof global_long_options);
210 allocated_options = ARRAY_SIZE(global_long_options);
211 n_options = n_global_long_options;
212 ctl_add_cmd_options(&options, &n_options, &allocated_options, OPT_LOCAL);
213 table_style.format = TF_LIST;
214
215 for (;;) {
216 int idx;
217 int c;
218
219 c = getopt_long(argc, argv, short_options, options, &idx);
220 if (c == -1) {
221 break;
222 }
223
224 switch (c) {
225 case OPT_DB:
226 db = optarg;
227 break;
228
229 case OPT_ONELINE:
230 oneline = true;
231 break;
232
233 case OPT_NO_SYSLOG:
234 vlog_set_levels(&VLM_sbctl, VLF_SYSLOG, VLL_WARN);
235 break;
236
237 case OPT_DRY_RUN:
238 dry_run = true;
239 break;
240
241 case OPT_LOCAL:
242 if (shash_find(local_options, options[idx].name)) {
243 ctl_fatal("'%s' option specified multiple times",
244 options[idx].name);
245 }
246 shash_add_nocopy(local_options,
247 xasprintf("--%s", options[idx].name),
248 optarg ? xstrdup(optarg) : NULL);
249 break;
250
251 case 'h':
252 usage();
253
254 case OPT_COMMANDS:
255 ctl_print_commands();
256
257 case OPT_OPTIONS:
258 ctl_print_options(global_long_options);
259
260 case 'V':
261 ovs_print_version(0, 0);
262 printf("DB Schema %s\n", sbrec_get_db_version());
263 exit(EXIT_SUCCESS);
264
265 case 't':
266 timeout = strtoul(optarg, NULL, 10);
267 if (timeout < 0) {
268 ctl_fatal("value %s on -t or --timeout is invalid", optarg);
269 }
270 break;
271
272 VLOG_OPTION_HANDLERS
273 TABLE_OPTION_HANDLERS(&table_style)
274 STREAM_SSL_OPTION_HANDLERS
275
276 case '?':
277 exit(EXIT_FAILURE);
278
279 default:
280 abort();
281 }
282 }
283 free(short_options);
284
285 if (!db) {
286 db = sbctl_default_db();
287 }
288
289 for (i = n_global_long_options; options[i].name; i++) {
290 free(CONST_CAST(char *, options[i].name));
291 }
292 free(options);
293 }
294
295 static void
296 usage(void)
297 {
298 printf("\
299 %s: OVN southbound DB management utility\n\
300 \n\
301 For debugging and testing only, not for use in production.\n\
302 \n\
303 usage: %s [OPTIONS] COMMAND [ARG...]\n\
304 \n\
305 General commands:\n\
306 show print overview of database contents\n\
307 \n\
308 Chassis commands:\n\
309 chassis-add CHASSIS ENCAP-TYPE ENCAP-IP create a new chassis named\n\
310 CHASSIS with ENCAP-TYPE tunnels\n\
311 and ENCAP-IP\n\
312 chassis-del CHASSIS delete CHASSIS and all of its encaps\n\
313 and gateway_ports\n\
314 \n\
315 Port binding commands:\n\
316 lport-bind LPORT CHASSIS bind logical port LPORT to CHASSIS\n\
317 lport-unbind LPORT reset the port binding of logical port LPORT\n\
318 \n\
319 Logical flow commands:\n\
320 lflow-list [DATAPATH] List logical flows for all or a single datapath\n\
321 dump-flows [DATAPATH] Alias for lflow-list\n\
322 \n\
323 %s\
324 \n\
325 Options:\n\
326 --db=DATABASE connect to DATABASE\n\
327 (default: %s)\n\
328 -t, --timeout=SECS wait at most SECS seconds\n\
329 --dry-run do not commit changes to database\n\
330 --oneline print exactly one line of output per command\n",
331 program_name, program_name, ctl_get_db_cmd_usage(), ctl_default_db());
332 vlog_usage();
333 printf("\
334 --no-syslog equivalent to --verbose=sbctl:syslog:warn\n");
335 printf("\n\
336 Other options:\n\
337 -h, --help display this help message\n\
338 -V, --version display version information\n");
339 stream_usage("database", true, true, false);
340 exit(EXIT_SUCCESS);
341 }
342
343 \f
344 /* ovs-sbctl specific context. Inherits the 'struct ctl_context' as base. */
345 struct sbctl_context {
346 struct ctl_context base;
347
348 /* A cache of the contents of the database.
349 *
350 * A command that needs to use any of this information must first call
351 * sbctl_context_populate_cache(). A command that changes anything that
352 * could invalidate the cache must either call
353 * sbctl_context_invalidate_cache() or manually update the cache to
354 * maintain its correctness. */
355 bool cache_valid;
356 /* Maps from chassis name to struct sbctl_chassis. */
357 struct shash chassis;
358 /* Maps from lport name to struct sbctl_port_binding. */
359 struct shash port_bindings;
360 };
361
362 /* Casts 'base' into 'struct sbctl_context'. */
363 static struct sbctl_context *
364 sbctl_context_cast(struct ctl_context *base)
365 {
366 return CONTAINER_OF(base, struct sbctl_context, base);
367 }
368
369 struct sbctl_chassis {
370 const struct sbrec_chassis *ch_cfg;
371 };
372
373 struct sbctl_port_binding {
374 const struct sbrec_port_binding *bd_cfg;
375 };
376
377 static void
378 sbctl_context_invalidate_cache(struct ctl_context *ctx)
379 {
380 struct sbctl_context *sbctl_ctx = sbctl_context_cast(ctx);
381
382 if (!sbctl_ctx->cache_valid) {
383 return;
384 }
385 sbctl_ctx->cache_valid = false;
386 shash_destroy_free_data(&sbctl_ctx->chassis);
387 shash_destroy_free_data(&sbctl_ctx->port_bindings);
388 }
389
390 static void
391 sbctl_context_populate_cache(struct ctl_context *ctx)
392 {
393 struct sbctl_context *sbctl_ctx = sbctl_context_cast(ctx);
394 const struct sbrec_chassis *chassis_rec;
395 const struct sbrec_port_binding *port_binding_rec;
396 struct sset chassis, port_bindings;
397
398 if (sbctl_ctx->cache_valid) {
399 /* Cache is already populated. */
400 return;
401 }
402 sbctl_ctx->cache_valid = true;
403 shash_init(&sbctl_ctx->chassis);
404 shash_init(&sbctl_ctx->port_bindings);
405 sset_init(&chassis);
406 SBREC_CHASSIS_FOR_EACH(chassis_rec, ctx->idl) {
407 struct sbctl_chassis *ch;
408
409 if (!sset_add(&chassis, chassis_rec->name)) {
410 VLOG_WARN("database contains duplicate chassis name (%s)",
411 chassis_rec->name);
412 continue;
413 }
414
415 ch = xmalloc(sizeof *ch);
416 ch->ch_cfg = chassis_rec;
417 shash_add(&sbctl_ctx->chassis, chassis_rec->name, ch);
418 }
419 sset_destroy(&chassis);
420
421 sset_init(&port_bindings);
422 SBREC_PORT_BINDING_FOR_EACH(port_binding_rec, ctx->idl) {
423 struct sbctl_port_binding *bd;
424
425 if (!sset_add(&port_bindings, port_binding_rec->logical_port)) {
426 VLOG_WARN("database contains duplicate port binding for logical "
427 "port (%s)",
428 port_binding_rec->logical_port);
429 continue;
430 }
431
432 bd = xmalloc(sizeof *bd);
433 bd->bd_cfg = port_binding_rec;
434 shash_add(&sbctl_ctx->port_bindings, port_binding_rec->logical_port,
435 bd);
436 }
437 sset_destroy(&port_bindings);
438 }
439
440 static void
441 check_conflicts(struct sbctl_context *sbctl_ctx, const char *name,
442 char *msg)
443 {
444 if (shash_find(&sbctl_ctx->chassis, name)) {
445 ctl_fatal("%s because a chassis named %s already exists",
446 msg, name);
447 }
448 free(msg);
449 }
450
451 static struct sbctl_chassis *
452 find_chassis(struct sbctl_context *sbctl_ctx, const char *name,
453 bool must_exist)
454 {
455 struct sbctl_chassis *sbctl_ch;
456
457 ovs_assert(sbctl_ctx->cache_valid);
458
459 sbctl_ch = shash_find_data(&sbctl_ctx->chassis, name);
460 if (must_exist && !sbctl_ch) {
461 ctl_fatal("no chassis named %s", name);
462 }
463
464 return sbctl_ch;
465 }
466
467 static struct sbctl_port_binding *
468 find_port_binding(struct sbctl_context *sbctl_ctx, const char *name,
469 bool must_exist)
470 {
471 struct sbctl_port_binding *bd;
472
473 ovs_assert(sbctl_ctx->cache_valid);
474
475 bd = shash_find_data(&sbctl_ctx->port_bindings, name);
476 if (must_exist && !bd) {
477 ctl_fatal("no port named %s", name);
478 }
479
480 return bd;
481 }
482
483 static void
484 pre_get_info(struct ctl_context *ctx)
485 {
486 ovsdb_idl_add_column(ctx->idl, &sbrec_chassis_col_name);
487 ovsdb_idl_add_column(ctx->idl, &sbrec_chassis_col_encaps);
488
489 ovsdb_idl_add_column(ctx->idl, &sbrec_encap_col_type);
490 ovsdb_idl_add_column(ctx->idl, &sbrec_encap_col_ip);
491
492 ovsdb_idl_add_column(ctx->idl, &sbrec_port_binding_col_logical_port);
493 ovsdb_idl_add_column(ctx->idl, &sbrec_port_binding_col_chassis);
494
495 ovsdb_idl_add_column(ctx->idl, &sbrec_logical_flow_col_logical_datapath);
496 ovsdb_idl_add_column(ctx->idl, &sbrec_logical_flow_col_pipeline);
497 ovsdb_idl_add_column(ctx->idl, &sbrec_logical_flow_col_actions);
498 ovsdb_idl_add_column(ctx->idl, &sbrec_logical_flow_col_priority);
499 ovsdb_idl_add_column(ctx->idl, &sbrec_logical_flow_col_table_id);
500 ovsdb_idl_add_column(ctx->idl, &sbrec_logical_flow_col_match);
501 ovsdb_idl_add_column(ctx->idl, &sbrec_logical_flow_col_external_ids);
502 }
503
504 static struct cmd_show_table cmd_show_tables[] = {
505 {&sbrec_table_chassis,
506 &sbrec_chassis_col_name,
507 {&sbrec_chassis_col_encaps,
508 NULL,
509 NULL},
510 {&sbrec_table_port_binding,
511 &sbrec_port_binding_col_logical_port,
512 &sbrec_port_binding_col_chassis}},
513
514 {&sbrec_table_encap,
515 &sbrec_encap_col_type,
516 {&sbrec_encap_col_ip,
517 &sbrec_encap_col_options,
518 NULL},
519 {NULL, NULL, NULL}},
520
521 {NULL, NULL, {NULL, NULL, NULL}, {NULL, NULL, NULL}},
522 };
523
524 static void
525 cmd_chassis_add(struct ctl_context *ctx)
526 {
527 struct sbctl_context *sbctl_ctx = sbctl_context_cast(ctx);
528 bool may_exist = shash_find(&ctx->options, "--may-exist") != NULL;
529 const char *ch_name, *encap_types, *encap_ip;
530
531 ch_name = ctx->argv[1];
532 encap_types = ctx->argv[2];
533 encap_ip = ctx->argv[3];
534
535 sbctl_context_populate_cache(ctx);
536 if (may_exist) {
537 struct sbctl_chassis *sbctl_ch;
538
539 sbctl_ch = find_chassis(sbctl_ctx, ch_name, false);
540 if (sbctl_ch) {
541 return;
542 }
543 }
544 check_conflicts(sbctl_ctx, ch_name,
545 xasprintf("cannot create a chassis named %s", ch_name));
546
547 char *tokstr = xstrdup(encap_types);
548 char *token, *save_ptr = NULL;
549 struct sset encap_set = SSET_INITIALIZER(&encap_set);
550 for (token = strtok_r(tokstr, ",", &save_ptr); token != NULL;
551 token = strtok_r(NULL, ",", &save_ptr)) {
552 sset_add(&encap_set, token);
553 }
554 free(tokstr);
555
556 size_t n_encaps = sset_count(&encap_set);
557 struct sbrec_encap **encaps = xmalloc(n_encaps * sizeof *encaps);
558 const char *encap_type;
559 int i = 0;
560 SSET_FOR_EACH (encap_type, &encap_set){
561 encaps[i] = sbrec_encap_insert(ctx->txn);
562
563 sbrec_encap_set_type(encaps[i], encap_type);
564 sbrec_encap_set_ip(encaps[i], encap_ip);
565 i++;
566 }
567 sset_destroy(&encap_set);
568
569 struct sbrec_chassis *ch = sbrec_chassis_insert(ctx->txn);
570 sbrec_chassis_set_name(ch, ch_name);
571 sbrec_chassis_set_encaps(ch, encaps, n_encaps);
572 free(encaps);
573
574 sbctl_context_invalidate_cache(ctx);
575 }
576
577 static void
578 cmd_chassis_del(struct ctl_context *ctx)
579 {
580 struct sbctl_context *sbctl_ctx = sbctl_context_cast(ctx);
581 bool must_exist = !shash_find(&ctx->options, "--if-exists");
582 struct sbctl_chassis *sbctl_ch;
583
584 sbctl_context_populate_cache(ctx);
585 sbctl_ch = find_chassis(sbctl_ctx, ctx->argv[1], must_exist);
586 if (sbctl_ch) {
587 if (sbctl_ch->ch_cfg) {
588 size_t i;
589
590 for (i = 0; i < sbctl_ch->ch_cfg->n_encaps; i++) {
591 sbrec_encap_delete(sbctl_ch->ch_cfg->encaps[i]);
592 }
593 sbrec_chassis_delete(sbctl_ch->ch_cfg);
594 }
595 shash_find_and_delete(&sbctl_ctx->chassis, ctx->argv[1]);
596 free(sbctl_ch);
597 }
598 }
599
600 static void
601 cmd_lport_bind(struct ctl_context *ctx)
602 {
603 struct sbctl_context *sbctl_ctx = sbctl_context_cast(ctx);
604 bool may_exist = shash_find(&ctx->options, "--may-exist") != NULL;
605 struct sbctl_chassis *sbctl_ch;
606 struct sbctl_port_binding *sbctl_bd;
607 char *lport_name, *ch_name;
608
609 /* port_binding must exist, chassis must exist! */
610 lport_name = ctx->argv[1];
611 ch_name = ctx->argv[2];
612
613 sbctl_context_populate_cache(ctx);
614 sbctl_bd = find_port_binding(sbctl_ctx, lport_name, true);
615 sbctl_ch = find_chassis(sbctl_ctx, ch_name, true);
616
617 if (sbctl_bd->bd_cfg->chassis) {
618 if (may_exist && sbctl_bd->bd_cfg->chassis == sbctl_ch->ch_cfg) {
619 return;
620 } else {
621 ctl_fatal("lport (%s) has already been binded to chassis (%s)",
622 lport_name, sbctl_bd->bd_cfg->chassis->name);
623 }
624 }
625 sbrec_port_binding_set_chassis(sbctl_bd->bd_cfg, sbctl_ch->ch_cfg);
626 sbctl_context_invalidate_cache(ctx);
627 }
628
629 static void
630 cmd_lport_unbind(struct ctl_context *ctx)
631 {
632 struct sbctl_context *sbctl_ctx = sbctl_context_cast(ctx);
633 bool must_exist = !shash_find(&ctx->options, "--if-exists");
634 struct sbctl_port_binding *sbctl_bd;
635 char *lport_name;
636
637 lport_name = ctx->argv[1];
638 sbctl_context_populate_cache(ctx);
639 sbctl_bd = find_port_binding(sbctl_ctx, lport_name, must_exist);
640 if (sbctl_bd) {
641 sbrec_port_binding_set_chassis(sbctl_bd->bd_cfg, NULL);
642 }
643 }
644
645 enum {
646 PL_INGRESS,
647 PL_EGRESS,
648 };
649
650 /* Help ensure we catch any future pipeline values */
651 static int
652 pipeline_encode(const char *pl)
653 {
654 if (!strcmp(pl, "ingress")) {
655 return PL_INGRESS;
656 } else if (!strcmp(pl, "egress")) {
657 return PL_EGRESS;
658 }
659
660 OVS_NOT_REACHED();
661 }
662
663 static int
664 lflow_cmp(const void *lf1_, const void *lf2_)
665 {
666 const struct sbrec_logical_flow *const *lf1p = lf1_;
667 const struct sbrec_logical_flow *const *lf2p = lf2_;
668 const struct sbrec_logical_flow *lf1 = *lf1p;
669 const struct sbrec_logical_flow *lf2 = *lf2p;
670
671 int pl1 = pipeline_encode(lf1->pipeline);
672 int pl2 = pipeline_encode(lf2->pipeline);
673
674 #define CMP(expr) \
675 do { \
676 int res; \
677 res = (expr); \
678 if (res) { \
679 return res; \
680 } \
681 } while (0)
682
683 CMP(uuid_compare_3way(&lf1->logical_datapath->header_.uuid,
684 &lf2->logical_datapath->header_.uuid));
685 CMP(pl1 - pl2);
686 CMP(lf1->table_id > lf2->table_id ? 1 :
687 (lf1->table_id < lf2->table_id ? -1 : 0));
688 CMP(lf1->priority > lf2->priority ? -1 :
689 (lf1->priority < lf2->priority ? 1 : 0));
690 CMP(strcmp(lf1->match, lf2->match));
691
692 #undef CMP
693
694 return 0;
695 }
696
697 static void
698 cmd_lflow_list(struct ctl_context *ctx)
699 {
700 const char *datapath = ctx->argc == 2 ? ctx->argv[1] : NULL;
701 struct uuid datapath_uuid = { .parts = { 0, }};
702 const struct sbrec_logical_flow **lflows;
703 const struct sbrec_logical_flow *lflow;
704 size_t n_flows = 0, n_capacity = 64;
705
706 if (datapath && !uuid_from_string(&datapath_uuid, datapath)) {
707 VLOG_ERR("Invalid format of datapath UUID");
708 return;
709 }
710
711 lflows = xmalloc(sizeof *lflows * n_capacity);
712 SBREC_LOGICAL_FLOW_FOR_EACH (lflow, ctx->idl) {
713 if (n_flows == n_capacity) {
714 lflows = x2nrealloc(lflows, &n_capacity, sizeof *lflows);
715 }
716 lflows[n_flows] = lflow;
717 n_flows++;
718 }
719
720 qsort(lflows, n_flows, sizeof *lflows, lflow_cmp);
721
722 const char *cur_pipeline = "";
723 size_t i;
724 for (i = 0; i < n_flows; i++) {
725 lflow = lflows[i];
726 if (datapath && !uuid_equals(&datapath_uuid,
727 &lflow->logical_datapath->header_.uuid)) {
728 continue;
729 }
730 if (strcmp(cur_pipeline, lflow->pipeline)) {
731 printf("Datapath: " UUID_FMT " Pipeline: %s\n",
732 UUID_ARGS(&lflow->logical_datapath->header_.uuid),
733 lflow->pipeline);
734 cur_pipeline = lflow->pipeline;
735 }
736
737 const char *table_name = smap_get(&lflow->external_ids, "stage-name");
738 printf(" table=%" PRId64 "(%16s), priority=%5" PRId64
739 ", match=(%s), action=(%s)\n",
740 lflow->table_id, table_name ? table_name : "",
741 lflow->priority, lflow->match, lflow->actions);
742 }
743
744 free(lflows);
745 }
746
747 \f
748 static const struct ctl_table_class tables[] = {
749 {&sbrec_table_chassis,
750 {{&sbrec_table_chassis, &sbrec_chassis_col_name, NULL},
751 {NULL, NULL, NULL}}},
752
753 {&sbrec_table_encap,
754 {{NULL, NULL, NULL},
755 {NULL, NULL, NULL}}},
756
757 {&sbrec_table_logical_flow,
758 {{&sbrec_table_logical_flow, NULL,
759 &sbrec_logical_flow_col_logical_datapath},
760 {NULL, NULL, NULL}}},
761
762 {&sbrec_table_multicast_group,
763 {{NULL, NULL, NULL},
764 {NULL, NULL, NULL}}},
765
766 {&sbrec_table_datapath_binding,
767 {{NULL, NULL, NULL},
768 {NULL, NULL, NULL}}},
769
770 {&sbrec_table_port_binding,
771 {{&sbrec_table_port_binding, &sbrec_port_binding_col_logical_port, NULL},
772 {NULL, NULL, NULL}}},
773
774 {NULL, {{NULL, NULL, NULL}, {NULL, NULL, NULL}}}
775 };
776
777 \f
778 static void
779 sbctl_context_init_command(struct sbctl_context *sbctl_ctx,
780 struct ctl_command *command)
781 {
782 ctl_context_init_command(&sbctl_ctx->base, command);
783 }
784
785 static void
786 sbctl_context_init(struct sbctl_context *sbctl_ctx,
787 struct ctl_command *command, struct ovsdb_idl *idl,
788 struct ovsdb_idl_txn *txn,
789 struct ovsdb_symbol_table *symtab)
790 {
791 ctl_context_init(&sbctl_ctx->base, command, idl, txn, symtab,
792 sbctl_context_invalidate_cache);
793 sbctl_ctx->cache_valid = false;
794 }
795
796 static void
797 sbctl_context_done_command(struct sbctl_context *sbctl_ctx,
798 struct ctl_command *command)
799 {
800 ctl_context_done_command(&sbctl_ctx->base, command);
801 }
802
803 static void
804 sbctl_context_done(struct sbctl_context *sbctl_ctx,
805 struct ctl_command *command)
806 {
807 ctl_context_done(&sbctl_ctx->base, command);
808 }
809
810 static void
811 run_prerequisites(struct ctl_command *commands, size_t n_commands,
812 struct ovsdb_idl *idl)
813 {
814 struct ctl_command *c;
815
816 for (c = commands; c < &commands[n_commands]; c++) {
817 if (c->syntax->prerequisites) {
818 struct sbctl_context sbctl_ctx;
819
820 ds_init(&c->output);
821 c->table = NULL;
822
823 sbctl_context_init(&sbctl_ctx, c, idl, NULL, NULL);
824 (c->syntax->prerequisites)(&sbctl_ctx.base);
825 sbctl_context_done(&sbctl_ctx, c);
826
827 ovs_assert(!c->output.string);
828 ovs_assert(!c->table);
829 }
830 }
831 }
832
833 static void
834 do_sbctl(const char *args, struct ctl_command *commands, size_t n_commands,
835 struct ovsdb_idl *idl)
836 {
837 struct ovsdb_idl_txn *txn;
838 enum ovsdb_idl_txn_status status;
839 struct ovsdb_symbol_table *symtab;
840 struct sbctl_context sbctl_ctx;
841 struct ctl_command *c;
842 struct shash_node *node;
843 char *error = NULL;
844
845 txn = the_idl_txn = ovsdb_idl_txn_create(idl);
846 if (dry_run) {
847 ovsdb_idl_txn_set_dry_run(txn);
848 }
849
850 ovsdb_idl_txn_add_comment(txn, "ovs-sbctl: %s", args);
851
852 symtab = ovsdb_symbol_table_create();
853 for (c = commands; c < &commands[n_commands]; c++) {
854 ds_init(&c->output);
855 c->table = NULL;
856 }
857 sbctl_context_init(&sbctl_ctx, NULL, idl, txn, symtab);
858 for (c = commands; c < &commands[n_commands]; c++) {
859 sbctl_context_init_command(&sbctl_ctx, c);
860 if (c->syntax->run) {
861 (c->syntax->run)(&sbctl_ctx.base);
862 }
863 sbctl_context_done_command(&sbctl_ctx, c);
864
865 if (sbctl_ctx.base.try_again) {
866 sbctl_context_done(&sbctl_ctx, NULL);
867 goto try_again;
868 }
869 }
870 sbctl_context_done(&sbctl_ctx, NULL);
871
872 SHASH_FOR_EACH (node, &symtab->sh) {
873 struct ovsdb_symbol *symbol = node->data;
874 if (!symbol->created) {
875 ctl_fatal("row id \"%s\" is referenced but never created (e.g. "
876 "with \"-- --id=%s create ...\")",
877 node->name, node->name);
878 }
879 if (!symbol->strong_ref) {
880 if (!symbol->weak_ref) {
881 VLOG_WARN("row id \"%s\" was created but no reference to it "
882 "was inserted, so it will not actually appear in "
883 "the database", node->name);
884 } else {
885 VLOG_WARN("row id \"%s\" was created but only a weak "
886 "reference to it was inserted, so it will not "
887 "actually appear in the database", node->name);
888 }
889 }
890 }
891
892 status = ovsdb_idl_txn_commit_block(txn);
893 if (status == TXN_UNCHANGED || status == TXN_SUCCESS) {
894 for (c = commands; c < &commands[n_commands]; c++) {
895 if (c->syntax->postprocess) {
896 sbctl_context_init(&sbctl_ctx, c, idl, txn, symtab);
897 (c->syntax->postprocess)(&sbctl_ctx.base);
898 sbctl_context_done(&sbctl_ctx, c);
899 }
900 }
901 }
902 error = xstrdup(ovsdb_idl_txn_get_error(txn));
903
904 switch (status) {
905 case TXN_UNCOMMITTED:
906 case TXN_INCOMPLETE:
907 OVS_NOT_REACHED();
908
909 case TXN_ABORTED:
910 /* Should not happen--we never call ovsdb_idl_txn_abort(). */
911 ctl_fatal("transaction aborted");
912
913 case TXN_UNCHANGED:
914 case TXN_SUCCESS:
915 break;
916
917 case TXN_TRY_AGAIN:
918 goto try_again;
919
920 case TXN_ERROR:
921 ctl_fatal("transaction error: %s", error);
922
923 case TXN_NOT_LOCKED:
924 /* Should not happen--we never call ovsdb_idl_set_lock(). */
925 ctl_fatal("database not locked");
926
927 default:
928 OVS_NOT_REACHED();
929 }
930 free(error);
931
932 ovsdb_symbol_table_destroy(symtab);
933
934 for (c = commands; c < &commands[n_commands]; c++) {
935 struct ds *ds = &c->output;
936
937 if (c->table) {
938 table_print(c->table, &table_style);
939 } else if (oneline) {
940 size_t j;
941
942 ds_chomp(ds, '\n');
943 for (j = 0; j < ds->length; j++) {
944 int ch = ds->string[j];
945 switch (ch) {
946 case '\n':
947 fputs("\\n", stdout);
948 break;
949
950 case '\\':
951 fputs("\\\\", stdout);
952 break;
953
954 default:
955 putchar(ch);
956 }
957 }
958 putchar('\n');
959 } else {
960 fputs(ds_cstr(ds), stdout);
961 }
962 ds_destroy(&c->output);
963 table_destroy(c->table);
964 free(c->table);
965
966 shash_destroy_free_data(&c->options);
967 }
968 free(commands);
969 ovsdb_idl_txn_destroy(txn);
970 ovsdb_idl_destroy(idl);
971
972 exit(EXIT_SUCCESS);
973
974 try_again:
975 /* Our transaction needs to be rerun, or a prerequisite was not met. Free
976 * resources and return so that the caller can try again. */
977 if (txn) {
978 ovsdb_idl_txn_abort(txn);
979 ovsdb_idl_txn_destroy(txn);
980 the_idl_txn = NULL;
981 }
982 ovsdb_symbol_table_destroy(symtab);
983 for (c = commands; c < &commands[n_commands]; c++) {
984 ds_destroy(&c->output);
985 table_destroy(c->table);
986 free(c->table);
987 }
988 free(error);
989 }
990
991 /* Frees the current transaction and the underlying IDL and then calls
992 * exit(status).
993 *
994 * Freeing the transaction and the IDL is not strictly necessary, but it makes
995 * for a clean memory leak report from valgrind in the normal case. That makes
996 * it easier to notice real memory leaks. */
997 static void
998 sbctl_exit(int status)
999 {
1000 if (the_idl_txn) {
1001 ovsdb_idl_txn_abort(the_idl_txn);
1002 ovsdb_idl_txn_destroy(the_idl_txn);
1003 }
1004 ovsdb_idl_destroy(the_idl);
1005 exit(status);
1006 }
1007
1008 static const struct ctl_command_syntax sbctl_commands[] = {
1009 /* Chassis commands. */
1010 {"chassis-add", 3, 3, "CHASSIS ENCAP-TYPE ENCAP-IP", pre_get_info,
1011 cmd_chassis_add, NULL, "--may-exist", RW},
1012 {"chassis-del", 1, 1, "CHASSIS", pre_get_info, cmd_chassis_del, NULL,
1013 "--if-exists", RW},
1014
1015 /* Port binding commands. */
1016 {"lport-bind", 2, 2, "LPORT CHASSIS", pre_get_info, cmd_lport_bind, NULL,
1017 "--may-exist", RW},
1018 {"lport-unbind", 1, 1, "LPORT", pre_get_info, cmd_lport_unbind, NULL,
1019 "--if-exists", RW},
1020
1021 /* Logical flow commands */
1022 {"lflow-list", 0, 1, "[DATAPATH]", pre_get_info, cmd_lflow_list, NULL,
1023 "", RO},
1024 {"dump-flows", 0, 1, "[DATAPATH]", pre_get_info, cmd_lflow_list, NULL,
1025 "", RO}, /* Friendly alias for lflow-list */
1026
1027 /* SSL commands (To Be Added). */
1028
1029 {NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, RO},
1030 };
1031
1032 /* Registers sbctl and common db commands. */
1033 static void
1034 sbctl_cmd_init(void)
1035 {
1036 ctl_init(tables, cmd_show_tables, sbctl_exit);
1037 ctl_register_commands(sbctl_commands);
1038 }