]>
Commit | Line | Data |
---|---|---|
3ed497fc | 1 | /* |
e0edde6f | 2 | * Copyright (c) 2009, 2010, 2011 Nicira, Inc. |
3ed497fc BP |
3 | * |
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: | |
7 | * | |
8 | * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | * | |
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. | |
15 | */ | |
16 | ||
17 | #include <config.h> | |
18 | ||
19 | #include "reconnect.h" | |
20 | ||
21 | #include <errno.h> | |
22 | #include <stdio.h> | |
23 | #include <stdlib.h> | |
24 | #include <string.h> | |
25 | ||
26 | #include "command-line.h" | |
27 | #include "compiler.h" | |
28 | #include "svec.h" | |
29 | #include "util.h" | |
1e8cf0f7 | 30 | #include "vlog.h" |
3ed497fc BP |
31 | |
32 | static struct reconnect *reconnect; | |
33 | static int now; | |
34 | ||
35 | static const struct command commands[]; | |
36 | ||
37 | static void diff_stats(const struct reconnect_stats *old, | |
5eda645e AE |
38 | const struct reconnect_stats *new, |
39 | int delta); | |
3ed497fc BP |
40 | |
41 | int | |
42 | main(void) | |
43 | { | |
480ce8ab | 44 | extern struct vlog_module VLM_reconnect; |
3ed497fc | 45 | struct reconnect_stats prev; |
a85c0bbc | 46 | unsigned int old_max_tries; |
3ed497fc BP |
47 | int old_time; |
48 | char line[128]; | |
49 | ||
c1a543a8 | 50 | vlog_set_levels(&VLM_reconnect, VLF_ANY_FACILITY, VLL_OFF); |
1e8cf0f7 | 51 | |
3ed497fc BP |
52 | now = 1000; |
53 | reconnect = reconnect_create(now); | |
54 | reconnect_set_name(reconnect, "remote"); | |
55 | reconnect_get_stats(reconnect, now, &prev); | |
56 | printf("### t=%d ###\n", now); | |
57 | old_time = now; | |
a85c0bbc | 58 | old_max_tries = reconnect_get_max_tries(reconnect); |
3ed497fc BP |
59 | while (fgets(line, sizeof line, stdin)) { |
60 | struct reconnect_stats cur; | |
61 | struct svec args; | |
62 | ||
63 | fputs(line, stdout); | |
64 | if (line[0] == '#') { | |
65 | continue; | |
66 | } | |
67 | ||
68 | svec_init(&args); | |
69 | svec_parse_words(&args, line); | |
70 | svec_terminate(&args); | |
71 | if (!svec_is_empty(&args)) { | |
72 | run_command(args.n, args.names, commands); | |
73 | } | |
74 | svec_destroy(&args); | |
75 | ||
76 | if (old_time != now) { | |
77 | printf("\n### t=%d ###\n", now); | |
3ed497fc BP |
78 | } |
79 | ||
80 | reconnect_get_stats(reconnect, now, &cur); | |
5eda645e | 81 | diff_stats(&prev, &cur, now - old_time); |
3ed497fc | 82 | prev = cur; |
a85c0bbc BP |
83 | if (reconnect_get_max_tries(reconnect) != old_max_tries) { |
84 | old_max_tries = reconnect_get_max_tries(reconnect); | |
85 | printf(" %u tries left\n", old_max_tries); | |
86 | } | |
5eda645e AE |
87 | |
88 | old_time = now; | |
3ed497fc BP |
89 | } |
90 | ||
91 | return 0; | |
92 | } | |
93 | ||
94 | static void | |
c69ee87c | 95 | do_enable(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) |
3ed497fc BP |
96 | { |
97 | reconnect_enable(reconnect, now); | |
98 | } | |
99 | ||
100 | static void | |
c69ee87c | 101 | do_disable(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) |
3ed497fc BP |
102 | { |
103 | reconnect_disable(reconnect, now); | |
104 | } | |
105 | ||
106 | static void | |
c69ee87c | 107 | do_force_reconnect(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) |
3ed497fc BP |
108 | { |
109 | reconnect_force_reconnect(reconnect, now); | |
110 | } | |
111 | ||
112 | static int | |
113 | error_from_string(const char *s) | |
114 | { | |
115 | if (!s) { | |
116 | return 0; | |
117 | } else if (!strcmp(s, "ECONNREFUSED")) { | |
118 | return ECONNREFUSED; | |
119 | } else if (!strcmp(s, "EOF")) { | |
120 | return EOF; | |
121 | } else { | |
122 | ovs_fatal(0, "unknown error '%s'", s); | |
123 | } | |
124 | } | |
125 | ||
126 | static void | |
c69ee87c | 127 | do_disconnected(int argc OVS_UNUSED, char *argv[]) |
3ed497fc BP |
128 | { |
129 | reconnect_disconnected(reconnect, now, error_from_string(argv[1])); | |
130 | } | |
131 | ||
132 | static void | |
c69ee87c | 133 | do_connecting(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) |
3ed497fc BP |
134 | { |
135 | reconnect_connecting(reconnect, now); | |
136 | } | |
137 | ||
138 | static void | |
c69ee87c | 139 | do_connect_failed(int argc OVS_UNUSED, char *argv[]) |
3ed497fc BP |
140 | { |
141 | reconnect_connect_failed(reconnect, now, error_from_string(argv[1])); | |
142 | } | |
143 | ||
144 | static void | |
c69ee87c | 145 | do_connected(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) |
3ed497fc BP |
146 | { |
147 | reconnect_connected(reconnect, now); | |
148 | } | |
149 | ||
150 | static void | |
c69ee87c | 151 | do_received(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) |
3ed497fc BP |
152 | { |
153 | reconnect_received(reconnect, now); | |
154 | } | |
155 | ||
156 | static void | |
157 | do_run(int argc, char *argv[]) | |
158 | { | |
159 | enum reconnect_action action; | |
160 | ||
161 | if (argc > 1) { | |
162 | now += atoi(argv[1]); | |
163 | } | |
164 | ||
165 | action = reconnect_run(reconnect, now); | |
166 | switch (action) { | |
167 | default: | |
168 | if (action != 0) { | |
169 | NOT_REACHED(); | |
170 | } | |
171 | break; | |
172 | ||
173 | case RECONNECT_CONNECT: | |
174 | printf(" should connect\n"); | |
175 | break; | |
176 | ||
177 | case RECONNECT_DISCONNECT: | |
178 | printf(" should disconnect\n"); | |
179 | break; | |
180 | ||
181 | case RECONNECT_PROBE: | |
182 | printf(" should send probe\n"); | |
183 | break; | |
184 | } | |
185 | } | |
186 | ||
187 | static void | |
c69ee87c | 188 | do_advance(int argc OVS_UNUSED, char *argv[]) |
3ed497fc BP |
189 | { |
190 | now += atoi(argv[1]); | |
191 | } | |
192 | ||
193 | static void | |
c69ee87c | 194 | do_timeout(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) |
3ed497fc BP |
195 | { |
196 | int timeout = reconnect_timeout(reconnect, now); | |
197 | if (timeout >= 0) { | |
198 | printf(" advance %d ms\n", timeout); | |
199 | now += timeout; | |
200 | } else { | |
201 | printf(" no timeout\n"); | |
202 | } | |
203 | } | |
204 | ||
a85c0bbc | 205 | static void |
c69ee87c | 206 | do_set_max_tries(int argc OVS_UNUSED, char *argv[]) |
a85c0bbc BP |
207 | { |
208 | reconnect_set_max_tries(reconnect, atoi(argv[1])); | |
209 | } | |
210 | ||
3ed497fc BP |
211 | static void |
212 | diff_stats(const struct reconnect_stats *old, | |
5eda645e AE |
213 | const struct reconnect_stats *new, |
214 | int delta) | |
3ed497fc BP |
215 | { |
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); | |
221 | } | |
222 | if (old->creation_time != new->creation_time | |
223 | || old->last_received != new->last_received | |
224 | || old->last_connected != new->last_connected) { | |
225 | printf(" created %lld, last received %lld, last connected %lld\n", | |
226 | new->creation_time, new->last_received, new->last_connected); | |
227 | } | |
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, | |
233 | new->seqno); | |
234 | } | |
5eda645e AE |
235 | if (old->is_connected != new->is_connected) { |
236 | printf(" %sconnected\n", new->is_connected ? "" : "dis"); | |
3ed497fc | 237 | } |
5eda645e AE |
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); | |
eba18f00 | 247 | } |
5eda645e AE |
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); | |
eba18f00 | 254 | } |
3ed497fc BP |
255 | } |
256 | ||
19df7f51 BP |
257 | static void |
258 | do_set_passive(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) | |
259 | { | |
260 | reconnect_set_passive(reconnect, true, now); | |
261 | } | |
262 | ||
263 | static void | |
264 | do_listening(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) | |
265 | { | |
266 | reconnect_listening(reconnect, now); | |
267 | } | |
268 | ||
269 | static void | |
270 | do_listen_error(int argc OVS_UNUSED, char *argv[]) | |
271 | { | |
272 | reconnect_listen_error(reconnect, now, atoi(argv[1])); | |
273 | } | |
274 | ||
3ed497fc BP |
275 | static const struct command commands[] = { |
276 | { "enable", 0, 0, do_enable }, | |
277 | { "disable", 0, 0, do_disable }, | |
278 | { "force-reconnect", 0, 0, do_force_reconnect }, | |
279 | { "disconnected", 0, 1, do_disconnected }, | |
280 | { "connecting", 0, 0, do_connecting }, | |
281 | { "connect-failed", 0, 1, do_connect_failed }, | |
282 | { "connected", 0, 0, do_connected }, | |
283 | { "received", 0, 0, do_received }, | |
284 | { "run", 0, 1, do_run }, | |
285 | { "advance", 1, 1, do_advance }, | |
286 | { "timeout", 0, 0, do_timeout }, | |
a85c0bbc | 287 | { "set-max-tries", 1, 1, do_set_max_tries }, |
19df7f51 BP |
288 | { "passive", 0, 0, do_set_passive }, |
289 | { "listening", 0, 0, do_listening }, | |
290 | { "listen-error", 1, 1, do_listen_error }, | |
3ed497fc BP |
291 | { NULL, 0, 0, NULL }, |
292 | }; |