From patchwork Mon Aug 15 20:04:44 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Siddhesh Poyarekar X-Patchwork-Id: 14593 Received: (qmail 116709 invoked by alias); 15 Aug 2016 20:05:19 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 116698 invoked by uid 89); 15 Aug 2016 20:05:18 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.4 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE, RCVD_IN_SORBS_WEB, SPF_NEUTRAL autolearn=no version=3.3.2 spammy=1416, 1096, H*f:sk:1471291, H*i:sk:1471291 X-HELO: homiemail-a124.g.dreamhost.com From: Siddhesh Poyarekar To: libc-alpha@sourceware.org Cc: carlos@redhat.com, fweimer@redhat.com Subject: [PATCH 2/2] Initialize tunable list with the GLIBC_TUNABLES environment variable Date: Tue, 16 Aug 2016 01:34:44 +0530 Message-Id: <1471291484-27379-3-git-send-email-siddhesh@sourceware.org> In-Reply-To: <1471291484-27379-1-git-send-email-siddhesh@sourceware.org> References: <1471291484-27379-1-git-send-email-siddhesh@sourceware.org> Read tunables values from the users using the GLIBC_TUNABLES environment variable. The value of this variable is a colon-separated list of name=value pairs. So a typical string would look like this: GLIBC_TUNABLES=glibc.malloc.mmap_threshold=2048:glibc.malloc.trim_threshold=1024 * elf/dl-tunables.c: Include mman.h and libc-internals.h. (tunables_strdup): New function. (parse_tunables): New function. (GLIBC_TUNABLES): New macro. (__tunables_init): Use the new functions and macro. * malloc/tst-malloc-usable-tunables.c: New test case. * malloc/tst-malloc-usable-static-tunables.c: New test case. * malloc/Makefile (tests, tests-static): Add tests. --- elf/dl-tunables.c | 99 ++++++++++++++++++++++++++++++ malloc/Makefile | 6 +- malloc/tst-malloc-usable-static-tunables.c | 1 + malloc/tst-malloc-usable-tunables.c | 1 + 4 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 malloc/tst-malloc-usable-static-tunables.c create mode 100644 malloc/tst-malloc-usable-tunables.c diff --git a/elf/dl-tunables.c b/elf/dl-tunables.c index b8f8fc0..ff71e9d 100644 --- a/elf/dl-tunables.c +++ b/elf/dl-tunables.c @@ -22,10 +22,14 @@ #include #include #include +#include +#include #define TUNABLES_INTERNAL 1 #include "dl-tunables.h" +#define GLIBC_TUNABLES "GLIBC_TUNABLES" + /* Compare environment names, bounded by the name hardcoded in glibc. */ static bool is_name (const char *orig, const char *envname) @@ -41,6 +45,27 @@ is_name (const char *orig, const char *envname) return false; } +static char *tunables_strdup (const char *in) +{ + size_t i = 0; + + while (in[i++]); + + char *out = __mmap (NULL, ALIGN_UP (i, __getpagesize ()), + PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, + 0); + + if (out == MAP_FAILED) + return NULL; + + i--; + + while (i-- > 0) + out[i] = in[i]; + + return out; +} + static char ** get_next_env (char **envp, char **name, size_t *namelen, char **val) { @@ -109,6 +134,72 @@ tunable_initialize (tunable_t *cur, const char *strval) } } +static void +parse_tunables (char *tunestr) +{ + if (tunestr == NULL || *tunestr == '\0') + return; + + char *p = tunestr; + + while (true) + { + char *name = p; + size_t len = 0; + + /* First, find where the name ends. */ + while (p[len] != '=' && p[len] != ':' && p[len] != '\0') + len++; + + /* If we reach the end of the string before getting a valid name-value + pair, bail out. */ + if (p[len] == '\0') + return; + + /* We did not find a valid name-value pair before encountering the + colon. */ + if (p[len]== ':') + { + p += len + 1; + continue; + } + + p += len + 1; + + char *value = p; + len = 0; + + while (p[len] != ':' && p[len] != '\0') + len++; + + char end = p[len]; + p[len] = '\0'; + + /* Add the tunable if it exists. */ + for (size_t i = 0; i < sizeof (tunable_list) / sizeof (tunable_t); i++) + { + tunable_t *cur = &tunable_list[i]; + + /* If we are in a secure context (AT_SECURE) then ignore the tunable + unless it is explicitly marked as secure. Tunable values take + precendence over their envvar aliases. */ + if (__libc_enable_secure && !cur->is_secure) + continue; + + if (is_name (cur->name, name)) + { + tunable_initialize (cur, value); + break; + } + } + + if (end == ':') + p += len + 1; + else + return; + } +} + /* Initialize the tunables list from the environment. For now we only use the ENV_ALIAS to find values. Later we will also use the tunable names to find values. */ @@ -121,6 +212,14 @@ __tunables_init (char **envp) while ((envp = get_next_env (envp, &envname, &len, &envval)) != NULL) { + if (is_name (GLIBC_TUNABLES, envname)) + { + char *val = tunables_strdup (envval); + if (val != NULL) + parse_tunables (val); + continue; + } + for (int i = 0; i < sizeof (tunable_list) / sizeof (tunable_t); i++) { tunable_t *cur = &tunable_list[i]; diff --git a/malloc/Makefile b/malloc/Makefile index de9aafe..599ae9d 100644 --- a/malloc/Makefile +++ b/malloc/Makefile @@ -30,8 +30,8 @@ tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \ tst-pvalloc tst-memalign tst-mallopt tst-scratch_buffer \ tst-malloc-backtrace tst-malloc-thread-exit \ tst-malloc-thread-fail tst-malloc-fork-deadlock \ - tst-mallocfork2 -tests-static := tst-malloc-usable-static + tst-mallocfork2 tst-malloc-usable-tunables +tests-static := tst-malloc-usable-static tst-malloc-usable-static-tunables tests += $(tests-static) test-srcs = tst-mtrace @@ -141,6 +141,8 @@ endif tst-mcheck-ENV = MALLOC_CHECK_=3 tst-malloc-usable-ENV = MALLOC_CHECK_=3 tst-malloc-usable-static-ENV = $(tst-malloc-usable-ENV) +tst-malloc-usable-tunables-ENV = GLIBC_TUNABLES=glibc.malloc.check=3 +tst-malloc-usable-static-tunables-ENV = $(tst-malloc-usable-tunables-ENV) # Uncomment this for test releases. For public releases it is too expensive. #CPPFLAGS-malloc.o += -DMALLOC_DEBUG=1 diff --git a/malloc/tst-malloc-usable-static-tunables.c b/malloc/tst-malloc-usable-static-tunables.c new file mode 100644 index 0000000..8907db0 --- /dev/null +++ b/malloc/tst-malloc-usable-static-tunables.c @@ -0,0 +1 @@ +#include diff --git a/malloc/tst-malloc-usable-tunables.c b/malloc/tst-malloc-usable-tunables.c new file mode 100644 index 0000000..8907db0 --- /dev/null +++ b/malloc/tst-malloc-usable-tunables.c @@ -0,0 +1 @@ +#include