[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] r9044: Make bandwidth accounting information get stored to the stat (in tor/trunk: . src/or)
- To: or-cvs@xxxxxxxxxxxxx
- Subject: [or-cvs] r9044: Make bandwidth accounting information get stored to the stat (in tor/trunk: . src/or)
- From: nickm@xxxxxxxx
- Date: Thu, 7 Dec 2006 13:57:42 -0500 (EST)
- Delivered-to: archiver@seul.org
- Delivered-to: or-cvs-outgoing@seul.org
- Delivered-to: or-cvs@seul.org
- Delivery-date: Thu, 07 Dec 2006 13:58:08 -0500
- Reply-to: or-talk@xxxxxxxxxxxxx
- Sender: owner-or-cvs@xxxxxxxxxxxxx
Author: nickm
Date: 2006-12-07 13:57:37 -0500 (Thu, 07 Dec 2006)
New Revision: 9044
Modified:
tor/trunk/
tor/trunk/ChangeLog
tor/trunk/src/or/hibernate.c
tor/trunk/src/or/main.c
tor/trunk/src/or/or.h
Log:
r11462@Kushana: nickm | 2006-12-07 13:42:21 -0500
Make bandwidth accounting information get stored to the state file as well as bw_accounting. Read from the state file if it is more recent than bw_accounting, or if bw_accounting is not there.
Property changes on: tor/trunk
___________________________________________________________________
svk:merge ticket from /tor/trunk [r11462] on c95137ef-5f19-0410-b913-86e773d04f59
Modified: tor/trunk/ChangeLog
===================================================================
--- tor/trunk/ChangeLog 2006-12-07 18:57:29 UTC (rev 9043)
+++ tor/trunk/ChangeLog 2006-12-07 18:57:37 UTC (rev 9044)
@@ -1,4 +1,9 @@
Changes in version 0.1.2.5-xxxx - 200?-??-??
+ o Minor features
+ - Start using the state file to store bandwidth accounting data:
+ the bw_accounting file is now obsolete. We'll keep generating it
+ for a while for people who are still using 0.1.2.4-alpha.
+
o Minor bugfixes;
- Fix a bug when a PF socket is first used. (Patch from Fabian
Keil.)
Modified: tor/trunk/src/or/hibernate.c
===================================================================
--- tor/trunk/src/or/hibernate.c 2006-12-07 18:57:29 UTC (rev 9043)
+++ tor/trunk/src/or/hibernate.c 2006-12-07 18:57:37 UTC (rev 9044)
@@ -420,12 +420,8 @@
configure_accounting(now);
}
if (time_to_record_bandwidth_usage(now)) {
- if (accounting_record_bandwidth_usage(now)) {
- log_err(LD_FS, "Couldn't record bandwidth usage to disk; exiting.");
- /* This can fail when we're out of fd's, causing a crash.
- * The current answer is to reserve 32 more than we need, in
- * set_max_file_descriptors(). */
- exit(1);
+ if (accounting_record_bandwidth_usage(now, get_or_state())) {
+ log_warn(LD_FS, "Couldn't record bandwidth usage to disk.");
}
}
}
@@ -538,7 +534,7 @@
/** Save all our bandwidth tracking information to disk. Return 0 on
* success, -1 on failure. */
int
-accounting_record_bandwidth_usage(time_t now)
+accounting_record_bandwidth_usage(time_t now, or_state_t *state)
{
char buf[128];
char fname[512];
@@ -546,9 +542,12 @@
char time2[ISO_TIME_LEN+1];
char *cp = buf;
time_t tmp;
- /* Format is:
- Version\nTime\nTime\nRead\nWrite\nSeconds\nExpected-Rate\n */
+ int r;
+ /* First, update bw_accounting. Until 0.1.2.5-x, this was the only place
+ * we stored this information. The format is:
+ * Version\nTime\nTime\nRead\nWrite\nSeconds\nExpected-Rate\n */
+
format_iso_time(time1, interval_start_time);
format_iso_time(time2, now);
/* now check to see if they're valid times -- if they're not,
@@ -568,8 +567,17 @@
(unsigned long)expected_bandwidth_usage);
tor_snprintf(fname, sizeof(fname), "%s/bw_accounting",
get_options()->DataDirectory);
+ r = write_str_to_file(fname, buf, 0);
- return write_str_to_file(fname, buf, 0);
+ /* Now update the state */
+ state->AccountingIntervalStart = interval_start_time;
+ state->AccountingBytesReadInInterval = n_bytes_read_in_interval;
+ state->AccountingBytesWrittenInInterval = n_bytes_written_in_interval;
+ state->AccountingSecondsActive = n_seconds_active_in_interval;
+ state->AccountingExpectedUsage = expected_bandwidth_usage;
+ state->dirty = 1;
+
+ return r;
}
/** Read stored accounting information from disk. Return 0 on success;
@@ -582,60 +590,80 @@
time_t t1, t2;
uint64_t n_read, n_written;
uint32_t expected_bw, n_seconds;
- smartlist_t *elts;
- int ok;
+ smartlist_t *elts = NULL;
+ int ok, use_state=0, r=-1;
+ or_state_t *state = get_or_state();
tor_snprintf(fname, sizeof(fname), "%s/bw_accounting",
get_options()->DataDirectory);
- if (!(s = read_file_to_str(fname, 0, NULL))) {
- return 0;
+ elts = smartlist_create();
+ if ((s = read_file_to_str(fname, 0, NULL)) == NULL) {
+ /* We have an old-format bw_accounting file. */
+ use_state = 1;
}
- elts = smartlist_create();
- smartlist_split_string(elts, s, "\n", SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK,0);
- tor_free(s);
+ if (!use_state) {
+ smartlist_split_string(elts, s, "\n",
+ SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK,0);
+ tor_free(s);
- if (smartlist_len(elts)<1 ||
- atoi(smartlist_get(elts,0)) != BW_ACCOUNTING_VERSION) {
- log_warn(LD_ACCT, "Unrecognized bw_accounting file version: %s",
- (const char*)smartlist_get(elts,0));
- goto err;
+ if (smartlist_len(elts)<1 ||
+ atoi(smartlist_get(elts,0)) != BW_ACCOUNTING_VERSION) {
+ log_warn(LD_ACCT, "Unrecognized bw_accounting file version: %s",
+ (const char*)smartlist_get(elts,0));
+ use_state = 1;
+ }
}
- if (smartlist_len(elts) < 7) {
+ if (!use_state && smartlist_len(elts) < 7) {
log_warn(LD_ACCT, "Corrupted bw_accounting file: %d lines",
smartlist_len(elts));
- goto err;
+ use_state = 1;
}
+ if (!use_state && parse_iso_time(smartlist_get(elts,2), &t2)) {
+ log_warn(LD_ACCT, "Error parsing bandwidth usage last-written time");
+ use_state = 1;
+ }
+ if (use_state || t2 <= state->LastWritten) {
+ /* Okay; it looks like the state file is more up-to-date than the
+ * bw_accounting file, or the bw_accounting file is nonexistant,
+ * or the bw_accounting file is corrupt.
+ */
+ log_info(LD_ACCT, "Reading bandwdith accounting data from state file");
+ n_bytes_read_in_interval = state->AccountingBytesReadInInterval;
+ n_bytes_written_in_interval = state->AccountingBytesWrittenInInterval;
+ n_seconds_active_in_interval = state->AccountingSecondsActive;
+ interval_start_time = state->AccountingIntervalStart;
+ expected_bandwidth_usage = state->AccountingExpectedUsage;
+ r = 0;
+ goto done;
+ }
+
if (parse_iso_time(smartlist_get(elts,1), &t1)) {
log_warn(LD_ACCT, "Error parsing bandwidth usage start time.");
- goto err;
+ goto done;
}
- if (parse_iso_time(smartlist_get(elts,2), &t2)) {
- log_warn(LD_ACCT, "Error parsing bandwidth usage last-written time");
- goto err;
- }
n_read = tor_parse_uint64(smartlist_get(elts,3), 10, 0, UINT64_MAX,
&ok, NULL);
if (!ok) {
log_warn(LD_ACCT, "Error parsing number of bytes read");
- goto err;
+ goto done;
}
n_written = tor_parse_uint64(smartlist_get(elts,4), 10, 0, UINT64_MAX,
&ok, NULL);
if (!ok) {
log_warn(LD_ACCT, "Error parsing number of bytes written");
- goto err;
+ goto done;
}
n_seconds = (uint32_t)tor_parse_ulong(smartlist_get(elts,5), 10,0,ULONG_MAX,
&ok, NULL);
if (!ok) {
log_warn(LD_ACCT, "Error parsing number of seconds live");
- goto err;
+ goto done;
}
expected_bw =(uint32_t)tor_parse_ulong(smartlist_get(elts,6), 10,0,ULONG_MAX,
&ok, NULL);
if (!ok) {
log_warn(LD_ACCT, "Error parsing expected bandwidth");
- goto err;
+ goto done;
}
n_bytes_read_in_interval = n_read;
@@ -656,14 +684,14 @@
(unsigned long)((uint64_t)expected_bandwidth_usage*1024/60),
U64_PRINTF_ARG(n_bytes_read_in_interval),
U64_PRINTF_ARG(n_bytes_written_in_interval));
- SMARTLIST_FOREACH(elts, char *, cp, tor_free(cp));
- smartlist_free(elts);
- return 0;
- err:
- SMARTLIST_FOREACH(elts, char *, cp, tor_free(cp));
- smartlist_free(elts);
- return -1;
+ r = 0;
+ done:
+ if (elts) {
+ SMARTLIST_FOREACH(elts, char *, cp, tor_free(cp));
+ smartlist_free(elts);
+ }
+ return r;
}
/** Return true iff we have sent/received all the bytes we are willing
@@ -731,7 +759,7 @@
}
hibernate_state = new_state;
- accounting_record_bandwidth_usage(now);
+ accounting_record_bandwidth_usage(now, get_or_state());
}
/** Called when we've been hibernating and our timeout is reached. */
@@ -798,7 +826,7 @@
connection_mark_for_close(conn);
}
- accounting_record_bandwidth_usage(now);
+ accounting_record_bandwidth_usage(now, get_or_state());
}
/** Called when hibernate_end_time has arrived. */
Modified: tor/trunk/src/or/main.c
===================================================================
--- tor/trunk/src/or/main.c 2006-12-07 18:57:29 UTC (rev 9043)
+++ tor/trunk/src/or/main.c 2006-12-07 18:57:37 UTC (rev 9044)
@@ -1066,7 +1066,7 @@
log_notice(LD_GENERAL,"Received reload signal (hup). Reloading config.");
if (accounting_is_enabled(options))
- accounting_record_bandwidth_usage(time(NULL));
+ accounting_record_bandwidth_usage(time(NULL), get_or_state());
router_reset_warnings();
routerlist_reset_warnings();
@@ -1594,7 +1594,7 @@
if (options->PidFile)
unlink(options->PidFile);
if (accounting_is_enabled(options))
- accounting_record_bandwidth_usage(time(NULL));
+ accounting_record_bandwidth_usage(time(NULL), get_or_state());
or_state_save();
}
tor_free_all(0); /* move tor_free_all back into the ifdef below later. XXX*/
Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h 2006-12-07 18:57:29 UTC (rev 9043)
+++ tor/trunk/src/or/or.h 2006-12-07 18:57:37 UTC (rev 9044)
@@ -1655,9 +1655,10 @@
/** Persistent state for an onion router, as saved to disk. */
typedef struct {
uint32_t _magic;
+ /** True iff this state has been changed since it was last read/written
+ * to the disk. */
int dirty;
- /* XXXX These options aren't actually attached to anything yet. */
time_t LastWritten;
time_t AccountingIntervalStart;
uint64_t AccountingBytesReadInInterval;
@@ -2261,7 +2262,7 @@
void configure_accounting(time_t now);
void accounting_run_housekeeping(time_t now);
void accounting_add_bytes(size_t n_read, size_t n_written, int seconds);
-int accounting_record_bandwidth_usage(time_t now);
+int accounting_record_bandwidth_usage(time_t now, or_state_t *state);
void hibernate_begin_shutdown(void);
int we_are_hibernating(void);
void consider_hibernation(time_t now);