[ovs-dev] [stress 4/4] Implement stress option framework.

Ethan Jackson ethan at nicira.com
Tue Nov 30 20:42:05 UTC 2010


Looks good to me.

I wonder if we should get the build system to enable the default
stress values.  Seems like a good idea to me.  We should also start
looking for places in the code that might benefit from this kind of
testing.

Ethan

On Mon, Nov 1, 2010 at 4:13 PM, Ben Pfaff <blp at nicira.com> wrote:
> Stress options allow developers testing Open vSwitch to trigger behavior
> that otherwise would occur only in corner cases.  Developers and testers
> can thereby more easily discover bugs that would otherwise manifest only
> rarely or nondeterministically.  Stress options may cause surprising
> behavior even when they do not actually reveal bugs, so they should only be
> enabled as part of testing Open vSwitch.
>
> This commit implements the framework and adds a few example stress options.
>
> This commit started from code written by Andrew Lambeth.
>
> CC: Andrew Lambeth <wal at nicira.com>
> ---
>  AUTHORS                    |    1 +
>  lib/automake.mk            |    9 ++-
>  lib/netlink.c              |   17 ++++
>  lib/stream-fd.c            |   25 +++++-
>  lib/stress-unixctl.man     |   72 ++++++++++++++
>  lib/stress.c               |  222 ++++++++++++++++++++++++++++++++++++++++++++
>  lib/stress.h               |   92 ++++++++++++++++++
>  ovsdb/ovsdb-server.1.in    |    1 +
>  ovsdb/ovsdb-server.c       |    2 +
>  vswitchd/ovs-vswitchd.8.in |    1 +
>  vswitchd/ovs-vswitchd.c    |    2 +
>  11 files changed, 441 insertions(+), 3 deletions(-)
>  create mode 100644 lib/stress-unixctl.man
>  create mode 100644 lib/stress.c
>  create mode 100644 lib/stress.h
>
> diff --git a/AUTHORS b/AUTHORS
> index 6a81668..937e76b 100644
> --- a/AUTHORS
> +++ b/AUTHORS
> @@ -1,6 +1,7 @@
>  The following people, in alphabetical order, have either authored or
>  signed off on commits in the Open vSwitch version control repository.
>
> +Andrew Lambeth          wal at nicira.com
>  Andy Southgate          andy.southgate at citrix.com
>  Ben Pfaff               blp at nicira.com
>  Bryan Phillippe         bp at toroki.com
> diff --git a/lib/automake.mk b/lib/automake.mk
> index 4c9e8f0..a9ec70e 100644
> --- a/lib/automake.mk
> +++ b/lib/automake.mk
> @@ -125,6 +125,8 @@ lib_libopenvswitch_a_SOURCES = \
>        lib/stream-unix.c \
>        lib/stream.c \
>        lib/stream.h \
> +       lib/stress.c \
> +       lib/stress.h \
>        lib/string.h \
>        lib/svec.c \
>        lib/svec.h \
> @@ -212,6 +214,7 @@ EXTRA_DIST += \
>        lib/ssl-peer-ca-cert.man \
>        lib/ssl.man \
>        lib/ssl-syn.man \
> +       lib/stress-unixctl.man \
>        lib/unixctl.man \
>        lib/unixctl-syn.man \
>        lib/vconn-active.man \
> @@ -220,7 +223,6 @@ EXTRA_DIST += \
>        lib/vlog-syn.man \
>        lib/vlog.man
>
> -
>  lib/dirs.c: Makefile
>        ($(ro_c) && \
>         echo 'const char ovs_pkgdatadir[] = "$(pkgdatadir)";' && \
> @@ -252,6 +254,11 @@ lib/coverage.def: $(DIST_SOURCES)
>        sed -n 's|^COVERAGE_DEFINE(\([_a-zA-Z0-9]\{1,\}\)).*$$|COVERAGE_COUNTER(\1)|p' $(all_sources) | LC_ALL=C sort -u > $@
>  CLEANFILES += lib/coverage.def
>
> +lib/stress.$(OBJEXT): lib/stress.def
> +lib/stress.def: $(DIST_SOURCES)
> +       sed -n '/^STRESS_OPTION(/,/);$$/{s/);$$/)/;p}' $(all_sources) > $@
> +CLEANFILES += lib/stress.def
> +
>  lib/vlog.$(OBJEXT): lib/vlog-modules.def
>  lib/vlog-modules.def: $(DIST_SOURCES)
>        sed -n 's|^VLOG_DEFINE_\(THIS_\)\{0,1\}MODULE(\([_a-zA-Z0-9]\{1,\}\)).*$$|VLOG_MODULE(\2)|p' $(all_sources) | LC_ALL=C sort -u > $@
> diff --git a/lib/netlink.c b/lib/netlink.c
> index 8806f91..ba32ca3 100644
> --- a/lib/netlink.c
> +++ b/lib/netlink.c
> @@ -29,6 +29,7 @@
>  #include "netlink-protocol.h"
>  #include "ofpbuf.h"
>  #include "poll-loop.h"
> +#include "stress.h"
>  #include "timeval.h"
>  #include "util.h"
>  #include "vlog.h"
> @@ -259,6 +260,15 @@ nl_sock_sendv(struct nl_sock *sock, const struct iovec iov[], size_t n_iov,
>     return error;
>  }
>
> +/* This stress option is useful for testing that OVS properly tolerates
> + * -ENOBUFS on NetLink sockets.  Such errors are unavoidable because they can
> + * occur if the kernel cannot temporarily allocate enough GFP_ATOMIC memory to
> + * reply to a request.  They can also occur if messages arrive on a multicast
> + * channel faster than OVS can process them. */
> +STRESS_OPTION(
> +    netlink_overflow, "simulate netlink socket receive buffer overflow",
> +    5, 1, -1, 100);
> +
>  /* Tries to receive a netlink message from the kernel on 'sock'.  If
>  * successful, stores the received message into '*bufp' and returns 0.  The
>  * caller is responsible for destroying the message with ofpbuf_delete().  On
> @@ -340,9 +350,16 @@ try_again:
>         ofpbuf_delete(buf);
>         return EPROTO;
>     }
> +
> +    if (STRESS(netlink_overflow)) {
> +        ofpbuf_delete(buf);
> +        return ENOBUFS;
> +    }
> +
>     *bufp = buf;
>     log_nlmsg(__func__, 0, buf->data, buf->size);
>     COVERAGE_INC(netlink_received);
> +
>     return 0;
>  }
>
> diff --git a/lib/stream-fd.c b/lib/stream-fd.c
> index ad15dca..2026db6 100644
> --- a/lib/stream-fd.c
> +++ b/lib/stream-fd.c
> @@ -28,6 +28,7 @@
>  #include "leak-checker.h"
>  #include "poll-loop.h"
>  #include "socket-util.h"
> +#include "stress.h"
>  #include "util.h"
>  #include "stream-provider.h"
>  #include "stream.h"
> @@ -96,19 +97,39 @@ fd_connect(struct stream *stream)
>     return check_connection_completion(s->fd);
>  }
>
> +STRESS_OPTION(
> +    stream_flaky_recv, "simulate failure of fd stream recvs",
> +    100, 0, -1, 0);
> +
>  static ssize_t
>  fd_recv(struct stream *stream, void *buffer, size_t n)
>  {
>     struct stream_fd *s = stream_fd_cast(stream);
> -    ssize_t retval = read(s->fd, buffer, n);
> +    ssize_t retval;
> +
> +    if (STRESS(stream_flaky_recv)) {
> +        return -EIO;
> +    }
> +
> +    retval = read(s->fd, buffer, n);
>     return retval >= 0 ? retval : -errno;
>  }
>
> +STRESS_OPTION(
> +    stream_flaky_send, "simulate failure of fd stream sends",
> +    100, 0, -1, 0);
> +
>  static ssize_t
>  fd_send(struct stream *stream, const void *buffer, size_t n)
>  {
>     struct stream_fd *s = stream_fd_cast(stream);
> -    ssize_t retval = write(s->fd, buffer, n);
> +    ssize_t retval;
> +
> +    if (STRESS(stream_flaky_send)) {
> +        return -EIO;
> +    }
> +
> +    retval = write(s->fd, buffer, n);
>     return (retval > 0 ? retval
>             : retval == 0 ? -EAGAIN
>             : -errno);
> diff --git a/lib/stress-unixctl.man b/lib/stress-unixctl.man
> new file mode 100644
> index 0000000..ad265ee
> --- /dev/null
> +++ b/lib/stress-unixctl.man
> @@ -0,0 +1,72 @@
> +.SS "STRESS OPTION COMMANDS"
> +These command manage stress options, which allow developers testing
> +Open vSwitch to trigger behavior that otherwise would occur only in
> +corner cases.  Developers and testers can thereby more easily discover
> +bugs that would otherwise manifest only rarely or
> +nondeterministically.  Stress options may cause surprising behavior
> +even when they do not actually reveal bugs, so they should only be
> +enabled as part of testing Open vSwitch.
> +.
> +.IP "\fBstress/enable\fR"
> +.IQ "\fBstress/disable\fR"
> +All stress options are disabled by default.  Use \fBstress/enable\fR
> +to enable stress options and \fBstress/disable\fR to disable them.
> +.
> +.IP "\fBstress/list\fR"
> +Lists and describes the available stress options and their settings in
> +tabular form.  The columns in the table are:
> +.RS
> +.IP "NAME"
> +A single-word identifier for the option, used to identify stress
> +options to \fBstress/set\fR.
> +.
> +.IP "DESCRIPTION"
> +A description for a person unfamiliar with the detailed internals of
> +the code what behavior the option affects.
> +.
> +.IP "PERIOD"
> +Currently configured trigger period.  If the stress option is
> +disabled, this is \fBdisabled\fR.  Otherwise this is a number giving
> +the number of occurrences of the event between activations of the
> +stress option triggers.
> +.
> +.IP "MODE"
> +If the stress option is disabled, this is \fBn/a\fR.  Otherwise it is
> +\fBperiodic\fR if the stress option triggers after exactly the period,
> +or \fBrandom\fR if it triggers randomly but on average after the
> +number of occurrences specified by the period.
> +.
> +.IP "COUNTER"
> +If the stress option is disabled, this is \fBn/a\fR.  Otherwise it is
> +the number of occurrences of the event before the next time the stress
> +option triggers.
> +.
> +.IP "HITS"
> +The number of times that this stress option has triggered since this
> +program started.
> +.
> +.IP "RECOMMENDED"
> +A suggested period for a person unfamiliar with the internals.  It
> +should put reasonable stress on the system without crippling it.
> +.
> +.IP "MINIMUM"
> +.IQ "MAXIMUM"
> +Minimum and maximum values allowed for the period.
> +.
> +.IP "DEFAULT"
> +The default period, used when stress options have been enabled (with
> +\fBstress/enable\fR) but this particular stress option has not been
> +specifically configured (with \fBstress/set\fR).  It is \fBdisabled\fR
> +if the option is disabled by default.  It is nonzero for options that
> +can be left on at low levels without noticable impact to the end user.
> +.RE
> +.
> +.IP "\fBstress/set \fIoption\fR \fIperiod\fR [\fBrandom\fR|\fBperiodic\fR]"
> +Sets the period at which stress \fIoption\fR triggers to
> +\fIperiod\fR.  A \fIperiod\fR of 0 disables \fIoption\fR.  Specify
> +\fBrandom\fR to make the option trigger randomly with an average
> +period of \fIperiod\fR, or \fBperiodic\fR to trigger exactly every
> +\fIperiod\fR events; the latter is the default.
> +.IP
> +If stress options have not been enabled with \fBstress/enable\fR, this
> +command has no effect.
> diff --git a/lib/stress.c b/lib/stress.c
> new file mode 100644
> index 0000000..53f6fc0
> --- /dev/null
> +++ b/lib/stress.c
> @@ -0,0 +1,222 @@
> +/*
> + * Copyright (c) 2010 Nicira Networks.
> + *
> + * 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 "stress.h"
> +#include <stdlib.h>
> +#include <string.h>
> +#include "unixctl.h"
> +#include "dynamic-string.h"
> +#include "random.h"
> +#include "util.h"
> +#include "vlog.h"
> +
> +VLOG_DEFINE_THIS_MODULE(stress);
> +
> +/* The stress options. */
> +#if USE_LINKER_SECTIONS
> +extern struct stress_option *__start_stress_options[];
> +extern struct stress_option *__stop_stress_options[];
> +#define stress_options __start_stress_options
> +#define n_stress_options (__stop_stress_options - __start_stress_options)
> +#else  /* !USE_LINKER_SECTIONS */
> +#undef STRESS_OPTION
> +#define STRESS_OPTION(NAME, DESCRIPTION, RECOMMENDED, MIN, MAX, DEFAULT) \
> +        STRESS_OPTION__(NAME, DESCRIPTION, RECOMMENDED, MIN, MAX, DEFAULT);
> +#include "stress.def"
> +#undef STRESS_OPTION
> +
> +struct stress_option *stress_options[] = {
> +#define STRESS_OPTION(NAME, DESCRIPTION, RECOMMENDED, MIN, MAX, DEFAULT) \
> +        &stress_##NAME,
> +#include "stress.def"
> +#undef STRESS_OPTION
> +};
> +#define n_stress_options ARRAY_SIZE(stress_options)
> +#endif  /* !USE_LINKER_SECTIONS */
> +
> +/* Enable stress options? */
> +static bool stress_enabled;
> +
> +static void
> +stress_reset(struct stress_option *option)
> +{
> +    if (!option->period || !stress_enabled) {
> +        option->counter = UINT_MAX;
> +    } else if (!option->random) {
> +        option->counter = option->period;
> +    } else if (option->period < UINT32_MAX / 2) {
> +        /* Random distribution with mean of option->period. */
> +        option->counter = random_uint32() % ((2 * option->period) - 1) + 1;
> +    } else {
> +        option->counter = random_uint32();
> +    }
> +}
> +
> +static void
> +stress_enable(bool enable)
> +{
> +    if (stress_enabled != enable) {
> +        int i;
> +
> +        stress_enabled = enable;
> +        for (i = 0; i < n_stress_options; i++) {
> +            stress_reset(stress_options[i]);
> +        }
> +    }
> +}
> +
> +bool
> +stress_sample_slowpath__(struct stress_option *option)
> +{
> +    stress_reset(option);
> +    if (option->period && stress_enabled) {
> +        static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1);
> +
> +        option->hits++;
> +        VLOG_DBG_RL(&rl, "%s hit (%llu total)", option->name, option->hits);
> +
> +        return true;
> +    } else {
> +        return false;
> +    }
> +}
> +
> +static void
> +stress_set(struct stress_option *option, unsigned int period, bool random)
> +{
> +    if (period > option->max) {
> +        period = option->max;
> +    }
> +    if (period < option->min) {
> +        period = option->min;
> +    }
> +    if (period != option->period || random != option->random) {
> +        option->random = random;
> +        option->period = period;
> +        stress_reset(option);
> +    }
> +}
> +
> +static void
> +stress_unixctl_list(struct unixctl_conn *conn, const char *args,
> +                    void *aux OVS_UNUSED)
> +{
> +    int i, found = 0;
> +    struct ds results;
> +
> +    ds_init(&results);
> +    ds_put_cstr(&results, "NAME (DESCRIPTION)\n");
> +    ds_put_format(&results, "%11s %10s %10s %10s\n",
> +                  "PERIOD", "MODE", "COUNTER", "HITS");
> +    ds_put_format(&results, "%11s %10s %10s %10s\n",
> +                  "RECOMMENDED", "MINIMUM", "MAXIMUM", "DEFAULT");
> +    for (i = 0; i < n_stress_options; i++) {
> +        struct stress_option *option = stress_options[i];
> +        if (!*args || strstr(option->name, args)) {
> +            ds_put_format(&results, "\n%s (%s)\n",
> +                          option->name, option->description);
> +            if (option->period) {
> +                ds_put_format(&results, "%11u %10s ", option->period,
> +                              option->random ? "random" : "periodic");
> +                if (stress_enabled) {
> +                    ds_put_format(&results, "%10u", option->counter);
> +                } else {
> +                    ds_put_cstr(&results, "     n/a");
> +                }
> +            } else {
> +                ds_put_format(&results, "%11s %10s %10s",
> +                              "disabled", "n/a", "n/a");
> +            }
> +            ds_put_format(&results, " %10llu\n", option->hits);
> +            ds_put_format(&results, "%11u %10u %10u ",
> +                          option->recommended, option->min, option->max);
> +            if (!option->def) {
> +                ds_put_format(&results, "%10s", "disabled");
> +            } else {
> +                ds_put_format(&results, "%10u", option->def);
> +            }
> +            ds_put_char(&results, '\n');
> +            found++;
> +        }
> +    }
> +    if (found) {
> +        unixctl_command_reply(conn, 200, ds_cstr(&results));
> +    } else {
> +        unixctl_command_reply(conn, 404, "");
> +    }
> +    ds_destroy(&results);
> +}
> +
> +static void
> +stress_unixctl_enable(struct unixctl_conn *conn, const char *args OVS_UNUSED,
> +                      void *aux OVS_UNUSED)
> +{
> +    stress_enable(true);
> +    unixctl_command_reply(conn, 200, "");
> +}
> +
> +static void
> +stress_unixctl_disable(struct unixctl_conn *conn, const char *args OVS_UNUSED,
> +                       void *aux OVS_UNUSED)
> +{
> +    stress_enable(false);
> +    unixctl_command_reply(conn, 200, "");
> +}
> +
> +static void
> +stress_unixctl_set(struct unixctl_conn *conn, const char *args_,
> +                   void *aux OVS_UNUSED)
> +{
> +    int code = 404;
> +    char *args = xstrdup(args_);
> +    char *save_ptr = NULL;
> +    char *option_name;
> +    char *option_val;
> +
> +    option_name = strtok_r(args, " ", &save_ptr);
> +    option_val = strtok_r(NULL, " ", &save_ptr);
> +    if (option_val) {
> +        int i;
> +        for (i = 0; i < n_stress_options; i++) {
> +            struct stress_option *option = stress_options[i];
> +            if (!strcmp(option_name, option->name)) {
> +                unsigned int period = strtoul(option_val, NULL, 0);
> +                bool random = strstr(args_, "random");
> +
> +                stress_set(option, period, random);
> +                code = 200;
> +                break;
> +            }
> +        }
> +    }
> +    unixctl_command_reply(conn, code, "");
> +    free(args);
> +}
> +
> +/* Exposes ovs-appctl access to the stress options.
> + *
> + * This function is not required to simply reference stress options and have
> + * them fire at their default periods.
> + */
> +void
> +stress_init_command(void)
> +{
> +    unixctl_command_register("stress/list", stress_unixctl_list, NULL);
> +    unixctl_command_register("stress/set", stress_unixctl_set, NULL);
> +    unixctl_command_register("stress/enable", stress_unixctl_enable, NULL);
> +    unixctl_command_register("stress/disable", stress_unixctl_disable, NULL);
> +}
> diff --git a/lib/stress.h b/lib/stress.h
> new file mode 100644
> index 0000000..4244fca
> --- /dev/null
> +++ b/lib/stress.h
> @@ -0,0 +1,92 @@
> +/*
> + * Copyright (c) 2010 Nicira Networks.
> + *
> + * 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.
> + */
> +
> +#ifndef STRESS_H
> +#define STRESS_H 1
> +
> +#include <stdbool.h>
> +
> +struct stress_option {
> +    /* Properties. */
> +    char *name;                 /* Short identifier string */
> +    char *description;          /* Description of what the option stresses. */
> +    unsigned int recommended;   /* Recommended period. */
> +    unsigned int min;           /* Minimum period that can be set. */
> +    unsigned int max;           /* Maximum period that can be set. */
> +    unsigned int def;           /* Default value. */
> +
> +    /* Configuration. */
> +    unsigned int period;        /* Desired period for firing, 0 to disable. */
> +    bool random;                /* Fire randomly or exactly at period? */
> +
> +    /* State. */
> +    unsigned int counter;       /* Number of hits before next firing. */
> +    unsigned long long int hits; /* Hits since last reset. */
> +};
> +
> +/* Creates and initializes a global instance of a stress option.
> + *
> + * NAME is a single word descriptive identifier for the option.  This is the
> + * token to pass in to the STRESS() macro at the sites where exectution is to
> + * be controlled by the option.
> + *
> + * DESCRIPTION is a quoted string that should describe to a person unfamiliar
> + * with the detailed internals of the code what behavior the option affects.
> + *
> + * RECOMMENDED is a suggested value for a person unfamiliar with the internals.
> + * It should put reasonable stress on the system without crippling it.
> + *
> + * MIN and MAX are the minimum and maximum values allowed for the option.
> + *
> + * DEFAULT is the default value for the option.  Specify 0 to disable the
> + * option by default, which should be the usual choice.  But some options can
> + * be left on at low levels without noticable impact to the end user.  An
> + * example would be failing to allocate a buffer for every 100000th packet
> + * processed by the system.
> + */
> +#if USE_LINKER_SECTIONS
> +#define STRESS_OPTION(NAME, DESCRIPTION, RECOMMENDED, MIN, MAX, DEFAULT) \
> +        STRESS_OPTION__(NAME, DESCRIPTION, RECOMMENDED, MIN, MAX, DEFAULT); \
> +        struct stress_option *stress_option_ptr_##NAME                  \
> +            __attribute__((section("stress_options"))) = &stress_##NAME
> +#else
> +#define STRESS_OPTION(NAME, DESCRIPTION, RECOMMENDED, MIN, MAX, DEFAULT) \
> +        extern struct stress_option stress_##NAME
> +#endif
> +
> +/* Yields true if stress option NAME should be triggered,
> + * false otherwise. */
> +#define STRESS(NAME) stress_sample__(&stress_##NAME)
> +
> +void stress_init_command(void);
> +
> +/* Implementation details. */
> +
> +#define STRESS_OPTION__(NAME, DESCRIPTION, RECOMMENDED, MIN, MAX, DEFAULT) \
> +        struct stress_option stress_##NAME =                            \
> +        { #NAME, DESCRIPTION, RECOMMENDED, MIN, MAX, DEFAULT,           \
> +          DEFAULT ? DEFAULT : 0,                /* period */            \
> +          false,                                /* random */            \
> +          UINT_MAX,                             /* counter */           \
> +          0 }                                   /* hits */
> +
> +bool stress_sample_slowpath__(struct stress_option *);
> +static inline bool stress_sample__(struct stress_option *option)
> +{
> +    return --option->counter == 0 && stress_sample_slowpath__(option);
> +}
> +
> +#endif /* STRESS_H */
> diff --git a/ovsdb/ovsdb-server.1.in b/ovsdb/ovsdb-server.1.in
> index d7beba7..2cb2045 100644
> --- a/ovsdb/ovsdb-server.1.in
> +++ b/ovsdb/ovsdb-server.1.in
> @@ -99,6 +99,7 @@ This command might be useful for debugging issues with database
>  clients.
>  .
>  .so lib/vlog-unixctl.man
> +.so lib/stress-unixctl.man
>  .SH "SEE ALSO"
>  .
>  .BR ovsdb\-tool (1).
> diff --git a/ovsdb/ovsdb-server.c b/ovsdb/ovsdb-server.c
> index 45d7a77..0c37a8e 100644
> --- a/ovsdb/ovsdb-server.c
> +++ b/ovsdb/ovsdb-server.c
> @@ -39,6 +39,7 @@
>  #include "row.h"
>  #include "stream-ssl.h"
>  #include "stream.h"
> +#include "stress.h"
>  #include "svec.h"
>  #include "table.h"
>  #include "timeval.h"
> @@ -87,6 +88,7 @@ main(int argc, char *argv[])
>
>     proctitle_init(argc, argv);
>     set_program_name(argv[0]);
> +    stress_init_command();
>     signal(SIGPIPE, SIG_IGN);
>     process_init();
>
> diff --git a/vswitchd/ovs-vswitchd.8.in b/vswitchd/ovs-vswitchd.8.in
> index e59893f..908b68e 100644
> --- a/vswitchd/ovs-vswitchd.8.in
> +++ b/vswitchd/ovs-vswitchd.8.in
> @@ -183,6 +183,7 @@ status of \fIslave\fR changes.
>  Returns the hash value which would be used for \fImac\fR.
>  .
>  .so lib/vlog-unixctl.man
> +.so lib/stress-unixctl.man
>  .SH "SEE ALSO"
>  .BR ovs\-appctl (8),
>  .BR ovs\-brcompatd (8),
> diff --git a/vswitchd/ovs-vswitchd.c b/vswitchd/ovs-vswitchd.c
> index c307c92..f80b0ad 100644
> --- a/vswitchd/ovs-vswitchd.c
> +++ b/vswitchd/ovs-vswitchd.c
> @@ -40,6 +40,7 @@
>  #include "signals.h"
>  #include "stream-ssl.h"
>  #include "stream.h"
> +#include "stress.h"
>  #include "svec.h"
>  #include "timeval.h"
>  #include "unixctl.h"
> @@ -66,6 +67,7 @@ main(int argc, char *argv[])
>
>     proctitle_init(argc, argv);
>     set_program_name(argv[0]);
> +    stress_init_command();
>     remote = parse_options(argc, argv);
>     signal(SIGPIPE, SIG_IGN);
>     sighup = signal_register(SIGHUP);
> --
> 1.7.1
>
>
> _______________________________________________
> dev mailing list
> dev at openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev_openvswitch.org
>




More information about the dev mailing list