2 * Copyright (c) 2009, 2010, 2011, 2012, 2014 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 extern struct vlog_module VLM_reconnect
;
43 struct reconnect_stats prev
;
44 unsigned int old_max_tries
;
48 vlog_set_levels(&VLM_reconnect
, VLF_ANY_DESTINATION
, VLL_OFF
);
51 reconnect
= reconnect_create(now
);
52 reconnect_set_name(reconnect
, "remote");
53 reconnect_get_stats(reconnect
, now
, &prev
);
54 printf("### t=%d ###\n", now
);
56 old_max_tries
= reconnect_get_max_tries(reconnect
);
57 while (fgets(line
, sizeof line
, stdin
)) {
58 struct reconnect_stats cur
;
67 svec_parse_words(&args
, line
);
68 svec_terminate(&args
);
69 if (!svec_is_empty(&args
)) {
70 struct ovs_cmdl_context ctx
= {
74 ovs_cmdl_run_command(&ctx
, get_all_commands());
78 if (old_time
!= now
) {
79 printf("\n### t=%d ###\n", now
);
82 reconnect_get_stats(reconnect
, now
, &cur
);
83 diff_stats(&prev
, &cur
, now
- old_time
);
85 if (reconnect_get_max_tries(reconnect
) != old_max_tries
) {
86 old_max_tries
= reconnect_get_max_tries(reconnect
);
87 printf(" %u tries left\n", old_max_tries
);
95 do_enable(struct ovs_cmdl_context
*ctx OVS_UNUSED
)
97 reconnect_enable(reconnect
, now
);
101 do_disable(struct ovs_cmdl_context
*ctx OVS_UNUSED
)
103 reconnect_disable(reconnect
, now
);
107 do_force_reconnect(struct ovs_cmdl_context
*ctx OVS_UNUSED
)
109 reconnect_force_reconnect(reconnect
, now
);
113 error_from_string(const char *s
)
117 } else if (!strcmp(s
, "ECONNREFUSED")) {
119 } else if (!strcmp(s
, "EOF")) {
122 ovs_fatal(0, "unknown error '%s'", s
);
127 do_disconnected(struct ovs_cmdl_context
*ctx
)
129 reconnect_disconnected(reconnect
, now
, error_from_string(ctx
->argv
[1]));
133 do_connecting(struct ovs_cmdl_context
*ctx OVS_UNUSED
)
135 reconnect_connecting(reconnect
, now
);
139 do_connect_failed(struct ovs_cmdl_context
*ctx
)
141 reconnect_connect_failed(reconnect
, now
, error_from_string(ctx
->argv
[1]));
145 do_connected(struct ovs_cmdl_context
*ctx OVS_UNUSED
)
147 reconnect_connected(reconnect
, now
);
151 do_activity(struct ovs_cmdl_context
*ctx OVS_UNUSED
)
153 reconnect_activity(reconnect
, now
);
157 do_run(struct ovs_cmdl_context
*ctx
)
159 enum reconnect_action action
;
162 now
+= atoi(ctx
->argv
[1]);
165 action
= reconnect_run(reconnect
, now
);
173 case RECONNECT_CONNECT
:
174 printf(" should connect\n");
177 case RECONNECT_DISCONNECT
:
178 printf(" should disconnect\n");
181 case RECONNECT_PROBE
:
182 printf(" should send probe\n");
188 do_advance(struct ovs_cmdl_context
*ctx
)
190 now
+= atoi(ctx
->argv
[1]);
194 do_timeout(struct ovs_cmdl_context
*ctx OVS_UNUSED
)
196 int timeout
= reconnect_timeout(reconnect
, now
);
198 printf(" advance %d ms\n", timeout
);
201 printf(" no timeout\n");
206 do_set_max_tries(struct ovs_cmdl_context
*ctx
)
208 reconnect_set_max_tries(reconnect
, atoi(ctx
->argv
[1]));
212 diff_stats(const struct reconnect_stats
*old
,
213 const struct reconnect_stats
*new,
216 if (old
->state
!= new->state
217 || old
->state_elapsed
!= new->state_elapsed
218 || old
->backoff
!= new->backoff
) {
219 printf(" in %s for %u ms (%d ms backoff)\n",
220 new->state
, new->state_elapsed
, new->backoff
);
222 if (old
->creation_time
!= new->creation_time
223 || old
->last_activity
!= new->last_activity
224 || old
->last_connected
!= new->last_connected
) {
225 printf(" created %lld, last activity %lld, last connected %lld\n",
226 new->creation_time
, new->last_activity
, new->last_connected
);
228 if (old
->n_successful_connections
!= new->n_successful_connections
229 || old
->n_attempted_connections
!= new->n_attempted_connections
230 || old
->seqno
!= new->seqno
) {
231 printf(" %u successful connections out of %u attempts, seqno %u\n",
232 new->n_successful_connections
, new->n_attempted_connections
,
235 if (old
->is_connected
!= new->is_connected
) {
236 printf(" %sconnected\n", new->is_connected
? "" : "dis");
238 if (old
->last_connected
!= new->last_connected
239 || (old
->msec_since_connect
!= new->msec_since_connect
- delta
240 && !(old
->msec_since_connect
== UINT_MAX
241 && new->msec_since_connect
== UINT_MAX
))
242 || (old
->total_connected_duration
!= new->total_connected_duration
- delta
243 && !(old
->total_connected_duration
== 0
244 && new->total_connected_duration
== 0))) {
245 printf(" last connected %u ms ago, connected %u ms total\n",
246 new->msec_since_connect
, new->total_connected_duration
);
248 if (old
->last_disconnected
!= new->last_disconnected
249 || (old
->msec_since_disconnect
!= new->msec_since_disconnect
- delta
250 && !(old
->msec_since_disconnect
== UINT_MAX
251 && new->msec_since_disconnect
== UINT_MAX
))) {
252 printf(" disconnected at %llu ms (%u ms ago)\n",
253 new->last_disconnected
, new->msec_since_disconnect
);
258 do_set_passive(struct ovs_cmdl_context
*ctx OVS_UNUSED
)
260 reconnect_set_passive(reconnect
, true, now
);
264 do_listening(struct ovs_cmdl_context
*ctx OVS_UNUSED
)
266 reconnect_listening(reconnect
, now
);
270 do_listen_error(struct ovs_cmdl_context
*ctx
)
272 reconnect_listen_error(reconnect
, now
, atoi(ctx
->argv
[1]));
275 static const struct ovs_cmdl_command all_commands
[] = {
276 { "enable", NULL
, 0, 0, do_enable
},
277 { "disable", NULL
, 0, 0, do_disable
},
278 { "force-reconnect", NULL
, 0, 0, do_force_reconnect
},
279 { "disconnected", NULL
, 0, 1, do_disconnected
},
280 { "connecting", NULL
, 0, 0, do_connecting
},
281 { "connect-failed", NULL
, 0, 1, do_connect_failed
},
282 { "connected", NULL
, 0, 0, do_connected
},
283 { "activity", NULL
, 0, 0, do_activity
},
284 { "run", NULL
, 0, 1, do_run
},
285 { "advance", NULL
, 1, 1, do_advance
},
286 { "timeout", NULL
, 0, 0, do_timeout
},
287 { "set-max-tries", NULL
, 1, 1, do_set_max_tries
},
288 { "passive", NULL
, 0, 0, do_set_passive
},
289 { "listening", NULL
, 0, 0, do_listening
},
290 { "listen-error", NULL
, 1, 1, do_listen_error
},
291 { NULL
, NULL
, 0, 0, NULL
},
294 static const struct ovs_cmdl_command
*
295 get_all_commands(void)
300 OVSTEST_REGISTER("test-reconnect", test_reconnect_main
);