[tor-commits] [tor/master] Issue a `STATUS_SERVER` event on meaningful hibernation state changes.

nickm at torproject.org nickm at torproject.org
Tue Apr 26 17:40:26 UTC 2016


commit a19f4192dabe62ab74e3bf3048fa4209bff595ce
Author: Yawning Angel <yawning at schwanenlied.me>
Date:   Wed Mar 30 20:19:11 2016 +0000

    Issue a `STATUS_SERVER` event on meaningful hibernation state changes.
    
    Implements feature #18685.
---
 changes/feature18685 |  3 +++
 src/or/hibernate.c   | 51 +++++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 48 insertions(+), 6 deletions(-)

diff --git a/changes/feature18685 b/changes/feature18685
new file mode 100644
index 0000000..a6d3dcd
--- /dev/null
+++ b/changes/feature18685
@@ -0,0 +1,3 @@
+  o Minor features (controller):
+    - Fire a `STATUS_SERVER` event whenever the hibernation status changes
+      between "awake"/"soft"/"hard".
diff --git a/src/or/hibernate.c b/src/or/hibernate.c
index 9408925..3666abb 100644
--- a/src/or/hibernate.c
+++ b/src/or/hibernate.c
@@ -28,6 +28,7 @@ hibernating, phase 2:
 #include "config.h"
 #include "connection.h"
 #include "connection_edge.h"
+#include "control.h"
 #include "hibernate.h"
 #include "main.h"
 #include "router.h"
@@ -111,11 +112,34 @@ static int cfg_start_day = 0,
            cfg_start_min = 0;
 /** @} */
 
+static const char *hibernate_state_to_string(hibernate_state_t state);
 static void reset_accounting(time_t now);
 static int read_bandwidth_usage(void);
 static time_t start_of_accounting_period_after(time_t now);
 static time_t start_of_accounting_period_containing(time_t now);
 static void accounting_set_wakeup_time(void);
+static void on_hibernate_state_change(hibernate_state_t prev_state);
+
+/**
+ * Return the human-readable name for the hibernation state <b>state</b>
+ */
+static const char *
+hibernate_state_to_string(hibernate_state_t state)
+{
+  static char buf[64];
+  switch (state) {
+    case HIBERNATE_STATE_EXITING: return "EXITING";
+    case HIBERNATE_STATE_LOWBANDWIDTH: return "SOFT";
+    case HIBERNATE_STATE_DORMANT: return "HARD";
+    case HIBERNATE_STATE_INITIAL:
+    case HIBERNATE_STATE_LIVE:
+      return "AWAKE";
+    default:
+      log_warn(LD_BUG, "unknown hibernate state %d", state);
+      tor_snprintf(buf, sizeof(buf), "unknown [%d]", state);
+      return buf;
+  }
+}
 
 /* ************
  * Functions for bandwidth accounting.
@@ -935,6 +959,7 @@ consider_hibernation(time_t now)
 {
   int accounting_enabled = get_options()->AccountingMax != 0;
   char buf[ISO_TIME_LEN+1];
+  hibernate_state_t prev_state = hibernate_state;
 
   /* If we're in 'exiting' mode, then we just shut down after the interval
    * elapses. */
@@ -990,6 +1015,10 @@ consider_hibernation(time_t now)
       hibernate_end_time_elapsed(now);
     }
   }
+
+  /* Dispatch a controller event if the hibernation state changed. */
+  if (hibernate_state != prev_state)
+    on_hibernate_state_change(prev_state);
 }
 
 /** Helper function: called when we get a GETINFO request for an
@@ -1007,12 +1036,8 @@ getinfo_helper_accounting(control_connection_t *conn,
   if (!strcmp(question, "accounting/enabled")) {
     *answer = tor_strdup(accounting_is_enabled(get_options()) ? "1" : "0");
   } else if (!strcmp(question, "accounting/hibernating")) {
-    if (hibernate_state == HIBERNATE_STATE_DORMANT)
-      *answer = tor_strdup("hard");
-    else if (hibernate_state == HIBERNATE_STATE_LOWBANDWIDTH)
-      *answer = tor_strdup("soft");
-    else
-      *answer = tor_strdup("awake");
+    *answer = tor_strdup(hibernate_state_to_string(hibernate_state));
+    tor_strlower(*answer);
   } else if (!strcmp(question, "accounting/bytes")) {
       tor_asprintf(answer, U64_FORMAT" "U64_FORMAT,
                  U64_PRINTF_ARG(n_bytes_read_in_interval),
@@ -1062,6 +1087,20 @@ getinfo_helper_accounting(control_connection_t *conn,
   return 0;
 }
 
+/**
+ * Helper function: called when the hibernation state changes, and sends a
+ * SERVER_STATUS event to notify interested controllers of the accounting
+ * state change.
+ */
+static void
+on_hibernate_state_change(hibernate_state_t prev_state)
+{
+  (void)prev_state; /* Should we do something with this? */
+  control_event_server_status(LOG_NOTICE,
+                              "HIBERNATION_STATUS STATUS=%s",
+                              hibernate_state_to_string(hibernate_state));
+}
+
 #ifdef TOR_UNIT_TESTS
 /**
  * Manually change the hibernation state.  Private; used only by the unit





More information about the tor-commits mailing list