Make ovs-appctl easier to use and synchronize its interface with ovs-vsctl.
authorBen Pfaff <blp@nicira.com>
Mon, 9 Nov 2009 22:46:38 +0000 (14:46 -0800)
committerBen Pfaff <blp@nicira.com>
Mon, 9 Nov 2009 22:46:38 +0000 (14:46 -0800)
It is inconvenient to type the whole path to the Unix daemon socket when
using ovs-appctl.  Allow the name of the daemon to be used instead when
a pidfile exists in the default location, and contact ovs-vswitchd by
default.

Also, the various options for manipulating vlog were invented before the
general-purpose command mechanism existed.  Get rid of all of the action
options in favor of just specifying the command to be executed as
non-option arguments.

Finally, there simply wasn't much value in allowing multiple targets or
options to be specified; these variations were never used in practice.  So
simplify the interface by making it one target, one action per invocation.

Also, make ovs-vsctl use the same syntax for its --target option.

Based on work by Justin Pettit.

12 files changed:
INSTALL.Linux
debian/openvswitch-switch.logrotate
lib/unixctl.c
lib/vlog-unixctl.man
lib/vlog.man
utilities/ovs-appctl.8.in
utilities/ovs-appctl.c
utilities/ovs-vsctl.8.in
utilities/ovs-vsctl.in
vswitchd/ovs-brcompatd.8.in
vswitchd/ovs-brcompatd.c
xenserver/etc_init.d_vswitch

index 9767f99..38b0269 100644 (file)
@@ -156,14 +156,12 @@ respectively.
 
 At runtime, you may make ovs-vswitchd reload its configuration file
 and update its configuration accordingly by sending it a SIGHUP
-signal.  The ovs-appctl utility can also be used to do this with a
-command such as:
+signal.  The ovs-appctl utility can also be used to do this:
 
-    % ovs-appctl -t <pid> -e vswitchd/reload
+    % ovs-appctl vswitchd/reload
 
-where <pid> is ovs-vswitchd's process ID.  In the latter case,
-ovs-appctl will not exit until the reload and reconfiguration is
-complete.
+In the latter case, ovs-appctl will wait for ovs-vswitchd to finish
+reloading before it exits.
 
 Bug Reporting
 -------------
index a45cc2a..3da57e0 100644 (file)
@@ -6,6 +6,6 @@
         missingok
         rotate 30
         postrotate
-                ovs-appctl --target /var/run/ovs-openflowd.pid --reopen
+                ovs-appctl --target=ovs-openflowd vlog/reopen
         endscript
 }
index e774ffe..164a7db 100644 (file)
@@ -168,7 +168,7 @@ unixctl_command_reply(struct unixctl_conn *conn,
  * A program that (optionally) daemonizes itself should call this function
  * *after* daemonization, so that the socket name contains the pid of the
  * daemon instead of the pid of the program that exited.  (Otherwise,
- * "ovs-appctl --target <program>.pid" will fail.)
+ * "ovs-appctl --target=<program>" will fail.)
  *
  * Returns 0 if successful, otherwise a positive errno value.  If successful,
  * sets '*serverp' to the new unixctl_server, otherwise to NULL. */
index 5c79875..86eece3 100644 (file)
@@ -7,7 +7,7 @@ Sets the logging level for \fImodule\fR in \fIfacility\fR to
 .RS
 .IP \(bu
 \fImodule\fR may be any valid module name (as displayed by the
-\fB--list\fR action on \fBovs-appctl\fR(8)), or the special name
+\fB--list\fR action on \fBovs\-appctl\fR(8)), or the special name
 \fBANY\fR to set the logging levels for all modules.
 .
 .IP \(bu
@@ -26,7 +26,7 @@ logged.  If it is omitted, \fIlevel\fR defaults to \fBdbg\fR.
 .RE
 .IP "\fBvlog/set PATTERN:\fIfacility\fB:\fIpattern\fR"
 Sets the log pattern for \fIfacility\fR to \fIpattern\fR.  Refer to
-\fBovs-appctl\fR(8) for a description of the valid syntax for \fIpattern\fR.
+\fBovs\-appctl\fR(8) for a description of the valid syntax for \fIpattern\fR.
 .
 .IP "\fBvlog/list\fR"
 Lists the supported logging modules and their current levels.
index 0bd8a26..8827931 100644 (file)
@@ -7,7 +7,7 @@ Sets the logging level for \fImodule\fR in \fIfacility\fR to
 .RS
 .IP \(bu
 \fImodule\fR may be any valid module name (as displayed by the
-\fB--list\fR action on \fBovs-appctl\fR(8)), or the special name
+\fB--list\fR action on \fBovs\-appctl\fR(8)), or the special name
 \fBANY\fR to set the logging levels for all modules.
 
 .IP \(bu
@@ -35,7 +35,7 @@ Sets the maximum logging verbosity level, equivalent to
 .TP
 \fB-vPATTERN:\fIfacility\fB:\fIpattern\fR, \fB--verbose=PATTERN:\fIfacility\fB:\fIpattern\fR
 Sets the log pattern for \fIfacility\fR to \fIpattern\fR.  Refer to
-\fBovs-appctl\fR(8) for a description of the valid syntax for \fIpattern\fR.
+\fBovs\-appctl\fR(8) for a description of the valid syntax for \fIpattern\fR.
 
 .TP
 \fB--log-file\fR[\fB=\fIfile\fR]
index 61ce4d4..4ad20f2 100644 (file)
@@ -4,58 +4,65 @@
 .  ns
 .  IP "\\$1"
 ..
-.TH ovs\-appctl 8 "April 2009" "Open vSwitch" "Open vSwitch Manual"
+.TH ovs\-appctl 8 "November 2009" "Open vSwitch" "Open vSwitch Manual"
 .ds PN ovs\-appctl
 
 .SH NAME
 ovs\-appctl \- utility for configuring running Open vSwitch daemons
 
 .SH SYNOPSIS
-\fBovs\-appctl\fR [\fB-h\fR | \fB--help\fR] [\fItarget\fR...] [\fIaction\fR...]
-.sp 1
-The available \fItarget\fR options are:
+\fBovs\-appctl\fR [\fB--target=\fItarget\fR | \fB-t\fR \fItarget\fR]
+\fIcommand \fR[\fIarg\fR...]
 .br
-[\fB-t\fR \fIsocket\fR | \fB--target=\fIsocket\fR]
-.sp 1
-The available \fIaction\fR options are:
+\fBovs\-appctl\fR --help
 .br
-[\fB-l\fR | \fB--list\fR] [\fB-s\fR
-\fImodule\fR[\fB:\fIfacility\fR[\fB:\fIlevel\fR]] |
-\fB--set=\fImodule\fR[\fB:\fIfacility\fR[\fB:\fIlevel\fR]]]
-[\fB-r\fR | \fB--reopen\fR]
-[\fB-e\fR | \fB--execute=\fIcommand\fR]
-
+\fBovs\-appctl\fR --version
 .SH DESCRIPTION
-The \fBovs\-appctl\fR program connects to one or more running
-Open vSwitch daemons (such as \fBovs\-vswitchd\fR(8)), as specified by the
-user, and sends them commands to query or modify their behavior.
-Its primary purpose is currently to adjust daemons' logging levels.
-
-\fBovs\-appctl\fR applies one or more actions to each of one or more
-target processes.  Targets may be specified using:
-
-.IP "\fB-t \fIsocket\fR"
-.IQ "\fB--target=\fIsocket\fR"
-The specified \fIsocket\fR must be the name of a Unix domain socket
-for a \fBovs\-appctl\fR-controllable process.  If \fIsocket\fR does not
-begin with \fB/\fR, it is treated as relative to \fB@RUNDIR@\fR.
-
-Each Open vSwitch daemon by default creates a socket named
-\fB@RUNDIR@/\fIprogram\fB.\fIpid\fB.ctl\fR, where \fIprogram\fR is
-the program's name (such as \fBovs\-vswitchd\fR) and \fIpid\fR is the
-daemon's PID.
-
-.PP
-The available actions are:
-
-.IP "\fB-l\fR"
-.IQ "\fB--list\fR"
-Print the list of known logging modules and their current levels to
-stdout.
-
-.IP "\fB-s\fR \fImodule\fR[\fB:\fIfacility\fR[\fB:\fIlevel\fR]]"
-.IQ "\fB--set=\fImodule\fR[\fB:\fIfacility\fR[\fB:\fIlevel\fR]]"
-
+Open vSwitch daemons accept certain commands at runtime to control
+their behavior and query their settings.  Every daemon accepts the
+commands for querying and adjusting its logging settings documented
+under \fBLOGGING COMMANDS\fR below, and \fBovs\-vswitchd\fR in
+particular accepts a number of additional commands documented in
+\fBovs\-vswitchd\fR(8).
+
+The \fBovs\-appctl\fR program provides a simple way to invoke these
+commands.  The command to be sent is specified on \fBovs\-appctl\fR's
+command line as non-option arguments.  \fBovs\-appctl\fR sends the
+command and prints the daemon's response on standard output.
+
+In normal use only a single option is accepted:
+
+.IP "\fB\-t \fItarget\fR"
+.IQ "\fB\-\-target=\fItarget\fR"
+Tells \fBovs\-appctl\fR which daemon to contact.
+.IP
+If \fItarget\fR begins with \fB/\fR it must name a Unix domain socket
+on which an Open vSwitch daemon is listening for control channel
+connections.  By default, each daemon listens on a Unix domain socket
+named \fB@RUNDIR@/\fIprogram\fB.\fIpid\fB.ctl\fR, where \fIprogram\fR
+is the program's name and \fIpid\fR is its process ID.  For example,
+if \fBovs-vswitchd\fR has PID 123, it would listen on
+\fB@RUNDIR@/ovs-vswitchd.123.ctl\fR.
+.IP
+Otherwise, \fBovs\-appctl\fR looks for a pidfile, that is, a file
+whose contents are the process ID of a running process as a decimal
+number, named \fB@RUNDIR@/\fItarget\fB.pid\fR.  (The \fB\-\-pidfile\fR
+option makes an Open vSwitch daemon create a pidfile.)
+\fBovs\-appctl\fR reads the pidfile, then looks for a Unix socket
+named \fB@RUNDIR@/\fItarget\fB.\fIpid\fB.ctl\fR, where \fIpid\fR is
+replaced by the process ID read from the pidfile, and uses that file
+as if it had been specified directly as the target.
+.IP
+The default target is \fBovs\-vswitchd\fR.
+.
+.SH LOGGING COMMANDS
+Every Open vSwitch daemon supports the following commands for
+examining and adjusting log levels.
+.
+.IP "\fBvlog/list\fR"
+Lists the known logging modules and their current levels.
+.
+.IP "\fBvlog/set\fR \fImodule\fR[\fB:\fIfacility\fR[\fB:\fIlevel\fR]]"
 Sets the logging level for \fImodule\fR in \fIfacility\fR to
 \fIlevel\fR.  The \fImodule\fR may be any valid module name (as
 displayed by the \fB--list\fR option) or the special name \fBANY\fR to
@@ -67,10 +74,8 @@ logging levels for both facilities.  If it is omitted,
 \fBemer\fR, \fBerr\fR, \fBwarn\fR, \fBinfo\fR, or \fBdbg\fR, designating the
 minimum severity of a message for it to be logged.  If it is omitted,
 \fIlevel\fR defaults to \fBdbg\fR.
-
-.IP "\fB-s PATTERN:\fIfacility\fB:\fIpattern\fR"
-.IQ "\fB--set=PATTERN:\fIfacility\fB:\fIpattern\fR"
-
+.
+.IP "\fBvlog/set PATTERN:\fIfacility\fB:\fIpattern\fR"
 Sets the log pattern for \fIfacility\fR to \fIpattern\fR.  Each time a
 message is logged to \fIfacility\fR, \fIpattern\fR determines the
 message's formatting.  Most characters in \fIpattern\fR are copied
@@ -140,27 +145,29 @@ width.  (A field wider than \fIwidth\fR is not truncated to fit.)
 The default pattern for console output is \fB%d{%b %d
 %H:%M:%S}|%05N|%c|%p|%m\fR; for syslog output, \fB%05N|%c|%p|%m\fR.
 
-.IP \fB-r\fR
-.IQ \fB--reopen\fR
-Causes the target application to close and reopen its log file.  (This
+.IP "\fBvlog/reopen\fR"
+Causes the daemon to close and reopen its log file.  (This
 is useful after rotating log files, to cause a new log file to be
 used.)
 
 This has no effect if the target application was not invoked with the
 \fB--log-file\fR option.
 
-.IP "\fB-e \fIcommand\fR"
-.IQ "\fB--execute=\fIcommand\fR"
-Passes the specified \fIcommand\fR literally to the target application
-and prints its response to stdout, if successful, or to stderr if an
-error occurs.  Use \fB-e help\fR to print a list of available commands.
-
 .SH OPTIONS
 
 .so lib/common.man
 
+.SH BUGS
+
+The protocol used to speak to Open vSwitch daemons does not contain a
+quoting mechanism, so command arguments should not generally contain
+white space.
+
 .SH "SEE ALSO"
 
+\fBovs\-appctl\fR can control the following daemons:
+.BR ovs\-vswitchd (8),
+.BR ovs\-openflowd (8),
 .BR ovs\-controller (8),
-.BR ovs\-dpctl (8),
-.BR ovs\-openflowd (8)
+.BR ovs\-brcompatd (8),
+.BR ovs\-discover (8).
index 9349662..060e8e2 100644 (file)
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 #include <config.h>
-#include "vlog.h"
 
-#include <dirent.h>
 #include <errno.h>
 #include <getopt.h>
-#include <stdarg.h>
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 
 #include "command-line.h"
-#include "compiler.h"
+#include "daemon.h"
+#include "dirs.h"
+#include "dynamic-string.h"
 #include "timeval.h"
 #include "unixctl.h"
 #include "util.h"
 
-static void
-usage(char *prog_name, int exit_code)
-{
-    printf("Usage: %s [TARGET] [ACTION...]\n"
-           "Targets:\n"
-           "  -t, --target=TARGET  Path to Unix domain socket\n"
-           "Actions:\n"
-           "  -l, --list         List current settings\n"
-           "  -s, --set=MODULE[:FACILITY[:LEVEL]]\n"
-           "        Set MODULE and FACILITY log level to LEVEL\n"
-           "        MODULE may be any valid module name or 'ANY'\n"
-           "        FACILITY may be 'syslog', 'console', 'file', or 'ANY' (default)\n"
-           "        LEVEL may be 'emer', 'err', 'warn', 'info', or 'dbg' (default)\n"
-           "  -r, --reopen       Make the program reopen its log file\n"
-           "  -e, --execute=COMMAND  Execute control COMMAND and print its output\n"
-           "Other options:\n"
-           "  -h, --help         Print this helpful information\n"
-           "  -V, --version      Display version information\n",
-           prog_name);
-    exit(exit_code);
-}
+static void usage(void);
+static const char *parse_command_line(int argc, char *argv[]);
+static struct unixctl_client *connect_to_target(const char *target);
 
-static char *
-transact(struct unixctl_client *client, const char *request, bool *ok)
+int
+main(int argc, char *argv[])
 {
-    int code;
+    struct unixctl_client *client;
+    const char *target;
+    struct ds request;
+    int code, error;
     char *reply;
-    int error = unixctl_client_transact(client, request, &code, &reply);
-    if (error) {
-        fprintf(stderr, "%s: transaction error: %s\n",
-                unixctl_client_target(client), strerror(error));
-        *ok = false;
-        return xstrdup("");
-    } else {
-        if (code / 100 != 2) {
-            fprintf(stderr, "%s: server returned reply code %03d\n",
-                    unixctl_client_target(client), code);
+    int i;
+
+    set_program_name(argv[0]);
+    time_init();
+
+    /* Parse command line and connect to target. */
+    target = parse_command_line(argc, argv);
+    client = connect_to_target(target);
+
+    /* Compose request. */
+    ds_init(&request);
+    for (i = optind; i < argc; i++) {
+        if (i != optind) {
+            ds_put_char(&request, ' ');
         }
-        return reply;
+        ds_put_cstr(&request, argv[i]);
     }
-}
 
-static void
-transact_ack(struct unixctl_client *client, const char *request, bool *ok)
-{
-    free(transact(client, request, ok));
-}
-
-static void
-execute_command(struct unixctl_client *client, const char *request, bool *ok)
-{
-    int code;
-    char *reply;
-    int error = unixctl_client_transact(client, request, &code, &reply);
+    /* Transact request and process reply. */
+    error = unixctl_client_transact(client, ds_cstr(&request), &code, &reply);
     if (error) {
-        fprintf(stderr, "%s: transaction error: %s\n",
-                unixctl_client_target(client), strerror(error));
-        *ok = false;
-    } else {
-        if (code / 100 != 2) {
-            fprintf(stderr, "%s: server returned reply code %03d\n",
-                    unixctl_client_target(client), code);
-            fputs(reply, stderr);
-            *ok = false;
-        } else {
-            fputs(reply, stdout);
-        }
+        ovs_fatal(error, "%s: transaction error", target);
+    }
+    if (code / 100 != 2) {
+        ovs_error(0, "%s: server returned reply code %03d", target, code);
+        exit(2);
     }
+    fputs(reply, stdout);
+
+    return 0;
 }
 
 static void
-add_target(struct unixctl_client ***clients, size_t *n_clients,
-           const char *path, bool *ok)
+usage(void)
 {
-    struct unixctl_client *client;
-    int error = unixctl_client_create(path, &client);
-    if (error) {
-        fprintf(stderr, "Error connecting to \"%s\": %s\n",
-                path, strerror(error));
-        *ok = false;
-    } else {
-        *clients = xrealloc(*clients, sizeof *clients * (*n_clients + 1));
-        (*clients)[*n_clients] = client;
-        ++*n_clients;
-    }
+    printf("%s, for querying and controlling Open vSwitch daemon\n"
+           "usage: %s [TARGET] COMMAND [ARG...]\n"
+           "Targets:\n"
+           "  -t, --target=TARGET  pidfile or socket to contact\n"
+           "Common commands:"
+           "  help               List commands supported by the target\n"
+           "  vlog/list          List current logging levels\n"
+           "  vlog/set MODULE[:FACILITY[:LEVEL]]\n"
+           "        Set MODULE and FACILITY log level to LEVEL\n"
+           "        MODULE may be any valid module name or 'ANY'\n"
+           "        FACILITY may be 'syslog', 'console', 'file', or 'ANY' (default)\n"
+           "        LEVEL may be 'emer', 'err', 'warn', 'info', or 'dbg' (default)\n"
+           "  vlog/reopen        Make the program reopen its log file\n"
+           "Other options:\n"
+           "  -h, --help         Print this helpful information\n"
+           "  -V, --version      Display version information\n",
+           program_name, program_name);
+    exit(EXIT_SUCCESS);
 }
 
-int main(int argc, char *argv[])
+static const char *
+parse_command_line(int argc, char *argv[])
 {
     static const struct option long_options[] = {
-        /* Target options must come first. */
         {"target", required_argument, NULL, 't'},
+        {"execute", no_argument, NULL, 'e'},
         {"help", no_argument, NULL, 'h'},
         {"version", no_argument, NULL, 'V'},
-
-        /* Action options come afterward. */
-        {"list", no_argument, NULL, 'l'},
-        {"set", required_argument, NULL, 's'},
-        {"reopen", no_argument, NULL, 'r'},
-        {"execute", required_argument, NULL, 'e'},
         {0, 0, 0, 0},
     };
-    char *short_options;
-
-    /* Determine targets. */
-    bool ok = true;
-    int n_actions = 0;
-    struct unixctl_client **clients = NULL;
-    size_t n_clients = 0;
+    const char *target;
+    int e_options;
 
-    set_program_name(argv[0]);
-    time_init();
-
-    short_options = long_options_to_short_options(long_options);
+    target = NULL;
+    e_options = 0;
     for (;;) {
         int option;
-        size_t i;
 
-        option = getopt_long(argc, argv, short_options, long_options, NULL);
+        option = getopt_long(argc, argv, "+t:hVe", long_options, NULL);
         if (option == -1) {
             break;
         }
-        if (!strchr("thV", option) && n_clients == 0) {
-            ovs_fatal(0, "no targets specified (use --help for help)");
-        } else {
-            ++n_actions;
-        }
         switch (option) {
         case 't':
-            add_target(&clients, &n_clients, optarg, &ok);
-            break;
-
-        case 'l':
-            for (i = 0; i < n_clients; i++) {
-                struct unixctl_client *client = clients[i];
-                char *reply;
-
-                printf("%s:\n", unixctl_client_target(client));
-                reply = transact(client, "vlog/list", &ok);
-                fputs(reply, stdout);
-                free(reply);
-            }
-            break;
-
-        case 's':
-            for (i = 0; i < n_clients; i++) {
-                struct unixctl_client *client = clients[i];
-                char *request = xasprintf("vlog/set %s", optarg);
-                transact_ack(client, request, &ok);
-                free(request);
-            }
-            break;
-
-        case 'r':
-            for (i = 0; i < n_clients; i++) {
-                struct unixctl_client *client = clients[i];
-                char *request = xstrdup("vlog/reopen");
-                transact_ack(client, request, &ok);
-                free(request);
+            if (target) {
+                ovs_fatal(0, "-t or --target may be specified only once");
             }
+            target = optarg;
             break;
 
         case 'e':
-            for (i = 0; i < n_clients; i++) {
-                execute_command(clients[i], optarg, &ok);
+            /* 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(argv[0], EXIT_SUCCESS);
+            usage();
             break;
 
         case 'V':
@@ -213,9 +152,45 @@ int main(int argc, char *argv[])
             NOT_REACHED();
         }
     }
-    if (!n_actions) {
-        fprintf(stderr,
-                "warning: no actions specified (use --help for help)\n");
+
+    if (optind >= argc) {
+        ovs_fatal(0, "at least one non-option argument is required "
+                  "(use --help for help)");
+    }
+
+    return target ? target : "ovs-vswitchd";
+}
+
+static struct unixctl_client *
+connect_to_target(const char *target)
+{
+    struct unixctl_client *client;
+    char *socket_name;
+    int error;
+
+    if (target[0] != '/') {
+        char *pidfile_name;
+        char *socket_name;
+        pid_t pid;
+
+        pidfile_name = xasprintf("%s/%s.pid", ovs_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",
+                                ovs_rundir, target, (long int) pid);
+    } else {
+        socket_name = xstrdup(target);
+    }
+
+    error = unixctl_client_create(socket_name, &client);
+    if (error) {
+        ovs_fatal(error, "cannot connect to \"%s\"", socket_name);
     }
-    exit(ok ? 0 : 1);
+    free(socket_name);
+
+    return client;
 }
+
index 7f6326e..2eea7fd 100644 (file)
@@ -4,7 +4,7 @@
 .  ns
 .  IP "\\$1"
 ..
-.TH ovs\-vsctl 8 "September 2009" "Open vSwitch" "Open vSwitch Manual"
+.TH ovs\-vsctl 8 "November 2009" "Open vSwitch" "Open vSwitch Manual"
 .ds PN ovs\-vsctl
 .
 .SH NAME
@@ -68,30 +68,24 @@ it bypasses the Open vSwitch configuration file locking protocol.
 .IP "\fB\-t \fItarget\fR"
 .IQ "\fB\-\-target=\fItarget\fR"
 Configures how \fBovs\-vsctl\fR contacts \fBovs\-vswitchd\fR to
-instruct it to reload its configuration file.  The \fItarget\fR takes
-one of two forms:
-.RS
-.IP \(bu
-The name of a Unix domain socket on which \fBovs\-vswitchd\fR is
-listening for control channel connections.  By default,
-\fBovs\-vswitchd\fR listens on a Unix domain socket named
-\fB@RUNDIR@/ovs\-vswitchd.\fIpid\fR.ctl\fR, where \fIpid\fR is the
-\fBovs\-vswitchd\fR process's process ID.
-.IP \(bu
-The name of a pidfile, that is, a file whose contents are the process
-ID of a running process as a decimal number.  \fBovs\-vswitchd\fR
-creates a pidfile if it is invoked with the \fB\-\-pidfile\fR option.
-\fBovs\-vsctl\fR reads the pidfile, then looks for a Unix socket named
-\fB@RUNDIR@/ovs\-vswitchd.\fIpid\fR.ctl\fR, where \fIpid\fR is
+instruct it to reload its configuration file.
+.IP
+If \fItarget\fR begins with \fB/\fR it must name a Unix domain socket
+on which \fBovs\-vswitchd\fR is listening for control channel
+connections.  By default, \fBovs\-vswitchd\fR listens on a Unix domain
+socket named \fB@RUNDIR@/ovs\-vswitchd.\fIpid\fB.ctl\fR, where
+\fIpid\fR is \fBovs\-vswitchd\fR's process ID.
+.IP
+Otherwise, \fBovs\-appctl\fR looks for a pidfile, that is, a file
+whose contents are the process ID of a running process as a decimal
+number, named \fB@RUNDIR@/\fItarget\fB.pid\fR.  (The \fB\-\-pidfile\fR
+option makes an Open vSwitch daemon create a pidfile.)
+\fBovs\-appctl\fR reads the pidfile, then looks for a Unix socket
+named \fB@RUNDIR@/\fItarget\fB.\fIpid\fB.ctl\fR, where \fIpid\fR is
 replaced by the process ID read from \fItarget\fR, and uses that file
 as if it had been specified directly as the target.
-.RE
-.IP
-If \fItarget\fR does not begin with \fB/\fR, then \fB@RUNDIR@/\fR is
-implicitly prefixed to it.
 .IP
-If neither \fB\-t\fR nor \fB\-\-target\fR is specified, the default target is
-\fB@RUNDIR@/ovs\-vswitchd.pid\fR.
+The default target is \fBovs\-vswitchd\fR.
 .IP "\fB\-\-no\-reload\fR"
 Prevents \fBovs\-vsctl\fR from telling \fBovs\-vswitchd\fR to reload
 its configuration file.
index cc9f52b..e5b54c7 100755 (executable)
@@ -31,7 +31,7 @@ if argv0.find('/') >= 0:
 DEFAULT_VSWITCHD_CONF = "@sysconfdir@/ovs-vswitchd.conf"
 VSWITCHD_CONF = DEFAULT_VSWITCHD_CONF
 
-DEFAULT_VSWITCHD_TARGET = "@RUNDIR@/ovs-vswitchd.pid"
+DEFAULT_VSWITCHD_TARGET = "ovs-vswitchd"
 VSWITCHD_TARGET = DEFAULT_VSWITCHD_TARGET
 
 RELOAD_VSWITCHD = True
@@ -159,11 +159,10 @@ def do_cfg_save(cfg, file):
 
 def cfg_reload():
     target = VSWITCHD_TARGET
+    if not target.startswith('/'):
+        pid = read_first_line_of_file('%s/%s.pid' % ('@RUNDIR@', target))
+        target = '%s/%s.%s.ctl' % ('@RUNDIR@', target, pid)
     s = os.stat(target)
-    if stat.S_ISREG(s.st_mode):
-        pid = read_first_line_of_file(target)
-        target = "@RUNDIR@/ovs-vswitchd.%s.ctl" % pid
-        s = os.stat(target)
     if not stat.S_ISSOCK(s.st_mode):
         raise Error("%s is not a Unix domain socket, cannot reload" % target)
     skt = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
@@ -348,7 +347,7 @@ General options:
   --no-syslog                 do not write mesages to syslog
   -c, --config=FILE           set configuration file
                               (default: %(config)s)
-  -t, --target=PIDFILE|SOCKET set ovs-vswitchd target
+  -t, --target=PROGRAM|SOCKET set ovs-vswitchd target
                               (default: %(target)s)
   --no-reload                 do not make ovs-vswitchd reload its configuration
   -h, --help                  display this help message and exit
@@ -552,8 +551,6 @@ def main():
             VSWITCHD_CONF = optarg
         elif opt == "-t" or opt == "--target":
             global VSWITCHD_TARGET
-            if optarg[0] != '/':
-                optarg = '@RUNDIR@/' + optarg
             VSWITCHD_TARGET = optarg
         elif opt == "--no-reload":
             global RELOAD_VSWITCHD
index cd911ca..e1d448d 100644 (file)
@@ -29,10 +29,8 @@ replaced by a single \fB%\fR.  The \fB%\fR character may not otherwise
 appear in \fIcommand\fR.
 .IP
 The commands that are substituted into \fIcommand\fR are those that
-can be listed by passing \fB-e help\fR to \fBovs\-appctl\fR with
-\fBovs\-vswitchd\fR as target.  The command that is substituted may
-include white space-separated arguments, so \fIcommand\fR should include
-shell quotes around \fB%s\fR.
+can be listed by passing \fBhelp\fR to \fBovs\-appctl\fR with
+\fBovs\-vswitchd\fR as target.
 .IP
 \fIcommand\fR must not redirect \fBovs\-appctl\fR's standard output or
 standard error streams, because \fBovs\-brcompatd\fR expects to read
index d4a59c3..99d08c5 100644 (file)
@@ -1165,10 +1165,7 @@ parse_options(int argc, char *argv[])
     char *short_options = long_options_to_short_options(long_options);
     int error;
 
-    appctl_command = xasprintf("%s/ovs-appctl -t "
-                               "%s/ovs-vswitchd.`cat %s/ovs-vswitchd.pid`.ctl "
-                               "-e '%%s'",
-                               ovs_bindir, ovs_rundir, ovs_rundir);
+    appctl_command = xasprintf("%s/ovs-appctl %%s", ovs_bindir);
     for (;;) {
         int c;
 
index 01450ed..09f5d79 100755 (executable)
@@ -105,16 +105,13 @@ function remove_modules {
 
 function reload_vswitchd {
     if [ -f "$VSWITCHD_PIDFILE" ]; then
-        "$appctl" \
-            --target=ovs-vswitchd.$(cat "$VSWITCHD_PIDFILE").ctl \
-            --execute=vswitchd/reload
+        "$appctl" --target=/var/run/ovs-vswitchd.`cat $VSWITCHD_PIDFILE`.ctl vswitchd/reload
     fi
 }
 
 function reload_brcompatd {
     if [ -f "$BRCOMPATD_PIDFILE" ]; then
-        "$appctl" \
-            --target=ovs-brcompatd.$(cat "$BRCOMPATD_PIDFILE").ctl --reopen
+        "$appctl" --target=/var/run/ovs-brcompatd.`cat $BRCOMPATD_PIDFILE`.ctl vlog/reopen
     fi
 }
 
@@ -197,7 +194,7 @@ function start_brcompatd {
         valgrind_opt="valgrind --log-file=$BRCOMPATD_VALGRIND_LOG $BRCOMPATD_VALGRIND_OPT"
         daemonize="n"
     fi
-    appctl_cmd="$appctl -t /var/run/ovs-vswitchd.\`cat $VSWITCHD_PIDFILE\`.ctl -e '%s'"
+    appctl_cmd="$appctl --target=/var/run/ovs-vswitchd.\`cat $VSWITCHD_PIDFILE\`.ctl %s"
     if [ "$daemonize" != "y" ]; then
         # Start in background and force a "success" message
         action "Starting ovs-brcompatd ($strace_opt$valgrind_opt)" true