]>
Commit | Line | Data |
---|---|---|
3ed497fc | 1 | /* |
c69ee87c | 2 | * Copyright (c) 2009, 2010 Nicira Networks. |
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, | |
38 | const struct reconnect_stats *new); | |
39 | ||
40 | int | |
41 | main(void) | |
42 | { | |
480ce8ab | 43 | extern struct vlog_module VLM_reconnect; |
3ed497fc | 44 | struct reconnect_stats prev; |
a85c0bbc | 45 | unsigned int old_max_tries; |
3ed497fc BP |
46 | int old_time; |
47 | char line[128]; | |
48 | ||
480ce8ab | 49 | vlog_set_levels(&VLM_reconnect, VLF_ANY_FACILITY, VLL_EMER); |
1e8cf0f7 | 50 | |
3ed497fc BP |
51 | now = 1000; |
52 | reconnect = reconnect_create(now); | |
53 | reconnect_set_name(reconnect, "remote"); | |
54 | reconnect_get_stats(reconnect, now, &prev); | |
55 | printf("### t=%d ###\n", now); | |
56 | old_time = now; | |
a85c0bbc | 57 | old_max_tries = reconnect_get_max_tries(reconnect); |
3ed497fc BP |
58 | while (fgets(line, sizeof line, stdin)) { |
59 | struct reconnect_stats cur; | |
60 | struct svec args; | |
61 | ||
62 | fputs(line, stdout); | |
63 | if (line[0] == '#') { | |
64 | continue; | |
65 | } | |
66 | ||
67 | svec_init(&args); | |
68 | svec_parse_words(&args, line); | |
69 | svec_terminate(&args); | |
70 | if (!svec_is_empty(&args)) { | |
71 | run_command(args.n, args.names, commands); | |
72 | } | |
73 | svec_destroy(&args); | |
74 | ||
75 | if (old_time != now) { | |
76 | printf("\n### t=%d ###\n", now); | |
77 | old_time = now; | |
78 | } | |
79 | ||
80 | reconnect_get_stats(reconnect, now, &cur); | |
81 | diff_stats(&prev, &cur); | |
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 | } | |
3ed497fc BP |
87 | } |
88 | ||
89 | return 0; | |
90 | } | |
91 | ||
92 | static void | |
c69ee87c | 93 | do_enable(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) |
3ed497fc BP |
94 | { |
95 | reconnect_enable(reconnect, now); | |
96 | } | |
97 | ||
98 | static void | |
c69ee87c | 99 | do_disable(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) |
3ed497fc BP |
100 | { |
101 | reconnect_disable(reconnect, now); | |
102 | } | |
103 | ||
104 | static void | |
c69ee87c | 105 | do_force_reconnect(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) |
3ed497fc BP |
106 | { |
107 | reconnect_force_reconnect(reconnect, now); | |
108 | } | |
109 | ||
110 | static int | |
111 | error_from_string(const char *s) | |
112 | { | |
113 | if (!s) { | |
114 | return 0; | |
115 | } else if (!strcmp(s, "ECONNREFUSED")) { | |
116 | return ECONNREFUSED; | |
117 | } else if (!strcmp(s, "EOF")) { | |
118 | return EOF; | |
119 | } else { | |
120 | ovs_fatal(0, "unknown error '%s'", s); | |
121 | } | |
122 | } | |
123 | ||
124 | static void | |
c69ee87c | 125 | do_disconnected(int argc OVS_UNUSED, char *argv[]) |
3ed497fc BP |
126 | { |
127 | reconnect_disconnected(reconnect, now, error_from_string(argv[1])); | |
128 | } | |
129 | ||
130 | static void | |
c69ee87c | 131 | do_connecting(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) |
3ed497fc BP |
132 | { |
133 | reconnect_connecting(reconnect, now); | |
134 | } | |
135 | ||
136 | static void | |
c69ee87c | 137 | do_connect_failed(int argc OVS_UNUSED, char *argv[]) |
3ed497fc BP |
138 | { |
139 | reconnect_connect_failed(reconnect, now, error_from_string(argv[1])); | |
140 | } | |
141 | ||
142 | static void | |
c69ee87c | 143 | do_connected(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) |
3ed497fc BP |
144 | { |
145 | reconnect_connected(reconnect, now); | |
146 | } | |
147 | ||
148 | static void | |
c69ee87c | 149 | do_received(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) |
3ed497fc BP |
150 | { |
151 | reconnect_received(reconnect, now); | |
152 | } | |
153 | ||
154 | static void | |
155 | do_run(int argc, char *argv[]) | |
156 | { | |
157 | enum reconnect_action action; | |
158 | ||
159 | if (argc > 1) { | |
160 | now += atoi(argv[1]); | |
161 | } | |
162 | ||
163 | action = reconnect_run(reconnect, now); | |
164 | switch (action) { | |
165 | default: | |
166 | if (action != 0) { | |
167 | NOT_REACHED(); | |
168 | } | |
169 | break; | |
170 | ||
171 | case RECONNECT_CONNECT: | |
172 | printf(" should connect\n"); | |
173 | break; | |
174 | ||
175 | case RECONNECT_DISCONNECT: | |
176 | printf(" should disconnect\n"); | |
177 | break; | |
178 | ||
179 | case RECONNECT_PROBE: | |
180 | printf(" should send probe\n"); | |
181 | break; | |
182 | } | |
183 | } | |
184 | ||
185 | static void | |
c69ee87c | 186 | do_advance(int argc OVS_UNUSED, char *argv[]) |
3ed497fc BP |
187 | { |
188 | now += atoi(argv[1]); | |
189 | } | |
190 | ||
191 | static void | |
c69ee87c | 192 | do_timeout(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) |
3ed497fc BP |
193 | { |
194 | int timeout = reconnect_timeout(reconnect, now); | |
195 | if (timeout >= 0) { | |
196 | printf(" advance %d ms\n", timeout); | |
197 | now += timeout; | |
198 | } else { | |
199 | printf(" no timeout\n"); | |
200 | } | |
201 | } | |
202 | ||
a85c0bbc | 203 | static void |
c69ee87c | 204 | do_set_max_tries(int argc OVS_UNUSED, char *argv[]) |
a85c0bbc BP |
205 | { |
206 | reconnect_set_max_tries(reconnect, atoi(argv[1])); | |
207 | } | |
208 | ||
3ed497fc BP |
209 | static void |
210 | diff_stats(const struct reconnect_stats *old, | |
211 | const struct reconnect_stats *new) | |
212 | { | |
213 | if (old->state != new->state | |
214 | || old->state_elapsed != new->state_elapsed | |
215 | || old->backoff != new->backoff) { | |
216 | printf(" in %s for %u ms (%d ms backoff)\n", | |
217 | new->state, new->state_elapsed, new->backoff); | |
218 | } | |
219 | if (old->creation_time != new->creation_time | |
220 | || old->last_received != new->last_received | |
221 | || old->last_connected != new->last_connected) { | |
222 | printf(" created %lld, last received %lld, last connected %lld\n", | |
223 | new->creation_time, new->last_received, new->last_connected); | |
224 | } | |
225 | if (old->n_successful_connections != new->n_successful_connections | |
226 | || old->n_attempted_connections != new->n_attempted_connections | |
227 | || old->seqno != new->seqno) { | |
228 | printf(" %u successful connections out of %u attempts, seqno %u\n", | |
229 | new->n_successful_connections, new->n_attempted_connections, | |
230 | new->seqno); | |
231 | } | |
232 | if (old->is_connected != new->is_connected | |
233 | || old->current_connection_duration != new->current_connection_duration | |
234 | || old->total_connected_duration != new->total_connected_duration) { | |
235 | printf(" %sconnected (%u ms), total %u ms connected\n", | |
236 | new->is_connected ? "" : "not ", | |
237 | new->current_connection_duration, | |
238 | new->total_connected_duration); | |
239 | } | |
240 | } | |
241 | ||
19df7f51 BP |
242 | static void |
243 | do_set_passive(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) | |
244 | { | |
245 | reconnect_set_passive(reconnect, true, now); | |
246 | } | |
247 | ||
248 | static void | |
249 | do_listening(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) | |
250 | { | |
251 | reconnect_listening(reconnect, now); | |
252 | } | |
253 | ||
254 | static void | |
255 | do_listen_error(int argc OVS_UNUSED, char *argv[]) | |
256 | { | |
257 | reconnect_listen_error(reconnect, now, atoi(argv[1])); | |
258 | } | |
259 | ||
3ed497fc BP |
260 | static const struct command commands[] = { |
261 | { "enable", 0, 0, do_enable }, | |
262 | { "disable", 0, 0, do_disable }, | |
263 | { "force-reconnect", 0, 0, do_force_reconnect }, | |
264 | { "disconnected", 0, 1, do_disconnected }, | |
265 | { "connecting", 0, 0, do_connecting }, | |
266 | { "connect-failed", 0, 1, do_connect_failed }, | |
267 | { "connected", 0, 0, do_connected }, | |
268 | { "received", 0, 0, do_received }, | |
269 | { "run", 0, 1, do_run }, | |
270 | { "advance", 1, 1, do_advance }, | |
271 | { "timeout", 0, 0, do_timeout }, | |
a85c0bbc | 272 | { "set-max-tries", 1, 1, do_set_max_tries }, |
19df7f51 BP |
273 | { "passive", 0, 0, do_set_passive }, |
274 | { "listening", 0, 0, do_listening }, | |
275 | { "listen-error", 1, 1, do_listen_error }, | |
3ed497fc BP |
276 | { NULL, 0, 0, NULL }, |
277 | }; | |
278 |