Thx a lot Russel, for the review,~ On Mon, Jul 6, 2015 at 11:02 AM, Russell Bryant <rbry...@redhat.com> wrote:
> On 07/05/2015 01:38 AM, Alex Wang wrote: > > This commit adds ovn-sbctl to ovn family by using the db-ctl-base > > library. > > > > Signed-off-by: Alex Wang <al...@nicira.com> > > Acked-by: Ben Pfaff <b...@nicira.com> > > > > --- > > PATCH->V2: > > - change command add/del-ch to add/del-chassis. > > - refine the manual based on comments from Ben. > > --- > > manpages.mk | 12 + > > ovn/.gitignore | 2 + > > ovn/automake.mk | 9 + > > ovn/ovn-sbctl.8.in | 160 ++++++++++ > > ovn/ovn-sbctl.c | 837 > ++++++++++++++++++++++++++++++++++++++++++++++++++++ > > tests/automake.mk | 5 +- > > tests/ovn-sbctl.at | 61 ++++ > > tests/testsuite.at | 1 + > > 8 files changed, 1085 insertions(+), 2 deletions(-) > > create mode 100644 ovn/ovn-sbctl.8.in > > create mode 100644 ovn/ovn-sbctl.c > > create mode 100644 tests/ovn-sbctl.at > > > > diff --git a/manpages.mk b/manpages.mk > > index 3cec260..032cb26 100644 > > --- a/manpages.mk > > +++ b/manpages.mk > > @@ -1,5 +1,17 @@ > > # Generated automatically -- do not modify! -*- buffer-read-only: t > -*- > > > > +ovn/ovn-sbctl.8: \ > > + ovn/ovn-sbctl.8.in \ > > + lib/db-ctl-base.man \ > > + lib/table.man \ > > + ovsdb/remote-active.man \ > > + ovsdb/remote-passive.man > > +ovn/ovn-sbctl.8.in: > > +lib/db-ctl-base.man: > > +lib/table.man: > > +ovsdb/remote-active.man: > > +ovsdb/remote-passive.man: > > + > > ovsdb/ovsdb-client.1: \ > > ovsdb/ovsdb-client.1.in \ > > lib/common-syn.man \ > > diff --git a/ovn/.gitignore b/ovn/.gitignore > > index 4c13616..2d4835a 100644 > > --- a/ovn/.gitignore > > +++ b/ovn/.gitignore > > @@ -7,3 +7,5 @@ > > /ovn-sb.pic > > /ovn-nbctl > > /ovn-nbctl.8 > > +/ovn-sbctl > > +/ovn-sbctl.8 > > This isn't really related to this patch, but maybe we should create a > ovn/utilities/ directory for ovn-nbctl, ovn-sbctl, and whatever else we > come up with. > Yeah, makes sense, > > diff --git a/ovn/ovn-sbctl.8.in b/ovn/ovn-sbctl.8.in > > new file mode 100644 > > index 0000000..1cf9b7d > > --- /dev/null > > +++ b/ovn/ovn-sbctl.8.in > > @@ -0,0 +1,160 @@ > > +.\" -*- nroff -*- > > How about doing this in the XML format? It seems much easier to read > and edit that way. > This is to take advantage of the lib/db-ctl-base.man. Maybe I should convert all ovs-vsctl, vtep-ctl, ovs-sbctl manpage to xml format. > > new file mode 100644 > > index 0000000..8c82d03 > > --- /dev/null > > +++ b/ovn/ovn-sbctl.c > > @@ -0,0 +1,837 @@ > > +/* > > + * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015 Nicira, Inc. > > Presumably just 2015? > > Though these days I personally prefer not including this line at all > since it's not necessary, and is rarely accurate in a collaborative open > source project. Keeping it is consistent with the rest of OVS, though ... > > > + * > Sorry for the careless copy/past, will fix it, and be more careful, > > + * Licensed under the Apache License, Version 2.0 (the "License"); > > + * you may not use this file except in compliance with the License. > > + * You may obtain a copy of the License at: > > + * > > + * http://www.apache.org/licenses/LICENSE-2.0 > > + * > > + * Unless required by applicable law or agreed to in writing, software > > + * distributed under the License is distributed on an "AS IS" BASIS, > > + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or > implied. > > + * See the License for the specific language governing permissions and > > + * limitations under the License. > > + */ > > + > > +#include <config.h> > > + > > +#include <ctype.h> > > +#include <errno.h> > > +#include <float.h> > > +#include <getopt.h> > > +#include <inttypes.h> > > +#include <signal.h> > > +#include <stdarg.h> > > +#include <stdlib.h> > > +#include <string.h> > > +#include <unistd.h> > > + > > +#include "db-ctl-base.h" > > + > > +#include "command-line.h" > > +#include "compiler.h" > > +#include "dynamic-string.h" > > +#include "fatal-signal.h" > > +#include "json.h" > > +#include "ovsdb-data.h" > > +#include "ovsdb-idl.h" > > +#include "poll-loop.h" > > +#include "process.h" > > +#include "sset.h" > > +#include "shash.h" > > +#include "ovn/lib/ovn-sb-idl.h" > > +#include "table.h" > > +#include "timeval.h" > > +#include "util.h" > > +#include "openvswitch/vlog.h" > > + > > +VLOG_DEFINE_THIS_MODULE(sbctl); > > + > > +struct sbctl_context; > > + > > +/* --db: The database server to contact. */ > > +static const char *db; > > + > > +/* --oneline: Write each command's output as a single line? */ > > +static bool oneline; > > + > > +/* --dry-run: Do not commit any changes. */ > > +static bool dry_run; > > + > > +/* --timeout: Time to wait for a connection to 'db'. */ > > +static int timeout; > > + > > +/* Format for table output. */ > > +static struct table_style table_style = TABLE_STYLE_DEFAULT; > > + > > +static void sbctl_cmd_init(void); > > +OVS_NO_RETURN static void usage(void); > > +static void parse_options(int argc, char *argv[], struct shash > *local_options); > > +static void run_prerequisites(struct ctl_command[], size_t n_commands, > > + struct ovsdb_idl *); > > +static void do_sbctl(const char *args, struct ctl_command *, size_t n, > > + struct ovsdb_idl *); > > + > > +int > > +main(int argc, char *argv[]) > > +{ > > + extern struct vlog_module VLM_reconnect; > > + struct ovsdb_idl *idl; > > + struct ctl_command *commands; > > + struct shash local_options; > > + unsigned int seqno; > > + size_t n_commands; > > + char *args; > > + > > + set_program_name(argv[0]); > > + fatal_ignore_sigpipe(); > > + vlog_set_levels(NULL, VLF_CONSOLE, VLL_WARN); > > + vlog_set_levels(&VLM_reconnect, VLF_ANY_DESTINATION, VLL_WARN); > > + sbrec_init(); > > + > > + sbctl_cmd_init(); > > + > > + /* Log our arguments. This is often valuable for debugging > systems. */ > > + args = process_escape_args(argv); > > + VLOG(ctl_might_write_to_db(argv) ? VLL_INFO : VLL_DBG, "Called as > %s", args); > > + > > + /* Parse command line. */ > > + shash_init(&local_options); > > + parse_options(argc, argv, &local_options); > > + commands = ctl_parse_commands(argc - optind, argv + optind, > &local_options, > > + &n_commands); > > + > > + if (timeout) { > > + time_alarm(timeout); > > + } > > + > > + /* Initialize IDL. */ > > + idl = the_idl = ovsdb_idl_create(db, &sbrec_idl_class, false, > false); > > + run_prerequisites(commands, n_commands, idl); > > + > > + /* Execute the commands. > > + * > > + * 'seqno' is the database sequence number for which we last tried > to > > + * execute our transaction. There's no point in trying to commit > more than > > + * once for any given sequence number, because if the transaction > fails > > + * it's because the database changed and we need to obtain an > up-to-date > > + * view of the database before we try the transaction again. */ > > + seqno = ovsdb_idl_get_seqno(idl); > > + for (;;) { > > + ovsdb_idl_run(idl); > > + if (!ovsdb_idl_is_alive(idl)) { > > + int retval = ovsdb_idl_get_last_error(idl); > > + ctl_fatal("%s: database connection failed (%s)", > > + db, ovs_retval_to_string(retval)); > > + } > > + > > + if (seqno != ovsdb_idl_get_seqno(idl)) { > > + seqno = ovsdb_idl_get_seqno(idl); > > + do_sbctl(args, commands, n_commands, idl); > > + } > > + > > + if (seqno == ovsdb_idl_get_seqno(idl)) { > > + ovsdb_idl_wait(idl); > > + poll_block(); > > + } > > + } > > +} > > + > > +static void > > +parse_options(int argc, char *argv[], struct shash *local_options) > > +{ > > + enum { > > + OPT_DB = UCHAR_MAX + 1, > > + OPT_ONELINE, > > + OPT_NO_SYSLOG, > > + OPT_DRY_RUN, > > + OPT_PEER_CA_CERT, > > + OPT_LOCAL, > > + OPT_COMMANDS, > > + OPT_OPTIONS, > > + VLOG_OPTION_ENUMS, > > + TABLE_OPTION_ENUMS > > + }; > > + static const struct option global_long_options[] = { > > + {"db", required_argument, NULL, OPT_DB}, > > + {"no-syslog", no_argument, NULL, OPT_NO_SYSLOG}, > > + {"dry-run", no_argument, NULL, OPT_DRY_RUN}, > > + {"oneline", no_argument, NULL, OPT_ONELINE}, > > + {"timeout", required_argument, NULL, 't'}, > > + {"help", no_argument, NULL, 'h'}, > > + {"commands", no_argument, NULL, OPT_COMMANDS}, > > + {"options", no_argument, NULL, OPT_OPTIONS}, > > + {"version", no_argument, NULL, 'V'}, > > + VLOG_LONG_OPTIONS, > > + TABLE_LONG_OPTIONS, > > + {NULL, 0, NULL, 0}, > > + }; > > + const int n_global_long_options = ARRAY_SIZE(global_long_options) - > 1; > > + char *tmp, *short_options; > > + > > + struct option *options; > > + size_t allocated_options; > > + size_t n_options; > > + size_t i; > > + > > + tmp = ovs_cmdl_long_options_to_short_options(global_long_options); > > + short_options = xasprintf("+%s", tmp); > > + free(tmp); > > + > > + /* We want to parse both global and command-specific options here, > but > > + * getopt_long() isn't too convenient for the job. We copy our > global > > + * options into a dynamic array, then append all of the > command-specific > > + * options. */ > > + options = xmemdup(global_long_options, sizeof global_long_options); > > + allocated_options = ARRAY_SIZE(global_long_options); > > + n_options = n_global_long_options; > > + ctl_add_cmd_options(&options, &n_options, &allocated_options, > OPT_LOCAL); > > + table_style.format = TF_LIST; > > + > > + for (;;) { > > + int idx; > > + int c; > > + > > + c = getopt_long(argc, argv, short_options, options, &idx); > > + if (c == -1) { > > + break; > > + } > > + > > + switch (c) { > > + case OPT_DB: > > + db = optarg; > > + break; > > + > > + case OPT_ONELINE: > > + oneline = true; > > + break; > > + > > + case OPT_NO_SYSLOG: > > + vlog_set_levels(&VLM_sbctl, VLF_SYSLOG, VLL_WARN); > > + break; > > + > > + case OPT_DRY_RUN: > > + dry_run = true; > > + break; > > + > > + case OPT_LOCAL: > > + if (shash_find(local_options, options[idx].name)) { > > + ctl_fatal("'%s' option specified multiple times", > > + options[idx].name); > > + } > > + shash_add_nocopy(local_options, > > + xasprintf("--%s", options[idx].name), > > + optarg ? xstrdup(optarg) : NULL); > > + break; > > + > > + case 'h': > > + usage(); > > + > > + case OPT_COMMANDS: > > + ctl_print_commands(); > > + > > + case OPT_OPTIONS: > > + ctl_print_options(global_long_options); > > + > > + case 'V': > > + ovs_print_version(0, 0); > > + printf("DB Schema %s\n", sbrec_get_db_version()); > > + exit(EXIT_SUCCESS); > > + > > + case 't': > > + timeout = strtoul(optarg, NULL, 10); > > + if (timeout < 0) { > > + ctl_fatal("value %s on -t or --timeout is invalid", > > + optarg); > > + } > > + break; > > + > > + VLOG_OPTION_HANDLERS > > + TABLE_OPTION_HANDLERS(&table_style) > > + > > + case '?': > > + exit(EXIT_FAILURE); > > + > > + default: > > + abort(); > > + } > > + } > > + free(short_options); > > + > > + if (!db) { > > + db = ctl_default_db(); > > + } > > + > > + for (i = n_global_long_options; options[i].name; i++) { > > + free(CONST_CAST(char *, options[i].name)); > > + } > > + free(options); > > +} > > + > > +static void > > +usage(void) > > +{ > > + printf("\ > > +%s: ovs-vswitchd management utility\n\ > > +usage: %s [OPTIONS] COMMAND [ARG...]\n\ > > +\n\ > > +SouthBound DB commands:\n\ > > + show print overview of database contents\n\ > > +\n\ > > +Chassis commands:\n\ > > + add-chassis CHASSIS create a new chassis named CHASSIS\n\ > > + del-chassis CHASSIS delete CHASSIS and all of its encaps,\n\ > > + and gateway_ports\n\ > > +\n\ > > +Binding commands:\n\ > > + bind-lport LPORT CHASSIS bind logical port LPORT to CHASSIS\n\ > > + unbind-lport LPORT delete the binding of logical port > LPORT\n\ > > I'm trying to think of when any of these commands would be used. > add-chassis and bind-lport are always done by ovn-controller. I could > see del-chassis needed in some cases where ovn-controller didn't exit > cleanly and an administrator is trying to do some cleanup. I suppose > unbind-port could be used in cleanup, too. > > Are these commands just for test automation with ovn-controller out of > the picture? If so, maybe the help output could make it clear that the > commands should never be needed? > > I'm just asking because I want to avoid making OVN confusing by exposing > things to administrators that should never really be used. > Yeah, these are only for testing purpose. I'll make it clear in usage() !~ > -- > Russell Bryant > _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev