2 * Copyright (c) 2009, 2010, 2011, 2012, 2014, 2016 Nicira, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include "reconnect.h"
24 #include "command-line.h"
29 #include "openvswitch/vlog.h"
31 static struct reconnect *reconnect;
34 static void diff_stats(const struct reconnect_stats *old,
35 const struct reconnect_stats *new,
37 static const struct ovs_cmdl_command *get_all_commands(void);
40 test_reconnect_main(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
42 struct reconnect_stats prev;
43 unsigned int old_max_tries;
47 vlog_set_levels_from_string_assert("reconnect:off");
50 reconnect = reconnect_create(now);
51 reconnect_set_name(reconnect, "remote");
52 reconnect_get_stats(reconnect, now, &prev);
53 printf("### t=%d ###\n", now);
55 old_max_tries = reconnect_get_max_tries(reconnect);
56 while (fgets(line, sizeof line, stdin)) {
57 struct reconnect_stats cur;
66 svec_parse_words(&args, line);
67 svec_terminate(&args);
68 if (!svec_is_empty(&args)) {
69 struct ovs_cmdl_context ctx = {
73 ovs_cmdl_run_command(&ctx, get_all_commands());
77 if (old_time != now) {
78 printf("\n### t=%d ###\n", now);
81 reconnect_get_stats(reconnect, now, &cur);
82 diff_stats(&prev, &cur, now - old_time);
84 if (reconnect_get_max_tries(reconnect) != old_max_tries) {
85 old_max_tries = reconnect_get_max_tries(reconnect);
86 printf(" %u tries left\n", old_max_tries);
94 do_enable(struct ovs_cmdl_context *ctx OVS_UNUSED)
96 reconnect_enable(reconnect, now);
100 do_disable(struct ovs_cmdl_context *ctx OVS_UNUSED)
102 reconnect_disable(reconnect, now);
106 do_force_reconnect(struct ovs_cmdl_context *ctx OVS_UNUSED)
108 reconnect_force_reconnect(reconnect, now);
112 error_from_string(const char *s)
116 } else if (!strcmp(s, "ECONNREFUSED")) {
118 } else if (!strcmp(s, "EOF")) {
121 ovs_fatal(0, "unknown error '%s'", s);
126 do_disconnected(struct ovs_cmdl_context *ctx)
128 reconnect_disconnected(reconnect, now, error_from_string(ctx->argv[1]));
132 do_connecting(struct ovs_cmdl_context *ctx OVS_UNUSED)
134 reconnect_connecting(reconnect, now);
138 do_connect_failed(struct ovs_cmdl_context *ctx)
140 reconnect_connect_failed(reconnect, now, error_from_string(ctx->argv[1]));
144 do_connected(struct ovs_cmdl_context *ctx OVS_UNUSED)
146 reconnect_connected(reconnect, now);
150 do_activity(struct ovs_cmdl_context *ctx OVS_UNUSED)
152 reconnect_activity(reconnect, now);
156 do_run(struct ovs_cmdl_context *ctx)
158 enum reconnect_action action;
161 now += atoi(ctx->argv[1]);
164 action = reconnect_run(reconnect, now);
172 case RECONNECT_CONNECT:
173 printf(" should connect\n");
176 case RECONNECT_DISCONNECT:
177 printf(" should disconnect\n");
180 case RECONNECT_PROBE:
181 printf(" should send probe\n");
187 do_advance(struct ovs_cmdl_context *ctx)
189 now += atoi(ctx->argv[1]);
193 do_timeout(struct ovs_cmdl_context *ctx OVS_UNUSED)
195 int timeout = reconnect_timeout(reconnect, now);
197 printf(" advance %d ms\n", timeout);
200 printf(" no timeout\n");
205 do_set_max_tries(struct ovs_cmdl_context *ctx)
207 reconnect_set_max_tries(reconnect, atoi(ctx->argv[1]));
211 diff_stats(const struct reconnect_stats *old,
212 const struct reconnect_stats *new,
215 if (old->state != new->state
216 || old->state_elapsed != new->state_elapsed
217 || old->backoff != new->backoff) {
218 printf(" in %s for %u ms (%d ms backoff)\n",
219 new->state, new->state_elapsed, new->backoff);
221 if (old->creation_time != new->creation_time
222 || old->last_activity != new->last_activity
223 || old->last_connected != new->last_connected) {
224 printf(" created %lld, last activity %lld, last connected %lld\n",
225 new->creation_time, new->last_activity, new->last_connected);
227 if (old->n_successful_connections != new->n_successful_connections
228 || old->n_attempted_connections != new->n_attempted_connections
229 || old->seqno != new->seqno) {
230 printf(" %u successful connections out of %u attempts, seqno %u\n",
231 new->n_successful_connections, new->n_attempted_connections,
234 if (old->is_connected != new->is_connected) {
235 printf(" %sconnected\n", new->is_connected ? "" : "dis");
237 if (old->last_connected != new->last_connected
238 || (old->msec_since_connect != new->msec_since_connect - delta
239 && !(old->msec_since_connect == UINT_MAX
240 && new->msec_since_connect == UINT_MAX))
241 || (old->total_connected_duration != new->total_connected_duration - delta
242 && !(old->total_connected_duration == 0
243 && new->total_connected_duration == 0))) {
244 printf(" last connected %u ms ago, connected %u ms total\n",
245 new->msec_since_connect, new->total_connected_duration);
247 if (old->last_disconnected != new->last_disconnected
248 || (old->msec_since_disconnect != new->msec_since_disconnect - delta
249 && !(old->msec_since_disconnect == UINT_MAX
250 && new->msec_since_disconnect == UINT_MAX))) {
251 printf(" disconnected at %llu ms (%u ms ago)\n",
252 new->last_disconnected, new->msec_since_disconnect);
257 do_set_passive(struct ovs_cmdl_context *ctx OVS_UNUSED)
259 reconnect_set_passive(reconnect, true, now);
263 do_listening(struct ovs_cmdl_context *ctx OVS_UNUSED)
265 reconnect_listening(reconnect, now);
269 do_listen_error(struct ovs_cmdl_context *ctx)
271 reconnect_listen_error(reconnect, now, atoi(ctx->argv[1]));
274 static const struct ovs_cmdl_command all_commands[] = {
275 { "enable", NULL, 0, 0, do_enable },
276 { "disable", NULL, 0, 0, do_disable },
277 { "force-reconnect", NULL, 0, 0, do_force_reconnect },
278 { "disconnected", NULL, 0, 1, do_disconnected },
279 { "connecting", NULL, 0, 0, do_connecting },
280 { "connect-failed", NULL, 0, 1, do_connect_failed },
281 { "connected", NULL, 0, 0, do_connected },
282 { "activity", NULL, 0, 0, do_activity },
283 { "run", NULL, 0, 1, do_run },
284 { "advance", NULL, 1, 1, do_advance },
285 { "timeout", NULL, 0, 0, do_timeout },
286 { "set-max-tries", NULL, 1, 1, do_set_max_tries },
287 { "passive", NULL, 0, 0, do_set_passive },
288 { "listening", NULL, 0, 0, do_listening },
289 { "listen-error", NULL, 1, 1, do_listen_error },
290 { NULL, NULL, 0, 0, NULL },
293 static const struct ovs_cmdl_command *
294 get_all_commands(void)
299 OVSTEST_REGISTER("test-reconnect", test_reconnect_main);