[or-cvs] Keep bandwidth history accross restarts/crashes

Peter Palfrader weasel at seul.org
Fri Dec 23 23:56:45 UTC 2005


Update of /home/or/cvsroot/tor/src/or
In directory moria:/tmp/cvs-serv10054/src/or

Modified Files:
	config.c main.c or.h rephist.c 
Log Message:
Keep bandwidth history accross restarts/crashes

Index: config.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/config.c,v
retrieving revision 1.465
retrieving revision 1.466
diff -u -p -d -r1.465 -r1.466
--- config.c	15 Dec 2005 21:39:37 -0000	1.465
+++ config.c	23 Dec 2005 23:56:42 -0000	1.466
@@ -229,6 +229,13 @@ static config_var_t _state_vars[] = {
   VAR("HelperNodes",             LINELIST_V,  HelperNodes,          NULL),
   VAR("LastWritten",             ISOTIME,     LastWritten,          NULL),
 
+  VAR("BWHistoryReadEnds",       ISOTIME,     BWHistoryReadEnds,      NULL),
+  VAR("BWHistoryReadInterval",   UINT,        BWHistoryReadInterval,  NULL),
+  VAR("BWHistoryReadValues",     CSV,         BWHistoryReadValues,    NULL),
+  VAR("BWHistoryWriteEnds",      ISOTIME,     BWHistoryWriteEnds,     NULL),
+  VAR("BWHistoryWriteInterval",  UINT,        BWHistoryWriteInterval, NULL),
+  VAR("BWHistoryWriteValues",    CSV,         BWHistoryWriteValues,   NULL),
+
   { NULL, CONFIG_TYPE_OBSOLETE, 0, NULL, NULL }
 };
 
@@ -3516,7 +3523,8 @@ or_state_set(or_state_t *new_state)
   global_state = new_state;
   if (helper_nodes_parse_state(global_state, 1, &err)<0)
     warn(LD_GENERAL,"Unparseable helper nodes state: %s",err);
-
+  if (rep_hist_load_state(global_state, &err)<0)
+    warn(LD_GENERAL,"Unparseable bandwidth history state: %s",err);
 }
 
 /* DOCDOC */
@@ -3589,6 +3597,7 @@ or_state_save(void)
   char *fname;
 
   helper_nodes_update_state(global_state);
+  rep_hist_update_state(global_state);
 
   if (!global_state->dirty)
     return 0;

Index: main.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/main.c,v
retrieving revision 1.603
retrieving revision 1.604
diff -u -p -d -r1.603 -r1.604
--- main.c	15 Dec 2005 22:10:03 -0000	1.603
+++ main.c	23 Dec 2005 23:56:42 -0000	1.604
@@ -779,6 +779,9 @@ run_scheduled_events(time_t now)
      * and the rend cache. */
     rep_history_clean(now - options->RephistTrackTime);
     rend_cache_clean();
+    /* And while we are at it, save the state with bandwidth history
+     * and more. */
+    or_state_save();
   }
 
   /* Caches need to fetch running_routers; directory clients don't. */
@@ -1494,6 +1497,7 @@ tor_cleanup(void)
     unlink(options->PidFile);
   if (accounting_is_enabled(options))
     accounting_record_bandwidth_usage(time(NULL));
+  or_state_save();
   tor_free_all(0); /* move tor_free_all back into the ifdef below later. XXX*/
   crypto_global_cleanup();
 #ifdef USE_DMALLOC

Index: or.h
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/or.h,v
retrieving revision 1.763
retrieving revision 1.764
diff -u -p -d -r1.763 -r1.764
--- or.h	15 Dec 2005 21:51:12 -0000	1.763
+++ or.h	23 Dec 2005 23:56:42 -0000	1.764
@@ -1369,6 +1369,13 @@ typedef struct {
   uint64_t AccountingExpectedUsage;
 
   config_line_t *HelperNodes;
+
+  time_t      BWHistoryReadEnds;
+  int         BWHistoryReadInterval;
+  smartlist_t *BWHistoryReadValues;
+  time_t      BWHistoryWriteEnds;
+  int         BWHistoryWriteInterval;
+  smartlist_t *BWHistoryWriteValues;
 } or_state_t;
 
 #define MAX_SOCKS_REPLY_LEN 1024
@@ -2024,6 +2031,9 @@ void rep_hist_note_used_internal(time_t 
 int rep_hist_get_predicted_internal(time_t now, int *need_uptime,
                                     int *need_capacity);
 
+int rep_hist_update_state(or_state_t *state);
+int rep_hist_load_state(or_state_t *state, const char **err);
+
 void rep_hist_free_all(void);
 
 /********************************* rendclient.c ***************************/

Index: rephist.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/rephist.c,v
retrieving revision 1.73
retrieving revision 1.74
diff -u -p -d -r1.73 -r1.74
--- rephist.c	14 Dec 2005 20:40:40 -0000	1.73
+++ rephist.c	23 Dec 2005 23:56:42 -0000	1.74
@@ -580,6 +580,41 @@ rep_hist_bandwidth_assess(void)
 }
 
 /**
+ * Print the bandwidth history of b (either read_array or write_array)
+ * into the buffer pointed to by buf.  The format is simply comma
+ * separated numbers, from oldest to newest.
+ *
+ * It returns the number of bytes written.
+ */
+size_t
+rep_hist_fill_bandwidth_history(char *buf, size_t len, bw_array_t *b)
+{
+  char *cp = buf;
+  int i, n;
+
+  if (b->num_maxes_set <= b->next_max_idx) {
+    /* We haven't been through the circular array yet; time starts at i=0.*/
+    i = 0;
+  } else {
+    /* We've been around the array at least once.  The next i to be
+       overwritten is the oldest. */
+    i = b->next_max_idx;
+  }
+
+  for (n=0; n<b->num_maxes_set; ++n,++i) {
+    while (i >= NUM_TOTALS) i -= NUM_TOTALS;
+    if (n==(b->num_maxes_set-1))
+      tor_snprintf(cp, len-(cp-buf), U64_FORMAT,
+                   U64_PRINTF_ARG(b->totals[i]));
+    else
+      tor_snprintf(cp, len-(cp-buf), U64_FORMAT",",
+                   U64_PRINTF_ARG(b->totals[i]));
+    cp += strlen(cp);
+  }
+  return cp-buf;
+}
+
+/**
  * Allocate and return lines for representing this server's bandwidth
  * history in its descriptor.
  */
@@ -588,7 +623,7 @@ rep_hist_get_bandwidth_lines(void)
 {
   char *buf, *cp;
   char t[ISO_TIME_LEN+1];
-  int r, i, n;
+  int r;
   bw_array_t *b;
   size_t len;
 
@@ -604,31 +639,117 @@ rep_hist_get_bandwidth_lines(void)
                  r ? "read-history" : "write-history", t,
                  NUM_SECS_BW_SUM_INTERVAL);
     cp += strlen(cp);
-
-    if (b->num_maxes_set <= b->next_max_idx)
-      /* We haven't been through the circular array yet; time starts at i=0.*/
-      i = 0;
-    else
-      /* We've been around the array at least once.  The next i to be
-         overwritten is the oldest. */
-      i = b->next_max_idx;
-
-    for (n=0; n<b->num_maxes_set; ++n,++i) {
-      while (i >= NUM_TOTALS) i -= NUM_TOTALS;
-      if (n==(b->num_maxes_set-1))
-        tor_snprintf(cp, len-(cp-buf), U64_FORMAT,
-                     U64_PRINTF_ARG(b->totals[i]));
-      else
-        tor_snprintf(cp, len-(cp-buf), U64_FORMAT",",
-                     U64_PRINTF_ARG(b->totals[i]));
-      cp += strlen(cp);
-    }
+    cp += rep_hist_fill_bandwidth_history(cp, len-(cp-buf), b);
     strlcat(cp, "\n", len-(cp-buf));
     ++cp;
   }
   return buf;
 }
 
+/** Update the state with bandwidth history
+ * A return value of 0 means nothing was updated,
+ * a value of 1 means something has
+ */
+int
+rep_hist_update_state(or_state_t *state)
+{
+  int len, r;
+  char *buf, *cp;
+  smartlist_t **s_values;
+  time_t *s_begins;
+  int *s_interval;
+  bw_array_t *b;
+
+  len = 20*NUM_TOTALS+1;
+  buf = tor_malloc_zero(len);
+
+  for (r=0;r<2;++r) {
+    b = r?read_array:write_array;
+    s_begins  = r?&state->BWHistoryReadEnds    :&state->BWHistoryWriteEnds;
+    s_interval= r?&state->BWHistoryReadInterval:&state->BWHistoryWriteInterval;
+    s_values  = r?&state->BWHistoryReadValues  :&state->BWHistoryWriteValues;
+
+    *s_begins = b->next_period;
+    *s_interval = NUM_SECS_BW_SUM_INTERVAL;
+    if (*s_values) {
+      SMARTLIST_FOREACH(*s_values, char *, cp, tor_free(cp));
+      smartlist_free(*s_values);
+    }
+    cp = buf;
+    cp += rep_hist_fill_bandwidth_history(cp, len, b);
+    tor_snprintf(cp, len-(cp-buf), cp == buf ? U64_FORMAT : ","U64_FORMAT,
+                 U64_PRINTF_ARG(b->total_in_period));
+    *s_values = smartlist_create();
+    smartlist_split_string(*s_values, buf, ",", SPLIT_SKIP_SPACE, 0);
+  }
+  tor_free(buf);
+  state->dirty = 1;
+  return 1;
+}
+
+/** Set bandwidth history from our saved state.
+ */
+int
+rep_hist_load_state(or_state_t *state, const char **err)
+{
+  time_t s_begins, start;
+  time_t now = time(NULL);
+  uint64_t v;
+  int r,i,ok;
+  int all_ok = 1;
+  int s_interval;
+  smartlist_t *s_values;
+  bw_array_t *b;
+
+  /* Assert they already have been malloced */
+  tor_assert(read_array && write_array);
+
+  for (r=0;r<2;++r) {
+    b = r?read_array:write_array;
+    s_begins = r?state->BWHistoryReadEnds:state->BWHistoryWriteEnds;
+    s_interval =  r?state->BWHistoryReadInterval:state->BWHistoryWriteInterval;
+    s_values =  r?state->BWHistoryReadValues:state->BWHistoryWriteValues;
+    if (s_values && s_begins >= now - NUM_SECS_BW_SUM_INTERVAL*NUM_TOTALS) {
+      start = s_begins - s_interval*(smartlist_len(s_values));
+
+      b->cur_obs_time = start;
+      b->next_period = start + NUM_SECS_BW_SUM_INTERVAL;
+      SMARTLIST_FOREACH(s_values, char *, cp, {
+        v = tor_parse_uint64(cp, 10, 0, UINT64_MAX, &ok, NULL);
+        if (!ok) {
+          all_ok=0;
+          notice(LD_GENERAL, "Could not parse '%s' into a number.'", cp);
+        }
+        add_obs(b, start, v);
+        start += NUM_SECS_BW_SUM_INTERVAL;
+      });
+    }
+
+    /* Clean up maxima and observed */
+    /* Do we really want to zero this for the purpose of max capacity? */
+    for (i=0; i<NUM_SECS_ROLLING_MEASURE; ++i) {
+      b->obs[i] = 0;
+    }
+    b->total_obs = 0;
+    for (i=0; i<NUM_TOTALS; ++i) {
+      b->maxima[i] = 0;
+    }
+    b->max_total = 0;
+  }
+
+  if (!all_ok) {
+    if (err)
+      *err = "Parsing of bandwidth history values failed";
+    /* and create fresh arrays */
+    tor_free(read_array);
+    tor_free(write_array);
+    read_array = bw_array_new();
+    write_array = bw_array_new();
+    return -1;
+  }
+  return 0;
+}
+
 /** A list of port numbers that have been used recently. */
 static smartlist_t *predicted_ports_list=NULL;
 /** The corresponding most recently used time for each port. */



More information about the tor-commits mailing list