diff options
Diffstat (limited to 'src/feature/hibernate/hibernate.c')
-rw-r--r-- | src/feature/hibernate/hibernate.c | 35 |
1 files changed, 20 insertions, 15 deletions
diff --git a/src/feature/hibernate/hibernate.c b/src/feature/hibernate/hibernate.c index 09932c97ac..f7847d9a16 100644 --- a/src/feature/hibernate/hibernate.c +++ b/src/feature/hibernate/hibernate.c @@ -35,8 +35,9 @@ hibernating, phase 2: #include "core/mainloop/connection.h" #include "core/or/connection_edge.h" #include "core/or/connection_or.h" -#include "feature/control/control.h" +#include "feature/control/control_events.h" #include "lib/crypt_ops/crypto_rand.h" +#include "lib/defs/time.h" #include "feature/hibernate/hibernate.h" #include "core/mainloop/mainloop.h" #include "feature/relay/router.h" @@ -56,7 +57,7 @@ hibernating, phase 2: * Coverity. Here's a kludge to unconfuse it. */ # define __INCLUDE_LEVEL__ 2 -# endif /* defined(__COVERITY__) && !defined(__INCLUDE_LEVEL__) */ +#endif /* defined(__COVERITY__) && !defined(__INCLUDE_LEVEL__) */ #include <systemd/sd-daemon.h> #endif /* defined(HAVE_SYSTEMD) */ @@ -66,8 +67,9 @@ 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; -/** If we are shutting down, when do we plan finally exit? Set to 0 if - * we aren't shutting down. */ +/** If we are shutting down, when do we plan to finally exit? Set to 0 if we + * aren't shutting down. (This is obsolete; scheduled shutdowns are supposed + * to happen from mainloop_schedule_shutdown() now.) */ static time_t shutdown_time = 0; /** A timed event that we'll use when it's time to wake up from @@ -560,7 +562,7 @@ time_to_record_bandwidth_usage(time_t now) /* Note every 600 sec */ #define NOTE_INTERVAL (600) /* Or every 20 megabytes */ -#define NOTE_BYTES 20*(1024*1024) +#define NOTE_BYTES (20*1024*1024) static uint64_t last_read_bytes_noted = 0; static uint64_t last_written_bytes_noted = 0; static time_t last_time_noted = 0; @@ -813,7 +815,7 @@ hibernate_soft_limit_reached(void) * We want to stop accepting connections when ALL of the following are true: * - We expect to use up the remaining bytes in under 3 hours * - We have used up 95% of our bytes. - * - We have less than 500MB of bytes left. + * - We have less than 500MBytes left. */ uint64_t soft_limit = (uint64_t) (acct_max * SOFT_LIM_PCT); if (acct_max > SOFT_LIM_BYTES && acct_max - SOFT_LIM_BYTES > soft_limit) { @@ -831,8 +833,6 @@ hibernate_soft_limit_reached(void) return get_accounting_bytes() >= soft_limit; } -#define TOR_USEC_PER_SEC (1000000) - /** Called when we get a SIGINT, or when bandwidth soft limit is * reached. Puts us into "loose hibernation": we don't accept new * connections, but we continue handling old ones. */ @@ -867,7 +867,13 @@ hibernate_begin(hibernate_state_t new_state, time_t now) log_notice(LD_GENERAL,"Interrupt: we have stopped accepting new " "connections, and will shut down in %d seconds. Interrupt " "again to exit now.", options->ShutdownWaitLength); - shutdown_time = time(NULL) + options->ShutdownWaitLength; + /* We add an arbitrary delay here so that even if something goes wrong + * with the mainloop shutdown code, we can still shutdown from + * consider_hibernation() if we call it... but so that the + * mainloop_schedule_shutdown() mechanism will be the first one called. + */ + shutdown_time = time(NULL) + options->ShutdownWaitLength + 5; + mainloop_schedule_shutdown(options->ShutdownWaitLength); #ifdef HAVE_SYSTEMD /* tell systemd that we may need more than the default 90 seconds to shut * down so they don't kill us. add some extra time to actually finish @@ -887,7 +893,7 @@ hibernate_begin(hibernate_state_t new_state, time_t now) */ sd_notifyf(0, "EXTEND_TIMEOUT_USEC=%" PRIu64, ((uint64_t)(options->ShutdownWaitLength) + 30) * TOR_USEC_PER_SEC); -#endif +#endif /* defined(HAVE_SYSTEMD) */ } else { /* soft limit reached */ hibernate_end_time = interval_end_time; } @@ -1096,11 +1102,12 @@ consider_hibernation(time_t now) hibernate_state_t prev_state = hibernate_state; /* If we're in 'exiting' mode, then we just shut down after the interval - * elapses. */ + * elapses. The mainloop was supposed to catch this via + * mainloop_schedule_shutdown(), but apparently it didn't. */ if (hibernate_state == HIBERNATE_STATE_EXITING) { tor_assert(shutdown_time); if (shutdown_time <= now) { - log_notice(LD_GENERAL, "Clean shutdown finished. Exiting."); + log_notice(LD_BUG, "Mainloop did not catch shutdown event; exiting."); tor_shutdown_event_loop_and_exit(0); } return; /* if exiting soon, don't worry about bandwidth limits */ @@ -1112,7 +1119,7 @@ consider_hibernation(time_t now) if (hibernate_end_time > now && accounting_enabled) { /* If we're hibernating, don't wake up until it's time, regardless of * whether we're in a new interval. */ - return ; + return; } else { hibernate_end_time_elapsed(now); } @@ -1240,8 +1247,6 @@ on_hibernate_state_change(hibernate_state_t prev_state) if (prev_state != HIBERNATE_STATE_INITIAL) { rescan_periodic_events(get_options()); } - - reschedule_per_second_timer(); } /** Free all resources held by the accounting module */ |