Make ovs-vswitchd report when it is done configuring; make ovs-vsctl wait.
[sliver-openvswitch.git] / utilities / ovs-vsctl.c
1 /*
2  * Copyright (c) 2009 Nicira Networks.
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 <assert.h>
20 #include <errno.h>
21 #include <getopt.h>
22 #include <inttypes.h>
23 #include <signal.h>
24 #include <stdarg.h>
25 #include <stdlib.h>
26 #include <string.h>
27
28 #include "command-line.h"
29 #include "compiler.h"
30 #include "dirs.h"
31 #include "dynamic-string.h"
32 #include "json.h"
33 #include "ovsdb-idl.h"
34 #include "poll-loop.h"
35 #include "svec.h"
36 #include "vswitchd/vswitch-idl.h"
37 #include "timeval.h"
38 #include "util.h"
39
40 #include "vlog.h"
41 #define THIS_MODULE VLM_vsctl
42
43 /* --db: The database server to contact. */
44 static const char *db;
45
46 /* --oneline: Write each command's output as a single line? */
47 static bool oneline;
48
49 /* --dry-run: Do not commit any changes. */
50 static bool dry_run;
51
52 /* --no-wait: Wait for ovs-vswitchd to reload its configuration? */
53 static bool wait_for_reload = true;
54
55 /* --timeout: Time to wait for a connection to 'db'. */
56 static int timeout = 5;
57
58 static void vsctl_fatal(const char *, ...) PRINTF_FORMAT(1, 2) NO_RETURN;
59 static char *default_db(void);
60 static void usage(void) NO_RETURN;
61 static void parse_options(int argc, char *argv[]);
62
63 static void check_vsctl_command(int argc, char *argv[]);
64 static void do_vsctl(int argc, char *argv[], struct ovsdb_idl *idl);
65
66 int
67 main(int argc, char *argv[])
68 {
69     struct ovsdb_idl *idl;
70     unsigned int seqno;
71     struct ds args;
72     int start, n_commands;
73     int trials;
74     int i;
75
76     set_program_name(argv[0]);
77     signal(SIGPIPE, SIG_IGN);
78     time_init();
79     vlog_init();
80     vlog_set_levels(VLM_ANY_MODULE, VLF_CONSOLE, VLL_WARN);
81     vlog_set_levels(VLM_reconnect, VLF_ANY_FACILITY, VLL_WARN);
82     parse_options(argc, argv);
83
84     if (timeout) {
85         time_alarm(timeout);
86     }
87
88     /* Log our arguments.  This is often valuable for debugging systems. */
89     ds_init(&args);
90     for (i = 1; i < argc; i++) {
91         ds_put_format(&args, " %s", argv[i]);
92     }
93     VLOG_INFO("Called as%s", ds_cstr(&args));
94     ds_destroy(&args);
95
96     /* Do basic command syntax checking. */
97     n_commands = 0;
98     for (start = i = optind; i <= argc; i++) {
99         if (i == argc || !strcmp(argv[i], "--")) {
100             if (i > start) {
101                 check_vsctl_command(i - start, &argv[start]);
102                 n_commands++;
103             }
104             start = i + 1;
105         }
106     }
107     if (!n_commands) {
108         vsctl_fatal("missing command name (use --help for help)");
109     }
110
111     /* Now execute the commands. */
112     idl = ovsdb_idl_create(db, &ovsrec_idl_class);
113     seqno = ovsdb_idl_get_seqno(idl);
114     trials = 0;
115     for (;;) {
116         unsigned int new_seqno;
117
118         ovsdb_idl_run(idl);
119         new_seqno = ovsdb_idl_get_seqno(idl);
120         if (new_seqno != seqno) {
121             if (++trials > 5) {
122                 vsctl_fatal("too many database inconsistency failures");
123             }
124             do_vsctl(argc - optind, argv + optind, idl);
125             seqno = new_seqno;
126         }
127
128         ovsdb_idl_wait(idl);
129         poll_block();
130     }
131 }
132
133 static void
134 vsctl_fatal(const char *format, ...)
135 {
136     char *message;
137     va_list args;
138
139     va_start(args, format);
140     message = xvasprintf(format, args);
141     va_end(args);
142
143     vlog_set_levels(VLM_vsctl, VLF_CONSOLE, VLL_EMER);
144     VLOG_ERR("%s", message);
145     ovs_fatal(0, "%s", message);
146 }
147
148 static void
149 parse_options(int argc, char *argv[])
150 {
151     enum {
152         OPT_DB = UCHAR_MAX + 1,
153         OPT_ONELINE,
154         OPT_NO_SYSLOG,
155         OPT_NO_WAIT,
156         OPT_DRY_RUN
157     };
158     static struct option long_options[] = {
159         {"db", required_argument, 0, OPT_DB},
160         {"no-syslog", no_argument, 0, OPT_NO_SYSLOG},
161         {"no-wait", no_argument, 0, OPT_NO_WAIT},
162         {"dry-run", no_argument, 0, OPT_DRY_RUN},
163         {"oneline", no_argument, 0, OPT_ONELINE},
164         {"timeout", required_argument, 0, 't'},
165         {"verbose", optional_argument, 0, 'v'},
166         {"help", no_argument, 0, 'h'},
167         {"version", no_argument, 0, 'V'},
168         {0, 0, 0, 0},
169     };
170
171
172     for (;;) {
173         unsigned long int timeout;
174         int c;
175
176         c = getopt_long(argc, argv, "+v::hVt:", long_options, NULL);
177         if (c == -1) {
178             break;
179         }
180
181         switch (c) {
182         case OPT_DB:
183             db = optarg;
184             break;
185
186         case OPT_ONELINE:
187             oneline = true;
188             break;
189
190         case OPT_NO_SYSLOG:
191             vlog_set_levels(VLM_vsctl, VLF_SYSLOG, VLL_WARN);
192             break;
193
194         case OPT_NO_WAIT:
195             wait_for_reload = false;
196             break;
197
198         case OPT_DRY_RUN:
199             dry_run = true;
200             break;
201
202         case 'h':
203             usage();
204
205         case 'V':
206             OVS_PRINT_VERSION(0, 0);
207             exit(EXIT_SUCCESS);
208
209         case 't':
210             timeout = strtoul(optarg, NULL, 10);
211             if (timeout < 0) {
212                 ovs_fatal(0, "value %s on -t or --timeout is invalid",
213                           optarg);
214             }
215             break;
216
217         case 'v':
218             vlog_set_verbosity(optarg);
219             break;
220
221         case '?':
222             exit(EXIT_FAILURE);
223
224         default:
225             abort();
226         }
227     }
228
229     if (!db) {
230         db = default_db();
231     }
232 }
233
234 static void
235 usage(void)
236 {
237     printf("%s: ovs-vswitchd management utility\n"
238            "usage: %s [OPTIONS] COMMAND [ARG...]\n",
239            program_name, program_name);
240     printf("\nBridge commands:\n"
241            "  add-br BRIDGE               "
242            "create a new bridge named BRIDGE\n"
243            "  add-br BRIDGE PARENT VLAN   "
244            "create new fake bridge BRIDGE in PARENT on VLAN\n"
245            "  del-br BRIDGE               "
246            "delete BRIDGE and all of its ports\n"
247            "  list-br                     "
248            "print the names of all the bridges\n"
249            "  br-exists BRIDGE            "
250            "test whether BRIDGE exists\n"
251            "  br-to-vlan BRIDGE           "
252            "print the VLAN which BRIDGE is on\n"
253            "  br-to-parent BRIDGE         "
254            "print the parent of BRIDGE\n"
255            "  br-set-external-id BRIDGE KEY VALUE"
256            "  set KEY on BRIDGE to VALUE\n"
257            "  br-set-external-id BRIDGE KEY"
258            "  unset KEY on BRIDGE\n"
259            "  br-get-external-id BRIDGE KEY"
260            "  print value of KEY on BRIDGE\n"
261            "  br-get-external-id BRIDGE"
262            "  list key-value pairs on BRIDGE\n"
263         );
264     printf("\nPort commands:\n"
265            "  list-ports BRIDGE           "
266            "print the names of all the ports on BRIDGE\n"
267            "  add-port BRIDGE PORT        "
268            "add network device PORT to BRIDGE\n"
269            "  add-bond BRIDGE PORT IFACE...  "
270            "add new bonded port PORT in BRIDGE from IFACES\n"
271            "  del-port [BRIDGE] PORT      "
272            "delete PORT (which may be bonded) from BRIDGE\n"
273            "  port-to-br PORT             "
274            "print name of bridge that contains PORT\n"
275            "  port-set-external-id PORT KEY VALUE"
276            "  set KEY on PORT to VALUE\n"
277            "  port-set-external-id PORT KEY"
278            "  unset KEY on PORT\n"
279            "  port-get-external-id PORT KEY"
280            "  print value of KEY on PORT\n"
281            "  port-get-external-id PORT"
282            "  list key-value pairs on PORT\n"
283            "A bond is considered to be a single port.\n"
284         );
285     printf("\nInterface commands (a bond consists of multiple interfaces):\n"
286            "  list-ifaces BRIDGE          "
287            "print the names of all the interfaces on BRIDGE\n"
288            "  iface-to-br IFACE           "
289            "print name of bridge that contains IFACE\n"
290            "  iface-set-external-id IFACE KEY VALUE"
291            "  set KEY on IFACE to VALUE\n"
292            "  iface-set-external-id IFACE KEY"
293            "  unset KEY on IFACE\n"
294            "  iface-get-external-id IFACE KEY"
295            "  print value of KEY on IFACE\n"
296            "  iface-get-external-id IFACE"
297            "  list key-value pairs on IFACE\n"
298         );
299     printf("\nOptions:\n"
300            "  --db=DATABASE               "
301            "connect to DATABASE\n"
302            "                              "
303            "(default: %s)\n"
304            "  --oneline                   "
305            "print exactly one line of output per command\n",
306            default_db());
307     vlog_usage();
308     printf("\nOther options:\n"
309            "  -h, --help                  "
310            "display this help message\n"
311            "  -V, --version               "
312            "display version information\n");
313     exit(EXIT_SUCCESS);
314 }
315
316 static char *
317 default_db(void)
318 {
319     static char *def;
320     if (!def) {
321         def = xasprintf("unix:%s/ovsdb-server", ovs_rundir);
322     }
323     return def;
324 }
325 \f
326 struct vsctl_context {
327     int argc;
328     char **argv;
329     const struct ovsrec_open_vswitch *ovs;
330     struct ds output;
331     struct shash options;
332 };
333
334 struct vsctl_bridge {
335     struct ovsrec_bridge *br_cfg;
336     char *name;
337     struct vsctl_bridge *parent;
338     int vlan;
339 };
340
341 struct vsctl_port {
342     struct ovsrec_port *port_cfg;
343     struct vsctl_bridge *bridge;
344 };
345
346 struct vsctl_iface {
347     struct ovsrec_interface *iface_cfg;
348     struct vsctl_port *port;
349 };
350
351 struct vsctl_info {
352     struct shash bridges;
353     struct shash ports;
354     struct shash ifaces;
355 };
356
357 static struct ovsdb_idl_txn *
358 txn_from_openvswitch(const struct ovsrec_open_vswitch *ovs)
359 {
360     return ovsdb_idl_txn_get(&ovs->header_);
361 }
362
363 static struct vsctl_bridge *
364 add_bridge(struct vsctl_info *b,
365            struct ovsrec_bridge *br_cfg, const char *name,
366            struct vsctl_bridge *parent, int vlan)
367 {
368     struct vsctl_bridge *br = xmalloc(sizeof *br);
369     br->br_cfg = br_cfg;
370     br->name = xstrdup(name);
371     br->parent = parent;
372     br->vlan = vlan;
373     shash_add(&b->bridges, br->name, br);
374     return br;
375 }
376
377 static bool
378 port_is_fake_bridge(const struct ovsrec_port *port_cfg)
379 {
380     return (port_cfg->fake_bridge
381             && port_cfg->tag
382             && *port_cfg->tag >= 1 && *port_cfg->tag <= 4095);
383 }
384
385 static struct vsctl_bridge *
386 find_vlan_bridge(struct vsctl_info *info,
387                  struct vsctl_bridge *parent, int vlan)
388 {
389     struct shash_node *node;
390
391     SHASH_FOR_EACH (node, &info->bridges) {
392         struct vsctl_bridge *br = node->data;
393         if (br->parent == parent && br->vlan == vlan) {
394             return br;
395         }
396     }
397
398     return NULL;
399 }
400
401 static void
402 free_info(struct vsctl_info *info)
403 {
404     struct shash_node *node;
405
406     SHASH_FOR_EACH (node, &info->bridges) {
407         struct vsctl_bridge *bridge = node->data;
408         free(bridge->name);
409         free(bridge);
410     }
411     shash_destroy(&info->bridges);
412
413     SHASH_FOR_EACH (node, &info->ports) {
414         struct vsctl_port *port = node->data;
415         free(port);
416     }
417     shash_destroy(&info->ports);
418
419     SHASH_FOR_EACH (node, &info->ifaces) {
420         struct vsctl_iface *iface = node->data;
421         free(iface);
422     }
423     shash_destroy(&info->ifaces);
424 }
425
426 static void
427 get_info(const struct ovsrec_open_vswitch *ovs, struct vsctl_info *info)
428 {
429     struct shash bridges, ports;
430     size_t i;
431
432     shash_init(&info->bridges);
433     shash_init(&info->ports);
434     shash_init(&info->ifaces);
435
436     shash_init(&bridges);
437     shash_init(&ports);
438     for (i = 0; i < ovs->n_bridges; i++) {
439         struct ovsrec_bridge *br_cfg = ovs->bridges[i];
440         struct vsctl_bridge *br;
441         size_t j;
442
443         if (!shash_add_once(&bridges, br_cfg->name, NULL)) {
444             VLOG_WARN("%s: database contains duplicate bridge name",
445                       br_cfg->name);
446             continue;
447         }
448         br = add_bridge(info, br_cfg, br_cfg->name, NULL, 0);
449         if (!br) {
450             continue;
451         }
452
453         for (j = 0; j < br_cfg->n_ports; j++) {
454             struct ovsrec_port *port_cfg = br_cfg->ports[j];
455
456             if (!shash_add_once(&ports, port_cfg->name, NULL)) {
457                 VLOG_WARN("%s: database contains duplicate port name",
458                           port_cfg->name);
459                 continue;
460             }
461
462             if (port_is_fake_bridge(port_cfg)
463                 && shash_add_once(&bridges, port_cfg->name, NULL)) {
464                 add_bridge(info, NULL, port_cfg->name, br, *port_cfg->tag);
465             }
466         }
467     }
468     shash_destroy(&bridges);
469     shash_destroy(&ports);
470
471     shash_init(&bridges);
472     shash_init(&ports);
473     for (i = 0; i < ovs->n_bridges; i++) {
474         struct ovsrec_bridge *br_cfg = ovs->bridges[i];
475         struct vsctl_bridge *br;
476         size_t j;
477
478         if (!shash_add_once(&bridges, br_cfg->name, NULL)) {
479             continue;
480         }
481         br = shash_find_data(&info->bridges, br_cfg->name);
482         for (j = 0; j < br_cfg->n_ports; j++) {
483             struct ovsrec_port *port_cfg = br_cfg->ports[j];
484             struct vsctl_port *port;
485             size_t k;
486
487             if (!shash_add_once(&ports, port_cfg->name, NULL)) {
488                 continue;
489             }
490
491             if (port_is_fake_bridge(port_cfg)
492                 && !shash_add_once(&bridges, port_cfg->name, NULL)) {
493                 continue;
494             }
495
496             port = xmalloc(sizeof *port);
497             port->port_cfg = port_cfg;
498             if (port_cfg->tag
499                 && *port_cfg->tag >= 1 && *port_cfg->tag <= 4095) {
500                 port->bridge = find_vlan_bridge(info, br, *port_cfg->tag);
501                 if (!port->bridge) {
502                     port->bridge = br;
503                 }
504             } else {
505                 port->bridge = br;
506             }
507             shash_add(&info->ports, port_cfg->name, port);
508
509             for (k = 0; k < port_cfg->n_interfaces; k++) {
510                 struct ovsrec_interface *iface_cfg = port_cfg->interfaces[k];
511                 struct vsctl_iface *iface;
512
513                 if (shash_find(&info->ifaces, iface_cfg->name)) {
514                     VLOG_WARN("%s: database contains duplicate interface name",
515                               iface_cfg->name);
516                     continue;
517                 }
518
519                 iface = xmalloc(sizeof *iface);
520                 iface->iface_cfg = iface_cfg;
521                 iface->port = port;
522                 shash_add(&info->ifaces, iface_cfg->name, iface);
523             }
524         }
525     }
526     shash_destroy(&bridges);
527     shash_destroy(&ports);
528 }
529
530 static void
531 check_conflicts(struct vsctl_info *info, const char *name,
532                 char *msg)
533 {
534     struct vsctl_iface *iface;
535     struct vsctl_port *port;
536
537     if (shash_find(&info->bridges, name)) {
538         vsctl_fatal("%s because a bridge named %s already exists",
539                     msg, name);
540     }
541
542     port = shash_find_data(&info->ports, name);
543     if (port) {
544         vsctl_fatal("%s because a port named %s already exists on "
545                     "bridge %s", msg, name, port->bridge->name);
546     }
547
548     iface = shash_find_data(&info->ifaces, name);
549     if (iface) {
550         vsctl_fatal("%s because an interface named %s already exists "
551                     "on bridge %s", msg, name, iface->port->bridge->name);
552     }
553
554     free(msg);
555 }
556
557 static struct vsctl_bridge *
558 find_bridge(struct vsctl_info *info, const char *name, bool must_exist)
559 {
560     struct vsctl_bridge *br = shash_find_data(&info->bridges, name);
561     if (must_exist && !br) {
562         vsctl_fatal("no bridge named %s", name);
563     }
564     return br;
565 }
566
567 static struct vsctl_port *
568 find_port(struct vsctl_info *info, const char *name, bool must_exist)
569 {
570     struct vsctl_port *port = shash_find_data(&info->ports, name);
571     if (port && !strcmp(name, port->bridge->name)) {
572         port = NULL;
573     }
574     if (must_exist && !port) {
575         vsctl_fatal("no port named %s", name);
576     }
577     return port;
578 }
579
580 static struct vsctl_iface *
581 find_iface(struct vsctl_info *info, const char *name, bool must_exist)
582 {
583     struct vsctl_iface *iface = shash_find_data(&info->ifaces, name);
584     if (iface && !strcmp(name, iface->port->bridge->name)) {
585         iface = NULL;
586     }
587     if (must_exist && !iface) {
588         vsctl_fatal("no interface named %s", name);
589     }
590     return iface;
591 }
592
593 static void
594 bridge_insert_port(struct ovsrec_bridge *br, struct ovsrec_port *port)
595 {
596     struct ovsrec_port **ports;
597     size_t i;
598
599     ports = xmalloc(sizeof *br->ports * (br->n_ports + 1));
600     for (i = 0; i < br->n_ports; i++) {
601         ports[i] = br->ports[i];
602     }
603     ports[br->n_ports] = port;
604     ovsrec_bridge_set_ports(br, ports, br->n_ports + 1);
605     free(ports);
606 }
607
608 static void
609 bridge_delete_port(struct ovsrec_bridge *br, struct ovsrec_port *port)
610 {
611     struct ovsrec_port **ports;
612     size_t i, n;
613
614     ports = xmalloc(sizeof *br->ports * br->n_ports);
615     for (i = n = 0; i < br->n_ports; i++) {
616         if (br->ports[i] != port) {
617             ports[n++] = br->ports[i];
618         }
619     }
620     ovsrec_bridge_set_ports(br, ports, n);
621     free(ports);
622 }
623
624 static void
625 ovs_insert_bridge(const struct ovsrec_open_vswitch *ovs,
626                   struct ovsrec_bridge *bridge)
627 {
628     struct ovsrec_bridge **bridges;
629     size_t i;
630
631     bridges = xmalloc(sizeof *ovs->bridges * (ovs->n_bridges + 1));
632     for (i = 0; i < ovs->n_bridges; i++) {
633         bridges[i] = ovs->bridges[i];
634     }
635     bridges[ovs->n_bridges] = bridge;
636     ovsrec_open_vswitch_set_bridges(ovs, bridges, ovs->n_bridges + 1);
637     free(bridges);
638 }
639
640 static void
641 ovs_delete_bridge(const struct ovsrec_open_vswitch *ovs,
642                   struct ovsrec_bridge *bridge)
643 {
644     struct ovsrec_bridge **bridges;
645     size_t i, n;
646
647     bridges = xmalloc(sizeof *ovs->bridges * ovs->n_bridges);
648     for (i = n = 0; i < ovs->n_bridges; i++) {
649         if (ovs->bridges[i] != bridge) {
650             bridges[n++] = ovs->bridges[i];
651         }
652     }
653     ovsrec_open_vswitch_set_bridges(ovs, bridges, n);
654     free(bridges);
655 }
656
657 static void
658 cmd_init(struct vsctl_context *ctx UNUSED)
659 {
660 }
661
662 static void
663 cmd_add_br(struct vsctl_context *ctx)
664 {
665     const char *br_name = ctx->argv[1];
666     struct vsctl_info info;
667
668     get_info(ctx->ovs, &info);
669     check_conflicts(&info, br_name,
670                     xasprintf("cannot create a bridge named %s", br_name));
671
672     if (ctx->argc == 2) {
673         struct ovsrec_bridge *br;
674         struct ovsrec_port *port;
675         struct ovsrec_interface *iface;
676
677         iface = ovsrec_interface_insert(txn_from_openvswitch(ctx->ovs));
678         ovsrec_interface_set_name(iface, br_name);
679
680         port = ovsrec_port_insert(txn_from_openvswitch(ctx->ovs));
681         ovsrec_port_set_name(port, br_name);
682         ovsrec_port_set_interfaces(port, &iface, 1);
683
684         br = ovsrec_bridge_insert(txn_from_openvswitch(ctx->ovs));
685         ovsrec_bridge_set_name(br, br_name);
686         ovsrec_bridge_set_ports(br, &port, 1);
687
688         ovs_insert_bridge(ctx->ovs, br);
689     } else if (ctx->argc == 3) {
690         vsctl_fatal("'%s' command takes exactly 1 or 3 arguments",
691                     ctx->argv[0]);
692     } else if (ctx->argc == 4) {
693         const char *parent_name = ctx->argv[2];
694         int vlan = atoi(ctx->argv[3]);
695         struct ovsrec_bridge *br;
696         struct vsctl_bridge *parent;
697         struct ovsrec_port *port;
698         struct ovsrec_interface *iface;
699         int64_t tag = vlan;
700
701         if (vlan < 1 || vlan > 4095) {
702             vsctl_fatal("%s: vlan must be between 1 and 4095", ctx->argv[0]);
703         }
704
705         parent = find_bridge(&info, parent_name, false);
706         if (parent && parent->vlan) {
707             vsctl_fatal("cannot create brdige with fake bridge as parent");
708         }
709         if (!parent) {
710             vsctl_fatal("parent bridge %s does not exist", parent_name);
711         }
712         br = parent->br_cfg;
713
714         iface = ovsrec_interface_insert(txn_from_openvswitch(ctx->ovs));
715         ovsrec_interface_set_name(iface, br_name);
716         ovsrec_interface_set_type(iface, "internal");
717
718         port = ovsrec_port_insert(txn_from_openvswitch(ctx->ovs));
719         ovsrec_port_set_name(port, br_name);
720         ovsrec_port_set_interfaces(port, &iface, 1);
721         ovsrec_port_set_fake_bridge(port, true);
722         ovsrec_port_set_tag(port, &tag, 1);
723
724         bridge_insert_port(br, port);
725     } else {
726         NOT_REACHED();
727     }
728
729     free_info(&info);
730 }
731
732 static void
733 del_port(struct vsctl_info *info, struct vsctl_port *port)
734 {
735     struct shash_node *node;
736
737     SHASH_FOR_EACH (node, &info->ifaces) {
738         struct vsctl_iface *iface = node->data;
739         if (iface->port == port) {
740             ovsrec_interface_delete(iface->iface_cfg);
741         }
742     }
743     ovsrec_port_delete(port->port_cfg);
744
745     bridge_delete_port((port->bridge->parent
746                         ? port->bridge->parent->br_cfg
747                         : port->bridge->br_cfg), port->port_cfg);
748 }
749
750 static void
751 cmd_del_br(struct vsctl_context *ctx)
752 {
753     bool must_exist = !shash_find(&ctx->options, "--if-exists");
754     struct vsctl_bridge *bridge;
755     struct vsctl_info info;
756
757     get_info(ctx->ovs, &info);
758     bridge = find_bridge(&info, ctx->argv[1], must_exist);
759     if (bridge) {
760         struct shash_node *node;
761
762         SHASH_FOR_EACH (node, &info.ports) {
763             struct vsctl_port *port = node->data;
764             if (port->bridge == bridge
765                 || !strcmp(port->port_cfg->name, bridge->name)) {
766                 del_port(&info, port);
767             }
768         }
769         if (bridge->br_cfg) {
770             ovsrec_bridge_delete(bridge->br_cfg);
771             ovs_delete_bridge(ctx->ovs, bridge->br_cfg);
772         }
773     }
774     free_info(&info);
775 }
776
777 static void
778 output_sorted(struct svec *svec, struct ds *output)
779 {
780     const char *name;
781     size_t i;
782
783     svec_sort(svec);
784     SVEC_FOR_EACH (i, name, svec) {
785         ds_put_format(output, "%s\n", name);
786     }
787 }
788
789 static void
790 cmd_list_br(struct vsctl_context *ctx)
791 {
792     struct shash_node *node;
793     struct vsctl_info info;
794     struct svec bridges;
795
796     get_info(ctx->ovs, &info);
797
798     svec_init(&bridges);
799     SHASH_FOR_EACH (node, &info.bridges) {
800         struct vsctl_bridge *br = node->data;
801         svec_add(&bridges, br->name);
802     }
803     output_sorted(&bridges, &ctx->output);
804     svec_destroy(&bridges);
805
806     free_info(&info);
807 }
808
809 static void
810 cmd_br_exists(struct vsctl_context *ctx)
811 {
812     struct vsctl_info info;
813
814     get_info(ctx->ovs, &info);
815     if (!find_bridge(&info, ctx->argv[1], false)) {
816         exit(2);
817     }
818     free_info(&info);
819 }
820
821 /* Returns true if 'b_prefix' (of length 'b_prefix_len') concatenated with 'b'
822  * equals 'a', false otherwise. */
823 static bool
824 key_matches(const char *a,
825             const char *b_prefix, size_t b_prefix_len, const char *b)
826 {
827     return !strncmp(a, b_prefix, b_prefix_len) && !strcmp(a + b_prefix_len, b);
828 }
829
830 static void
831 set_external_id(char **old_keys, char **old_values, size_t old_n,
832                 char *key, char *value,
833                 char ***new_keysp, char ***new_valuesp, size_t *new_np)
834 {
835     char **new_keys;
836     char **new_values;
837     size_t new_n;
838     size_t i;
839
840     new_keys = xmalloc(sizeof *new_keys * (old_n + 1));
841     new_values = xmalloc(sizeof *new_values * (old_n + 1));
842     new_n = 0;
843     for (i = 0; i < old_n; i++) {
844         if (strcmp(key, old_keys[i])) {
845             new_keys[new_n] = old_keys[i];
846             new_values[new_n] = old_values[i];
847             new_n++;
848         }
849     }
850     if (value) {
851         new_keys[new_n] = key;
852         new_values[new_n] = value;
853         new_n++;
854     }
855     *new_keysp = new_keys;
856     *new_valuesp = new_values;
857     *new_np = new_n;
858 }
859
860 static void
861 cmd_br_set_external_id(struct vsctl_context *ctx)
862 {
863     struct vsctl_info info;
864     struct vsctl_bridge *bridge;
865     char **keys, **values;
866     size_t n;
867
868     get_info(ctx->ovs, &info);
869     bridge = find_bridge(&info, ctx->argv[1], true);
870     if (bridge->br_cfg) {
871         set_external_id(bridge->br_cfg->key_external_ids,
872                         bridge->br_cfg->value_external_ids,
873                         bridge->br_cfg->n_external_ids,
874                         ctx->argv[2], ctx->argc >= 4 ? ctx->argv[3] : NULL,
875                         &keys, &values, &n);
876         ovsrec_bridge_set_external_ids(bridge->br_cfg, keys, values, n);
877     } else {
878         char *key = xasprintf("fake-bridge-%s", ctx->argv[2]);
879         struct vsctl_port *port = shash_find_data(&info.ports, ctx->argv[1]);
880         set_external_id(port->port_cfg->key_external_ids,
881                         port->port_cfg->value_external_ids,
882                         port->port_cfg->n_external_ids,
883                         key, ctx->argc >= 4 ? ctx->argv[3] : NULL,
884                         &keys, &values, &n);
885         ovsrec_port_set_external_ids(port->port_cfg, keys, values, n);
886         free(key);
887     }
888     free(keys);
889     free(values);
890
891     free_info(&info);
892 }
893
894 static void
895 get_external_id(char **keys, char **values, size_t n,
896                 const char *prefix, const char *key,
897                 struct ds *output)
898 {
899     size_t prefix_len = strlen(prefix);
900     struct svec svec;
901     size_t i;
902
903     svec_init(&svec);
904     for (i = 0; i < n; i++) {
905         if (!key && !strncmp(keys[i], prefix, prefix_len)) {
906             svec_add_nocopy(&svec, xasprintf("%s=%s",
907                                              keys[i] + prefix_len, values[i]));
908         } else if (key_matches(keys[i], prefix, prefix_len, key)) {
909             svec_add(&svec, values[i]);
910             break;
911         }
912     }
913     output_sorted(&svec, output);
914     svec_destroy(&svec);
915 }
916
917 static void
918 cmd_br_get_external_id(struct vsctl_context *ctx)
919 {
920     struct vsctl_info info;
921     struct vsctl_bridge *bridge;
922
923     get_info(ctx->ovs, &info);
924     bridge = find_bridge(&info, ctx->argv[1], true);
925     if (bridge->br_cfg) {
926         get_external_id(bridge->br_cfg->key_external_ids,
927                         bridge->br_cfg->value_external_ids,
928                         bridge->br_cfg->n_external_ids,
929                         "", ctx->argc >= 3 ? ctx->argv[2] : NULL,
930                         &ctx->output);
931     } else {
932         struct vsctl_port *port = shash_find_data(&info.ports, ctx->argv[1]);
933         get_external_id(port->port_cfg->key_external_ids,
934                         port->port_cfg->value_external_ids,
935                         port->port_cfg->n_external_ids,
936                         "fake-bridge-", ctx->argc >= 3 ? ctx->argv[2] : NULL, &ctx->output);
937     }
938     free_info(&info);
939 }
940
941
942 static void
943 cmd_list_ports(struct vsctl_context *ctx)
944 {
945     struct vsctl_bridge *br;
946     struct shash_node *node;
947     struct vsctl_info info;
948     struct svec ports;
949
950     get_info(ctx->ovs, &info);
951     br = find_bridge(&info, ctx->argv[1], true);
952
953     svec_init(&ports);
954     SHASH_FOR_EACH (node, &info.ports) {
955         struct vsctl_port *port = node->data;
956
957         if (strcmp(port->port_cfg->name, br->name) && br == port->bridge) {
958             svec_add(&ports, port->port_cfg->name);
959         }
960     }
961     output_sorted(&ports, &ctx->output);
962     svec_destroy(&ports);
963
964     free_info(&info);
965 }
966
967 static void
968 add_port(const struct ovsrec_open_vswitch *ovs,
969          const char *br_name, const char *port_name,
970          char *iface_names[], int n_ifaces)
971 {
972     struct vsctl_info info;
973     struct vsctl_bridge *bridge;
974     struct ovsrec_interface **ifaces;
975     struct ovsrec_port *port;
976     size_t i;
977
978     get_info(ovs, &info);
979     check_conflicts(&info, port_name,
980                     xasprintf("cannot create a port named %s", port_name));
981     /* XXX need to check for conflicts on interfaces too */
982     bridge = find_bridge(&info, br_name, true);
983
984     ifaces = xmalloc(n_ifaces * sizeof *ifaces);
985     for (i = 0; i < n_ifaces; i++) {
986         ifaces[i] = ovsrec_interface_insert(txn_from_openvswitch(ovs));
987         ovsrec_interface_set_name(ifaces[i], iface_names[i]);
988     }
989
990     port = ovsrec_port_insert(txn_from_openvswitch(ovs));
991     ovsrec_port_set_name(port, port_name);
992     ovsrec_port_set_interfaces(port, ifaces, n_ifaces);
993     free(ifaces);
994
995     if (bridge->vlan) {
996         int64_t tag = bridge->vlan;
997         ovsrec_port_set_tag(port, &tag, 1);
998     }
999
1000     bridge_insert_port((bridge->parent ? bridge->parent->br_cfg
1001                         : bridge->br_cfg), port);
1002
1003     free_info(&info);
1004 }
1005
1006 static void
1007 cmd_add_port(struct vsctl_context *ctx)
1008 {
1009     add_port(ctx->ovs, ctx->argv[1], ctx->argv[2], &ctx->argv[2], 1);
1010 }
1011
1012 static void
1013 cmd_add_bond(struct vsctl_context *ctx)
1014 {
1015     add_port(ctx->ovs, ctx->argv[1], ctx->argv[2], &ctx->argv[3], ctx->argc - 3);
1016 }
1017
1018 static void
1019 cmd_del_port(struct vsctl_context *ctx)
1020 {
1021     bool must_exist = !shash_find(&ctx->options, "--if-exists");
1022     struct vsctl_info info;
1023
1024     get_info(ctx->ovs, &info);
1025     if (ctx->argc == 2) {
1026         struct vsctl_port *port = find_port(&info, ctx->argv[1], must_exist);
1027         if (port) {
1028             del_port(&info, port);
1029         }
1030     } else if (ctx->argc == 3) {
1031         struct vsctl_bridge *bridge = find_bridge(&info, ctx->argv[1], true);
1032         struct vsctl_port *port = find_port(&info, ctx->argv[2], must_exist);
1033
1034         if (port) {
1035             if (port->bridge == bridge) {
1036                 del_port(&info, port);
1037             } else if (port->bridge->parent == bridge) {
1038                 vsctl_fatal("bridge %s does not have a port %s (although its "
1039                             "parent bridge %s does)",
1040                             ctx->argv[1], ctx->argv[2], bridge->parent->name);
1041             } else {
1042                 vsctl_fatal("bridge %s does not have a port %s",
1043                             ctx->argv[1], ctx->argv[2]);
1044             }
1045         }
1046     }
1047     free_info(&info);
1048 }
1049
1050 static void
1051 cmd_port_to_br(struct vsctl_context *ctx)
1052 {
1053     struct vsctl_port *port;
1054     struct vsctl_info info;
1055
1056     get_info(ctx->ovs, &info);
1057     port = find_port(&info, ctx->argv[1], true);
1058     ds_put_format(&ctx->output, "%s\n", port->bridge->name);
1059     free_info(&info);
1060 }
1061
1062 static void
1063 cmd_port_set_external_id(struct vsctl_context *ctx)
1064 {
1065     struct vsctl_info info;
1066     struct vsctl_port *port;
1067     char **keys, **values;
1068     size_t n;
1069
1070     get_info(ctx->ovs, &info);
1071     port = find_port(&info, ctx->argv[1], true);
1072     set_external_id(port->port_cfg->key_external_ids,
1073                     port->port_cfg->value_external_ids,
1074                     port->port_cfg->n_external_ids,
1075                     ctx->argv[2], ctx->argc >= 4 ? ctx->argv[3] : NULL,
1076                     &keys, &values, &n);
1077     ovsrec_port_set_external_ids(port->port_cfg, keys, values, n);
1078     free(keys);
1079     free(values);
1080
1081     free_info(&info);
1082 }
1083
1084 static void
1085 cmd_port_get_external_id(struct vsctl_context *ctx)
1086 {
1087     struct vsctl_info info;
1088     struct vsctl_port *port;
1089
1090     get_info(ctx->ovs, &info);
1091     port = find_port(&info, ctx->argv[1], true);
1092     get_external_id(port->port_cfg->key_external_ids,
1093                     port->port_cfg->value_external_ids,
1094                     port->port_cfg->n_external_ids,
1095                     "",  ctx->argc >= 3 ? ctx->argv[2] : NULL, &ctx->output);
1096     free_info(&info);
1097 }
1098
1099 static void
1100 cmd_br_to_vlan(struct vsctl_context *ctx)
1101 {
1102     struct vsctl_bridge *bridge;
1103     struct vsctl_info info;
1104
1105     get_info(ctx->ovs, &info);
1106     bridge = find_bridge(&info, ctx->argv[1], true);
1107     ds_put_format(&ctx->output, "%d\n", bridge->vlan);
1108     free_info(&info);
1109 }
1110
1111 static void
1112 cmd_br_to_parent(struct vsctl_context *ctx)
1113 {
1114     struct vsctl_bridge *bridge;
1115     struct vsctl_info info;
1116
1117     get_info(ctx->ovs, &info);
1118     bridge = find_bridge(&info, ctx->argv[1], true);
1119     if (bridge->parent) {
1120         bridge = bridge->parent;
1121     }
1122     ds_put_format(&ctx->output, "%s\n", bridge->name);
1123     free_info(&info);
1124 }
1125
1126 static void
1127 cmd_list_ifaces(struct vsctl_context *ctx)
1128 {
1129     struct vsctl_bridge *br;
1130     struct shash_node *node;
1131     struct vsctl_info info;
1132     struct svec ifaces;
1133
1134     get_info(ctx->ovs, &info);
1135     br = find_bridge(&info, ctx->argv[1], true);
1136
1137     svec_init(&ifaces);
1138     SHASH_FOR_EACH (node, &info.ifaces) {
1139         struct vsctl_iface *iface = node->data;
1140
1141         if (strcmp(iface->iface_cfg->name, br->name)
1142             && br == iface->port->bridge) {
1143             svec_add(&ifaces, iface->iface_cfg->name);
1144         }
1145     }
1146     output_sorted(&ifaces, &ctx->output);
1147     svec_destroy(&ifaces);
1148
1149     free_info(&info);
1150 }
1151
1152 static void
1153 cmd_iface_to_br(struct vsctl_context *ctx)
1154 {
1155     struct vsctl_iface *iface;
1156     struct vsctl_info info;
1157
1158     get_info(ctx->ovs, &info);
1159     iface = find_iface(&info, ctx->argv[1], true);
1160     ds_put_format(&ctx->output, "%s\n", iface->port->bridge->name);
1161     free_info(&info);
1162 }
1163
1164 static void
1165 cmd_iface_set_external_id(struct vsctl_context *ctx)
1166 {
1167     struct vsctl_info info;
1168     struct vsctl_iface *iface;
1169     char **keys, **values;
1170     size_t n;
1171
1172     get_info(ctx->ovs, &info);
1173     iface = find_iface(&info, ctx->argv[1], true);
1174     set_external_id(iface->iface_cfg->key_external_ids,
1175                     iface->iface_cfg->value_external_ids,
1176                     iface->iface_cfg->n_external_ids,
1177                     ctx->argv[2], ctx->argc >= 4 ? ctx->argv[3] : NULL,
1178                     &keys, &values, &n);
1179     ovsrec_interface_set_external_ids(iface->iface_cfg, keys, values, n);
1180     free(keys);
1181     free(values);
1182
1183     free_info(&info);
1184 }
1185
1186 static void
1187 cmd_iface_get_external_id(struct vsctl_context *ctx)
1188 {
1189     struct vsctl_info info;
1190     struct vsctl_iface *iface;
1191
1192     get_info(ctx->ovs, &info);
1193     iface = find_iface(&info, ctx->argv[1], true);
1194     get_external_id(iface->iface_cfg->key_external_ids,
1195                     iface->iface_cfg->value_external_ids,
1196                     iface->iface_cfg->n_external_ids,
1197                     "",  ctx->argc >= 3 ? ctx->argv[2] : NULL, &ctx->output);
1198     free_info(&info);
1199 }
1200 \f
1201 typedef void vsctl_handler_func(struct vsctl_context *);
1202
1203 struct vsctl_command {
1204     const char *name;
1205     int min_args;
1206     int max_args;
1207     vsctl_handler_func *handler;
1208     const char *options;
1209 };
1210
1211 static void run_vsctl_command(int argc, char *argv[],
1212                               const struct ovsrec_open_vswitch *ovs,
1213                               struct ds *output);
1214
1215 static struct json *
1216 where_uuid_equals(const struct uuid *uuid)
1217 {
1218     return
1219         json_array_create_1(
1220             json_array_create_3(
1221                 json_string_create("_uuid"),
1222                 json_string_create("=="),
1223                 json_array_create_2(
1224                     json_string_create("uuid"),
1225                     json_string_create_nocopy(
1226                         xasprintf(UUID_FMT, UUID_ARGS(uuid))))));
1227 }
1228
1229 static void
1230 do_vsctl(int argc, char *argv[], struct ovsdb_idl *idl)
1231 {
1232     struct ovsdb_idl_txn *txn;
1233     const struct ovsrec_open_vswitch *ovs;
1234     enum ovsdb_idl_txn_status status;
1235     struct ds comment, *output;
1236     int64_t next_cfg;
1237     int n_output;
1238     int i, start;
1239
1240     txn = ovsdb_idl_txn_create(idl);
1241     if (dry_run) {
1242         ovsdb_idl_txn_set_dry_run(txn);
1243     }
1244
1245     ds_init(&comment);
1246     ds_put_cstr(&comment, "ovs-vsctl:");
1247     for (i = 0; i < argc; i++) {
1248         ds_put_format(&comment, " %s", argv[i]);
1249     }
1250     ovsdb_idl_txn_add_comment(txn, ds_cstr(&comment));
1251     ds_destroy(&comment);
1252
1253     ovs = ovsrec_open_vswitch_first(idl);
1254     if (!ovs) {
1255         /* XXX add verification that table is empty */
1256         ovs = ovsrec_open_vswitch_insert(txn);
1257     }
1258
1259     if (wait_for_reload) {
1260         struct json *where = where_uuid_equals(&ovs->header_.uuid);
1261         ovsdb_idl_txn_increment(txn, "Open_vSwitch", "next_cfg",
1262                                 where);
1263         json_destroy(where);
1264     }
1265
1266     output = xmalloc(argc * sizeof *output);
1267     n_output = 0;
1268     for (start = i = 0; i <= argc; i++) {
1269         if (i == argc || !strcmp(argv[i], "--")) {
1270             if (i > start) {
1271                 ds_init(&output[n_output]);
1272                 run_vsctl_command(i - start, &argv[start], ovs,
1273                                   &output[n_output++]);
1274             }
1275             start = i + 1;
1276         }
1277     }
1278
1279     while ((status = ovsdb_idl_txn_commit(txn)) == TXN_INCOMPLETE) {
1280         ovsdb_idl_run(idl);
1281         ovsdb_idl_wait(idl);
1282         ovsdb_idl_txn_wait(txn);
1283         poll_block();
1284     }
1285     if (wait_for_reload && status == TXN_SUCCESS) {
1286         next_cfg = ovsdb_idl_txn_get_increment_new_value(txn);
1287     }
1288     ovsdb_idl_txn_destroy(txn);
1289
1290     switch (status) {
1291     case TXN_INCOMPLETE:
1292         NOT_REACHED();
1293
1294     case TXN_ABORTED:
1295         /* Should not happen--we never call ovsdb_idl_txn_abort(). */
1296         vsctl_fatal("transaction aborted");
1297
1298     case TXN_UNCHANGED:
1299     case TXN_SUCCESS:
1300         break;
1301
1302     case TXN_TRY_AGAIN:
1303         for (i = 0; i < n_output; i++) {
1304             ds_destroy(&output[i]);
1305         }
1306         return;
1307
1308     case TXN_ERROR:
1309         vsctl_fatal("transaction error");
1310
1311     default:
1312         NOT_REACHED();
1313     }
1314
1315     for (i = 0; i < n_output; i++) {
1316         struct ds *ds = &output[i];
1317         if (oneline) {
1318             size_t j;
1319
1320             ds_chomp(ds, '\n');
1321             for (j = 0; j < ds->length; j++) {
1322                 int c = ds->string[j];
1323                 switch (c) {
1324                 case '\n':
1325                     fputs("\\n", stdout);
1326                     break;
1327
1328                 case '\\':
1329                     fputs("\\\\", stdout);
1330                     break;
1331
1332                 default:
1333                     putchar(c);
1334                 }
1335             }
1336             putchar('\n');
1337         } else {
1338             fputs(ds_cstr(ds), stdout);
1339         }
1340     }
1341
1342     if (wait_for_reload && status != TXN_UNCHANGED) {
1343         for (;;) {
1344             const struct ovsrec_open_vswitch *ovs;
1345
1346             ovsdb_idl_run(idl);
1347             OVSREC_OPEN_VSWITCH_FOR_EACH (ovs, idl) {
1348                 if (ovs->cur_cfg >= next_cfg) {
1349                     goto done;
1350                 }
1351             }
1352             ovsdb_idl_wait(idl);
1353             poll_block();
1354         }
1355     done: ;
1356     }
1357
1358     exit(EXIT_SUCCESS);
1359 }
1360
1361 static vsctl_handler_func *
1362 get_vsctl_handler(int argc, char *argv[], struct vsctl_context *ctx)
1363 {
1364     static const struct vsctl_command all_commands[] = {
1365         /* Open vSwitch commands. */
1366         {"init", 0, 0, cmd_init, ""},
1367
1368         /* Bridge commands. */
1369         {"add-br", 1, 3, cmd_add_br, ""},
1370         {"del-br", 1, 1, cmd_del_br, "--if-exists"},
1371         {"list-br", 0, 0, cmd_list_br, ""},
1372         {"br-exists", 1, 1, cmd_br_exists, ""},
1373         {"br-to-vlan", 1, 1, cmd_br_to_vlan, ""},
1374         {"br-to-parent", 1, 1, cmd_br_to_parent, ""},
1375         {"br-set-external-id", 2, 3, cmd_br_set_external_id, ""},
1376         {"br-get-external-id", 1, 2, cmd_br_get_external_id, ""},
1377
1378         /* Port commands. */
1379         {"list-ports", 1, 1, cmd_list_ports, ""},
1380         {"add-port", 2, 2, cmd_add_port, ""},
1381         {"add-bond", 4, INT_MAX, cmd_add_bond, ""},
1382         {"del-port", 1, 2, cmd_del_port, "--if-exists"},
1383         {"port-to-br", 1, 1, cmd_port_to_br, ""},
1384         {"port-set-external-id", 2, 3, cmd_port_set_external_id, ""},
1385         {"port-get-external-id", 1, 2, cmd_port_get_external_id, ""},
1386
1387         /* Interface commands. */
1388         {"list-ifaces", 1, 1, cmd_list_ifaces, ""},
1389         {"iface-to-br", 1, 1, cmd_iface_to_br, ""},
1390         {"iface-set-external-id", 2, 3, cmd_iface_set_external_id, ""},
1391         {"iface-get-external-id", 1, 2, cmd_iface_get_external_id, ""},
1392     };
1393
1394     const struct vsctl_command *p;
1395     int i;
1396
1397     shash_init(&ctx->options);
1398     for (i = 0; i < argc; i++) {
1399         if (argv[i][0] != '-') {
1400             break;
1401         }
1402         if (!shash_add_once(&ctx->options, argv[i], NULL)) {
1403             vsctl_fatal("'%s' option specified multiple times", argv[i]);
1404         }
1405     }
1406     if (i == argc) {
1407         vsctl_fatal("missing command name");
1408     }
1409
1410     for (p = all_commands; p < &all_commands[ARRAY_SIZE(all_commands)]; p++) {
1411         if (!strcmp(p->name, argv[i])) {
1412             struct shash_node *node;
1413             int n_arg;
1414
1415             SHASH_FOR_EACH (node, &ctx->options) {
1416                 const char *s = strstr(p->options, node->name);
1417                 int end = s ? s[strlen(node->name)] : EOF;
1418                 if (end != ',' && end != ' ' && end != '\0') {
1419                     vsctl_fatal("'%s' command has no '%s' option",
1420                                 argv[i], node->name);
1421                 }
1422             }
1423
1424             n_arg = argc - i - 1;
1425             if (n_arg < p->min_args) {
1426                 vsctl_fatal("'%s' command requires at least %d arguments",
1427                             p->name, p->min_args);
1428             } else if (n_arg > p->max_args) {
1429                 vsctl_fatal("'%s' command takes at most %d arguments",
1430                             p->name, p->max_args);
1431             } else {
1432                 ctx->argc = n_arg + 1;
1433                 ctx->argv = &argv[i];
1434                 return p->handler;
1435             }
1436         }
1437     }
1438
1439     vsctl_fatal("unknown command '%s'; use --help for help", argv[i]);
1440 }
1441
1442 static void
1443 check_vsctl_command(int argc, char *argv[])
1444 {
1445     struct vsctl_context ctx;
1446
1447     get_vsctl_handler(argc, argv, &ctx);
1448     shash_destroy(&ctx.options);
1449 }
1450
1451 static void
1452 run_vsctl_command(int argc, char *argv[],
1453                   const struct ovsrec_open_vswitch *ovs, struct ds *output)
1454 {
1455     vsctl_handler_func *function;
1456     struct vsctl_context ctx;
1457
1458     function = get_vsctl_handler(argc, argv, &ctx);
1459     ctx.ovs = ovs;
1460     ds_init(&ctx.output);
1461     function(&ctx);
1462     *output = ctx.output;
1463     shash_destroy(&ctx.options);
1464 }