On Fri, Jul 12, 2013 at 2:54 PM, Ben Pfaff <b...@nicira.com> wrote: > The "stress" library was introduced years ago. We intended at the time to > start using it to provoke errors in testing, to make sure that Open vSwitch > was resilient against those errors. The intention was good, but there were > few actual implementations of stress options, and the testing never > materialized. > > Rather than adapt the stress library for thread safety, this seems like a > good opportunity to remove it, so this commit does so. >
> Signed-off-by: Ben Pfaff <b...@nicira.com> > Looks good to me. > --- > lib/automake.mk | 8 -- > lib/netlink-socket.c | 14 --- > lib/stream-fd.c | 17 ---- > lib/stress-unixctl.man | 72 --------------- > lib/stress.c | 219 > -------------------------------------------- > lib/stress.h | 94 ------------------- > manpages.mk | 4 - > 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, 0 insertions(+), 434 deletions(-) > delete mode 100644 lib/stress-unixctl.man > delete mode 100644 lib/stress.c > delete mode 100644 lib/stress.h > > diff --git a/lib/automake.mk b/lib/automake.mk > index 507ca97..280fc8b 100644 > --- a/lib/automake.mk > +++ b/lib/automake.mk > @@ -182,8 +182,6 @@ lib_libopenvswitch_a_SOURCES = \ > lib/stream-unix.c \ > lib/stream.c \ > lib/stream.h \ > - lib/stress.c \ > - lib/stress.h \ > lib/string.c \ > lib/string.h \ > lib/svec.c \ > @@ -306,7 +304,6 @@ MAN_FRAGMENTS += \ > lib/ssl-peer-ca-cert.man \ > lib/ssl.man \ > lib/ssl-syn.man \ > - lib/stress-unixctl.man \ > lib/table.man \ > lib/unixctl.man \ > lib/unixctl-syn.man \ > @@ -383,11 +380,6 @@ 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-socket.c b/lib/netlink-socket.c > index dfe39ac..aa7fca2 100644 > --- a/lib/netlink-socket.c > +++ b/lib/netlink-socket.c > @@ -31,7 +31,6 @@ > #include "ofpbuf.h" > #include "poll-loop.h" > #include "socket-util.h" > -#include "stress.h" > #include "util.h" > #include "vlog.h" > > @@ -309,15 +308,6 @@ nl_sock_send_seq(struct nl_sock *sock, const struct > ofpbuf *msg, > return nl_sock_send__(sock, msg, nlmsg_seq, wait); > } > > -/* 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); > - > static int > nl_sock_recv__(struct nl_sock *sock, struct ofpbuf *buf, bool wait) > { > @@ -373,10 +363,6 @@ nl_sock_recv__(struct nl_sock *sock, struct ofpbuf > *buf, bool wait) > return EPROTO; > } > > - if (STRESS(netlink_overflow)) { > - return ENOBUFS; > - } > - > buf->size = MIN(retval, buf->allocated); > if (retval > buf->allocated) { > COVERAGE_INC(netlink_recv_jumbo); > diff --git a/lib/stream-fd.c b/lib/stream-fd.c > index d102582..1171f32 100644 > --- a/lib/stream-fd.c > +++ b/lib/stream-fd.c > @@ -26,7 +26,6 @@ > #include "fatal-signal.h" > #include "poll-loop.h" > #include "socket-util.h" > -#include "stress.h" > #include "util.h" > #include "stream-provider.h" > #include "stream.h" > @@ -89,38 +88,22 @@ 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; > > - 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; > > - if (STRESS(stream_flaky_send)) { > - return -EIO; > - } > - > retval = write(s->fd, buffer, n); > return (retval > 0 ? retval > : retval == 0 ? -EAGAIN > diff --git a/lib/stress-unixctl.man b/lib/stress-unixctl.man > deleted file mode 100644 > index d2716a9..0000000 > --- a/lib/stress-unixctl.man > +++ /dev/null > @@ -1,72 +0,0 @@ > -.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 noticeable 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 > deleted file mode 100644 > index a14209e..0000000 > --- a/lib/stress.c > +++ /dev/null > @@ -1,219 +0,0 @@ > -/* > - * Copyright (c) 2010, 2011 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 "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, int argc OVS_UNUSED, > - const char *argv[] OVS_UNUSED, 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 (!argv[1] || strstr(option->name, argv[1])) { > - 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, ds_cstr(&results)); > - } else { > - unixctl_command_reply_error(conn, NULL); > - } > - ds_destroy(&results); > -} > - > -static void > -stress_unixctl_enable(struct unixctl_conn *conn, int argc OVS_UNUSED, > - const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED) > -{ > - stress_enable(true); > - unixctl_command_reply(conn, NULL); > -} > - > -static void > -stress_unixctl_disable(struct unixctl_conn *conn, int argc OVS_UNUSED, > - const char *argv[] OVS_UNUSED, void *aux > OVS_UNUSED) > -{ > - stress_enable(false); > - unixctl_command_reply(conn, NULL); > -} > - > -static void > -stress_unixctl_set(struct unixctl_conn *conn, int argc OVS_UNUSED, > - const char *argv[], void *aux OVS_UNUSED) > -{ > - const char *option_name = argv[1]; > - const char *option_val = argv[2]; > - 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 = !strcmp(argv[3], "random"); > - > - stress_set(option, period, random); > - unixctl_command_reply(conn, NULL); > - return; > - } > - } > - > - unixctl_command_reply_error(conn, NULL); > -} > - > -/* 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", "", 0, 1, > - stress_unixctl_list, NULL); > - unixctl_command_register("stress/set", "option period [random | > periodic]", > - 2, 3, stress_unixctl_set, NULL); > - unixctl_command_register("stress/enable", "", 0, 0, > - stress_unixctl_enable, NULL); > - unixctl_command_register("stress/disable", "", 0, 0, > - stress_unixctl_disable, NULL); > -} > diff --git a/lib/stress.h b/lib/stress.h > deleted file mode 100644 > index 8f3d359..0000000 > --- a/lib/stress.h > +++ /dev/null > @@ -1,94 +0,0 @@ > -/* > - * Copyright (c) 2010, 2011 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. > - */ > - > -#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 noticeable 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); \ > - extern struct stress_option *stress_option_ptr_##NAME; \ > - 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) \ > - extern struct stress_option stress_##NAME; \ > - 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/manpages.mk b/manpages.mk > index ed0d999..263f2ea 100644 > --- a/manpages.mk > +++ b/manpages.mk > @@ -42,7 +42,6 @@ ovsdb/ovsdb-server.1: \ > lib/ssl-bootstrap.man \ > lib/ssl-syn.man \ > lib/ssl.man \ > - lib/stress-unixctl.man \ > lib/unixctl-syn.man \ > lib/unixctl.man \ > lib/vlog-syn.man \ > @@ -61,7 +60,6 @@ lib/ssl-bootstrap-syn.man: > lib/ssl-bootstrap.man: > lib/ssl-syn.man: > lib/ssl.man: > -lib/stress-unixctl.man: > lib/unixctl-syn.man: > lib/unixctl.man: > lib/vlog-syn.man: > @@ -232,7 +230,6 @@ vswitchd/ovs-vswitchd.8: \ > lib/memory-unixctl.man \ > lib/ssl-bootstrap.man \ > lib/ssl.man \ > - lib/stress-unixctl.man \ > lib/vlog-unixctl.man \ > lib/vlog.man \ > ofproto/ofproto-dpif-unixctl.man \ > @@ -246,7 +243,6 @@ lib/daemon.man: > lib/memory-unixctl.man: > lib/ssl-bootstrap.man: > lib/ssl.man: > -lib/stress-unixctl.man: > lib/vlog-unixctl.man: > lib/vlog.man: > ofproto/ofproto-dpif-unixctl.man: > diff --git a/ovsdb/ovsdb-server.1.in b/ovsdb/ovsdb-server.1.in > index 1201e6f..4628b59 100644 > --- a/ovsdb/ovsdb-server.1.in > +++ b/ovsdb/ovsdb-server.1.in > @@ -176,7 +176,6 @@ the command line or through the > \fBovsdb\-server/add\-db\fR command. > .so lib/vlog-unixctl.man > .so lib/memory-unixctl.man > .so lib/coverage-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 912f599..ab44b3a 100644 > --- a/ovsdb/ovsdb-server.c > +++ b/ovsdb/ovsdb-server.c > @@ -45,7 +45,6 @@ > #include "shash.h" > #include "stream-ssl.h" > #include "stream.h" > -#include "stress.h" > #include "sset.h" > #include "table.h" > #include "timeval.h" > @@ -137,7 +136,6 @@ 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 f17f873..3eb87a6 100644 > --- a/vswitchd/ovs-vswitchd.8.in > +++ b/vswitchd/ovs-vswitchd.8.in > @@ -208,7 +208,6 @@ enabled. > .so lib/vlog-unixctl.man > .so lib/memory-unixctl.man > .so lib/coverage-unixctl.man > -.so lib/stress-unixctl.man > . > .SH "OPENFLOW IMPLEMENTATION" > . > diff --git a/vswitchd/ovs-vswitchd.c b/vswitchd/ovs-vswitchd.c > index 322ce60..bc45dac 100644 > --- a/vswitchd/ovs-vswitchd.c > +++ b/vswitchd/ovs-vswitchd.c > @@ -42,7 +42,6 @@ > #include "simap.h" > #include "stream-ssl.h" > #include "stream.h" > -#include "stress.h" > #include "svec.h" > #include "timeval.h" > #include "unixctl.h" > @@ -74,7 +73,6 @@ main(int argc, char *argv[]) > > proctitle_init(argc, argv); > set_program_name(argv[0]); > - stress_init_command(); > remote = parse_options(argc, argv, &unixctl_path); > signal(SIGPIPE, SIG_IGN); > sighup = signal_register(SIGHUP); > -- > 1.7.2.5 > > _______________________________________________ > dev mailing list > dev@openvswitch.org > http://openvswitch.org/mailman/listinfo/dev >
_______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev