Message ID | 20190902170904.25100-1-nusiddiq@redhat.com |
---|---|
State | Superseded |
Headers | show |
Series | [ovs-dev,ovn,1/2] Add ovn-appctl utility | expand |
Bleep bloop. Greetings Numan Siddique, I am a robot and I have tried out your patch. Thanks for your contribution. I encountered some error that I wasn't expecting. See the details below. checkpatch: WARNING: Line lacks whitespace around operator WARNING: Line lacks whitespace around operator #555 FILE: utilities/ovn-appctl.c:90: -t, --target=TARGET pidfile or socket to contact\n\ WARNING: Line lacks whitespace around operator #557 FILE: utilities/ovn-appctl.c:92: list-commands List commands supported by the target\n\ WARNING: Line lacks whitespace around operator #559 FILE: utilities/ovn-appctl.c:94: vlog/list List current logging levels\n\ WARNING: Line lacks whitespace around operator WARNING: Line lacks whitespace around operator #560 FILE: utilities/ovn-appctl.c:95: vlog/list-pattern List logging patterns for each destination.\n\ WARNING: Line lacks whitespace around operator #561 FILE: utilities/ovn-appctl.c:96: vlog/set [SPEC]\n\ WARNING: Line lacks whitespace around operator #566 FILE: utilities/ovn-appctl.c:101: vlog/reopen Make the program reopen its log file\n\ WARNING: Line lacks whitespace around operator WARNING: Line lacks whitespace around operator #568 FILE: utilities/ovn-appctl.c:103: --timeout=SECS wait at most SECS seconds for a response\n\ WARNING: Line lacks whitespace around operator #570 FILE: utilities/ovn-appctl.c:105: -V, --version Display ovs-appctl version information\n", WARNING: Line is 113 characters long (recommended limit is 79) #731 FILE: utilities/ovn-ctl:68: ovn-appctl -t $OVN_RUNDIR/ovnnb_db.ctl ovsdb-server/set-active-ovsdb-server `cat $ovnnb_active_conf_file` WARNING: Line is 87 characters long (recommended limit is 79) #732 FILE: utilities/ovn-ctl:69: ovn-appctl -t $OVN_RUNDIR/ovnnb_db.ctl ovsdb-server/connect-active-ovsdb-server WARNING: Line is 113 characters long (recommended limit is 79) #742 FILE: utilities/ovn-ctl:82: ovn-appctl -t $OVN_RUNDIR/ovnsb_db.ctl ovsdb-server/set-active-ovsdb-server `cat $ovnsb_active_conf_file` WARNING: Line is 87 characters long (recommended limit is 79) #743 FILE: utilities/ovn-ctl:83: ovn-appctl -t $OVN_RUNDIR/ovnsb_db.ctl ovsdb-server/connect-active-ovsdb-server WARNING: Line is 86 characters long (recommended limit is 79) #752 FILE: utilities/ovn-ctl:92: ovn-appctl -t $OVN_RUNDIR/ovnnb_db.ctl ovsdb-server/disconnect-active-ovsdb-server WARNING: Line is 86 characters long (recommended limit is 79) #758 FILE: utilities/ovn-ctl:97: ovn-appctl -t $OVN_RUNDIR/ovnsb_db.ctl ovsdb-server/disconnect-active-ovsdb-server WARNING: Line is 98 characters long (recommended limit is 79) #767 FILE: utilities/ovn-ctl:277: ovn-appctl -t $OVN_RUNDIR/ovn${1}_db.ctl ovsdb-server/sync-status | awk '{if(NR==1) print $2}' Lines checked: 773, Warnings: 18, Errors: 0 Please check this out. If you feel there has been an error, please email aconole@redhat.com Thanks, 0-day Robot
On 9/2/19 1:09 PM, nusiddiq@redhat.com wrote: > From: Numan Siddique <nusiddiq@redhat.com> > > Now that OVN has it's own rundir, "ovs-appctl -t ovn-controller/ovn-northd" > doesn't work. To fix this, ovn-appctl utility is added which > looks for the OVN pid/ctl files in the ovn rundir. > > The code is taken from ovs-appctl.c and modified to use ovn_rundir() > instead of ovs_rundir(). > > Signed-off-by: Numan Siddique <nusiddiq@redhat.com> > --- > rhel/ovn-fedora.spec.in | 2 + > utilities/.gitignore | 2 + > utilities/automake.mk | 13 +- > utilities/ovn-appctl.8.xml | 352 +++++++++++++++++++++++++++++++++++++ > utilities/ovn-appctl.c | 239 +++++++++++++++++++++++++ > utilities/ovn-ctl | 18 +- > 6 files changed, 615 insertions(+), 11 deletions(-) > create mode 100644 utilities/ovn-appctl.8.xml > create mode 100644 utilities/ovn-appctl.c > > diff --git a/rhel/ovn-fedora.spec.in b/rhel/ovn-fedora.spec.in > index 14035de9a..9ee807fab 100644 > --- a/rhel/ovn-fedora.spec.in > +++ b/rhel/ovn-fedora.spec.in > @@ -430,6 +430,7 @@ fi > %{_bindir}/ovn-sbctl > %{_bindir}/ovn-trace > %{_bindir}/ovn-detrace > +%{_bindir}/ovn-appctl > %{_datadir}/ovn/scripts/ovn-ctl > %{_datadir}/ovn/scripts/ovn-lib > %{_datadir}/ovn/scripts/ovndb-servers.ocf > @@ -440,6 +441,7 @@ fi > %{_mandir}/man8/ovn-nbctl.8* > %{_mandir}/man8/ovn-trace.8* > %{_mandir}/man1/ovn-detrace.1* > +%{_mandir}/man8/ovn-appctl.8* > #%{_mandir}/man7/ovn-architecture.7* - Uncomment this once the manpage is fixed > %{_mandir}/man8/ovn-sbctl.8* > #%{_mandir}/man5/ovn-nb.5* - Uncomment this once the manpage is fixed > diff --git a/utilities/.gitignore b/utilities/.gitignore > index 1d01e0b28..b319e8366 100644 > --- a/utilities/.gitignore > +++ b/utilities/.gitignore > @@ -3,6 +3,8 @@ > /ovn-nbctl.8 > /ovn-sbctl > /ovn-sbctl.8 > +/ovn-appctl > +/ovn-appctl.8 > /ovn-trace > /ovn-trace.8 > /ovn-detrace > diff --git a/utilities/automake.mk b/utilities/automake.mk > index 21dd8ccdf..ab0f6003a 100644 > --- a/utilities/automake.mk > +++ b/utilities/automake.mk > @@ -8,7 +8,8 @@ man_MANS += \ > utilities/ovn-nbctl.8 \ > utilities/ovn-sbctl.8 \ > utilities/ovn-trace.8 \ > - utilities/ovn-detrace.1 > + utilities/ovn-detrace.1 \ > + utilities/ovn-appctl.8 > > MAN_ROOTS += \ > utilities/ovn-sbctl.8.in \ > @@ -27,6 +28,7 @@ EXTRA_DIST += \ > utilities/ovn-docker-overlay-driver.in \ > utilities/ovn-docker-underlay-driver.in \ > utilities/ovn-nbctl.8.xml \ > + utilities/ovn-appctl.8.xml \ > utilities/ovn-trace.8.xml \ > utilities/ovn-detrace.in \ > utilities/ovndb-servers.ocf \ > @@ -49,7 +51,9 @@ CLEANFILES += \ > utilities/ovn-sbctl.8 \ > utilities/ovn-trace.8 \ > utilities/ovn-detrace.1 \ > - utilities/ovn-detrace > + utilities/ovn-detrace \ > + utilities/ovn-appctl.8 \ > + utilities/ovn-appctl > > utilities/ovn-lib: $(top_builddir)/config.status > > @@ -68,4 +72,9 @@ bin_PROGRAMS += utilities/ovn-trace > utilities_ovn_trace_SOURCES = utilities/ovn-trace.c > utilities_ovn_trace_LDADD = lib/libovn.la $(OVSDB_LIBDIR)/libovsdb.la $(OVS_LIBDIR)/libopenvswitch.la > > +# ovn-nbctl > +bin_PROGRAMS += utilities/ovn-appctl > +utilities_ovn_appctl_SOURCES = utilities/ovn-appctl.c > +utilities_ovn_appctl_LDADD = lib/libovn.la $(OVSDB_LIBDIR)/libovsdb.la $(OVS_LIBDIR)/libopenvswitch.la > + > include utilities/bugtool/automake.mk > diff --git a/utilities/ovn-appctl.8.xml b/utilities/ovn-appctl.8.xml > new file mode 100644 > index 000000000..32a42a766 > --- /dev/null > +++ b/utilities/ovn-appctl.8.xml > @@ -0,0 +1,352 @@ > +<?xml version="1.0" encoding="utf-8"?> > +<manpage program="ovn-appctl" section="8" title="ovn-appctl"> > + <h1>Name</h1> > + <p>ovn-appctl -- utility for configuring running OVN daemons</p> > + > + <h1>Synopsis</h1> > + <p> > + <code> ovn-appctl</code> [--target=target | -t target] > + [-T secs | --timeout=secs] <var>command</var> [<var>arg</var>...] > + </p> > + <p><code>ovn-appctl</code> --help </p> > + <p><code>ovn-appctl</code> --version </p> > + > + <h1>Description</h1> > + <p> > + OVN daemons accept certain commands at runtime to control their behavior > + and query their settings. Every daemon accepts a common set of commands > + documented under COMMON COMMANDS below. Some daemons support additional > + commands documented in their own manpages. > + </p> > + > + <p> > + The <code>ovn-appctl</code> program provides a simple way to invoke > + these commands. The command to be sent is specified on > + <code>ovn-appctl's</code> command line as non-option arguments. > + <code>ovn-appctl</code> sends the command and prints the daemon's > + response on standard output. > + </p> > + > + <p> > + <code>ovn-ctl</code> is exactly similar to Open vSwitch > + <code>ovs-appctl</code> utility. > + </p> > + > + <h1>Command Commands</h1> > + <p> > + Every OVN daemon supports a common set of commands, which are documented > + in this section. > + </p> > + > + <h2>General Commands</h2> > + <p> > + These commands display daemon-specific commands and the running version. > + Note that these commands are different from the --help and --version > + options that return information about the <code>ovn-appctl</code> > + utility itself. > + </p> > + > + <dl> > + <dt><code>list-commands</code></dt> > + <dd> > + Lists the commands supported by the target. > + </dd> > + > + <dt><code>version</code></dt> > + <dd> > + Displays the version and compilation date of the target. > + </dd> > + </dl> > + > + <h2>Logging Commands</h2> > + <p> > + OVN has several log levels. The highest-severity log level is: > + </p> > + > + <dl> > + <dt><code>off</code></dt> > + <dd> > + No message is ever logged at this level, so setting a logging > + destination's log level to off disables logging to that > + destination. > + </dd> > + </dl> > + > + <p> > + The following log levels, in order of descending severity, are > + available: > + </p> > + > + <dl> > + <dt><code>emer</code></dt> > + <dd> > + A major failure forced a process to abort. > + </dd> > + > + <dt><code>err</code></dt> > + <dd> > + A high-level operation or a subsystem failed. Attention is warranted. > + </dd> > + > + <dt><code>warn</code></dt> > + <dd> > + A low-level operation failed, but higher-level subsystems may be able > + to recover. > + </dd> > + > + <dt><code>info</code></dt> > + <dd> > + Information that may be useful in retrospect when investigating a > + problem. > + </dd> > + > + <dt><code>dbg</code></dt> > + <dd> > + Information useful only to someone with intricate knowledge of the > + system, or that would commonly cause too-voluminous log output. > + Log messages at this level are not logged by default. > + </dd> > + </dl> > + > + <p> > + Every OVN daemon supports the following commands for examining and > + adjusting log levels. > + </p> > + > + <dl> > + <dt><code>vlog/list</code></dt> > + <dd> > + Lists the known logging modules and their current levels. > + </dd> > + > + <dt><code>vlog/list-pattern</code></dt> > + <dd> > + Lists logging pattern used for each destination. > + </dd> > + > + <dt><code>vlog/set <var>[spec]</var></code></dt> > + <dd> > + Sets logging levels. Without any spec, sets the log level for every > + module and destination to dbg. Otherwise, spec is a list of words > + separated by spaces or commas or colons, up to one from each > + category below: > + <ul> > + <li> > + A valid module name, as displayed by the vlog/list command on > + ovn-appctl(8), limits the log level change to the specified module. > + </li> > + > + <li> > + <p> > + <code>syslog</code>, <code>console</code>, or <code>file</code>, > + to limit the log level change to only to the system log, to the > + console, or to a file, respectively. > + </p> > + > + <p> > + On Windows platform, <code>syslog</code> is accepted as a word > + and is only useful if the target was started with the > + <code>--syslog-target</code> option (the word has no effect > + otherwise). > + </p> > + </li> > + > + <li> > + <code>off</code>, <code>emer</code>, <code>err</code>, > + <code>warn</code>, <code>info</code>, or <code>dbg</code>, to > + control the log level. Messages of the given severity or higher > + will be logged, and messages of lower severity will be filtered > + out. <code>off</code> filters out all messages. > + </li> > + </ul> > + > + <p> > + Case is not significant within <var>spec</var>. > + </p> > + </dd> > + > + <dt> > + <code>vlog/set PATTERN</code>:<var>destination</var>: > + <var>pattern</var> > + </dt> > + <dd> > + Sets the log pattern for <var>destination</var> to <var>pattern</var>. > + Each time a message is logged to destination, pattern determines the > + message's formatting. Most characters in pattern are copied literally > + to the log, but special escapes beginning with <code>%</code> are > + expanded as follows: > + > + <ul> > + <li> > + <code>%A</code> : The name of the application logging the > + message, e.g. ovn-controller. > + </li> > + > + <li> > + <code>%B</code> : The RFC5424 syslog PRI of the message. > + </li> > + > + <li> > + <code>%c</code> : The name of the module > + (as shown by ovn-appctl --list) logging the message. > + </li> > + > + <li> > + <code>%d</code> : The current date and time in ISO 8601 format > + (YYYY-MM-DD HH:MM:SS). > + </li> > + > + <li> > + <code>%d<var>{format}</var></code> : The current date and time in > + the specified format, which takes the same format as the template > + argument to strftime(3). As an extension, any # characters in > + format will be replaced by fractional seconds, e.g. use > + <code>%H:%M:%S.###</code> for the time to the nearest millisecond. > + Sub-second times are only approximate and currently decimal places > + after the third will always be reported as zero. > + </li> > + > + <li> > + <code>%D</code> : The current UTC date and time in ISO 8601 format > + <code>(YYYY-MM-DD HH:MM:SS)</code>. > + </li> > + > + <li> > + <code>%D<var>{format}</var></code> : The current UTC date and time > + in the specified format, which takes the same format as the > + template argument to strftime(3). Supports the same extension for > + sub-second resolution as <code>%d{...}</code>. > + </li> > + > + <li> > + <code>%E</code> : The hostname of the node running the application. > + </li> > + > + <li> > + <code>%m</code> : The message being logged. > + </li> > + > + <li> > + <code>%N</code> : A serial number for this message within this run > + of the program, as a decimal number. The first message a program > + logs has serial number 1, the second one has serial number 2, > + and so on. > + </li> > + > + <li> > + <code>%n</code> : A new-line. > + </li> > + > + <li> > + <code>%p</code> : The level at which the message is logged, e.g. > + <code>DBG</code>. > + </li> > + > + <li> > + <code>%P</code> : The program's process ID (pid), as a decimal > + number. > + </li> > + > + <li> > + <code>%r</code> : The number of milliseconds elapsed from the start > + of the application to the time the message was logged. > + </li> > + > + <li> > + <code>%t</code> : The subprogram name, that is, an identifying name > + for the process or thread that emitted the log message, such as > + monitor for the process used for --monitor or main for the primary > + process or thread in a program. > + </li> > + > + <li> > + <code>%T</code> : The subprogram name enclosed in parentheses, e.g. > + (monitor), or the empty string for the primary process or thread in > + a program. > + </li> > + > + <li> > + <code>%%</code> : A literal %. > + </li> > + </ul> > + > + <p> > + A few options may appear between the % and the format specifier > + character, in this order: > + </p> > + > + <ul> > + <li> > + <code>-</code> : Left justify the escape's expansion within its field > + width. Right justification is the default. > + </li> > + > + <li> > + <code>-</code> : Pad the field to the field width with 0s. Padding > + with spaces is the default. > + </li> > + </ul> > + > + <p> > + <var>width</var> A number specifies the minimum field width. If the > + escape expands to fewer characters than width then it is padded to > + fill the field width. (A field wider than width is not truncated to > + fit.) > + </p> > + > + <p> > + The default pattern for console and file output is > + <code>%D{%Y-%m-%dT %H:%M:%SZ}|%05N|%c|%p|%m;</code> for syslog > + output, <code>%05N|%c|%p|%m</code>. > + </p> > + </dd> > + > + <dt><code>vlog/set FACILITY:<var>facility</var></code></dt> > + <dd> > + Sets the RFC5424 facility of the log message. facility can be one of > + <code>kern</code>, <code>user</code>, <code>mail</code>, > + <code>daemon</code>, <code>auth</code>, <code>syslog</code>, > + <code>lpr</code>, <code>news</code>, <code>uucp</code>, > + <code>clock</code>, <code>ftp</code>, <code>ntp</code>, > + <code>audit</code>, <code>alert</code>, <code>clock2</code>, > + <code>local0</code>, <code>local1</code>, <code>local2</code>, > + <code>local3</code>, <code>local4</code>, <code>local5</code>, > + <code>local6</code> or <code>local7</code>. > + </dd> > + > + <dt><code>vlog/close</code></dt> > + <dd> > + Causes the daemon to close its log file, if it is open. > + (Use <code>vlog/reopen</code> to reopen it later.) > + </dd> > + > + <dt><code>vlog/reopen</code></dt> > + <dd> > + <p> > + Causes the daemon to close its log file, if it is open, and then > + reopen it. (This is useful after rotating log files, to cause a > + new log file to be used.) > + </p> > + > + <p> > + This has no effect if the target application was not invoked > + with the <code>--log-file</code> option. > + </p> > + </dd> > + </dl> > + > + <h1>Options</h1> > + <dl> > + <dt><code>-h</code></dt> > + <dt><code>--help</code></dt> > + <dd> > + Prints a brief help message to the console. > + </dd> > + > + <dt><code>-V</code></dt> > + <dt><code>--version</code></dt> > + <dd> > + Prints version information to the console. > + </dd> > + </dl> > +</manpage> > \ No newline at end of file > diff --git a/utilities/ovn-appctl.c b/utilities/ovn-appctl.c > new file mode 100644 > index 000000000..3a80a1e3b > --- /dev/null > +++ b/utilities/ovn-appctl.c > @@ -0,0 +1,239 @@ > +/* > + * Copyright (c) 2019 Nicira, Inc. > + * > + * 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 <errno.h> > +#include <getopt.h> > +#include <stdio.h> > +#include <string.h> > +#include <stdlib.h> > + > +#include "command-line.h" > +#include "daemon.h" > +#include "lib/ovn-dirs.h" > +#include "openvswitch/dynamic-string.h" > +#include "jsonrpc.h" > +#include "process.h" > +#include "timeval.h" > +#include "unixctl.h" > +#include "util.h" > +#include "openvswitch/vlog.h" > + > +static void usage(void); > +static const char *parse_command_line(int argc, char *argv[]); > +static struct jsonrpc *connect_to_target(const char *target); > + > +int > +main(int argc, char *argv[]) > +{ > + char *cmd_result, *cmd_error; > + struct jsonrpc *client; > + char *cmd, **cmd_argv; > + const char *target; > + int cmd_argc; > + int error; > + > + set_program_name(argv[0]); > + > + /* Parse command line and connect to target. */ > + target = parse_command_line(argc, argv); > + client = connect_to_target(target); > + > + /* Transact request and process reply. */ > + cmd = argv[optind++]; > + cmd_argc = argc - optind; > + cmd_argv = cmd_argc ? argv + optind : NULL; > + error = unixctl_client_transact(client, cmd, cmd_argc, cmd_argv, > + &cmd_result, &cmd_error); > + if (error) { > + ovs_fatal(error, "%s: transaction error", target); > + } > + > + if (cmd_error) { > + jsonrpc_close(client); > + fputs(cmd_error, stderr); > + ovs_error(0, "%s: server returned an error", target); > + exit(2); > + } else if (cmd_result) { > + fputs(cmd_result, stdout); > + } else { > + OVS_NOT_REACHED(); > + } > + > + jsonrpc_close(client); > + free(cmd_result); > + free(cmd_error); > + return 0; > +} > + > +static void > +usage(void) > +{ > + printf("\ > +%s, for querying and controlling OVN daemon\n\ > +usage: %s [TARGET] COMMAND [ARG...]\n\ > +Targets:\n\ > + -t, --target=TARGET pidfile or socket to contact\n\ > +Common commands:\n\ > + list-commands List commands supported by the target\n\ > + version Print version of the target\n\ > + vlog/list List current logging levels\n\ > + vlog/list-pattern List logging patterns for each destination.\n\ > + vlog/set [SPEC]\n\ > + Set log levels as detailed in SPEC, which may include:\n\ > + A valid module name (all modules, by default)\n\ > + 'syslog', 'console', 'file' (all destinations, by default))\n\ > + 'off', 'emer', 'err', 'warn', 'info', or 'dbg' ('dbg', bydefault)\n\ > + vlog/reopen Make the program reopen its log file\n\ > +Other options:\n\ > + --timeout=SECS wait at most SECS seconds for a response\n\ > + -h, --help Print this helpful information\n\ > + -V, --version Display ovs-appctl version information\n", s/ovs/ovn/ > + program_name, program_name); > + exit(EXIT_SUCCESS); > +} > + > +static const char * > +parse_command_line(int argc, char *argv[]) > +{ > + enum { > + OPT_START = UCHAR_MAX + 1, > + VLOG_OPTION_ENUMS > + }; > + static const struct option long_options[] = { > + {"target", required_argument, NULL, 't'}, > + {"execute", no_argument, NULL, 'e'}, > + {"help", no_argument, NULL, 'h'}, > + {"option", no_argument, NULL, 'o'}, > + {"version", no_argument, NULL, 'V'}, > + {"timeout", required_argument, NULL, 'T'}, > + VLOG_LONG_OPTIONS, > + {NULL, 0, NULL, 0}, > + }; > + char *short_options_ = > + ovs_cmdl_long_options_to_short_options(long_options); > + char *short_options = xasprintf("+%s", short_options_); > + const char *target; > + int e_options; > + unsigned int timeout = 0; > + > + target = NULL; > + e_options = 0; > + for (;;) { > + int option; > + > + option = getopt_long(argc, argv, short_options, long_options, NULL); > + if (option == -1) { > + break; > + } > + switch (option) { > + case 't': > + if (target) { > + ovs_fatal(0, "-t or --target may be specified only once"); > + } > + target = optarg; > + break; > + > + case 'e': > + /* We ignore -e for compatibility. Older versions specified the > + * command as the argument to -e. Since the current version takes > + * the command as non-option arguments and we say that -e has no > + * arguments, this just works in the common case. */ > + if (e_options++) { > + ovs_fatal(0, "-e or --execute may be speciifed only once"); > + } > + break; > + > + case 'h': > + usage(); > + break; > + > + case 'o': > + ovs_cmdl_print_options(long_options); > + exit(EXIT_SUCCESS); > + > + case 'T': > + if (!str_to_uint(optarg, 10, &timeout) || !timeout) { > + ovs_fatal(0, "value %s on -T or --timeout is invalid", optarg); > + } > + break; > + > + case 'V': > + ovs_print_version(0, 0); > + exit(EXIT_SUCCESS); > + > + VLOG_OPTION_HANDLERS > + > + case '?': > + exit(EXIT_FAILURE); > + > + default: > + OVS_NOT_REACHED(); > + } > + } > + free(short_options_); > + free(short_options); > + > + ctl_timeout_setup(timeout); > + > + if (optind >= argc) { > + ovs_fatal(0, "at least one non-option argument is required " > + "(use --help for help)"); > + } > + > + return target ? target : "ovn-controller"; > +} > + > +static struct jsonrpc * > +connect_to_target(const char *target) > +{ > + struct jsonrpc *client; > + char *socket_name; > + int error; > + > +#ifndef _WIN32 > + if (target[0] != '/') { > + char *pidfile_name; > + pid_t pid; > + > + pidfile_name = xasprintf("%s/%s.pid", ovn_rundir(), target); > + pid = read_pidfile(pidfile_name); > + if (pid < 0) { > + ovs_fatal(-pid, "cannot read pidfile \"%s\"", pidfile_name); > + } > + free(pidfile_name); > + socket_name = xasprintf("%s/%s.%ld.ctl", > + ovn_rundir(), target, (long int) pid); > +#else > + /* On windows, if the 'target' contains ':', we make an assumption that > + * it is an absolute path. */ > + if (!strchr(target, ':')) { > + socket_name = xasprintf("%s/%s.ctl", ovn_rundir(), target); > +#endif > + } else { > + socket_name = xstrdup(target); > + } > + > + error = unixctl_client_create(socket_name, &client); > + if (error) { > + ovs_fatal(error, "cannot connect to \"%s\"", socket_name); > + } > + free(socket_name); > + > + return client; > +} > + > diff --git a/utilities/ovn-ctl b/utilities/ovn-ctl > index c955aa177..4242cd2c8 100755 > --- a/utilities/ovn-ctl > +++ b/utilities/ovn-ctl > @@ -44,13 +44,13 @@ pidfile_is_running () { > > stop_nb_ovsdb() { > if pidfile_is_running $DB_NB_PID; then > - ovs-appctl -t $OVN_RUNDIR/ovnnb_db.ctl exit > + ovn-appctl -t $OVN_RUNDIR/ovnnb_db.ctl exit > fi > } > > stop_sb_ovsdb() { > if pidfile_is_running $DB_SB_PID; then > - ovs-appctl -t $OVN_RUNDIR/ovnsb_db.ctl exit > + ovn-appctl -t $OVN_RUNDIR/ovnsb_db.ctl exit > fi > } > > @@ -65,8 +65,8 @@ demote_ovnnb() { > fi > > if test -e $ovnnb_active_conf_file; then > - ovs-appctl -t $OVN_RUNDIR/ovnnb_db.ctl ovsdb-server/set-active-ovsdb-server `cat $ovnnb_active_conf_file` > - ovs-appctl -t $OVN_RUNDIR/ovnnb_db.ctl ovsdb-server/connect-active-ovsdb-server > + ovn-appctl -t $OVN_RUNDIR/ovnnb_db.ctl ovsdb-server/set-active-ovsdb-server `cat $ovnnb_active_conf_file` > + ovn-appctl -t $OVN_RUNDIR/ovnnb_db.ctl ovsdb-server/connect-active-ovsdb-server > else > echo >&2 "$0: active server details not set" > exit 1 > @@ -79,8 +79,8 @@ demote_ovnsb() { > fi > > if test -e $ovnsb_active_conf_file; then > - ovs-appctl -t $OVN_RUNDIR/ovnsb_db.ctl ovsdb-server/set-active-ovsdb-server `cat $ovnsb_active_conf_file` > - ovs-appctl -t $OVN_RUNDIR/ovnsb_db.ctl ovsdb-server/connect-active-ovsdb-server > + ovn-appctl -t $OVN_RUNDIR/ovnsb_db.ctl ovsdb-server/set-active-ovsdb-server `cat $ovnsb_active_conf_file` > + ovn-appctl -t $OVN_RUNDIR/ovnsb_db.ctl ovsdb-server/connect-active-ovsdb-server > else > echo >&2 "$0: active server details not set" > exit 1 > @@ -89,12 +89,12 @@ demote_ovnsb() { > > promote_ovnnb() { > rm -f $ovnnb_active_conf_file > - ovs-appctl -t $OVN_RUNDIR/ovnnb_db.ctl ovsdb-server/disconnect-active-ovsdb-server > + ovn-appctl -t $OVN_RUNDIR/ovnnb_db.ctl ovsdb-server/disconnect-active-ovsdb-server > } > > promote_ovnsb() { > rm -f $ovnsb_active_conf_file > - ovs-appctl -t $OVN_RUNDIR/ovnsb_db.ctl ovsdb-server/disconnect-active-ovsdb-server > + ovn-appctl -t $OVN_RUNDIR/ovnsb_db.ctl ovsdb-server/disconnect-active-ovsdb-server > } > > start_ovsdb__() { > @@ -274,7 +274,7 @@ start_ovsdb () { > } > > sync_status() { > - ovs-appctl -t $OVN_RUNDIR/ovn${1}_db.ctl ovsdb-server/sync-status | awk '{if(NR==1) print $2}' > + ovn-appctl -t $OVN_RUNDIR/ovn${1}_db.ctl ovsdb-server/sync-status | awk '{if(NR==1) print $2}' > } > > status_ovnnb() { >
On Wed, Sep 4, 2019 at 11:21 PM Mark Michelson <mmichels@redhat.com> wrote: > On 9/2/19 1:09 PM, nusiddiq@redhat.com wrote: > > From: Numan Siddique <nusiddiq@redhat.com> > > > > Now that OVN has it's own rundir, "ovs-appctl -t > ovn-controller/ovn-northd" > > doesn't work. To fix this, ovn-appctl utility is added which > > looks for the OVN pid/ctl files in the ovn rundir. > > > > The code is taken from ovs-appctl.c and modified to use ovn_rundir() > > instead of ovs_rundir(). > > > > Signed-off-by: Numan Siddique <nusiddiq@redhat.com> > > --- > > rhel/ovn-fedora.spec.in | 2 + > > utilities/.gitignore | 2 + > > utilities/automake.mk | 13 +- > > utilities/ovn-appctl.8.xml | 352 +++++++++++++++++++++++++++++++++++++ > > utilities/ovn-appctl.c | 239 +++++++++++++++++++++++++ > > utilities/ovn-ctl | 18 +- > > 6 files changed, 615 insertions(+), 11 deletions(-) > > create mode 100644 utilities/ovn-appctl.8.xml > > create mode 100644 utilities/ovn-appctl.c > > > > diff --git a/rhel/ovn-fedora.spec.in b/rhel/ovn-fedora.spec.in > > index 14035de9a..9ee807fab 100644 > > --- a/rhel/ovn-fedora.spec.in > > +++ b/rhel/ovn-fedora.spec.in > > @@ -430,6 +430,7 @@ fi > > %{_bindir}/ovn-sbctl > > %{_bindir}/ovn-trace > > %{_bindir}/ovn-detrace > > +%{_bindir}/ovn-appctl > > %{_datadir}/ovn/scripts/ovn-ctl > > %{_datadir}/ovn/scripts/ovn-lib > > %{_datadir}/ovn/scripts/ovndb-servers.ocf > > @@ -440,6 +441,7 @@ fi > > %{_mandir}/man8/ovn-nbctl.8* > > %{_mandir}/man8/ovn-trace.8* > > %{_mandir}/man1/ovn-detrace.1* > > +%{_mandir}/man8/ovn-appctl.8* > > #%{_mandir}/man7/ovn-architecture.7* - Uncomment this once the manpage > is fixed > > %{_mandir}/man8/ovn-sbctl.8* > > #%{_mandir}/man5/ovn-nb.5* - Uncomment this once the manpage is fixed > > diff --git a/utilities/.gitignore b/utilities/.gitignore > > index 1d01e0b28..b319e8366 100644 > > --- a/utilities/.gitignore > > +++ b/utilities/.gitignore > > @@ -3,6 +3,8 @@ > > /ovn-nbctl.8 > > /ovn-sbctl > > /ovn-sbctl.8 > > +/ovn-appctl > > +/ovn-appctl.8 > > /ovn-trace > > /ovn-trace.8 > > /ovn-detrace > > diff --git a/utilities/automake.mk b/utilities/automake.mk > > index 21dd8ccdf..ab0f6003a 100644 > > --- a/utilities/automake.mk > > +++ b/utilities/automake.mk > > @@ -8,7 +8,8 @@ man_MANS += \ > > utilities/ovn-nbctl.8 \ > > utilities/ovn-sbctl.8 \ > > utilities/ovn-trace.8 \ > > - utilities/ovn-detrace.1 > > + utilities/ovn-detrace.1 \ > > + utilities/ovn-appctl.8 > > > > MAN_ROOTS += \ > > utilities/ovn-sbctl.8.in \ > > @@ -27,6 +28,7 @@ EXTRA_DIST += \ > > utilities/ovn-docker-overlay-driver.in \ > > utilities/ovn-docker-underlay-driver.in \ > > utilities/ovn-nbctl.8.xml \ > > + utilities/ovn-appctl.8.xml \ > > utilities/ovn-trace.8.xml \ > > utilities/ovn-detrace.in \ > > utilities/ovndb-servers.ocf \ > > @@ -49,7 +51,9 @@ CLEANFILES += \ > > utilities/ovn-sbctl.8 \ > > utilities/ovn-trace.8 \ > > utilities/ovn-detrace.1 \ > > - utilities/ovn-detrace > > + utilities/ovn-detrace \ > > + utilities/ovn-appctl.8 \ > > + utilities/ovn-appctl > > > > utilities/ovn-lib: $(top_builddir)/config.status > > > > @@ -68,4 +72,9 @@ bin_PROGRAMS += utilities/ovn-trace > > utilities_ovn_trace_SOURCES = utilities/ovn-trace.c > > utilities_ovn_trace_LDADD = lib/libovn.la $(OVSDB_LIBDIR)/libovsdb.la > $(OVS_LIBDIR)/libopenvswitch.la > > > > +# ovn-nbctl > > +bin_PROGRAMS += utilities/ovn-appctl > > +utilities_ovn_appctl_SOURCES = utilities/ovn-appctl.c > > +utilities_ovn_appctl_LDADD = lib/libovn.la $(OVSDB_LIBDIR)/libovsdb.la > $(OVS_LIBDIR)/libopenvswitch.la > > + > > include utilities/bugtool/automake.mk > > diff --git a/utilities/ovn-appctl.8.xml b/utilities/ovn-appctl.8.xml > > new file mode 100644 > > index 000000000..32a42a766 > > --- /dev/null > > +++ b/utilities/ovn-appctl.8.xml > > @@ -0,0 +1,352 @@ > > +<?xml version="1.0" encoding="utf-8"?> > > +<manpage program="ovn-appctl" section="8" title="ovn-appctl"> > > + <h1>Name</h1> > > + <p>ovn-appctl -- utility for configuring running OVN daemons</p> > > + > > + <h1>Synopsis</h1> > > + <p> > > + <code> ovn-appctl</code> [--target=target | -t target] > > + [-T secs | --timeout=secs] <var>command</var> [<var>arg</var>...] > > + </p> > > + <p><code>ovn-appctl</code> --help </p> > > + <p><code>ovn-appctl</code> --version </p> > > + > > + <h1>Description</h1> > > + <p> > > + OVN daemons accept certain commands at runtime to control their > behavior > > + and query their settings. Every daemon accepts a common set of > commands > > + documented under COMMON COMMANDS below. Some daemons support > additional > > + commands documented in their own manpages. > > + </p> > > + > > + <p> > > + The <code>ovn-appctl</code> program provides a simple way to > invoke > > + these commands. The command to be sent is specified on > > + <code>ovn-appctl's</code> command line as non-option arguments. > > + <code>ovn-appctl</code> sends the command and prints the daemon's > > + response on standard output. > > + </p> > > + > > + <p> > > + <code>ovn-ctl</code> is exactly similar to Open vSwitch > > + <code>ovs-appctl</code> utility. > > + </p> > > + > > + <h1>Command Commands</h1> > > + <p> > > + Every OVN daemon supports a common set of commands, which are > documented > > + in this section. > > + </p> > > + > > + <h2>General Commands</h2> > > + <p> > > + These commands display daemon-specific commands and the running > version. > > + Note that these commands are different from the --help and > --version > > + options that return information about the <code>ovn-appctl</code> > > + utility itself. > > + </p> > > + > > + <dl> > > + <dt><code>list-commands</code></dt> > > + <dd> > > + Lists the commands supported by the target. > > + </dd> > > + > > + <dt><code>version</code></dt> > > + <dd> > > + Displays the version and compilation date of the target. > > + </dd> > > + </dl> > > + > > + <h2>Logging Commands</h2> > > + <p> > > + OVN has several log levels. The highest-severity log level is: > > + </p> > > + > > + <dl> > > + <dt><code>off</code></dt> > > + <dd> > > + No message is ever logged at this level, so setting a logging > > + destination's log level to off disables logging to that > > + destination. > > + </dd> > > + </dl> > > + > > + <p> > > + The following log levels, in order of descending severity, are > > + available: > > + </p> > > + > > + <dl> > > + <dt><code>emer</code></dt> > > + <dd> > > + A major failure forced a process to abort. > > + </dd> > > + > > + <dt><code>err</code></dt> > > + <dd> > > + A high-level operation or a subsystem failed. Attention is > warranted. > > + </dd> > > + > > + <dt><code>warn</code></dt> > > + <dd> > > + A low-level operation failed, but higher-level subsystems may > be able > > + to recover. > > + </dd> > > + > > + <dt><code>info</code></dt> > > + <dd> > > + Information that may be useful in retrospect when investigating > a > > + problem. > > + </dd> > > + > > + <dt><code>dbg</code></dt> > > + <dd> > > + Information useful only to someone with intricate knowledge of > the > > + system, or that would commonly cause too-voluminous log output. > > + Log messages at this level are not logged by default. > > + </dd> > > + </dl> > > + > > + <p> > > + Every OVN daemon supports the following commands for examining and > > + adjusting log levels. > > + </p> > > + > > + <dl> > > + <dt><code>vlog/list</code></dt> > > + <dd> > > + Lists the known logging modules and their current levels. > > + </dd> > > + > > + <dt><code>vlog/list-pattern</code></dt> > > + <dd> > > + Lists logging pattern used for each destination. > > + </dd> > > + > > + <dt><code>vlog/set <var>[spec]</var></code></dt> > > + <dd> > > + Sets logging levels. Without any spec, sets the log level for > every > > + module and destination to dbg. Otherwise, spec is a list of > words > > + separated by spaces or commas or colons, up to one from each > > + category below: > > + <ul> > > + <li> > > + A valid module name, as displayed by the vlog/list command > on > > + ovn-appctl(8), limits the log level change to the specified > module. > > + </li> > > + > > + <li> > > + <p> > > + <code>syslog</code>, <code>console</code>, or > <code>file</code>, > > + to limit the log level change to only to the system log, > to the > > + console, or to a file, respectively. > > + </p> > > + > > + <p> > > + On Windows platform, <code>syslog</code> is accepted as a > word > > + and is only useful if the target was started with the > > + <code>--syslog-target</code> option (the word has no > effect > > + otherwise). > > + </p> > > + </li> > > + > > + <li> > > + <code>off</code>, <code>emer</code>, <code>err</code>, > > + <code>warn</code>, <code>info</code>, or <code>dbg</code>, > to > > + control the log level. Messages of the given severity or > higher > > + will be logged, and messages of lower severity will be > filtered > > + out. <code>off</code> filters out all messages. > > + </li> > > + </ul> > > + > > + <p> > > + Case is not significant within <var>spec</var>. > > + </p> > > + </dd> > > + > > + <dt> > > + <code>vlog/set PATTERN</code>:<var>destination</var>: > > + <var>pattern</var> > > + </dt> > > + <dd> > > + Sets the log pattern for <var>destination</var> to > <var>pattern</var>. > > + Each time a message is logged to destination, pattern > determines the > > + message's formatting. Most characters in pattern are copied > literally > > + to the log, but special escapes beginning with <code>%</code> > are > > + expanded as follows: > > + > > + <ul> > > + <li> > > + <code>%A</code> : The name of the application logging the > > + message, e.g. ovn-controller. > > + </li> > > + > > + <li> > > + <code>%B</code> : The RFC5424 syslog PRI of the message. > > + </li> > > + > > + <li> > > + <code>%c</code> : The name of the module > > + (as shown by ovn-appctl --list) logging the message. > > + </li> > > + > > + <li> > > + <code>%d</code> : The current date and time in ISO 8601 > format > > + (YYYY-MM-DD HH:MM:SS). > > + </li> > > + > > + <li> > > + <code>%d<var>{format}</var></code> : The current date and > time in > > + the specified format, which takes the same format as the > template > > + argument to strftime(3). As an extension, any # characters > in > > + format will be replaced by fractional seconds, e.g. use > > + <code>%H:%M:%S.###</code> for the time to the nearest > millisecond. > > + Sub-second times are only approximate and currently decimal > places > > + after the third will always be reported as zero. > > + </li> > > + > > + <li> > > + <code>%D</code> : The current UTC date and time in ISO 8601 > format > > + <code>(YYYY-MM-DD HH:MM:SS)</code>. > > + </li> > > + > > + <li> > > + <code>%D<var>{format}</var></code> : The current UTC date > and time > > + in the specified format, which takes the same format as the > > + template argument to strftime(3). Supports the same > extension for > > + sub-second resolution as <code>%d{...}</code>. > > + </li> > > + > > + <li> > > + <code>%E</code> : The hostname of the node running the > application. > > + </li> > > + > > + <li> > > + <code>%m</code> : The message being logged. > > + </li> > > + > > + <li> > > + <code>%N</code> : A serial number for this message within > this run > > + of the program, as a decimal number. The first message a > program > > + logs has serial number 1, the second one has serial number > 2, > > + and so on. > > + </li> > > + > > + <li> > > + <code>%n</code> : A new-line. > > + </li> > > + > > + <li> > > + <code>%p</code> : The level at which the message is logged, > e.g. > > + <code>DBG</code>. > > + </li> > > + > > + <li> > > + <code>%P</code> : The program's process ID (pid), as a > decimal > > + number. > > + </li> > > + > > + <li> > > + <code>%r</code> : The number of milliseconds elapsed from > the start > > + of the application to the time the message was logged. > > + </li> > > + > > + <li> > > + <code>%t</code> : The subprogram name, that is, an > identifying name > > + for the process or thread that emitted the log message, > such as > > + monitor for the process used for --monitor or main for the > primary > > + process or thread in a program. > > + </li> > > + > > + <li> > > + <code>%T</code> : The subprogram name enclosed in > parentheses, e.g. > > + (monitor), or the empty string for the primary process or > thread in > > + a program. > > + </li> > > + > > + <li> > > + <code>%%</code> : A literal %. > > + </li> > > + </ul> > > + > > + <p> > > + A few options may appear between the % and the format > specifier > > + character, in this order: > > + </p> > > + > > + <ul> > > + <li> > > + <code>-</code> : Left justify the escape's expansion within > its field > > + width. Right justification is the default. > > + </li> > > + > > + <li> > > + <code>-</code> : Pad the field to the field width with 0s. > Padding > > + with spaces is the default. > > + </li> > > + </ul> > > + > > + <p> > > + <var>width</var> A number specifies the minimum field width. > If the > > + escape expands to fewer characters than width then it is > padded to > > + fill the field width. (A field wider than width is not > truncated to > > + fit.) > > + </p> > > + > > + <p> > > + The default pattern for console and file output is > > + <code>%D{%Y-%m-%dT %H:%M:%SZ}|%05N|%c|%p|%m;</code> for syslog > > + output, <code>%05N|%c|%p|%m</code>. > > + </p> > > + </dd> > > + > > + <dt><code>vlog/set FACILITY:<var>facility</var></code></dt> > > + <dd> > > + Sets the RFC5424 facility of the log message. facility can be > one of > > + <code>kern</code>, <code>user</code>, <code>mail</code>, > > + <code>daemon</code>, <code>auth</code>, <code>syslog</code>, > > + <code>lpr</code>, <code>news</code>, <code>uucp</code>, > > + <code>clock</code>, <code>ftp</code>, <code>ntp</code>, > > + <code>audit</code>, <code>alert</code>, <code>clock2</code>, > > + <code>local0</code>, <code>local1</code>, <code>local2</code>, > > + <code>local3</code>, <code>local4</code>, <code>local5</code>, > > + <code>local6</code> or <code>local7</code>. > > + </dd> > > + > > + <dt><code>vlog/close</code></dt> > > + <dd> > > + Causes the daemon to close its log file, if it is open. > > + (Use <code>vlog/reopen</code> to reopen it later.) > > + </dd> > > + > > + <dt><code>vlog/reopen</code></dt> > > + <dd> > > + <p> > > + Causes the daemon to close its log file, if it is open, and > then > > + reopen it. (This is useful after rotating log files, to cause > a > > + new log file to be used.) > > + </p> > > + > > + <p> > > + This has no effect if the target application was not invoked > > + with the <code>--log-file</code> option. > > + </p> > > + </dd> > > + </dl> > > + > > + <h1>Options</h1> > > + <dl> > > + <dt><code>-h</code></dt> > > + <dt><code>--help</code></dt> > > + <dd> > > + Prints a brief help message to the console. > > + </dd> > > + > > + <dt><code>-V</code></dt> > > + <dt><code>--version</code></dt> > > + <dd> > > + Prints version information to the console. > > + </dd> > > + </dl> > > +</manpage> > > \ No newline at end of file > > diff --git a/utilities/ovn-appctl.c b/utilities/ovn-appctl.c > > new file mode 100644 > > index 000000000..3a80a1e3b > > --- /dev/null > > +++ b/utilities/ovn-appctl.c > > @@ -0,0 +1,239 @@ > > +/* > > + * Copyright (c) 2019 Nicira, Inc. > > + * > > + * 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 <errno.h> > > +#include <getopt.h> > > +#include <stdio.h> > > +#include <string.h> > > +#include <stdlib.h> > > + > > +#include "command-line.h" > > +#include "daemon.h" > > +#include "lib/ovn-dirs.h" > > +#include "openvswitch/dynamic-string.h" > > +#include "jsonrpc.h" > > +#include "process.h" > > +#include "timeval.h" > > +#include "unixctl.h" > > +#include "util.h" > > +#include "openvswitch/vlog.h" > > + > > +static void usage(void); > > +static const char *parse_command_line(int argc, char *argv[]); > > +static struct jsonrpc *connect_to_target(const char *target); > > + > > +int > > +main(int argc, char *argv[]) > > +{ > > + char *cmd_result, *cmd_error; > > + struct jsonrpc *client; > > + char *cmd, **cmd_argv; > > + const char *target; > > + int cmd_argc; > > + int error; > > + > > + set_program_name(argv[0]); > > + > > + /* Parse command line and connect to target. */ > > + target = parse_command_line(argc, argv); > > + client = connect_to_target(target); > > + > > + /* Transact request and process reply. */ > > + cmd = argv[optind++]; > > + cmd_argc = argc - optind; > > + cmd_argv = cmd_argc ? argv + optind : NULL; > > + error = unixctl_client_transact(client, cmd, cmd_argc, cmd_argv, > > + &cmd_result, &cmd_error); > > + if (error) { > > + ovs_fatal(error, "%s: transaction error", target); > > + } > > + > > + if (cmd_error) { > > + jsonrpc_close(client); > > + fputs(cmd_error, stderr); > > + ovs_error(0, "%s: server returned an error", target); > > + exit(2); > > + } else if (cmd_result) { > > + fputs(cmd_result, stdout); > > + } else { > > + OVS_NOT_REACHED(); > > + } > > + > > + jsonrpc_close(client); > > + free(cmd_result); > > + free(cmd_error); > > + return 0; > > +} > > + > > +static void > > +usage(void) > > +{ > > + printf("\ > > +%s, for querying and controlling OVN daemon\n\ > > +usage: %s [TARGET] COMMAND [ARG...]\n\ > > +Targets:\n\ > > + -t, --target=TARGET pidfile or socket to contact\n\ > > +Common commands:\n\ > > + list-commands List commands supported by the target\n\ > > + version Print version of the target\n\ > > + vlog/list List current logging levels\n\ > > + vlog/list-pattern List logging patterns for each destination.\n\ > > + vlog/set [SPEC]\n\ > > + Set log levels as detailed in SPEC, which may include:\n\ > > + A valid module name (all modules, by default)\n\ > > + 'syslog', 'console', 'file' (all destinations, by default))\n\ > > + 'off', 'emer', 'err', 'warn', 'info', or 'dbg' ('dbg', > bydefault)\n\ > > + vlog/reopen Make the program reopen its log file\n\ > > +Other options:\n\ > > + --timeout=SECS wait at most SECS seconds for a response\n\ > > + -h, --help Print this helpful information\n\ > > + -V, --version Display ovs-appctl version information\n", > > s/ovs/ovn/ > Thanks. Done. I submitted v2 - https://patchwork.ozlabs.org/project/openvswitch/list/?series=129875 Numan > > > + program_name, program_name); > > + exit(EXIT_SUCCESS); > > +} > > + > > +static const char * > > +parse_command_line(int argc, char *argv[]) > > +{ > > + enum { > > + OPT_START = UCHAR_MAX + 1, > > + VLOG_OPTION_ENUMS > > + }; > > + static const struct option long_options[] = { > > + {"target", required_argument, NULL, 't'}, > > + {"execute", no_argument, NULL, 'e'}, > > + {"help", no_argument, NULL, 'h'}, > > + {"option", no_argument, NULL, 'o'}, > > + {"version", no_argument, NULL, 'V'}, > > + {"timeout", required_argument, NULL, 'T'}, > > + VLOG_LONG_OPTIONS, > > + {NULL, 0, NULL, 0}, > > + }; > > + char *short_options_ = > > + ovs_cmdl_long_options_to_short_options(long_options); > > + char *short_options = xasprintf("+%s", short_options_); > > + const char *target; > > + int e_options; > > + unsigned int timeout = 0; > > + > > + target = NULL; > > + e_options = 0; > > + for (;;) { > > + int option; > > + > > + option = getopt_long(argc, argv, short_options, long_options, > NULL); > > + if (option == -1) { > > + break; > > + } > > + switch (option) { > > + case 't': > > + if (target) { > > + ovs_fatal(0, "-t or --target may be specified only > once"); > > + } > > + target = optarg; > > + break; > > + > > + case 'e': > > + /* We ignore -e for compatibility. Older versions > specified the > > + * command as the argument to -e. Since the current > version takes > > + * the command as non-option arguments and we say that -e > has no > > + * arguments, this just works in the common case. */ > > + if (e_options++) { > > + ovs_fatal(0, "-e or --execute may be speciifed only > once"); > > + } > > + break; > > + > > + case 'h': > > + usage(); > > + break; > > + > > + case 'o': > > + ovs_cmdl_print_options(long_options); > > + exit(EXIT_SUCCESS); > > + > > + case 'T': > > + if (!str_to_uint(optarg, 10, &timeout) || !timeout) { > > + ovs_fatal(0, "value %s on -T or --timeout is invalid", > optarg); > > + } > > + break; > > + > > + case 'V': > > + ovs_print_version(0, 0); > > + exit(EXIT_SUCCESS); > > + > > + VLOG_OPTION_HANDLERS > > + > > + case '?': > > + exit(EXIT_FAILURE); > > + > > + default: > > + OVS_NOT_REACHED(); > > + } > > + } > > + free(short_options_); > > + free(short_options); > > + > > + ctl_timeout_setup(timeout); > > + > > + if (optind >= argc) { > > + ovs_fatal(0, "at least one non-option argument is required " > > + "(use --help for help)"); > > + } > > + > > + return target ? target : "ovn-controller"; > > +} > > + > > +static struct jsonrpc * > > +connect_to_target(const char *target) > > +{ > > + struct jsonrpc *client; > > + char *socket_name; > > + int error; > > + > > +#ifndef _WIN32 > > + if (target[0] != '/') { > > + char *pidfile_name; > > + pid_t pid; > > + > > + pidfile_name = xasprintf("%s/%s.pid", ovn_rundir(), target); > > + pid = read_pidfile(pidfile_name); > > + if (pid < 0) { > > + ovs_fatal(-pid, "cannot read pidfile \"%s\"", pidfile_name); > > + } > > + free(pidfile_name); > > + socket_name = xasprintf("%s/%s.%ld.ctl", > > + ovn_rundir(), target, (long int) pid); > > +#else > > + /* On windows, if the 'target' contains ':', we make an assumption > that > > + * it is an absolute path. */ > > + if (!strchr(target, ':')) { > > + socket_name = xasprintf("%s/%s.ctl", ovn_rundir(), target); > > +#endif > > + } else { > > + socket_name = xstrdup(target); > > + } > > + > > + error = unixctl_client_create(socket_name, &client); > > + if (error) { > > + ovs_fatal(error, "cannot connect to \"%s\"", socket_name); > > + } > > + free(socket_name); > > + > > + return client; > > +} > > + > > diff --git a/utilities/ovn-ctl b/utilities/ovn-ctl > > index c955aa177..4242cd2c8 100755 > > --- a/utilities/ovn-ctl > > +++ b/utilities/ovn-ctl > > @@ -44,13 +44,13 @@ pidfile_is_running () { > > > > stop_nb_ovsdb() { > > if pidfile_is_running $DB_NB_PID; then > > - ovs-appctl -t $OVN_RUNDIR/ovnnb_db.ctl exit > > + ovn-appctl -t $OVN_RUNDIR/ovnnb_db.ctl exit > > fi > > } > > > > stop_sb_ovsdb() { > > if pidfile_is_running $DB_SB_PID; then > > - ovs-appctl -t $OVN_RUNDIR/ovnsb_db.ctl exit > > + ovn-appctl -t $OVN_RUNDIR/ovnsb_db.ctl exit > > fi > > } > > > > @@ -65,8 +65,8 @@ demote_ovnnb() { > > fi > > > > if test -e $ovnnb_active_conf_file; then > > - ovs-appctl -t $OVN_RUNDIR/ovnnb_db.ctl > ovsdb-server/set-active-ovsdb-server `cat $ovnnb_active_conf_file` > > - ovs-appctl -t $OVN_RUNDIR/ovnnb_db.ctl > ovsdb-server/connect-active-ovsdb-server > > + ovn-appctl -t $OVN_RUNDIR/ovnnb_db.ctl > ovsdb-server/set-active-ovsdb-server `cat $ovnnb_active_conf_file` > > + ovn-appctl -t $OVN_RUNDIR/ovnnb_db.ctl > ovsdb-server/connect-active-ovsdb-server > > else > > echo >&2 "$0: active server details not set" > > exit 1 > > @@ -79,8 +79,8 @@ demote_ovnsb() { > > fi > > > > if test -e $ovnsb_active_conf_file; then > > - ovs-appctl -t $OVN_RUNDIR/ovnsb_db.ctl > ovsdb-server/set-active-ovsdb-server `cat $ovnsb_active_conf_file` > > - ovs-appctl -t $OVN_RUNDIR/ovnsb_db.ctl > ovsdb-server/connect-active-ovsdb-server > > + ovn-appctl -t $OVN_RUNDIR/ovnsb_db.ctl > ovsdb-server/set-active-ovsdb-server `cat $ovnsb_active_conf_file` > > + ovn-appctl -t $OVN_RUNDIR/ovnsb_db.ctl > ovsdb-server/connect-active-ovsdb-server > > else > > echo >&2 "$0: active server details not set" > > exit 1 > > @@ -89,12 +89,12 @@ demote_ovnsb() { > > > > promote_ovnnb() { > > rm -f $ovnnb_active_conf_file > > - ovs-appctl -t $OVN_RUNDIR/ovnnb_db.ctl > ovsdb-server/disconnect-active-ovsdb-server > > + ovn-appctl -t $OVN_RUNDIR/ovnnb_db.ctl > ovsdb-server/disconnect-active-ovsdb-server > > } > > > > promote_ovnsb() { > > rm -f $ovnsb_active_conf_file > > - ovs-appctl -t $OVN_RUNDIR/ovnsb_db.ctl > ovsdb-server/disconnect-active-ovsdb-server > > + ovn-appctl -t $OVN_RUNDIR/ovnsb_db.ctl > ovsdb-server/disconnect-active-ovsdb-server > > } > > > > start_ovsdb__() { > > @@ -274,7 +274,7 @@ start_ovsdb () { > > } > > > > sync_status() { > > - ovs-appctl -t $OVN_RUNDIR/ovn${1}_db.ctl ovsdb-server/sync-status | > awk '{if(NR==1) print $2}' > > + ovn-appctl -t $OVN_RUNDIR/ovn${1}_db.ctl ovsdb-server/sync-status | > awk '{if(NR==1) print $2}' > > } > > > > status_ovnnb() { > > > >
diff --git a/rhel/ovn-fedora.spec.in b/rhel/ovn-fedora.spec.in index 14035de9a..9ee807fab 100644 --- a/rhel/ovn-fedora.spec.in +++ b/rhel/ovn-fedora.spec.in @@ -430,6 +430,7 @@ fi %{_bindir}/ovn-sbctl %{_bindir}/ovn-trace %{_bindir}/ovn-detrace +%{_bindir}/ovn-appctl %{_datadir}/ovn/scripts/ovn-ctl %{_datadir}/ovn/scripts/ovn-lib %{_datadir}/ovn/scripts/ovndb-servers.ocf @@ -440,6 +441,7 @@ fi %{_mandir}/man8/ovn-nbctl.8* %{_mandir}/man8/ovn-trace.8* %{_mandir}/man1/ovn-detrace.1* +%{_mandir}/man8/ovn-appctl.8* #%{_mandir}/man7/ovn-architecture.7* - Uncomment this once the manpage is fixed %{_mandir}/man8/ovn-sbctl.8* #%{_mandir}/man5/ovn-nb.5* - Uncomment this once the manpage is fixed diff --git a/utilities/.gitignore b/utilities/.gitignore index 1d01e0b28..b319e8366 100644 --- a/utilities/.gitignore +++ b/utilities/.gitignore @@ -3,6 +3,8 @@ /ovn-nbctl.8 /ovn-sbctl /ovn-sbctl.8 +/ovn-appctl +/ovn-appctl.8 /ovn-trace /ovn-trace.8 /ovn-detrace diff --git a/utilities/automake.mk b/utilities/automake.mk index 21dd8ccdf..ab0f6003a 100644 --- a/utilities/automake.mk +++ b/utilities/automake.mk @@ -8,7 +8,8 @@ man_MANS += \ utilities/ovn-nbctl.8 \ utilities/ovn-sbctl.8 \ utilities/ovn-trace.8 \ - utilities/ovn-detrace.1 + utilities/ovn-detrace.1 \ + utilities/ovn-appctl.8 MAN_ROOTS += \ utilities/ovn-sbctl.8.in \ @@ -27,6 +28,7 @@ EXTRA_DIST += \ utilities/ovn-docker-overlay-driver.in \ utilities/ovn-docker-underlay-driver.in \ utilities/ovn-nbctl.8.xml \ + utilities/ovn-appctl.8.xml \ utilities/ovn-trace.8.xml \ utilities/ovn-detrace.in \ utilities/ovndb-servers.ocf \ @@ -49,7 +51,9 @@ CLEANFILES += \ utilities/ovn-sbctl.8 \ utilities/ovn-trace.8 \ utilities/ovn-detrace.1 \ - utilities/ovn-detrace + utilities/ovn-detrace \ + utilities/ovn-appctl.8 \ + utilities/ovn-appctl utilities/ovn-lib: $(top_builddir)/config.status @@ -68,4 +72,9 @@ bin_PROGRAMS += utilities/ovn-trace utilities_ovn_trace_SOURCES = utilities/ovn-trace.c utilities_ovn_trace_LDADD = lib/libovn.la $(OVSDB_LIBDIR)/libovsdb.la $(OVS_LIBDIR)/libopenvswitch.la +# ovn-nbctl +bin_PROGRAMS += utilities/ovn-appctl +utilities_ovn_appctl_SOURCES = utilities/ovn-appctl.c +utilities_ovn_appctl_LDADD = lib/libovn.la $(OVSDB_LIBDIR)/libovsdb.la $(OVS_LIBDIR)/libopenvswitch.la + include utilities/bugtool/automake.mk diff --git a/utilities/ovn-appctl.8.xml b/utilities/ovn-appctl.8.xml new file mode 100644 index 000000000..32a42a766 --- /dev/null +++ b/utilities/ovn-appctl.8.xml @@ -0,0 +1,352 @@ +<?xml version="1.0" encoding="utf-8"?> +<manpage program="ovn-appctl" section="8" title="ovn-appctl"> + <h1>Name</h1> + <p>ovn-appctl -- utility for configuring running OVN daemons</p> + + <h1>Synopsis</h1> + <p> + <code> ovn-appctl</code> [--target=target | -t target] + [-T secs | --timeout=secs] <var>command</var> [<var>arg</var>...] + </p> + <p><code>ovn-appctl</code> --help </p> + <p><code>ovn-appctl</code> --version </p> + + <h1>Description</h1> + <p> + OVN daemons accept certain commands at runtime to control their behavior + and query their settings. Every daemon accepts a common set of commands + documented under COMMON COMMANDS below. Some daemons support additional + commands documented in their own manpages. + </p> + + <p> + The <code>ovn-appctl</code> program provides a simple way to invoke + these commands. The command to be sent is specified on + <code>ovn-appctl's</code> command line as non-option arguments. + <code>ovn-appctl</code> sends the command and prints the daemon's + response on standard output. + </p> + + <p> + <code>ovn-ctl</code> is exactly similar to Open vSwitch + <code>ovs-appctl</code> utility. + </p> + + <h1>Command Commands</h1> + <p> + Every OVN daemon supports a common set of commands, which are documented + in this section. + </p> + + <h2>General Commands</h2> + <p> + These commands display daemon-specific commands and the running version. + Note that these commands are different from the --help and --version + options that return information about the <code>ovn-appctl</code> + utility itself. + </p> + + <dl> + <dt><code>list-commands</code></dt> + <dd> + Lists the commands supported by the target. + </dd> + + <dt><code>version</code></dt> + <dd> + Displays the version and compilation date of the target. + </dd> + </dl> + + <h2>Logging Commands</h2> + <p> + OVN has several log levels. The highest-severity log level is: + </p> + + <dl> + <dt><code>off</code></dt> + <dd> + No message is ever logged at this level, so setting a logging + destination's log level to off disables logging to that + destination. + </dd> + </dl> + + <p> + The following log levels, in order of descending severity, are + available: + </p> + + <dl> + <dt><code>emer</code></dt> + <dd> + A major failure forced a process to abort. + </dd> + + <dt><code>err</code></dt> + <dd> + A high-level operation or a subsystem failed. Attention is warranted. + </dd> + + <dt><code>warn</code></dt> + <dd> + A low-level operation failed, but higher-level subsystems may be able + to recover. + </dd> + + <dt><code>info</code></dt> + <dd> + Information that may be useful in retrospect when investigating a + problem. + </dd> + + <dt><code>dbg</code></dt> + <dd> + Information useful only to someone with intricate knowledge of the + system, or that would commonly cause too-voluminous log output. + Log messages at this level are not logged by default. + </dd> + </dl> + + <p> + Every OVN daemon supports the following commands for examining and + adjusting log levels. + </p> + + <dl> + <dt><code>vlog/list</code></dt> + <dd> + Lists the known logging modules and their current levels. + </dd> + + <dt><code>vlog/list-pattern</code></dt> + <dd> + Lists logging pattern used for each destination. + </dd> + + <dt><code>vlog/set <var>[spec]</var></code></dt> + <dd> + Sets logging levels. Without any spec, sets the log level for every + module and destination to dbg. Otherwise, spec is a list of words + separated by spaces or commas or colons, up to one from each + category below: + <ul> + <li> + A valid module name, as displayed by the vlog/list command on + ovn-appctl(8), limits the log level change to the specified module. + </li> + + <li> + <p> + <code>syslog</code>, <code>console</code>, or <code>file</code>, + to limit the log level change to only to the system log, to the + console, or to a file, respectively. + </p> + + <p> + On Windows platform, <code>syslog</code> is accepted as a word + and is only useful if the target was started with the + <code>--syslog-target</code> option (the word has no effect + otherwise). + </p> + </li> + + <li> + <code>off</code>, <code>emer</code>, <code>err</code>, + <code>warn</code>, <code>info</code>, or <code>dbg</code>, to + control the log level. Messages of the given severity or higher + will be logged, and messages of lower severity will be filtered + out. <code>off</code> filters out all messages. + </li> + </ul> + + <p> + Case is not significant within <var>spec</var>. + </p> + </dd> + + <dt> + <code>vlog/set PATTERN</code>:<var>destination</var>: + <var>pattern</var> + </dt> + <dd> + Sets the log pattern for <var>destination</var> to <var>pattern</var>. + Each time a message is logged to destination, pattern determines the + message's formatting. Most characters in pattern are copied literally + to the log, but special escapes beginning with <code>%</code> are + expanded as follows: + + <ul> + <li> + <code>%A</code> : The name of the application logging the + message, e.g. ovn-controller. + </li> + + <li> + <code>%B</code> : The RFC5424 syslog PRI of the message. + </li> + + <li> + <code>%c</code> : The name of the module + (as shown by ovn-appctl --list) logging the message. + </li> + + <li> + <code>%d</code> : The current date and time in ISO 8601 format + (YYYY-MM-DD HH:MM:SS). + </li> + + <li> + <code>%d<var>{format}</var></code> : The current date and time in + the specified format, which takes the same format as the template + argument to strftime(3). As an extension, any # characters in + format will be replaced by fractional seconds, e.g. use + <code>%H:%M:%S.###</code> for the time to the nearest millisecond. + Sub-second times are only approximate and currently decimal places + after the third will always be reported as zero. + </li> + + <li> + <code>%D</code> : The current UTC date and time in ISO 8601 format + <code>(YYYY-MM-DD HH:MM:SS)</code>. + </li> + + <li> + <code>%D<var>{format}</var></code> : The current UTC date and time + in the specified format, which takes the same format as the + template argument to strftime(3). Supports the same extension for + sub-second resolution as <code>%d{...}</code>. + </li> + + <li> + <code>%E</code> : The hostname of the node running the application. + </li> + + <li> + <code>%m</code> : The message being logged. + </li> + + <li> + <code>%N</code> : A serial number for this message within this run + of the program, as a decimal number. The first message a program + logs has serial number 1, the second one has serial number 2, + and so on. + </li> + + <li> + <code>%n</code> : A new-line. + </li> + + <li> + <code>%p</code> : The level at which the message is logged, e.g. + <code>DBG</code>. + </li> + + <li> + <code>%P</code> : The program's process ID (pid), as a decimal + number. + </li> + + <li> + <code>%r</code> : The number of milliseconds elapsed from the start + of the application to the time the message was logged. + </li> + + <li> + <code>%t</code> : The subprogram name, that is, an identifying name + for the process or thread that emitted the log message, such as + monitor for the process used for --monitor or main for the primary + process or thread in a program. + </li> + + <li> + <code>%T</code> : The subprogram name enclosed in parentheses, e.g. + (monitor), or the empty string for the primary process or thread in + a program. + </li> + + <li> + <code>%%</code> : A literal %. + </li> + </ul> + + <p> + A few options may appear between the % and the format specifier + character, in this order: + </p> + + <ul> + <li> + <code>-</code> : Left justify the escape's expansion within its field + width. Right justification is the default. + </li> + + <li> + <code>-</code> : Pad the field to the field width with 0s. Padding + with spaces is the default. + </li> + </ul> + + <p> + <var>width</var> A number specifies the minimum field width. If the + escape expands to fewer characters than width then it is padded to + fill the field width. (A field wider than width is not truncated to + fit.) + </p> + + <p> + The default pattern for console and file output is + <code>%D{%Y-%m-%dT %H:%M:%SZ}|%05N|%c|%p|%m;</code> for syslog + output, <code>%05N|%c|%p|%m</code>. + </p> + </dd> + + <dt><code>vlog/set FACILITY:<var>facility</var></code></dt> + <dd> + Sets the RFC5424 facility of the log message. facility can be one of + <code>kern</code>, <code>user</code>, <code>mail</code>, + <code>daemon</code>, <code>auth</code>, <code>syslog</code>, + <code>lpr</code>, <code>news</code>, <code>uucp</code>, + <code>clock</code>, <code>ftp</code>, <code>ntp</code>, + <code>audit</code>, <code>alert</code>, <code>clock2</code>, + <code>local0</code>, <code>local1</code>, <code>local2</code>, + <code>local3</code>, <code>local4</code>, <code>local5</code>, + <code>local6</code> or <code>local7</code>. + </dd> + + <dt><code>vlog/close</code></dt> + <dd> + Causes the daemon to close its log file, if it is open. + (Use <code>vlog/reopen</code> to reopen it later.) + </dd> + + <dt><code>vlog/reopen</code></dt> + <dd> + <p> + Causes the daemon to close its log file, if it is open, and then + reopen it. (This is useful after rotating log files, to cause a + new log file to be used.) + </p> + + <p> + This has no effect if the target application was not invoked + with the <code>--log-file</code> option. + </p> + </dd> + </dl> + + <h1>Options</h1> + <dl> + <dt><code>-h</code></dt> + <dt><code>--help</code></dt> + <dd> + Prints a brief help message to the console. + </dd> + + <dt><code>-V</code></dt> + <dt><code>--version</code></dt> + <dd> + Prints version information to the console. + </dd> + </dl> +</manpage> \ No newline at end of file diff --git a/utilities/ovn-appctl.c b/utilities/ovn-appctl.c new file mode 100644 index 000000000..3a80a1e3b --- /dev/null +++ b/utilities/ovn-appctl.c @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2019 Nicira, Inc. + * + * 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 <errno.h> +#include <getopt.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#include "command-line.h" +#include "daemon.h" +#include "lib/ovn-dirs.h" +#include "openvswitch/dynamic-string.h" +#include "jsonrpc.h" +#include "process.h" +#include "timeval.h" +#include "unixctl.h" +#include "util.h" +#include "openvswitch/vlog.h" + +static void usage(void); +static const char *parse_command_line(int argc, char *argv[]); +static struct jsonrpc *connect_to_target(const char *target); + +int +main(int argc, char *argv[]) +{ + char *cmd_result, *cmd_error; + struct jsonrpc *client; + char *cmd, **cmd_argv; + const char *target; + int cmd_argc; + int error; + + set_program_name(argv[0]); + + /* Parse command line and connect to target. */ + target = parse_command_line(argc, argv); + client = connect_to_target(target); + + /* Transact request and process reply. */ + cmd = argv[optind++]; + cmd_argc = argc - optind; + cmd_argv = cmd_argc ? argv + optind : NULL; + error = unixctl_client_transact(client, cmd, cmd_argc, cmd_argv, + &cmd_result, &cmd_error); + if (error) { + ovs_fatal(error, "%s: transaction error", target); + } + + if (cmd_error) { + jsonrpc_close(client); + fputs(cmd_error, stderr); + ovs_error(0, "%s: server returned an error", target); + exit(2); + } else if (cmd_result) { + fputs(cmd_result, stdout); + } else { + OVS_NOT_REACHED(); + } + + jsonrpc_close(client); + free(cmd_result); + free(cmd_error); + return 0; +} + +static void +usage(void) +{ + printf("\ +%s, for querying and controlling OVN daemon\n\ +usage: %s [TARGET] COMMAND [ARG...]\n\ +Targets:\n\ + -t, --target=TARGET pidfile or socket to contact\n\ +Common commands:\n\ + list-commands List commands supported by the target\n\ + version Print version of the target\n\ + vlog/list List current logging levels\n\ + vlog/list-pattern List logging patterns for each destination.\n\ + vlog/set [SPEC]\n\ + Set log levels as detailed in SPEC, which may include:\n\ + A valid module name (all modules, by default)\n\ + 'syslog', 'console', 'file' (all destinations, by default))\n\ + 'off', 'emer', 'err', 'warn', 'info', or 'dbg' ('dbg', bydefault)\n\ + vlog/reopen Make the program reopen its log file\n\ +Other options:\n\ + --timeout=SECS wait at most SECS seconds for a response\n\ + -h, --help Print this helpful information\n\ + -V, --version Display ovs-appctl version information\n", + program_name, program_name); + exit(EXIT_SUCCESS); +} + +static const char * +parse_command_line(int argc, char *argv[]) +{ + enum { + OPT_START = UCHAR_MAX + 1, + VLOG_OPTION_ENUMS + }; + static const struct option long_options[] = { + {"target", required_argument, NULL, 't'}, + {"execute", no_argument, NULL, 'e'}, + {"help", no_argument, NULL, 'h'}, + {"option", no_argument, NULL, 'o'}, + {"version", no_argument, NULL, 'V'}, + {"timeout", required_argument, NULL, 'T'}, + VLOG_LONG_OPTIONS, + {NULL, 0, NULL, 0}, + }; + char *short_options_ = + ovs_cmdl_long_options_to_short_options(long_options); + char *short_options = xasprintf("+%s", short_options_); + const char *target; + int e_options; + unsigned int timeout = 0; + + target = NULL; + e_options = 0; + for (;;) { + int option; + + option = getopt_long(argc, argv, short_options, long_options, NULL); + if (option == -1) { + break; + } + switch (option) { + case 't': + if (target) { + ovs_fatal(0, "-t or --target may be specified only once"); + } + target = optarg; + break; + + case 'e': + /* We ignore -e for compatibility. Older versions specified the + * command as the argument to -e. Since the current version takes + * the command as non-option arguments and we say that -e has no + * arguments, this just works in the common case. */ + if (e_options++) { + ovs_fatal(0, "-e or --execute may be speciifed only once"); + } + break; + + case 'h': + usage(); + break; + + case 'o': + ovs_cmdl_print_options(long_options); + exit(EXIT_SUCCESS); + + case 'T': + if (!str_to_uint(optarg, 10, &timeout) || !timeout) { + ovs_fatal(0, "value %s on -T or --timeout is invalid", optarg); + } + break; + + case 'V': + ovs_print_version(0, 0); + exit(EXIT_SUCCESS); + + VLOG_OPTION_HANDLERS + + case '?': + exit(EXIT_FAILURE); + + default: + OVS_NOT_REACHED(); + } + } + free(short_options_); + free(short_options); + + ctl_timeout_setup(timeout); + + if (optind >= argc) { + ovs_fatal(0, "at least one non-option argument is required " + "(use --help for help)"); + } + + return target ? target : "ovn-controller"; +} + +static struct jsonrpc * +connect_to_target(const char *target) +{ + struct jsonrpc *client; + char *socket_name; + int error; + +#ifndef _WIN32 + if (target[0] != '/') { + char *pidfile_name; + pid_t pid; + + pidfile_name = xasprintf("%s/%s.pid", ovn_rundir(), target); + pid = read_pidfile(pidfile_name); + if (pid < 0) { + ovs_fatal(-pid, "cannot read pidfile \"%s\"", pidfile_name); + } + free(pidfile_name); + socket_name = xasprintf("%s/%s.%ld.ctl", + ovn_rundir(), target, (long int) pid); +#else + /* On windows, if the 'target' contains ':', we make an assumption that + * it is an absolute path. */ + if (!strchr(target, ':')) { + socket_name = xasprintf("%s/%s.ctl", ovn_rundir(), target); +#endif + } else { + socket_name = xstrdup(target); + } + + error = unixctl_client_create(socket_name, &client); + if (error) { + ovs_fatal(error, "cannot connect to \"%s\"", socket_name); + } + free(socket_name); + + return client; +} + diff --git a/utilities/ovn-ctl b/utilities/ovn-ctl index c955aa177..4242cd2c8 100755 --- a/utilities/ovn-ctl +++ b/utilities/ovn-ctl @@ -44,13 +44,13 @@ pidfile_is_running () { stop_nb_ovsdb() { if pidfile_is_running $DB_NB_PID; then - ovs-appctl -t $OVN_RUNDIR/ovnnb_db.ctl exit + ovn-appctl -t $OVN_RUNDIR/ovnnb_db.ctl exit fi } stop_sb_ovsdb() { if pidfile_is_running $DB_SB_PID; then - ovs-appctl -t $OVN_RUNDIR/ovnsb_db.ctl exit + ovn-appctl -t $OVN_RUNDIR/ovnsb_db.ctl exit fi } @@ -65,8 +65,8 @@ demote_ovnnb() { fi if test -e $ovnnb_active_conf_file; then - ovs-appctl -t $OVN_RUNDIR/ovnnb_db.ctl ovsdb-server/set-active-ovsdb-server `cat $ovnnb_active_conf_file` - ovs-appctl -t $OVN_RUNDIR/ovnnb_db.ctl ovsdb-server/connect-active-ovsdb-server + ovn-appctl -t $OVN_RUNDIR/ovnnb_db.ctl ovsdb-server/set-active-ovsdb-server `cat $ovnnb_active_conf_file` + ovn-appctl -t $OVN_RUNDIR/ovnnb_db.ctl ovsdb-server/connect-active-ovsdb-server else echo >&2 "$0: active server details not set" exit 1 @@ -79,8 +79,8 @@ demote_ovnsb() { fi if test -e $ovnsb_active_conf_file; then - ovs-appctl -t $OVN_RUNDIR/ovnsb_db.ctl ovsdb-server/set-active-ovsdb-server `cat $ovnsb_active_conf_file` - ovs-appctl -t $OVN_RUNDIR/ovnsb_db.ctl ovsdb-server/connect-active-ovsdb-server + ovn-appctl -t $OVN_RUNDIR/ovnsb_db.ctl ovsdb-server/set-active-ovsdb-server `cat $ovnsb_active_conf_file` + ovn-appctl -t $OVN_RUNDIR/ovnsb_db.ctl ovsdb-server/connect-active-ovsdb-server else echo >&2 "$0: active server details not set" exit 1 @@ -89,12 +89,12 @@ demote_ovnsb() { promote_ovnnb() { rm -f $ovnnb_active_conf_file - ovs-appctl -t $OVN_RUNDIR/ovnnb_db.ctl ovsdb-server/disconnect-active-ovsdb-server + ovn-appctl -t $OVN_RUNDIR/ovnnb_db.ctl ovsdb-server/disconnect-active-ovsdb-server } promote_ovnsb() { rm -f $ovnsb_active_conf_file - ovs-appctl -t $OVN_RUNDIR/ovnsb_db.ctl ovsdb-server/disconnect-active-ovsdb-server + ovn-appctl -t $OVN_RUNDIR/ovnsb_db.ctl ovsdb-server/disconnect-active-ovsdb-server } start_ovsdb__() { @@ -274,7 +274,7 @@ start_ovsdb () { } sync_status() { - ovs-appctl -t $OVN_RUNDIR/ovn${1}_db.ctl ovsdb-server/sync-status | awk '{if(NR==1) print $2}' + ovn-appctl -t $OVN_RUNDIR/ovn${1}_db.ctl ovsdb-server/sync-status | awk '{if(NR==1) print $2}' } status_ovnnb() {