From d10ae9c02808c10b19bca66cdc1972616b2b6646 Mon Sep 17 00:00:00 2001 From: Sebastian Hahn Date: Thu, 1 Sep 2011 05:21:50 +0200 Subject: Don't update AccountingSoftLimitHitAt on startup Add a "default" state which we use until we've decided whether we're live or hibernating. This allows us to properly track whether we're resuming a hibernation period or not. Fixes bug 2003. --- changes/bug2003 | 8 ++++++++ src/or/hibernate.c | 18 +++++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-) create mode 100644 changes/bug2003 diff --git a/changes/bug2003 b/changes/bug2003 new file mode 100644 index 0000000000..f1298dd639 --- /dev/null +++ b/changes/bug2003 @@ -0,0 +1,8 @@ + o Major bugfixes: + - Don't update the AccountingSoftLimitHitAt state file entry whenever + tor gets started. This prevents a wrong average bandwidth estimate, + which would cause relays to always start a new accounting interval at + the earliest possible moment. Fixes bug 2003; bugfix on 0.2.2.7-alpha. + Reported by BryonEldridge, who also helped immensely in tracking this + bug down. Thanks! + diff --git a/src/or/hibernate.c b/src/or/hibernate.c index aebce4cc88..badc96ba8e 100644 --- a/src/or/hibernate.c +++ b/src/or/hibernate.c @@ -41,14 +41,17 @@ typedef enum { HIBERNATE_STATE_LOWBANDWIDTH=3, /** We are hibernating, and we won't wake up till there's more bandwidth to * use. */ - HIBERNATE_STATE_DORMANT=4 + HIBERNATE_STATE_DORMANT=4, + /** We start out in state default, which means we havent decided which state + * we're in. */ + HIBERNATE_STATE_INITIAL=5 } hibernate_state_t; extern long stats_n_seconds_working; /* published uptime */ /** Are we currently awake, asleep, running out of bandwidth, or shutting * down? */ -static hibernate_state_t hibernate_state = HIBERNATE_STATE_LIVE; +static hibernate_state_t hibernate_state = HIBERNATE_STATE_INITIAL; /** If are hibernating, when do we plan to wake up? Set to 0 if we * aren't hibernating. */ static time_t hibernate_end_time = 0; @@ -804,10 +807,12 @@ static void hibernate_end(hibernate_state_t new_state) { tor_assert(hibernate_state == HIBERNATE_STATE_LOWBANDWIDTH || - hibernate_state == HIBERNATE_STATE_DORMANT); + hibernate_state == HIBERNATE_STATE_DORMANT || + hibernate_state == HIBERNATE_STATE_INITIAL); /* listeners will be relaunched in run_scheduled_events() in main.c */ - log_notice(LD_ACCT,"Hibernation period ended. Resuming normal activity."); + if (hibernate_state != HIBERNATE_STATE_INITIAL) + log_notice(LD_ACCT,"Hibernation period ended. Resuming normal activity."); hibernate_state = new_state; hibernate_end_time = 0; /* no longer hibernating */ @@ -939,7 +944,8 @@ consider_hibernation(time_t now) /* Else, we aren't hibernating. See if it's time to start hibernating, or to * go dormant. */ - if (hibernate_state == HIBERNATE_STATE_LIVE) { + if (hibernate_state == HIBERNATE_STATE_LIVE || + hibernate_state == HIBERNATE_STATE_INITIAL) { if (hibernate_soft_limit_reached()) { log_notice(LD_ACCT, "Bandwidth soft limit reached; commencing hibernation. " @@ -951,6 +957,8 @@ consider_hibernation(time_t now) "Commencing hibernation. We will wake up at %s local time.", buf); hibernate_go_dormant(now); + } else if (hibernate_state == HIBERNATE_STATE_INITIAL) { + hibernate_end(HIBERNATE_STATE_LIVE); } } -- cgit v1.2.3-54-g00ecf From 9bdde8902716bf923a78d8c287acadb0c4d2ffcd Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 7 Sep 2011 17:48:21 -0400 Subject: Make the unit tests pass again after the bug2003 fix --- src/or/hibernate.c | 28 ++++++++++------------------ src/or/hibernate.h | 22 ++++++++++++++++++++++ src/test/test_dir.c | 6 +++++- 3 files changed, 37 insertions(+), 19 deletions(-) diff --git a/src/or/hibernate.c b/src/or/hibernate.c index badc96ba8e..6b1217a446 100644 --- a/src/or/hibernate.c +++ b/src/or/hibernate.c @@ -21,6 +21,7 @@ hibernating, phase 2: - close all OR/AP/exit conns) */ +#define HIBERNATE_PRIVATE #include "or.h" #include "config.h" #include "connection.h" @@ -29,24 +30,6 @@ hibernating, phase 2: #include "main.h" #include "router.h" -/** Possible values of hibernate_state */ -typedef enum { - /** We are running normally. */ - HIBERNATE_STATE_LIVE=1, - /** We're trying to shut down cleanly, and we'll kill all active connections - * at shutdown_time. */ - HIBERNATE_STATE_EXITING=2, - /** We're running low on allocated bandwidth for this period, so we won't - * accept any new connections. */ - HIBERNATE_STATE_LOWBANDWIDTH=3, - /** We are hibernating, and we won't wake up till there's more bandwidth to - * use. */ - HIBERNATE_STATE_DORMANT=4, - /** We start out in state default, which means we havent decided which state - * we're in. */ - HIBERNATE_STATE_INITIAL=5 -} hibernate_state_t; - extern long stats_n_seconds_working; /* published uptime */ /** Are we currently awake, asleep, running out of bandwidth, or shutting @@ -1025,3 +1008,12 @@ getinfo_helper_accounting(control_connection_t *conn, return 0; } +/** + * Manually change the hibernation state. Private; used only by the unit + * tests. + */ +void +hibernate_set_state_for_testing_(hibernate_state_t newstate) +{ + hibernate_state = newstate; +} diff --git a/src/or/hibernate.h b/src/or/hibernate.h index 2aea0fab0c..fc5b08fcc8 100644 --- a/src/or/hibernate.h +++ b/src/or/hibernate.h @@ -25,5 +25,27 @@ int getinfo_helper_accounting(control_connection_t *conn, const char *question, char **answer, const char **errmsg); +#ifdef HIBERNATE_PRIVATE +/** Possible values of hibernate_state */ +typedef enum { + /** We are running normally. */ + HIBERNATE_STATE_LIVE=1, + /** We're trying to shut down cleanly, and we'll kill all active connections + * at shutdown_time. */ + HIBERNATE_STATE_EXITING=2, + /** We're running low on allocated bandwidth for this period, so we won't + * accept any new connections. */ + HIBERNATE_STATE_LOWBANDWIDTH=3, + /** We are hibernating, and we won't wake up till there's more bandwidth to + * use. */ + HIBERNATE_STATE_DORMANT=4, + /** We start out in state default, which means we havent decided which state + * we're in. */ + HIBERNATE_STATE_INITIAL=5 +} hibernate_state_t; + +void hibernate_set_state_for_testing_(hibernate_state_t newstate); +#endif + #endif diff --git a/src/test/test_dir.c b/src/test/test_dir.c index 8fd94289a9..8a0fe9a677 100644 --- a/src/test/test_dir.c +++ b/src/test/test_dir.c @@ -7,10 +7,12 @@ #define DIRSERV_PRIVATE #define DIRVOTE_PRIVATE #define ROUTER_PRIVATE +#define HIBERNATE_PRIVATE #include "or.h" #include "directory.h" #include "dirserv.h" #include "dirvote.h" +#include "hibernate.h" #include "networkstatus.h" #include "router.h" #include "routerlist.h" @@ -85,6 +87,8 @@ test_dir_formats(void) test_assert(pk1 && pk2 && pk3); + hibernate_set_state_for_testing_(HIBERNATE_STATE_LIVE); + get_platform_str(platform, sizeof(platform)); r1 = tor_malloc_zero(sizeof(routerinfo_t)); r1->address = tor_strdup("18.244.0.1"); @@ -1301,7 +1305,7 @@ test_dir_v3_networkstatus(void) } #define DIR_LEGACY(name) \ - { #name, legacy_test_helper, 0, &legacy_setup, test_dir_ ## name } + { #name, legacy_test_helper, TT_FORK, &legacy_setup, test_dir_ ## name } #define DIR(name) \ { #name, test_dir_##name, 0, NULL, NULL } -- cgit v1.2.3-54-g00ecf