mirror of
https://github.com/openvswitch/ovs
synced 2025-10-13 14:07:02 +00:00
This allows other libraries to use util.h that has already defined NOT_REACHED. Signed-off-by: Harold Lim <haroldl@vmware.com> Signed-off-by: Ben Pfaff <blp@nicira.com>
293 lines
7.8 KiB
C
293 lines
7.8 KiB
C
/*
|
|
* Copyright (c) 2009, 2010, 2011, 2012 Nicira, Inc.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at:
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include <config.h>
|
|
|
|
#include "reconnect.h"
|
|
|
|
#include <errno.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "command-line.h"
|
|
#include "compiler.h"
|
|
#include "svec.h"
|
|
#include "util.h"
|
|
#include "vlog.h"
|
|
|
|
static struct reconnect *reconnect;
|
|
static int now;
|
|
|
|
static const struct command commands[];
|
|
|
|
static void diff_stats(const struct reconnect_stats *old,
|
|
const struct reconnect_stats *new,
|
|
int delta);
|
|
|
|
int
|
|
main(void)
|
|
{
|
|
extern struct vlog_module VLM_reconnect;
|
|
struct reconnect_stats prev;
|
|
unsigned int old_max_tries;
|
|
int old_time;
|
|
char line[128];
|
|
|
|
vlog_set_levels(&VLM_reconnect, VLF_ANY_FACILITY, VLL_OFF);
|
|
|
|
now = 1000;
|
|
reconnect = reconnect_create(now);
|
|
reconnect_set_name(reconnect, "remote");
|
|
reconnect_get_stats(reconnect, now, &prev);
|
|
printf("### t=%d ###\n", now);
|
|
old_time = now;
|
|
old_max_tries = reconnect_get_max_tries(reconnect);
|
|
while (fgets(line, sizeof line, stdin)) {
|
|
struct reconnect_stats cur;
|
|
struct svec args;
|
|
|
|
fputs(line, stdout);
|
|
if (line[0] == '#') {
|
|
continue;
|
|
}
|
|
|
|
svec_init(&args);
|
|
svec_parse_words(&args, line);
|
|
svec_terminate(&args);
|
|
if (!svec_is_empty(&args)) {
|
|
run_command(args.n, args.names, commands);
|
|
}
|
|
svec_destroy(&args);
|
|
|
|
if (old_time != now) {
|
|
printf("\n### t=%d ###\n", now);
|
|
}
|
|
|
|
reconnect_get_stats(reconnect, now, &cur);
|
|
diff_stats(&prev, &cur, now - old_time);
|
|
prev = cur;
|
|
if (reconnect_get_max_tries(reconnect) != old_max_tries) {
|
|
old_max_tries = reconnect_get_max_tries(reconnect);
|
|
printf(" %u tries left\n", old_max_tries);
|
|
}
|
|
|
|
old_time = now;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void
|
|
do_enable(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
|
|
{
|
|
reconnect_enable(reconnect, now);
|
|
}
|
|
|
|
static void
|
|
do_disable(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
|
|
{
|
|
reconnect_disable(reconnect, now);
|
|
}
|
|
|
|
static void
|
|
do_force_reconnect(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
|
|
{
|
|
reconnect_force_reconnect(reconnect, now);
|
|
}
|
|
|
|
static int
|
|
error_from_string(const char *s)
|
|
{
|
|
if (!s) {
|
|
return 0;
|
|
} else if (!strcmp(s, "ECONNREFUSED")) {
|
|
return ECONNREFUSED;
|
|
} else if (!strcmp(s, "EOF")) {
|
|
return EOF;
|
|
} else {
|
|
ovs_fatal(0, "unknown error '%s'", s);
|
|
}
|
|
}
|
|
|
|
static void
|
|
do_disconnected(int argc OVS_UNUSED, char *argv[])
|
|
{
|
|
reconnect_disconnected(reconnect, now, error_from_string(argv[1]));
|
|
}
|
|
|
|
static void
|
|
do_connecting(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
|
|
{
|
|
reconnect_connecting(reconnect, now);
|
|
}
|
|
|
|
static void
|
|
do_connect_failed(int argc OVS_UNUSED, char *argv[])
|
|
{
|
|
reconnect_connect_failed(reconnect, now, error_from_string(argv[1]));
|
|
}
|
|
|
|
static void
|
|
do_connected(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
|
|
{
|
|
reconnect_connected(reconnect, now);
|
|
}
|
|
|
|
static void
|
|
do_activity(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
|
|
{
|
|
reconnect_activity(reconnect, now);
|
|
}
|
|
|
|
static void
|
|
do_run(int argc, char *argv[])
|
|
{
|
|
enum reconnect_action action;
|
|
|
|
if (argc > 1) {
|
|
now += atoi(argv[1]);
|
|
}
|
|
|
|
action = reconnect_run(reconnect, now);
|
|
switch (action) {
|
|
default:
|
|
if (action != 0) {
|
|
OVS_NOT_REACHED();
|
|
}
|
|
break;
|
|
|
|
case RECONNECT_CONNECT:
|
|
printf(" should connect\n");
|
|
break;
|
|
|
|
case RECONNECT_DISCONNECT:
|
|
printf(" should disconnect\n");
|
|
break;
|
|
|
|
case RECONNECT_PROBE:
|
|
printf(" should send probe\n");
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
do_advance(int argc OVS_UNUSED, char *argv[])
|
|
{
|
|
now += atoi(argv[1]);
|
|
}
|
|
|
|
static void
|
|
do_timeout(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
|
|
{
|
|
int timeout = reconnect_timeout(reconnect, now);
|
|
if (timeout >= 0) {
|
|
printf(" advance %d ms\n", timeout);
|
|
now += timeout;
|
|
} else {
|
|
printf(" no timeout\n");
|
|
}
|
|
}
|
|
|
|
static void
|
|
do_set_max_tries(int argc OVS_UNUSED, char *argv[])
|
|
{
|
|
reconnect_set_max_tries(reconnect, atoi(argv[1]));
|
|
}
|
|
|
|
static void
|
|
diff_stats(const struct reconnect_stats *old,
|
|
const struct reconnect_stats *new,
|
|
int delta)
|
|
{
|
|
if (old->state != new->state
|
|
|| old->state_elapsed != new->state_elapsed
|
|
|| old->backoff != new->backoff) {
|
|
printf(" in %s for %u ms (%d ms backoff)\n",
|
|
new->state, new->state_elapsed, new->backoff);
|
|
}
|
|
if (old->creation_time != new->creation_time
|
|
|| old->last_activity != new->last_activity
|
|
|| old->last_connected != new->last_connected) {
|
|
printf(" created %lld, last activity %lld, last connected %lld\n",
|
|
new->creation_time, new->last_activity, new->last_connected);
|
|
}
|
|
if (old->n_successful_connections != new->n_successful_connections
|
|
|| old->n_attempted_connections != new->n_attempted_connections
|
|
|| old->seqno != new->seqno) {
|
|
printf(" %u successful connections out of %u attempts, seqno %u\n",
|
|
new->n_successful_connections, new->n_attempted_connections,
|
|
new->seqno);
|
|
}
|
|
if (old->is_connected != new->is_connected) {
|
|
printf(" %sconnected\n", new->is_connected ? "" : "dis");
|
|
}
|
|
if (old->last_connected != new->last_connected
|
|
|| (old->msec_since_connect != new->msec_since_connect - delta
|
|
&& !(old->msec_since_connect == UINT_MAX
|
|
&& new->msec_since_connect == UINT_MAX))
|
|
|| (old->total_connected_duration != new->total_connected_duration - delta
|
|
&& !(old->total_connected_duration == 0
|
|
&& new->total_connected_duration == 0))) {
|
|
printf(" last connected %u ms ago, connected %u ms total\n",
|
|
new->msec_since_connect, new->total_connected_duration);
|
|
}
|
|
if (old->last_disconnected != new->last_disconnected
|
|
|| (old->msec_since_disconnect != new->msec_since_disconnect - delta
|
|
&& !(old->msec_since_disconnect == UINT_MAX
|
|
&& new->msec_since_disconnect == UINT_MAX))) {
|
|
printf(" disconnected at %llu ms (%u ms ago)\n",
|
|
new->last_disconnected, new->msec_since_disconnect);
|
|
}
|
|
}
|
|
|
|
static void
|
|
do_set_passive(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
|
|
{
|
|
reconnect_set_passive(reconnect, true, now);
|
|
}
|
|
|
|
static void
|
|
do_listening(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
|
|
{
|
|
reconnect_listening(reconnect, now);
|
|
}
|
|
|
|
static void
|
|
do_listen_error(int argc OVS_UNUSED, char *argv[])
|
|
{
|
|
reconnect_listen_error(reconnect, now, atoi(argv[1]));
|
|
}
|
|
|
|
static const struct command commands[] = {
|
|
{ "enable", 0, 0, do_enable },
|
|
{ "disable", 0, 0, do_disable },
|
|
{ "force-reconnect", 0, 0, do_force_reconnect },
|
|
{ "disconnected", 0, 1, do_disconnected },
|
|
{ "connecting", 0, 0, do_connecting },
|
|
{ "connect-failed", 0, 1, do_connect_failed },
|
|
{ "connected", 0, 0, do_connected },
|
|
{ "activity", 0, 0, do_activity },
|
|
{ "run", 0, 1, do_run },
|
|
{ "advance", 1, 1, do_advance },
|
|
{ "timeout", 0, 0, do_timeout },
|
|
{ "set-max-tries", 1, 1, do_set_max_tries },
|
|
{ "passive", 0, 0, do_set_passive },
|
|
{ "listening", 0, 0, do_listening },
|
|
{ "listen-error", 1, 1, do_listen_error },
|
|
{ NULL, 0, 0, NULL },
|
|
};
|