aboutsummaryrefslogtreecommitdiff
path: root/src/or
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2014-04-24 10:31:38 -0400
committerNick Mathewson <nickm@torproject.org>2014-04-24 10:31:38 -0400
commit67aa3685e7321322cbbc2bef7f87c9a885819af8 (patch)
tree46f3678112d650aea4f628b2dd4fe1d7c39c6be0 /src/or
parentaa1ad30fc9c629eea44d715041f29e4838ff3175 (diff)
parente3af72647db51e99186b9f284066dedcdc8c10d6 (diff)
downloadtor-67aa3685e7321322cbbc2bef7f87c9a885819af8.tar.gz
tor-67aa3685e7321322cbbc2bef7f87c9a885819af8.zip
Merge branch 'bug11396_v2_squashed'
Conflicts: src/or/main.c
Diffstat (limited to 'src/or')
-rw-r--r--src/or/config.c74
-rwxr-xr-xsrc/or/control.c4
-rw-r--r--src/or/main.c1
-rw-r--r--src/or/or.h5
4 files changed, 77 insertions, 7 deletions
diff --git a/src/or/config.c b/src/or/config.c
index c3ddb5c311..3954c582ef 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -307,7 +307,7 @@ static config_var_t option_vars_[] = {
V(MaxAdvertisedBandwidth, MEMUNIT, "1 GB"),
V(MaxCircuitDirtiness, INTERVAL, "10 minutes"),
V(MaxClientCircuitsPending, UINT, "32"),
- V(MaxMemInQueues, MEMUNIT, "8 GB"),
+ VAR("MaxMeminQueues", MEMUNIT, MaxMemInQueues_raw, "0"),
OBSOLETE("MaxOnionsPending"),
V(MaxOnionQueueDelay, MSEC_INTERVAL, "1750 msec"),
V(MinMeasuredBWsForAuthToIgnoreAdvertised, INT, "500"),
@@ -565,6 +565,8 @@ static void config_maybe_load_geoip_files_(const or_options_t *options,
static int options_validate_cb(void *old_options, void *options,
void *default_options,
int from_setconf, char **msg);
+static uint64_t compute_real_max_mem_in_queues(const uint64_t val,
+ int log_guess);
/** Magic value for or_options_t. */
#define OR_OPTIONS_MAGIC 9090909
@@ -2824,11 +2826,9 @@ options_validate(or_options_t *old_options, or_options_t *options,
REJECT("If EntryNodes is set, UseEntryGuards must be enabled.");
}
- if (options->MaxMemInQueues < (256 << 20)) {
- log_warn(LD_CONFIG, "MaxMemInQueues must be at least 256 MB for now. "
- "Ideally, have it as large as you can afford.");
- options->MaxMemInQueues = (256 << 20);
- }
+ options->MaxMemInQueues =
+ compute_real_max_mem_in_queues(options->MaxMemInQueues_raw,
+ server_mode(options));
options->AllowInvalid_ = 0;
@@ -3578,6 +3578,68 @@ options_validate(or_options_t *old_options, or_options_t *options,
#undef COMPLAIN
}
+/* Given the value that the user has set for MaxMemInQueues, compute the
+ * actual maximum value. We clip this value if it's too low, and autodetect
+ * it if it's set to 0. */
+static uint64_t
+compute_real_max_mem_in_queues(const uint64_t val, int log_guess)
+{
+ uint64_t result;
+
+ if (val == 0) {
+#define ONE_GIGABYTE (U64_LITERAL(1) << 30)
+#define ONE_MEGABYTE (U64_LITERAL(1) << 20)
+#if SIZEOF_VOID_P >= 8
+#define MAX_DEFAULT_MAXMEM (8*ONE_GIGABYTE)
+#else
+#define MAX_DEFAULT_MAXMEM (2*ONE_GIGABYTE)
+#endif
+ /* The user didn't pick a memory limit. Choose a very large one
+ * that is still smaller than the system memory */
+ static int notice_sent = 0;
+ size_t ram = 0;
+ if (get_total_system_memory(&ram) < 0) {
+ /* We couldn't determine our total system memory! */
+#if SIZEOF_VOID_P >= 8
+ /* 64-bit system. Let's hope for 8 GB. */
+ result = 8 * ONE_GIGABYTE;
+#else
+ /* (presumably) 32-bit system. Let's hope for 1 GB. */
+ result = ONE_GIGABYTE;
+#endif
+ } else {
+ /* We detected it, so let's pick 3/4 of the total RAM as our limit. */
+ const uint64_t avail = (ram / 4) * 3;
+
+ /* Make sure it's in range from 0.25 GB to 8 GB. */
+ if (avail > MAX_DEFAULT_MAXMEM) {
+ /* If you want to use more than this much RAM, you need to configure
+ it yourself */
+ result = MAX_DEFAULT_MAXMEM;
+ } else if (avail < ONE_GIGABYTE / 4) {
+ result = ONE_GIGABYTE / 4;
+ } else {
+ result = avail;
+ }
+ }
+ if (log_guess && ! notice_sent) {
+ log_notice(LD_CONFIG, "%sMaxMemInQueues is set to "U64_FORMAT" MB. "
+ "You can override this by setting MaxMemInQueues by hand.",
+ ram ? "Based on detected system memory, " : "",
+ U64_PRINTF_ARG(result / ONE_MEGABYTE));
+ notice_sent = 1;
+ }
+ return result;
+ } else if (val < ONE_GIGABYTE / 4) {
+ log_warn(LD_CONFIG, "MaxMemInQueues must be at least 256 MB for now. "
+ "Ideally, have it as large as you can afford.");
+ return ONE_GIGABYTE / 4;
+ } else {
+ /* The value was fine all along */
+ return val;
+ }
+}
+
/** Helper: return true iff s1 and s2 are both NULL, or both non-NULL
* equal strings. */
static int
diff --git a/src/or/control.c b/src/or/control.c
index 2815b7901e..d571900ac3 100755
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -1504,6 +1504,9 @@ getinfo_helper_misc(control_connection_t *conn, const char *question,
int max_fds=-1;
set_max_file_descriptors(0, &max_fds);
tor_asprintf(answer, "%d", max_fds);
+ } else if (!strcmp(question, "limits/max-mem-in-queues")) {
+ tor_asprintf(answer, U64_FORMAT,
+ U64_PRINTF_ARG(get_options()->MaxMemInQueues));
} else if (!strcmp(question, "dir-usage")) {
*answer = directory_dump_request_log();
} else if (!strcmp(question, "fingerprint")) {
@@ -2184,6 +2187,7 @@ static const getinfo_item_t getinfo_items[] = {
ITEM("process/user", misc,
"Username under which the tor process is running."),
ITEM("process/descriptor-limit", misc, "File descriptor limit."),
+ ITEM("limits/max-mem-in-queues", misc, "Actual limit on memory in queues"),
ITEM("dir-usage", misc, "Breakdown of bytes transferred over DirPort."),
PREFIX("desc-annotations/id/", dir, "Router annotations by hexdigest."),
PREFIX("dir/server/", dir,"Router descriptors as retrieved from a DirPort."),
diff --git a/src/or/main.c b/src/or/main.c
index 4770b7e6dd..6713d80368 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -2767,6 +2767,7 @@ sandbox_init_filter(void)
tor_strdup("/dev/urandom"),
tor_strdup("/dev/random"),
tor_strdup("/etc/hosts"),
+ tor_strdup("/proc/meminfo"),
NULL, 0
);
if (options->ServerDNSResolvConfFile)
diff --git a/src/or/or.h b/src/or/or.h
index 4ca7ecc605..701877c64b 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -3491,7 +3491,10 @@ typedef struct {
config_line_t *DirPort_lines;
config_line_t *DNSPort_lines; /**< Ports to listen on for DNS requests. */
- uint64_t MaxMemInQueues; /**< If we have more memory than this allocated
+ /* MaxMemInQueues value as input by the user. We clean this up to be
+ * MaxMemInQueues. */
+ uint64_t MaxMemInQueues_raw;
+ uint64_t MaxMemInQueues;/**< If we have more memory than this allocated
* for queues and buffers, run the OOM handler */
/** @name port booleans