[ovs-dev] [PATCH] Make ovs-appctl easier to use and synchronize its interface with ovs-vsctl.

Ben Pfaff blp at nicira.com
Thu Sep 17 18:26:46 UTC 2009


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.
---
 INSTALL.Linux                       |   10 +-
 debian/openvswitch-switch.logrotate |    2 +-
 lib/unixctl.c                       |    2 +-
 lib/vlog-unixctl.man                |    4 +-
 lib/vlog.man                        |    4 +-
 utilities/ovs-appctl.8.in           |  116 +++++++++--------
 utilities/ovs-appctl.c              |  249 +++++++++++++++--------------------
 utilities/ovs-vsctl.8.in            |   33 ++---
 utilities/ovs-vsctl.in              |   13 +-
 vswitchd/ovs-brcompatd.8.in         |    6 +-
 vswitchd/ovs-brcompatd.c            |    5 +-
 xenserver/etc_init.d_vswitch        |    9 +-
 12 files changed, 201 insertions(+), 252 deletions(-)

diff --git a/INSTALL.Linux b/INSTALL.Linux
index 9767f99..b6734ba 100644
--- a/INSTALL.Linux
+++ b/INSTALL.Linux
@@ -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-vswitch to finish
+reloading before it exits.
 
 Bug Reporting
 -------------
diff --git a/debian/openvswitch-switch.logrotate b/debian/openvswitch-switch.logrotate
index a45cc2a..3da57e0 100644
--- a/debian/openvswitch-switch.logrotate
+++ b/debian/openvswitch-switch.logrotate
@@ -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
 }
diff --git a/lib/unixctl.c b/lib/unixctl.c
index 7d6fdd6..a890a62 100644
--- a/lib/unixctl.c
+++ b/lib/unixctl.c
@@ -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. */
diff --git a/lib/vlog-unixctl.man b/lib/vlog-unixctl.man
index 5c79875..86eece3 100644
--- a/lib/vlog-unixctl.man
+++ b/lib/vlog-unixctl.man
@@ -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.
diff --git a/lib/vlog.man b/lib/vlog.man
index 0bd8a26..8827931 100644
--- a/lib/vlog.man
+++ b/lib/vlog.man
@@ -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]
diff --git a/utilities/ovs-appctl.8.in b/utilities/ovs-appctl.8.in
index d5e6b82..8d159fc 100644
--- a/utilities/ovs-appctl.8.in
+++ b/utilities/ovs-appctl.8.in
@@ -4,58 +4,65 @@
 .  ns
 .  IP "\\$1"
 ..
-.TH ovs\-appctl 8 "April 2009" "Open vSwitch" "Open vSwitch Manual"
+.TH ovs\-appctl 8 "September 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 \fIpid\fR | \fB--target=\fIpid\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 at RUNDIR@\fR.
-
-Each Open vSwitch daemon by default creates a socket named
-\fB at 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 at RUNDIR@/\fIprogram\fB.\fIpid\fR.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 at 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 at 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 at RUNDIR@/\fItarget\fR.\fIpid\fR.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.
+.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,25 +145,24 @@ 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"
 
 .BR ovs\-controller (8),
diff --git a/utilities/ovs-appctl.c b/utilities/ovs-appctl.c
index 9349662..e81547d 100644
--- a/utilities/ovs-appctl.c
+++ b/utilities/ovs-appctl.c
@@ -13,193 +13,118 @@
  * 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:"
+           "  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'},
         {"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;
 
-    set_program_name(argv[0]);
-    time_init();
-
-    short_options = long_options_to_short_options(long_options);
+    target = NULL;
     for (;;) {
         int option;
-        size_t i;
 
-        option = getopt_long(argc, argv, short_options, long_options, NULL);
+        option = getopt_long(argc, argv, "+t:hV", 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);
-            }
-            break;
-
-        case 'e':
-            for (i = 0; i < n_clients; i++) {
-                execute_command(clients[i], optarg, &ok);
+            if (target) {
+                ovs_fatal(0, "-t or --target may be specified only once");
             }
+            target = optarg;
             break;
 
         case 'h':
-            usage(argv[0], EXIT_SUCCESS);
+            usage();
             break;
 
         case 'V':
@@ -213,9 +138,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)");
     }
-    exit(ok ? 0 : 1);
+
+    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);
+    }
+    free(socket_name);
+
+    return client;
+}
+
diff --git a/utilities/ovs-vsctl.8.in b/utilities/ovs-vsctl.8.in
index b70f6c8..cd383c4 100644
--- a/utilities/ovs-vsctl.8.in
+++ b/utilities/ovs-vsctl.8.in
@@ -66,27 +66,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 at 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 at 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 at RUNDIR@/ovs\-vswitchd.\fIpid\fR.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 at 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 at RUNDIR@/\fItarget\fR.\fIpid\fR.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 at RUNDIR@/\fR is
-implicitly prefixed to it.
+The default target is \fBovs\-vswitchd\fR.
 .IP
 If neither \fB\-t\fR nor \fB\-\-target\fR is specified, the default target is
 \fB at RUNDIR@/ovs\-vswitchd.pid\fR.
diff --git a/utilities/ovs-vsctl.in b/utilities/ovs-vsctl.in
index 675f9dd..7270d01 100755
--- a/utilities/ovs-vsctl.in
+++ b/utilities/ovs-vsctl.in
@@ -30,7 +30,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
@@ -119,11 +119,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)
@@ -299,7 +298,7 @@ A bond is considered to consist of interfaces.
 General options:
   -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
@@ -462,8 +461,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
diff --git a/vswitchd/ovs-brcompatd.8.in b/vswitchd/ovs-brcompatd.8.in
index cd911ca..e1d448d 100644
--- a/vswitchd/ovs-brcompatd.8.in
+++ b/vswitchd/ovs-brcompatd.8.in
@@ -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
diff --git a/vswitchd/ovs-brcompatd.c b/vswitchd/ovs-brcompatd.c
index d351c05..190dcc3 100644
--- a/vswitchd/ovs-brcompatd.c
+++ b/vswitchd/ovs-brcompatd.c
@@ -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;
 
diff --git a/xenserver/etc_init.d_vswitch b/xenserver/etc_init.d_vswitch
index e63a001..7713b4f 100755
--- a/xenserver/etc_init.d_vswitch
+++ b/xenserver/etc_init.d_vswitch
@@ -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
-- 
1.6.3.3





More information about the dev mailing list