diff mbox series

[ovs-dev,v2] reconnect: Set defaults from environment variables.

Message ID ZUtd7nEJHzlCJyrw@SIT-SDELAP4051.int.lidl.net
State Superseded
Delegated to: Ilya Maximets
Headers show
Series [ovs-dev,v2] reconnect: Set defaults from environment variables. | expand

Checks

Context Check Description
ovsrobot/apply-robot success apply and check: success
ovsrobot/github-robot-_Build_and_Test success github build: passed
ovsrobot/intel-ovs-compilation success test: success

Commit Message

Felix Huettner Nov. 8, 2023, 10:07 a.m. UTC
this exposes the old constants regarding min backoff, max backoff and
probe interval using environment variables. In case previously users
wanted to tune the probe interval for all connections this required
setting this setting in multiple locations. E.g. to configure the probe
interval from a relay to the ovsdb server you need to call an appctl
command after the relay has started up.
The new environment variables make it easy to set them for all new
connections. The existing configuration options for these settings stay
in place and take precedence over the environment variables.
In case the environment variables are not specified/invalid formated we
default to the previous defaults.

Signed-off-by: Felix Huettner <felix.huettner@mail.schwarz>
---
v1->v2: fixed wrong function definitions
---
 NEWS                    |  7 +++++
 lib/jsonrpc.c           |  4 +--
 lib/reconnect.c         | 63 +++++++++++++++++++++++++++++++++++++----
 lib/reconnect.h         |  7 ++---
 ovsdb/jsonrpc-server.c  |  4 +--
 ovsdb/ovsdb-server.c    |  2 +-
 ovsdb/relay.h           |  2 --
 python/ovs/reconnect.py | 45 +++++++++++++++++++++++++++--
 8 files changed, 114 insertions(+), 20 deletions(-)

--
2.42.0

Diese E Mail enthält möglicherweise vertrauliche Inhalte und ist nur für die Verwertung durch den vorgesehenen Empfänger bestimmt.
Sollten Sie nicht der vorgesehene Empfänger sein, setzen Sie den Absender bitte unverzüglich in Kenntnis und löschen diese E Mail.

Hinweise zum Datenschutz finden Sie hier<https://www.datenschutz.schwarz>.


This e-mail may contain confidential content and is intended only for the specified recipient/s.
If you are not the intended recipient, please inform the sender immediately and delete this e-mail.

Information on data protection can be found here<https://www.datenschutz.schwarz>.

Comments

Eelco Chaudron Dec. 1, 2023, 9:38 a.m. UTC | #1
On 8 Nov 2023, at 11:07, Felix Huettner via dev wrote:

> this exposes the old constants regarding min backoff, max backoff and

This

> probe interval using environment variables. In case previously users
> wanted to tune the probe interval for all connections this required
> setting this setting in multiple locations. E.g. to configure the probe
> interval from a relay to the ovsdb server you need to call an appctl
> command after the relay has started up.
> The new environment variables make it easy to set them for all new
> connections. The existing configuration options for these settings stay
> in place and take precedence over the environment variables.
> In case the environment variables are not specified/invalid formated we

formatted

> default to the previous defaults.
>
> Signed-off-by: Felix Huettner <felix.huettner@mail.schwarz>

Hi Felix, this is not a full review, just some things I noticed when skimming the patch.

I see Ilya has it marked to review, so he might have some more specific comments.

//Eelco

> ---
> v1->v2: fixed wrong function definitions
> ---
>  NEWS                    |  7 +++++
>  lib/jsonrpc.c           |  4 +--
>  lib/reconnect.c         | 63 +++++++++++++++++++++++++++++++++++++----
>  lib/reconnect.h         |  7 ++---
>  ovsdb/jsonrpc-server.c  |  4 +--
>  ovsdb/ovsdb-server.c    |  2 +-
>  ovsdb/relay.h           |  2 --
>  python/ovs/reconnect.py | 45 +++++++++++++++++++++++++++--
>  8 files changed, 114 insertions(+), 20 deletions(-)
>
> diff --git a/NEWS b/NEWS
> index 6b45492f1..58266ae52 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -6,6 +6,13 @@ Post-v3.2.0
>         from older version is supported but it may trigger more leader elections
>         during the process, and error logs complaining unrecognized fields may
>         be observed on old nodes.
> +   - The environment variable OVS_RECONNECT_MIN_BACKOFF,
> +     OVS_RECONNECT_MAX_BACKOFF and OVS_RECONNECT_PROBE_INTERVAL, if set, allow
> +     users to tune the default reconnect configuration. E.g. adapting
> +     OVS_RECONNECT_PROBE_INTERVAL modifies the default probe interval, for all
> +     servers and clients. These variables are valid for all ovs code as well as
> +     the python client. Values set for individual connections (e.g. using the
> +     `inactivity_probe` column in the `Manager` tables) will take precedence.
>
>
>  v3.2.0 - 17 Aug 2023
> diff --git a/lib/jsonrpc.c b/lib/jsonrpc.c
> index c8ce5362e..7bf49fc81 100644
> --- a/lib/jsonrpc.c
> +++ b/lib/jsonrpc.c
> @@ -1269,8 +1269,8 @@ void
>  jsonrpc_session_enable_reconnect(struct jsonrpc_session *s)
>  {
>      reconnect_set_max_tries(s->reconnect, UINT_MAX);
> -    reconnect_set_backoff(s->reconnect, RECONNECT_DEFAULT_MIN_BACKOFF,
> -                          RECONNECT_DEFAULT_MAX_BACKOFF);
> +    reconnect_set_backoff(s->reconnect, reconnect_default_min_backoff(),
> +                          reconnect_default_max_backoff());
>  }
>
>  /* Forces 's' to drop its connection (if any) and reconnect. */
> diff --git a/lib/reconnect.c b/lib/reconnect.c
> index 89a0bcaf9..3e73d7cca 100644
> --- a/lib/reconnect.c
> +++ b/lib/reconnect.c
> @@ -99,9 +99,9 @@ reconnect_create(long long int now)
>      struct reconnect *fsm = xzalloc(sizeof *fsm);
>
>      fsm->name = xstrdup("void");
> -    fsm->min_backoff = RECONNECT_DEFAULT_MIN_BACKOFF;
> -    fsm->max_backoff = RECONNECT_DEFAULT_MAX_BACKOFF;
> -    fsm->probe_interval = RECONNECT_DEFAULT_PROBE_INTERVAL;
> +    fsm->min_backoff = reconnect_default_min_backoff();
> +    fsm->max_backoff = reconnect_default_max_backoff();
> +    fsm->probe_interval = reconnect_default_probe_interval();
>      fsm->passive = false;
>      fsm->info = VLL_INFO;
>
> @@ -163,7 +163,7 @@ reconnect_set_name(struct reconnect *fsm, const char *name)
>  }
>
>  /* Return the minimum number of milliseconds to back off between consecutive
> - * connection attempts.  The default is RECONNECT_DEFAULT_MIN_BACKOFF. */
> + * connection attempts.  The default is reconnect_default_min_backoff(). */
>  int
>  reconnect_get_min_backoff(const struct reconnect *fsm)
>  {
> @@ -171,7 +171,7 @@ reconnect_get_min_backoff(const struct reconnect *fsm)
>  }
>
>  /* Return the maximum number of milliseconds to back off between consecutive
> - * connection attempts.  The default is RECONNECT_DEFAULT_MAX_BACKOFF. */
> + * connection attempts.  The default is reconnect_default_max_backoff(). */
>  int
>  reconnect_get_max_backoff(const struct reconnect *fsm)
>  {
> @@ -190,6 +190,57 @@ reconnect_get_probe_interval(const struct reconnect *fsm)
>      return fsm->probe_interval;
>  }
>
> +/* Returns the default min_backoff value for reconnect. It uses the environment
> + * variable OVS_RECONNECT_MIN_BACKOFF if set and valid or otherwise defaults
> + * to 1 second. The return value is in ms. */
> +unsigned int reconnect_default_min_backoff(void) {
> +    static unsigned int default_min_backoff = 0;
> +    if (default_min_backoff == 0) {
> +        char *env = getenv("OVS_RECONNECT_MIN_BACKOFF");
> +        if (env && env[0]) {
> +            str_to_uint(env, 10, &default_min_backoff);
> +        }
> +        if (default_min_backoff == 0) {

I think we should define some sane minimum value. Or are we ok with 1ms? Some for all the others.

> +            default_min_backoff = 1000;

I think we should keep the default definitions, and use them here rather than the hard-coded numbers.
So this will become:

	default_min_backoff = RECONNECT_DEFAULT_MIN_BACKOFF

> +        }
> +    }
> +    return default_min_backoff;
> +}
> +
> +/* Returns the default max_backoff value for reconnect. It uses the environment
> + * variable OVS_RECONNECT_MAX_BACKOFF if set and valid or otherwise defaults
> + * to 8 second. The return value is in ms. */
> +unsigned int reconnect_default_max_backoff(void) {
> +    static unsigned int default_max_backoff = 0;
> +    if (default_max_backoff == 0) {
> +        char *env = getenv("OVS_RECONNECT_MAX_BACKOFF");
> +        if (env && env[0]) {
> +            str_to_uint(env, 10, &default_max_backoff);
> +        }
> +        if (default_max_backoff == 0) {
> +            default_max_backoff = 8000;
> +        }
> +    }
> +    return default_max_backoff;
> +}
> +
> +/* Returns the default probe_interval value for reconnect. It uses the
> + * environment variable OVS_RECONNECT_PROBE_INTERVAL if set and valid or
> + * otherwise defaults to 5 second. The return value is in ms. */
> +unsigned int reconnect_default_probe_interval(void) {
> +    static unsigned int default_probe_interval = 0;
> +    if (default_probe_interval == 0) {
> +        char *env = getenv("OVS_RECONNECT_PROBE_INTERVAL");
> +        if (env && env[0]) {
> +            str_to_uint(env, 10, &default_probe_interval);
> +        }
> +        if (default_probe_interval == 0) {
> +            default_probe_interval = 5000;
> +        }
> +    }
> +    return default_probe_interval;
> +}
> +
>  /* Limits the maximum number of times that 'fsm' will ask the client to try to
>   * reconnect to 'max_tries'.  UINT_MAX (the default) means an unlimited number
>   * of tries.
> @@ -234,7 +285,7 @@ reconnect_set_backoff(struct reconnect *fsm, int min_backoff, int max_backoff)
>      fsm->min_backoff = MAX(min_backoff, 1000);
>      fsm->max_backoff = (max_backoff
>                          ? MAX(max_backoff, 1000)
> -                        : RECONNECT_DEFAULT_MAX_BACKOFF);
> +                        : reconnect_default_max_backoff());
>      if (fsm->min_backoff > fsm->max_backoff) {
>          fsm->max_backoff = fsm->min_backoff;
>      }
> diff --git a/lib/reconnect.h b/lib/reconnect.h
> index 40cc569c4..b76ce0f15 100644
> --- a/lib/reconnect.h
> +++ b/lib/reconnect.h
> @@ -40,10 +40,9 @@ void reconnect_set_quiet(struct reconnect *, bool quiet);
>  const char *reconnect_get_name(const struct reconnect *);
>  void reconnect_set_name(struct reconnect *, const char *name);
>
> -/* Defaults, all in msecs. */
> -#define RECONNECT_DEFAULT_MIN_BACKOFF 1000
> -#define RECONNECT_DEFAULT_MAX_BACKOFF 8000
> -#define RECONNECT_DEFAULT_PROBE_INTERVAL 5000
> +unsigned int reconnect_default_min_backoff(void);
> +unsigned int reconnect_default_max_backoff(void);
> +unsigned int reconnect_default_probe_interval(void);
>
>  int reconnect_get_min_backoff(const struct reconnect *);
>  int reconnect_get_max_backoff(const struct reconnect *);
> diff --git a/ovsdb/jsonrpc-server.c b/ovsdb/jsonrpc-server.c
> index a3ca48a7b..5d8e98e1c 100644
> --- a/ovsdb/jsonrpc-server.c
> +++ b/ovsdb/jsonrpc-server.c
> @@ -211,9 +211,9 @@ struct ovsdb_jsonrpc_options *
>  ovsdb_jsonrpc_default_options(const char *target)
>  {
>      struct ovsdb_jsonrpc_options *options = xzalloc(sizeof *options);
> -    options->max_backoff = RECONNECT_DEFAULT_MAX_BACKOFF;
> +    options->max_backoff = reconnect_default_max_backoff();
>      options->probe_interval = (stream_or_pstream_needs_probes(target)
> -                               ? RECONNECT_DEFAULT_PROBE_INTERVAL
> +                               ? reconnect_default_probe_interval()
>                                 : 0);
>      return options;
>  }
> diff --git a/ovsdb/ovsdb-server.c b/ovsdb/ovsdb-server.c
> index 4d29043f4..78e62cdef 100644
> --- a/ovsdb/ovsdb-server.c
> +++ b/ovsdb/ovsdb-server.c
> @@ -330,7 +330,7 @@ main(int argc, char *argv[])
>      struct shash all_dbs;
>      struct shash_node *node;
>      int replication_probe_interval = REPLICATION_DEFAULT_PROBE_INTERVAL;
> -    int relay_source_probe_interval = RELAY_SOURCE_DEFAULT_PROBE_INTERVAL;
> +    int relay_source_probe_interval = reconnect_default_probe_interval();
>
>      ovs_cmdl_proctitle_init(argc, argv);
>      set_program_name(argv[0]);
> diff --git a/ovsdb/relay.h b/ovsdb/relay.h
> index 218caad65..bf7568701 100644
> --- a/ovsdb/relay.h
> +++ b/ovsdb/relay.h
> @@ -26,8 +26,6 @@ struct ovsdb;
>  struct ovsdb_schema;
>  struct uuid;
>
> -#define RELAY_SOURCE_DEFAULT_PROBE_INTERVAL RECONNECT_DEFAULT_PROBE_INTERVAL
> -
>  typedef struct ovsdb_error *(*schema_change_callback)(
>                                         struct ovsdb *,
>                                         const struct ovsdb_schema *,
> diff --git a/python/ovs/reconnect.py b/python/ovs/reconnect.py
> index 6b0d023ae..229d08bb6 100644
> --- a/python/ovs/reconnect.py
> +++ b/python/ovs/reconnect.py
> @@ -38,6 +38,9 @@ class Reconnect(object):
>      since there is no hidden state.  When not testing, just pass the return
>      value of ovs.time.msec().  (Perhaps this design should be revisited
>      later.)"""
> +    default_min_backoff = None
> +    default_max_backoff = None
> +    default_probe_interval = None
>
>      class Void(object):
>          name = "VOID"
> @@ -161,9 +164,9 @@ class Reconnect(object):
>          self.enable() and self.set_name() on the returned object."""
>
>          self.name = "void"
> -        self.min_backoff = 1000
> -        self.max_backoff = 8000
> -        self.probe_interval = 5000
> +        self.min_backoff = Reconnect.get_default_min_backoff()
> +        self.max_backoff = Reconnect.get_default_max_backoff()
> +        self.probe_interval = Reconnect.get_default_probe_interval()
>          self.passive = False
>          self.info_level = vlog.info
>
> @@ -231,6 +234,42 @@ class Reconnect(object):
>          self.run() returns ovs.reconnect.DISCONNECT."""
>          return self.probe_interval
>
> +    def get_default_min_backoff():
> +        """Returns the default min_backoff value for reconnect. It uses the
> +        environment variable OVS_RECONNECT_MIN_BACKOFF if set and valid or
> +        otherwise defaults to 1 second. The return value is in ms."""
> +        if Reconnect.default_min_backoff is None:
> +            try:
> +                Reconnect.default_min_backoff = int(os.environ.get(
> +                    "OVS_RECONNECT_MIN_BACKOFF", ""))
> +            except ValueError:
> +                Reconnect.default_min_backoff = 1000
> +        return Reconnect.default_min_backoff
> +
> +    def get_default_max_backoff():
> +        """Returns the default min_backoff value for reconnect. It uses the
> +        environment variable OVS_RECONNECT_MIN_BACKOFF if set and valid or
> +        otherwise defaults to 1 second. The return value is in ms."""
> +        if Reconnect.default_max_backoff is None:
> +            try:
> +                Reconnect.default_max_backoff = int(os.environ.get(
> +                    "OVS_RECONNECT_MAX_BACKOFF", ""))
> +            except ValueError:
> +                Reconnect.default_max_backoff = 8000
> +        return Reconnect.default_max_backoff
> +
> +    def get_default_probe_interval():
> +        """Returns the default probe_interval value for reconnect. It uses the
> +        environment variable OVS_RECONNECT_PROBE_INTERVAL if set and valid or
> +        otherwise defaults to 1 second. The return value is in ms."""
> +        if Reconnect.default_probe_interval is None:
> +            try:
> +                Reconnect.default_probe_interval = int(os.environ.get(
> +                    "OVS_RECONNECT_PROBE_INTERVAL", ""))
> +            except ValueError:
> +                Reconnect.default_probe_interval = 5000
> +        return Reconnect.default_probe_interval
> +
>      def set_max_tries(self, max_tries):
>          """Limits the maximum number of times that this object will ask the
>          client to try to reconnect to 'max_tries'.  None (the default) means an
> --
> 2.42.0
>
> Diese E Mail enthält möglicherweise vertrauliche Inhalte und ist nur für die Verwertung durch den vorgesehenen Empfänger bestimmt.
> Sollten Sie nicht der vorgesehene Empfänger sein, setzen Sie den Absender bitte unverzüglich in Kenntnis und löschen diese E Mail.
>
> Hinweise zum Datenschutz finden Sie hier<https://www.datenschutz.schwarz> .
>
>
> This e-mail may contain confidential content and is intended only for the specified recipient/s.
> If you are not the intended recipient, please inform the sender immediately and delete this e-mail.
>
> Information on data protection can be found here<https://www.datenschutz.schwarz> .
> _______________________________________________
> dev mailing list
> dev@openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
Felix Huettner Dec. 4, 2023, 10:38 a.m. UTC | #2
Hi Eelco,

thanks for the feedback. I updated it and send a v3.

On Fri, Dec 01, 2023 at 10:38:16AM +0100, Eelco Chaudron wrote:
>
>
> On 8 Nov 2023, at 11:07, Felix Huettner via dev wrote:
>
> > this exposes the old constants regarding min backoff, max backoff and
>
> This
>

sorry, i missed that one, so its still wrong. But if there is a v4 it
will be included.

> >
> > +/* Returns the default min_backoff value for reconnect. It uses the environment
> > + * variable OVS_RECONNECT_MIN_BACKOFF if set and valid or otherwise defaults
> > + * to 1 second. The return value is in ms. */
> > +unsigned int reconnect_default_min_backoff(void) {
> > +    static unsigned int default_min_backoff = 0;
> > +    if (default_min_backoff == 0) {
> > +        char *env = getenv("OVS_RECONNECT_MIN_BACKOFF");
> > +        if (env && env[0]) {
> > +            str_to_uint(env, 10, &default_min_backoff);
> > +        }
> > +        if (default_min_backoff == 0) {
>
> I think we should define some sane minimum value. Or are we ok with 1ms? Some for all the others.

I now defined 1000ms as minimum for the min_backoff and probe_interval
and used 2000ms for max_backoff. Let me know if you find other values
more reasonable.

>
> > +            default_min_backoff = 1000;
>
> I think we should keep the default definitions, and use them here rather than the hard-coded numbers.
> So this will become:
>
>       default_min_backoff = RECONNECT_DEFAULT_MIN_BACKOFF
>

Yes i readded them as defines at the top of the file (so they migrate
from reconnect.h to reconnect.c)

Thanks
Felix
Diese E Mail enthält möglicherweise vertrauliche Inhalte und ist nur für die Verwertung durch den vorgesehenen Empfänger bestimmt.
Sollten Sie nicht der vorgesehene Empfänger sein, setzen Sie den Absender bitte unverzüglich in Kenntnis und löschen diese E Mail.

Hinweise zum Datenschutz finden Sie hier<https://www.datenschutz.schwarz>.


This e-mail may contain confidential content and is intended only for the specified recipient/s.
If you are not the intended recipient, please inform the sender immediately and delete this e-mail.

Information on data protection can be found here<https://www.datenschutz.schwarz>.
Eelco Chaudron Dec. 7, 2023, 9:56 a.m. UTC | #3
On 4 Dec 2023, at 11:38, Felix Huettner wrote:

> Hi Eelco,
>
> thanks for the feedback. I updated it and send a v3.
>
> On Fri, Dec 01, 2023 at 10:38:16AM +0100, Eelco Chaudron wrote:
>>
>>
>> On 8 Nov 2023, at 11:07, Felix Huettner via dev wrote:
>>
>>> this exposes the old constants regarding min backoff, max backoff and
>>
>> This
>>
>
> sorry, i missed that one, so its still wrong. But if there is a v4 it
> will be included.

Thanks for fixing the items mentioned below. I’ll wait for Ilya to take a look at the v3 to see if we need more changes.

Cheers,

Eelco


>>>
>>> +/* Returns the default min_backoff value for reconnect. It uses the environment
>>> + * variable OVS_RECONNECT_MIN_BACKOFF if set and valid or otherwise defaults
>>> + * to 1 second. The return value is in ms. */
>>> +unsigned int reconnect_default_min_backoff(void) {
>>> +    static unsigned int default_min_backoff = 0;
>>> +    if (default_min_backoff == 0) {
>>> +        char *env = getenv("OVS_RECONNECT_MIN_BACKOFF");
>>> +        if (env && env[0]) {
>>> +            str_to_uint(env, 10, &default_min_backoff);
>>> +        }
>>> +        if (default_min_backoff == 0) {
>>
>> I think we should define some sane minimum value. Or are we ok with 1ms? Some for all the others.
>
> I now defined 1000ms as minimum for the min_backoff and probe_interval
> and used 2000ms for max_backoff. Let me know if you find other values
> more reasonable.
>
>>
>>> +            default_min_backoff = 1000;
>>
>> I think we should keep the default definitions, and use them here rather than the hard-coded numbers.
>> So this will become:
>>
>>       default_min_backoff = RECONNECT_DEFAULT_MIN_BACKOFF
>>
>
> Yes i readded them as defines at the top of the file (so they migrate
> from reconnect.h to reconnect.c)
>
> Thanks
> Felix
> Diese E Mail enthält möglicherweise vertrauliche Inhalte und ist nur für die Verwertung durch den vorgesehenen Empfänger bestimmt.
> Sollten Sie nicht der vorgesehene Empfänger sein, setzen Sie den Absender bitte unverzüglich in Kenntnis und löschen diese E Mail.
>
> Hinweise zum Datenschutz finden Sie hier<https://www.datenschutz.schwarz> .
>
>
> This e-mail may contain confidential content and is intended only for the specified recipient/s.
> If you are not the intended recipient, please inform the sender immediately and delete this e-mail.
>
> Information on data protection can be found here<https://www.datenschutz.schwarz> .
diff mbox series

Patch

diff --git a/NEWS b/NEWS
index 6b45492f1..58266ae52 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,13 @@  Post-v3.2.0
        from older version is supported but it may trigger more leader elections
        during the process, and error logs complaining unrecognized fields may
        be observed on old nodes.
+   - The environment variable OVS_RECONNECT_MIN_BACKOFF,
+     OVS_RECONNECT_MAX_BACKOFF and OVS_RECONNECT_PROBE_INTERVAL, if set, allow
+     users to tune the default reconnect configuration. E.g. adapting
+     OVS_RECONNECT_PROBE_INTERVAL modifies the default probe interval, for all
+     servers and clients. These variables are valid for all ovs code as well as
+     the python client. Values set for individual connections (e.g. using the
+     `inactivity_probe` column in the `Manager` tables) will take precedence.


 v3.2.0 - 17 Aug 2023
diff --git a/lib/jsonrpc.c b/lib/jsonrpc.c
index c8ce5362e..7bf49fc81 100644
--- a/lib/jsonrpc.c
+++ b/lib/jsonrpc.c
@@ -1269,8 +1269,8 @@  void
 jsonrpc_session_enable_reconnect(struct jsonrpc_session *s)
 {
     reconnect_set_max_tries(s->reconnect, UINT_MAX);
-    reconnect_set_backoff(s->reconnect, RECONNECT_DEFAULT_MIN_BACKOFF,
-                          RECONNECT_DEFAULT_MAX_BACKOFF);
+    reconnect_set_backoff(s->reconnect, reconnect_default_min_backoff(),
+                          reconnect_default_max_backoff());
 }

 /* Forces 's' to drop its connection (if any) and reconnect. */
diff --git a/lib/reconnect.c b/lib/reconnect.c
index 89a0bcaf9..3e73d7cca 100644
--- a/lib/reconnect.c
+++ b/lib/reconnect.c
@@ -99,9 +99,9 @@  reconnect_create(long long int now)
     struct reconnect *fsm = xzalloc(sizeof *fsm);

     fsm->name = xstrdup("void");
-    fsm->min_backoff = RECONNECT_DEFAULT_MIN_BACKOFF;
-    fsm->max_backoff = RECONNECT_DEFAULT_MAX_BACKOFF;
-    fsm->probe_interval = RECONNECT_DEFAULT_PROBE_INTERVAL;
+    fsm->min_backoff = reconnect_default_min_backoff();
+    fsm->max_backoff = reconnect_default_max_backoff();
+    fsm->probe_interval = reconnect_default_probe_interval();
     fsm->passive = false;
     fsm->info = VLL_INFO;

@@ -163,7 +163,7 @@  reconnect_set_name(struct reconnect *fsm, const char *name)
 }

 /* Return the minimum number of milliseconds to back off between consecutive
- * connection attempts.  The default is RECONNECT_DEFAULT_MIN_BACKOFF. */
+ * connection attempts.  The default is reconnect_default_min_backoff(). */
 int
 reconnect_get_min_backoff(const struct reconnect *fsm)
 {
@@ -171,7 +171,7 @@  reconnect_get_min_backoff(const struct reconnect *fsm)
 }

 /* Return the maximum number of milliseconds to back off between consecutive
- * connection attempts.  The default is RECONNECT_DEFAULT_MAX_BACKOFF. */
+ * connection attempts.  The default is reconnect_default_max_backoff(). */
 int
 reconnect_get_max_backoff(const struct reconnect *fsm)
 {
@@ -190,6 +190,57 @@  reconnect_get_probe_interval(const struct reconnect *fsm)
     return fsm->probe_interval;
 }

+/* Returns the default min_backoff value for reconnect. It uses the environment
+ * variable OVS_RECONNECT_MIN_BACKOFF if set and valid or otherwise defaults
+ * to 1 second. The return value is in ms. */
+unsigned int reconnect_default_min_backoff(void) {
+    static unsigned int default_min_backoff = 0;
+    if (default_min_backoff == 0) {
+        char *env = getenv("OVS_RECONNECT_MIN_BACKOFF");
+        if (env && env[0]) {
+            str_to_uint(env, 10, &default_min_backoff);
+        }
+        if (default_min_backoff == 0) {
+            default_min_backoff = 1000;
+        }
+    }
+    return default_min_backoff;
+}
+
+/* Returns the default max_backoff value for reconnect. It uses the environment
+ * variable OVS_RECONNECT_MAX_BACKOFF if set and valid or otherwise defaults
+ * to 8 second. The return value is in ms. */
+unsigned int reconnect_default_max_backoff(void) {
+    static unsigned int default_max_backoff = 0;
+    if (default_max_backoff == 0) {
+        char *env = getenv("OVS_RECONNECT_MAX_BACKOFF");
+        if (env && env[0]) {
+            str_to_uint(env, 10, &default_max_backoff);
+        }
+        if (default_max_backoff == 0) {
+            default_max_backoff = 8000;
+        }
+    }
+    return default_max_backoff;
+}
+
+/* Returns the default probe_interval value for reconnect. It uses the
+ * environment variable OVS_RECONNECT_PROBE_INTERVAL if set and valid or
+ * otherwise defaults to 5 second. The return value is in ms. */
+unsigned int reconnect_default_probe_interval(void) {
+    static unsigned int default_probe_interval = 0;
+    if (default_probe_interval == 0) {
+        char *env = getenv("OVS_RECONNECT_PROBE_INTERVAL");
+        if (env && env[0]) {
+            str_to_uint(env, 10, &default_probe_interval);
+        }
+        if (default_probe_interval == 0) {
+            default_probe_interval = 5000;
+        }
+    }
+    return default_probe_interval;
+}
+
 /* Limits the maximum number of times that 'fsm' will ask the client to try to
  * reconnect to 'max_tries'.  UINT_MAX (the default) means an unlimited number
  * of tries.
@@ -234,7 +285,7 @@  reconnect_set_backoff(struct reconnect *fsm, int min_backoff, int max_backoff)
     fsm->min_backoff = MAX(min_backoff, 1000);
     fsm->max_backoff = (max_backoff
                         ? MAX(max_backoff, 1000)
-                        : RECONNECT_DEFAULT_MAX_BACKOFF);
+                        : reconnect_default_max_backoff());
     if (fsm->min_backoff > fsm->max_backoff) {
         fsm->max_backoff = fsm->min_backoff;
     }
diff --git a/lib/reconnect.h b/lib/reconnect.h
index 40cc569c4..b76ce0f15 100644
--- a/lib/reconnect.h
+++ b/lib/reconnect.h
@@ -40,10 +40,9 @@  void reconnect_set_quiet(struct reconnect *, bool quiet);
 const char *reconnect_get_name(const struct reconnect *);
 void reconnect_set_name(struct reconnect *, const char *name);

-/* Defaults, all in msecs. */
-#define RECONNECT_DEFAULT_MIN_BACKOFF 1000
-#define RECONNECT_DEFAULT_MAX_BACKOFF 8000
-#define RECONNECT_DEFAULT_PROBE_INTERVAL 5000
+unsigned int reconnect_default_min_backoff(void);
+unsigned int reconnect_default_max_backoff(void);
+unsigned int reconnect_default_probe_interval(void);

 int reconnect_get_min_backoff(const struct reconnect *);
 int reconnect_get_max_backoff(const struct reconnect *);
diff --git a/ovsdb/jsonrpc-server.c b/ovsdb/jsonrpc-server.c
index a3ca48a7b..5d8e98e1c 100644
--- a/ovsdb/jsonrpc-server.c
+++ b/ovsdb/jsonrpc-server.c
@@ -211,9 +211,9 @@  struct ovsdb_jsonrpc_options *
 ovsdb_jsonrpc_default_options(const char *target)
 {
     struct ovsdb_jsonrpc_options *options = xzalloc(sizeof *options);
-    options->max_backoff = RECONNECT_DEFAULT_MAX_BACKOFF;
+    options->max_backoff = reconnect_default_max_backoff();
     options->probe_interval = (stream_or_pstream_needs_probes(target)
-                               ? RECONNECT_DEFAULT_PROBE_INTERVAL
+                               ? reconnect_default_probe_interval()
                                : 0);
     return options;
 }
diff --git a/ovsdb/ovsdb-server.c b/ovsdb/ovsdb-server.c
index 4d29043f4..78e62cdef 100644
--- a/ovsdb/ovsdb-server.c
+++ b/ovsdb/ovsdb-server.c
@@ -330,7 +330,7 @@  main(int argc, char *argv[])
     struct shash all_dbs;
     struct shash_node *node;
     int replication_probe_interval = REPLICATION_DEFAULT_PROBE_INTERVAL;
-    int relay_source_probe_interval = RELAY_SOURCE_DEFAULT_PROBE_INTERVAL;
+    int relay_source_probe_interval = reconnect_default_probe_interval();

     ovs_cmdl_proctitle_init(argc, argv);
     set_program_name(argv[0]);
diff --git a/ovsdb/relay.h b/ovsdb/relay.h
index 218caad65..bf7568701 100644
--- a/ovsdb/relay.h
+++ b/ovsdb/relay.h
@@ -26,8 +26,6 @@  struct ovsdb;
 struct ovsdb_schema;
 struct uuid;

-#define RELAY_SOURCE_DEFAULT_PROBE_INTERVAL RECONNECT_DEFAULT_PROBE_INTERVAL
-
 typedef struct ovsdb_error *(*schema_change_callback)(
                                        struct ovsdb *,
                                        const struct ovsdb_schema *,
diff --git a/python/ovs/reconnect.py b/python/ovs/reconnect.py
index 6b0d023ae..229d08bb6 100644
--- a/python/ovs/reconnect.py
+++ b/python/ovs/reconnect.py
@@ -38,6 +38,9 @@  class Reconnect(object):
     since there is no hidden state.  When not testing, just pass the return
     value of ovs.time.msec().  (Perhaps this design should be revisited
     later.)"""
+    default_min_backoff = None
+    default_max_backoff = None
+    default_probe_interval = None

     class Void(object):
         name = "VOID"
@@ -161,9 +164,9 @@  class Reconnect(object):
         self.enable() and self.set_name() on the returned object."""

         self.name = "void"
-        self.min_backoff = 1000
-        self.max_backoff = 8000
-        self.probe_interval = 5000
+        self.min_backoff = Reconnect.get_default_min_backoff()
+        self.max_backoff = Reconnect.get_default_max_backoff()
+        self.probe_interval = Reconnect.get_default_probe_interval()
         self.passive = False
         self.info_level = vlog.info

@@ -231,6 +234,42 @@  class Reconnect(object):
         self.run() returns ovs.reconnect.DISCONNECT."""
         return self.probe_interval

+    def get_default_min_backoff():
+        """Returns the default min_backoff value for reconnect. It uses the
+        environment variable OVS_RECONNECT_MIN_BACKOFF if set and valid or
+        otherwise defaults to 1 second. The return value is in ms."""
+        if Reconnect.default_min_backoff is None:
+            try:
+                Reconnect.default_min_backoff = int(os.environ.get(
+                    "OVS_RECONNECT_MIN_BACKOFF", ""))
+            except ValueError:
+                Reconnect.default_min_backoff = 1000
+        return Reconnect.default_min_backoff
+
+    def get_default_max_backoff():
+        """Returns the default min_backoff value for reconnect. It uses the
+        environment variable OVS_RECONNECT_MIN_BACKOFF if set and valid or
+        otherwise defaults to 1 second. The return value is in ms."""
+        if Reconnect.default_max_backoff is None:
+            try:
+                Reconnect.default_max_backoff = int(os.environ.get(
+                    "OVS_RECONNECT_MAX_BACKOFF", ""))
+            except ValueError:
+                Reconnect.default_max_backoff = 8000
+        return Reconnect.default_max_backoff
+
+    def get_default_probe_interval():
+        """Returns the default probe_interval value for reconnect. It uses the
+        environment variable OVS_RECONNECT_PROBE_INTERVAL if set and valid or
+        otherwise defaults to 1 second. The return value is in ms."""
+        if Reconnect.default_probe_interval is None:
+            try:
+                Reconnect.default_probe_interval = int(os.environ.get(
+                    "OVS_RECONNECT_PROBE_INTERVAL", ""))
+            except ValueError:
+                Reconnect.default_probe_interval = 5000
+        return Reconnect.default_probe_interval
+
     def set_max_tries(self, max_tries):
         """Limits the maximum number of times that this object will ask the
         client to try to reconnect to 'max_tries'.  None (the default) means an