This is the mail archive of the
glibc-cvs@sourceware.org
mailing list for the glibc project.
GNU C Library master sources branch siddhesh/tunables created. glibc-2.21-336-gef55017
- From: siddhesh at sourceware dot org
- To: glibc-cvs at sourceware dot org
- Date: 15 May 2015 11:02:07 -0000
- Subject: GNU C Library master sources branch siddhesh/tunables created. glibc-2.21-336-gef55017
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".
The branch, siddhesh/tunables has been created
at ef55017fc03722419146c42ff6cda9f21d3e5644 (commit)
- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=ef55017fc03722419146c42ff6cda9f21d3e5644
commit ef55017fc03722419146c42ff6cda9f21d3e5644
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date: Fri May 15 16:31:05 2015 +0530
Generate tunable IDs from a list file
diff --git a/scripts/gen-tunables.awk b/scripts/gen-tunables.awk
new file mode 100644
index 0000000..eefe518
--- /dev/null
+++ b/scripts/gen-tunables.awk
@@ -0,0 +1,64 @@
+BEGIN {
+ ns=""
+ top_ns=""
+}
+
+$2 == "{" {
+ if (top_ns == "") {
+ top_ns = $1
+ }
+ else if (ns == "") {
+ ns = $1
+ count = 0
+ }
+ else {
+ printf ("Unexpected occurrence of '{' inside a namespace: %s:%d\n",
+ FILENAME, FNR)
+ exit 1
+ }
+
+ next
+}
+
+$1 == "}" {
+ if (ns != "") {
+ ns = ""
+ }
+ else if (top_ns != "") {
+ top_ns = ""
+ }
+ else {
+ printf ("syntax error: extra }: %s:%d\n", FILENAME, FNR)
+ exit 1
+ }
+ next
+}
+
+{
+ if (ns == "") {
+ print "Invalid tunable outside a namespace"
+ exit 1
+ }
+ val[top_ns][ns][count] = $1
+ count = count + 1
+}
+
+END {
+ if (ns != "") {
+ print "Unterminated namespace. Is a closing brace missing?"
+ exit 1
+ }
+
+ print "typedef enum"
+ print "{"
+ for (t in val) {
+ for (n in val[t]) {
+ printf (" %s_%s,\n", t, n);
+ for (c in val[t][n]) {
+ printf (" %s_%s_%s,\n", t, n, val[t][n][c]);
+ }
+ }
+ }
+ print " TUNABLES_MAX"
+ print "} tunable_id_t;"
+}
diff --git a/tunables/Makefile b/tunables/Makefile
index cf73f26..ebc43de 100644
--- a/tunables/Makefile
+++ b/tunables/Makefile
@@ -24,4 +24,10 @@ include ../Makeconfig
routines = tunables
+$(objpfx)tunables.os: tunable-list.h
+
+tunable-list.h: $(..)scripts/gen-tunables.awk tunables.list
+ $(AWK) -f $^ > $@.tmp
+ mv $@{.tmp,}
+
include ../Rules
diff --git a/tunables/README b/tunables/README
index 37da2e6..48c6260 100644
--- a/tunables/README
+++ b/tunables/README
@@ -14,9 +14,16 @@ distributions for specific tunables if they want to add their own tunables.
Downstream implementations are discouraged from using the GLIBC namespace for
tunables they don't intend to push upstream.
+There are two steps to adding tunables:
+
+1. Add tunable IDs:
+
+TODO: finish this.
+
Modules that wish to use the tunables interface must define the
-TUNABLE_NAMESPACE macro. A tunable may then be added by adding the full ID of
-the tunable to the tunable_id_t enum and then calling the TUNABLE_REGISTER
+TUNABLE_NAMESPACE macro. To begin registering tunables, call the
+TUNABLE_NAMESPACE_BEGIN() macro. Tunables may be added by adding the full ID
+of the tunable to the tunable_id_t enum and then calling the TUNABLE_REGISTER
macro when it wants to read the environment variables to initialize the
variable that is to be tuned.
@@ -36,7 +43,9 @@ The TUNABLE_REGISTER macro takes the following arguments:
- size: Size of the tunable variable.
- type: Type of the tunable variable. It must be one of the values
- defined in the tunable_type_t enum.
+ defined in the tunable_type_t enum. If a value is safe to load
+ for setuid binaries, the type should be the OR of the actual
+ type and TUNABLE_TYPE_SECURE.
Future work:
------------
diff --git a/tunables/tunable-list.h b/tunables/tunable-list.h
new file mode 100644
index 0000000..e5083d5
--- /dev/null
+++ b/tunables/tunable-list.h
@@ -0,0 +1,9 @@
+typedef enum
+{
+ GLIBC_MALLOC,
+ GLIBC_MALLOC_MMAP_THRESHOLD,
+ GLIBC_MALLOC_TRIM_THRESHOLD,
+ GLIBC_MALLOC_ARENA_MAX,
+ GLIBC_MALLOC_ARENA_TEST,
+ TUNABLES_MAX
+} tunable_id_t;
diff --git a/tunables/tunables.h b/tunables/tunables.h
index 5e1120d..448c5d0 100644
--- a/tunables/tunables.h
+++ b/tunables/tunables.h
@@ -18,6 +18,8 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
+#include "tunable-list.h"
+
typedef enum
{
TUNABLE_TYPE_SECURE,
@@ -27,28 +29,25 @@ typedef enum
typedef struct _tunable tunable_t;
-/* Add your tunable IDs here. */
-typedef enum
-{
- TUNABLES_MAX
-} tunable_id_t;
-
+/* Build a full tunable name from a top namespace, tunable namespace and the
+ id. */
#define FULL_NAME(top,ns,id) (top ## _ ## ns ## _ ## id)
#define FULL_NAME_S(top,ns,id) (#top "_" #ns "_" #id)
+/* Start registering tunables in the current namespace. */
#define TUNABLES_NAMESPACE_BEGIN(size) \
tunables_namespace_begin (TUNABLE_NAMESPACE, size)
/* Register a tunable. This macro validates that the call is OK and then calls
tunable_init to do the real work of adding the tunable and setting its value
based on its environment variable(s). */
-#define TUNABLE_REGISTER(id,alias,val,size,type,secure) \
+#define TUNABLE_REGISTER(id,alias,val,size,type) \
({ \
static_assert (FULL_NAME (TOP_NAMESPACE, TUNABLE_NAMESPACE, id) \
< TUNABLES_MAX); \
- tunable_init (FULL_NAME (TOP_NAMESPACE, TUNABLE_NAMESPACE, id), \
- FULL_NAME_S (TOP_NAMESPACE, TUNABLE_NAMESPACE, id), \
- (alias), (val), (size), (type), (secure)); \
+ tunable_register (FULL_NAME (TOP_NAMESPACE, TUNABLE_NAMESPACE, id), \
+ FULL_NAME_S (TOP_NAMESPACE, TUNABLE_NAMESPACE, id), \
+ (alias), (val), (size), (type)); \
\
})
diff --git a/tunables/tunables.list b/tunables/tunables.list
new file mode 100644
index 0000000..3ef02c6
--- /dev/null
+++ b/tunables/tunables.list
@@ -0,0 +1,8 @@
+GLIBC {
+ MALLOC {
+ MMAP_THRESHOLD
+ TRIM_THRESHOLD
+ ARENA_MAX
+ ARENA_TEST
+ }
+}
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=85770027774728e6e073fe6542728bb48a89f99b
commit 85770027774728e6e073fe6542728bb48a89f99b
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date: Fri May 15 13:16:52 2015 +0530
malloc tunables support
diff --git a/malloc/arena.c b/malloc/arena.c
index d85f371..5259b74 100644
--- a/malloc/arena.c
+++ b/malloc/arena.c
@@ -19,6 +19,8 @@
#include <stdbool.h>
+#define TUNABLE_NAMESPACE MALLOC
+
/* Compile-time constants. */
#define HEAP_MIN_SIZE (32 * 1024)
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=af1ba23043a84a4e61df59704ed33dddf57e6c55
commit af1ba23043a84a4e61df59704ed33dddf57e6c55
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date: Fri May 15 13:16:24 2015 +0530
Tunables framework
Macro and function to register a tunable and initialize it from the
environment variable it is defined from.
diff --git a/Makeconfig b/Makeconfig
index 77752c0..fd6e0fb 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -874,7 +874,8 @@ CPPFLAGS = $(config-extra-cppflags) $(CPPUNDEFS) $(CPPFLAGS-config) \
$(CPPFLAGS-$(suffix $@)) \
$(foreach lib,$(libof-$(basename $(@F))) \
$(libof-$(<F)) $(libof-$(@F)),$(CPPFLAGS-$(lib))) \
- $(CPPFLAGS-$(<F)) $(CPPFLAGS-$(@F)) $(CPPFLAGS-$(basename $(@F)))
+ $(CPPFLAGS-$(<F)) $(CPPFLAGS-$(@F)) $(CPPFLAGS-$(basename $(@F))) \
+ -DTOP_NAMESPACE=GLIBC
override CFLAGS = -std=gnu99 $(gnu89-inline-CFLAGS) $(config-extra-cflags) \
$(filter-out %frame-pointer,$(+cflags)) $(+gccwarn-c) \
$(sysdep-CFLAGS) $(CFLAGS-$(suffix $@)) $(CFLAGS-$(<F)) \
@@ -1086,7 +1087,7 @@ all-subdirs = csu assert ctype locale intl catgets math setjmp signal \
grp pwd posix io termios resource misc socket sysvipc gmon \
gnulib iconv iconvdata wctype manual shadow gshadow po argp \
crypt localedata timezone rt conform debug \
- $(add-on-subdirs) dlfcn elf
+ $(add-on-subdirs) dlfcn elf tunables
ifndef avoid-generated
# sysd-sorted itself will contain rules making the sysd-sorted target
diff --git a/tunables/Makefile b/tunables/Makefile
new file mode 100644
index 0000000..cf73f26
--- /dev/null
+++ b/tunables/Makefile
@@ -0,0 +1,27 @@
+# Copyright (C) 2015 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, see
+# <http://www.gnu.org/licenses/>.
+
+#
+# Makefile for tunables.
+#
+subdir := tunables
+
+include ../Makeconfig
+
+routines = tunables
+
+include ../Rules
diff --git a/tunables/README b/tunables/README
new file mode 100644
index 0000000..37da2e6
--- /dev/null
+++ b/tunables/README
@@ -0,0 +1,48 @@
+ TUNABLE FRAMEWORK
+ =================
+
+The tunable framework allows modules within glibc to register variables that
+may be tweaked through an environment variable or an API call. It aims to
+enforce a strict namespace rule to bring consistency to naming of these tunable
+environment variables across the project.
+
+Adding a tunable:
+-----------------
+
+The TOP_NAMESPACE is defined by default as GLIBC and it may be overridden in
+distributions for specific tunables if they want to add their own tunables.
+Downstream implementations are discouraged from using the GLIBC namespace for
+tunables they don't intend to push upstream.
+
+Modules that wish to use the tunables interface must define the
+TUNABLE_NAMESPACE macro. A tunable may then be added by adding the full ID of
+the tunable to the tunable_id_t enum and then calling the TUNABLE_REGISTER
+macro when it wants to read the environment variables to initialize the
+variable that is to be tuned.
+
+The TUNABLE_REGISTER macro takes the following arguments:
+
+- id: The short name of the tunable. It will be concatenated with
+ the TOP_NAMESPACE and TUNABLE_NAMESPACE to build the full ID of
+ the tunable. It must match the tunable ID added to the
+ tunable_id_t enum.
+
+- alias: The old name of the tunable. This is for compatibility, to
+ support porting of already existing environment variables into
+ the tunables framework.
+
+- val: A pointer to the variable that is to be tuned.
+
+- size: Size of the tunable variable.
+
+- type: Type of the tunable variable. It must be one of the values
+ defined in the tunable_type_t enum.
+
+Future work:
+------------
+
+The framework currently only allows a one-time initialization of variables
+through environment variables and in some cases, modification of variables via
+an API call. A future goal for this project is to allow tweaking of some
+values in a running process, possibly through some kind of shared memory
+mechanism.
diff --git a/tunables/Versions b/tunables/Versions
new file mode 100644
index 0000000..b47493f
--- /dev/null
+++ b/tunables/Versions
@@ -0,0 +1,6 @@
+# Exports from tunables should only be in the GLIBC_PRIVATE namespace.
+libc {
+ GLIBC_PRIVATE {
+ tunable_init;
+ }
+}
diff --git a/tunables/tunables.c b/tunables/tunables.c
new file mode 100644
index 0000000..2e1157f
--- /dev/null
+++ b/tunables/tunables.c
@@ -0,0 +1,127 @@
+/* The tunable framework. See the README to know how to use the tunable in
+ a glibc module.
+
+ Copyright (C) 2015 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <sys/param.h>
+#include "tunables.h"
+
+extern char **__environ;
+
+/* A tunable. */
+struct _tunable
+{
+ char *name;
+ char *alias;
+ void *val;
+ size_t size;
+ tunable_type_t type;
+ bool initialized;
+};
+
+/* The full list of tunables. */
+static tunable_t tunable_list[TUNABLES_MAX];
+
+
+void
+tunables_namespace_begin (tunable_id_t id, size_t size)
+{
+ tunable_list[id].size = size;
+}
+
+/* Set the value of a tunable from its environment variable(s). */
+static void
+tunable_set (tunable_t *t, const char *val)
+{
+ switch (t->type & ~TUNABLE_TYPE_SECURE)
+ {
+ case TUNABLE_TYPE_SIZE_T:
+ *(size_t *) t->val = strtoul (val, NULL, 0);
+ case TUNABLE_TYPE_STRING:
+ memcpy (t->val, val, t->size);
+ default:
+ __builtin_trap ();
+ }
+ t->initialized = true;
+}
+
+/* Initialize all tunables in the namespace group specified by ID. */
+void
+tunables_init (tunable_id_t id)
+{
+ int end = tunable_list[id].size;
+
+ /* Traverse through the environment to find environment variables we may need
+ to set. */
+ char **envp = __environ;
+ while (*envp != NULL)
+ {
+ char *envline = *envp;
+ int len = 0;
+
+ while (envline[len] != '\0' && envline[len] != '=')
+ len++;
+
+ /* Just the name and no value. */
+ if (envline[len] == '\0')
+ continue;
+
+ for (int i = id; i < end; i++)
+ {
+ /* Skip over tunables that are either initialized or are not safe to
+ load for setuid binaries. */
+ if ((__libc_enable_secure
+ && (tunable_list[id].type & TUNABLE_TYPE_SECURE) == 0)
+ || tunable_list[id].initialized)
+ continue;
+
+ const char *name = tunable_list[id].name;
+ const char *alias = tunable_list[id].alias;
+ char *val = NULL;
+
+ if (memcmp (envline, name, MIN(len, strlen (name))) == 0)
+ val = &envline[len + 1];
+ else if (memcmp (envline, alias, MIN(len, strlen (alias))) == 0)
+ val = &envline[len + 1];
+
+ if (val != NULL)
+ {
+ tunable_set (&tunable_list[id], val);
+ break;
+ }
+ }
+ envp++;
+ }
+}
+
+/* Initialize a tunable and set its value via the set environment variable. */
+void
+tunable_register (tunable_id_t id, const char *name, const char *alias,
+ void *val, size_t size, tunable_type_t type)
+{
+ tunable_list[id].name = __strdup (name);
+ tunable_list[id].alias = alias ? __strdup (alias) : NULL;
+ tunable_list[id].val = val;
+ tunable_list[id].size = size;
+ tunable_list[id].type = type;
+}
diff --git a/tunables/tunables.h b/tunables/tunables.h
new file mode 100644
index 0000000..5e1120d
--- /dev/null
+++ b/tunables/tunables.h
@@ -0,0 +1,56 @@
+/* The tunable framework. See the README to know how to use the tunable in
+ a glibc module.
+
+ Copyright (C) 2015 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+typedef enum
+{
+ TUNABLE_TYPE_SECURE,
+ TUNABLE_TYPE_SIZE_T = 1 << 1,
+ TUNABLE_TYPE_STRING = 1 << 2
+} tunable_type_t;
+
+typedef struct _tunable tunable_t;
+
+/* Add your tunable IDs here. */
+typedef enum
+{
+ TUNABLES_MAX
+} tunable_id_t;
+
+#define FULL_NAME(top,ns,id) (top ## _ ## ns ## _ ## id)
+#define FULL_NAME_S(top,ns,id) (#top "_" #ns "_" #id)
+
+#define TUNABLES_NAMESPACE_BEGIN(size) \
+ tunables_namespace_begin (TUNABLE_NAMESPACE, size)
+
+/* Register a tunable. This macro validates that the call is OK and then calls
+ tunable_init to do the real work of adding the tunable and setting its value
+ based on its environment variable(s). */
+#define TUNABLE_REGISTER(id,alias,val,size,type,secure) \
+({ \
+ static_assert (FULL_NAME (TOP_NAMESPACE, TUNABLE_NAMESPACE, id) \
+ < TUNABLES_MAX); \
+ tunable_init (FULL_NAME (TOP_NAMESPACE, TUNABLE_NAMESPACE, id), \
+ FULL_NAME_S (TOP_NAMESPACE, TUNABLE_NAMESPACE, id), \
+ (alias), (val), (size), (type), (secure)); \
+ \
+})
+
+#define TUNABLES_NAMESPACE_INIT() \
+ tunables_init (TUNABLE_NAMESPACE, size)
-----------------------------------------------------------------------
hooks/post-receive
--
GNU C Library master sources