From: "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
To: Jeff Hostetler via GitGitGadget <gitgitgadget@gmail.com>
Cc: git@vger.kernel.org, peff@peff.net, jrnieder@gmail.com,
steadmon@google.com, Junio C Hamano <gitster@pobox.com>,
Jeff Hostetler <jeffhost@microsoft.com>
Subject: Re: [PATCH 4/4] trace2: use system config for default trace2 settings
Date: Thu, 28 Mar 2019 15:36:30 +0100 [thread overview]
Message-ID: <87wokj9ic1.fsf@evledraar.gmail.com> (raw)
In-Reply-To: <7e0d4e20fbb3abbc787bc216d2c4bd8c18860aed.1553779851.git.gitgitgadget@gmail.com>
On Thu, Mar 28 2019, Jeff Hostetler via GitGitGadget wrote:
Thanks for working on this!
Haven't given this any deep testing. Just some observations:
> From: Jeff Hostetler <jeffhost@microsoft.com>
>
> Teach git to read the system config (usually "/etc/gitconfig") for
> default Trace2 settings. This allows system-wide Trace2 settings to
> be installed and inherited to make it easier to manage a collection of
> systems.
>
> The original GIT_TR2* environment variables are loaded afterwards and
> can be used to override the system settings.
>
> Only the system config file is used. Trace2 config values are ignored
> in local, global, and other config files. Likewise, the "-c" command
> line arguments are ignored for Trace2 values. These limits are for
> performance reasons.
>
> (1) For users not using Trace2, there should be minimal overhead to
> detect that Trace2 is not enabled. In particular, Trace2 should not
> allocate lots of otherwise unused data strucutres.
>
> (2) For accurate performance measurements, Trace2 should be initialized
> as early in the git process as possible, and before most of the normal
> git process initialization (which involves discovering the .git directory
> and reading a hierarchy of config files).
>
> Added the GIT_TEST_TR2_SYSTEM_CONFIG environment variable for testing
> purposes to specify the pathname of a fake "system" config or disable
> use of the system config.
>
> Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
> ---
> Documentation/technical/api-trace2.txt | 31 ++++++
> Makefile | 1 +
> t/t0210-trace2-normal.sh | 41 +++++++-
> t/t0211-trace2-perf.sh | 41 +++++++-
> t/t0212-trace2-event.sh | 52 +++++++++-
> trace2.c | 4 +
> trace2.h | 7 +-
> trace2/tr2_cfg.c | 7 +-
> trace2/tr2_dst.c | 24 ++---
> trace2/tr2_dst.h | 3 +-
> trace2/tr2_sysenv.c | 125 +++++++++++++++++++++++++
> trace2/tr2_sysenv.h | 36 +++++++
> trace2/tr2_tgt_event.c | 19 ++--
> trace2/tr2_tgt_normal.c | 10 +-
> trace2/tr2_tgt_perf.c | 10 +-
> 15 files changed, 356 insertions(+), 55 deletions(-)
> create mode 100644 trace2/tr2_sysenv.c
> create mode 100644 trace2/tr2_sysenv.h
>
> diff --git a/Documentation/technical/api-trace2.txt b/Documentation/technical/api-trace2.txt
> index baaa1153bb..13ca595c69 100644
> --- a/Documentation/technical/api-trace2.txt
> +++ b/Documentation/technical/api-trace2.txt
> @@ -117,6 +117,37 @@ values are recognized.
> Socket type can be either `stream` or `dgram`. If the socket type is
> omitted, Git will try both.
>
> +== Trace2 Settings in System Config
> +
> +Trace2 also reads configuration information from the system config.
> +This is intended to help adminstrators to gather system-wide Git
> +performance data.
> +
> +Trace2 only reads the system configuration, it does not read global,
> +local, worktree, or `-c` config settings.
> +
> +Trace2 will try to load the following system configuration settings
> +and then read the corresponding environment variables at startup.
> +
> +....
> +---------------------------------------------------
> +trace2.normalTarget GIT_TR2
> +trace2.normalBrief GIT_TR2_BRIEF
> +
> +trace2.perfTarget GIT_TR2_PERF
> +trace2.perfBrief GIT_TR2_PERF_BRIEF
> +
> +trace2.eventTarget GIT_TR2_EVENT
> +trace2.eventBrief GIT_TR2_EVENT_BRIEF
> +trace2.eventNesting GIT_TR2_EVENT_NESTING
> +
> +trace2.configParams GIT_TR2_CONFIG_PARAMS
> +
> +trace2.destinationDebug GIT_TR2_DST_DEBUG
> +---------------------------------------------------
> +....
> +
> +
> == Trace2 API
>
> All public Trace2 functions and macros are defined in `trace2.h` and
> diff --git a/Makefile b/Makefile
> index 3e03290d8f..9ddfa3dfe7 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -1005,6 +1005,7 @@ LIB_OBJS += trace2/tr2_cfg.o
> LIB_OBJS += trace2/tr2_cmd_name.o
> LIB_OBJS += trace2/tr2_dst.o
> LIB_OBJS += trace2/tr2_sid.o
> +LIB_OBJS += trace2/tr2_sysenv.o
> LIB_OBJS += trace2/tr2_tbuf.o
> LIB_OBJS += trace2/tr2_tgt_event.o
> LIB_OBJS += trace2/tr2_tgt_normal.o
> diff --git a/t/t0210-trace2-normal.sh b/t/t0210-trace2-normal.sh
> index 03a0aedb1d..5d4c04ed30 100755
> --- a/t/t0210-trace2-normal.sh
> +++ b/t/t0210-trace2-normal.sh
> @@ -1,5 +1,14 @@
> #!/bin/sh
>
> +# Disable loading of Trace2 settings from the system config
> +# (usually "/etc/gitconfig") to eliminate system dependencies.
> +GIT_TEST_TR2_SYSTEM_CONFIG=0 && export GIT_TEST_TR2_SYSTEM_CONFIG
> +
> +# Turn off any inherited trace2 settings for this test.
> +unset GIT_TR2 GIT_TR2_PERF GIT_TR2_EVENT
> +unset GIT_TR2_BRIEF
> +unset GIT_TR2_CONFIG_PARAMS
> +
> test_description='test trace2 facility (normal target)'
> . ./test-lib.sh
>
> @@ -15,11 +24,6 @@ PATH="$TTDIR:$PATH" && export PATH
> # Warning: So you may see extra lines in artifact files when
> # Warning: interactively debugging.
>
> -# Turn off any inherited trace2 settings for this test.
> -unset GIT_TR2 GIT_TR2_PERF GIT_TR2_EVENT
> -unset GIT_TR2_BRIEF
> -unset GIT_TR2_CONFIG_PARAMS
> -
> V=$(git version | sed -e 's/^git version //') && export V
>
> # There are multiple trace2 targets: normal, perf, and event.
> @@ -132,4 +136,31 @@ test_expect_success 'normal stream, error event' '
> test_cmp expect actual
> '
>
> +# Now test using system config by using a mocked up config file
> +# rather than inheriting "/etc/gitconfig". Here we do not use
> +# GIT_TR2* environment variables.
> +
> +unset GIT_TR2_BRIEF
> +
> +MOCK=./mock_system_config
> +
> +test_expect_success 'setup mocked /etc/gitconfig' '
> + git config --file $MOCK trace2.normalTarget "$(pwd)/trace.normal" &&
> + git config --file $MOCK trace2.normalBrief 1
> +'
> +
> +test_expect_success 'using mock, normal stream, return code 0' '
> + test_when_finished "rm trace.normal actual expect" &&
> + GIT_TEST_TR2_SYSTEM_CONFIG="$MOCK" test-tool trace2 001return 0 &&
> + perl "$TEST_DIRECTORY/t0210/scrub_normal.perl" <trace.normal >actual &&
> + cat >expect <<-EOF &&
> + version $V
> + start _EXE_ trace2 001return 0
> + cmd_name trace2 (trace2)
> + exit elapsed:_TIME_ code:0
> + atexit elapsed:_TIME_ code:0
> + EOF
> + test_cmp expect actual
> +'
> +
> test_done
> diff --git a/t/t0211-trace2-perf.sh b/t/t0211-trace2-perf.sh
> index c9694b29f7..abe35b2186 100755
> --- a/t/t0211-trace2-perf.sh
> +++ b/t/t0211-trace2-perf.sh
> @@ -1,5 +1,14 @@
> #!/bin/sh
>
> +# Disable loading of Trace2 settings from the system config
> +# (usually "/etc/gitconfig") to eliminate system dependencies.
> +GIT_TEST_TR2_SYSTEM_CONFIG=0 && export GIT_TEST_TR2_SYSTEM_CONFIG
> +
> +# Turn off any inherited trace2 settings for this test.
> +unset GIT_TR2 GIT_TR2_PERF GIT_TR2_EVENT
> +unset GIT_TR2_PERF_BRIEF
> +unset GIT_TR2_CONFIG_PARAMS
> +
> test_description='test trace2 facility (perf target)'
> . ./test-lib.sh
>
> @@ -15,11 +24,6 @@ PATH="$TTDIR:$PATH" && export PATH
> # Warning: So you may see extra lines in artifact files when
> # Warning: interactively debugging.
>
> -# Turn off any inherited trace2 settings for this test.
> -unset GIT_TR2 GIT_TR2_PERF GIT_TR2_EVENT
> -unset GIT_TR2_PERF_BRIEF
> -unset GIT_TR2_CONFIG_PARAMS
> -
> V=$(git version | sed -e 's/^git version //') && export V
>
> # There are multiple trace2 targets: normal, perf, and event.
> @@ -150,4 +154,31 @@ test_expect_success 'perf stream, child processes' '
> test_cmp expect actual
> '
>
> +# Now test using system config by using a mocked up config file
> +# rather than inheriting "/etc/gitconfig". Here we do not use
> +# GIT_TR2* environment variables.
> +
> +unset GIT_TR2_PERF_BRIEF
> +
> +MOCK=./mock_system_config
> +
> +test_expect_success 'setup mocked /etc/gitconfig' '
> + git config --file $MOCK trace2.perfTarget "$(pwd)/trace.perf" &&
> + git config --file $MOCK trace2.perfBrief 1
> +'
> +
> +test_expect_success 'using mock, perf stream, return code 0' '
> + test_when_finished "rm trace.perf actual expect" &&
> + GIT_TEST_TR2_SYSTEM_CONFIG="$MOCK" test-tool trace2 001return 0 &&
> + perl "$TEST_DIRECTORY/t0211/scrub_perf.perl" <trace.perf >actual &&
> + cat >expect <<-EOF &&
> + d0|main|version|||||$V
> + d0|main|start||_T_ABS_|||_EXE_ trace2 001return 0
> + d0|main|cmd_name|||||trace2 (trace2)
> + d0|main|exit||_T_ABS_|||code:0
> + d0|main|atexit||_T_ABS_|||code:0
> + EOF
> + test_cmp expect actual
> +'
> +
> test_done
> diff --git a/t/t0212-trace2-event.sh b/t/t0212-trace2-event.sh
> index 028b6c5671..c535496261 100755
> --- a/t/t0212-trace2-event.sh
> +++ b/t/t0212-trace2-event.sh
> @@ -1,5 +1,14 @@
> #!/bin/sh
>
> +# Disable loading of Trace2 settings from the system config
> +# (usually "/etc/gitconfig") to eliminate system dependencies.
> +GIT_TEST_TR2_SYSTEM_CONFIG=0 && export GIT_TEST_TR2_SYSTEM_CONFIG
> +
> +# Turn off any inherited trace2 settings for this test.
> +unset GIT_TR2 GIT_TR2_PERF GIT_TR2_EVENT
> +unset GIT_TR2_BARE
> +unset GIT_TR2_CONFIG_PARAMS
> +
> test_description='test trace2 facility'
> . ./test-lib.sh
>
> @@ -17,11 +26,6 @@ PATH="$TTDIR:$PATH" && export PATH
> # Warning: So you may see extra lines in artifact files when
> # Warning: interactively debugging.
>
> -# Turn off any inherited trace2 settings for this test.
> -unset GIT_TR2 GIT_TR2_PERF GIT_TR2_EVENT
> -unset GIT_TR2_BARE
> -unset GIT_TR2_CONFIG_PARAMS
> -
> V=$(git version | sed -e 's/^git version //') && export V
>
> # There are multiple trace2 targets: normal, perf, and event.
> @@ -233,4 +237,42 @@ test_expect_success JSON_PP 'basic trace2_data' '
> test_cmp expect actual
> '
>
> +# Now test using system config by using a mocked up config file
> +# rather than inheriting "/etc/gitconfig". Here we do not use
> +# GIT_TR2* environment variables.
> +
> +MOCK=./mock_system_config
> +
> +test_expect_success 'setup mocked /etc/gitconfig' '
> + git config --file $MOCK trace2.eventTarget "$(pwd)/trace.event"
> +'
> +
> +test_expect_success JSON_PP 'using mock, event stream, error event' '
> + test_when_finished "rm trace.event actual expect" &&
> + GIT_TEST_TR2_SYSTEM_CONFIG="$MOCK" test-tool trace2 003error "hello world" "this is a test" &&
> + perl "$TEST_DIRECTORY/t0212/parse_events.perl" <trace.event >actual &&
> + sed -e "s/^|//" >expect <<-EOF &&
> + |VAR1 = {
> + | "_SID0_":{
> + | "argv":[
> + | "_EXE_",
> + | "trace2",
> + | "003error",
> + | "hello world",
> + | "this is a test"
> + | ],
> + | "errors":[
> + | "%s",
> + | "%s"
> + | ],
> + | "exit_code":0,
> + | "hierarchy":"trace2",
> + | "name":"trace2",
> + | "version":"$V"
> + | }
> + |};
> + EOF
> + test_cmp expect actual
> +'
> +
> test_done
> diff --git a/trace2.c b/trace2.c
> index 1c180062dd..490b3f071e 100644
> --- a/trace2.c
> +++ b/trace2.c
> @@ -10,6 +10,7 @@
> #include "trace2/tr2_cmd_name.h"
> #include "trace2/tr2_dst.h"
> #include "trace2/tr2_sid.h"
> +#include "trace2/tr2_sysenv.h"
> #include "trace2/tr2_tgt.h"
> #include "trace2/tr2_tls.h"
>
> @@ -120,6 +121,7 @@ static void tr2main_atexit_handler(void)
> tr2_sid_release();
> tr2_cmd_name_release();
> tr2_cfg_free_patterns();
> + tr2_sysenv_release();
>
> trace2_enabled = 0;
> }
> @@ -155,6 +157,8 @@ void trace2_initialize_fl(const char *file, int line)
> if (trace2_enabled)
> return;
>
> + tr2_sysenv_load();
> +
> if (!tr2_tgt_want_builtins())
> return;
> trace2_enabled = 1;
> diff --git a/trace2.h b/trace2.h
> index 8f89e70c44..cda8349058 100644
> --- a/trace2.h
> +++ b/trace2.h
> @@ -38,7 +38,8 @@ void trace2_initialize_clock(void);
>
> /*
> * Initialize TRACE2 tracing facility if any of the builtin TRACE2
> - * targets are enabled in the environment. Emits a 'version' event.
> + * targets are enabled in the system config or the environment.
> + * Emits a 'version' event.
> *
> * Cleanup/Termination is handled automatically by a registered
> * atexit() routine.
> @@ -125,8 +126,8 @@ void trace2_cmd_alias_fl(const char *file, int line, const char *alias,
> * Emit one or more 'def_param' events for "interesting" configuration
> * settings.
> *
> - * The environment variable "GIT_TR2_CONFIG_PARAMS" can be set to a
> - * list of patterns considered important. For example:
> + * Use the TR2_SYSENV_CFG_PARAM setting to register a list of patterns
> + * configured important. For example:
> *
> * GIT_TR2_CONFIG_PARAMS="core.*,remote.*.url"
> *
> diff --git a/trace2/tr2_cfg.c b/trace2/tr2_cfg.c
> index b329921ac5..caa7f06948 100644
> --- a/trace2/tr2_cfg.c
> +++ b/trace2/tr2_cfg.c
> @@ -1,8 +1,7 @@
> #include "cache.h"
> #include "config.h"
> -#include "tr2_cfg.h"
> -
> -#define TR2_ENVVAR_CFG_PARAM "GIT_TR2_CONFIG_PARAMS"
> +#include "trace2/tr2_cfg.h"
> +#include "trace2/tr2_sysenv.h"
>
> static struct strbuf **tr2_cfg_patterns;
> static int tr2_cfg_count_patterns;
> @@ -21,7 +20,7 @@ static int tr2_cfg_load_patterns(void)
> return tr2_cfg_count_patterns;
> tr2_cfg_loaded = 1;
>
> - envvar = getenv(TR2_ENVVAR_CFG_PARAM);
> + envvar = tr2_sysenv_get(TR2_SYSENV_CFG_PARAM);
> if (!envvar || !*envvar)
> return tr2_cfg_count_patterns;
>
> diff --git a/trace2/tr2_dst.c b/trace2/tr2_dst.c
> index fd490a43ad..575cd69aa9 100644
> --- a/trace2/tr2_dst.c
> +++ b/trace2/tr2_dst.c
> @@ -1,5 +1,6 @@
> #include "cache.h"
> #include "trace2/tr2_dst.h"
> +#include "trace2/tr2_sysenv.h"
>
> /*
> * If a Trace2 target cannot be opened for writing, we should issue a
> @@ -7,17 +8,13 @@
> * or socket and beyond the user's control -- especially since every
> * git command (and sub-command) will print the message. So we silently
> * eat these warnings and just discard the trace data.
> - *
> - * Enable the following environment variable to see these warnings.
> */
> -#define TR2_ENVVAR_DST_DEBUG "GIT_TR2_DST_DEBUG"
> -
> static int tr2_dst_want_warning(void)
> {
> static int tr2env_dst_debug = -1;
>
> if (tr2env_dst_debug == -1) {
> - const char *env_value = getenv(TR2_ENVVAR_DST_DEBUG);
> + const char *env_value = tr2_sysenv_get(TR2_SYSENV_DST_DEBUG);
> if (!env_value || !*env_value)
> tr2env_dst_debug = 0;
> else
> @@ -42,7 +39,9 @@ static int tr2_dst_try_path(struct tr2_dst *dst, const char *tgt_value)
> if (fd == -1) {
> if (tr2_dst_want_warning())
> warning("trace2: could not open '%s' for '%s' tracing: %s",
> - tgt_value, dst->env_var_name, strerror(errno));
> + tgt_value,
> + tr2_sysenv_display_name(dst->sysenv_var),
> + strerror(errno));
>
> tr2_dst_trace_disable(dst);
> return 0;
> @@ -116,7 +115,7 @@ static int tr2_dst_try_unix_domain_socket(struct tr2_dst *dst,
> if (!path || !*path) {
> if (tr2_dst_want_warning())
> warning("trace2: invalid AF_UNIX value '%s' for '%s' tracing",
> - tgt_value, dst->env_var_name);
> + tgt_value, tr2_sysenv_display_name(dst->sysenv_var));
>
> tr2_dst_trace_disable(dst);
> return 0;
> @@ -126,7 +125,7 @@ static int tr2_dst_try_unix_domain_socket(struct tr2_dst *dst,
> strlen(path) >= sizeof(((struct sockaddr_un *)0)->sun_path)) {
> if (tr2_dst_want_warning())
> warning("trace2: invalid AF_UNIX path '%s' for '%s' tracing",
> - path, dst->env_var_name);
> + path, tr2_sysenv_display_name(dst->sysenv_var));
>
> tr2_dst_trace_disable(dst);
> return 0;
> @@ -148,7 +147,7 @@ static int tr2_dst_try_unix_domain_socket(struct tr2_dst *dst,
> error:
> if (tr2_dst_want_warning())
> warning("trace2: could not connect to socket '%s' for '%s' tracing: %s",
> - path, dst->env_var_name, strerror(e));
> + path, tr2_sysenv_display_name(dst->sysenv_var), strerror(e));
>
> tr2_dst_trace_disable(dst);
> return 0;
> @@ -168,7 +167,7 @@ static void tr2_dst_malformed_warning(struct tr2_dst *dst,
> struct strbuf buf = STRBUF_INIT;
>
> strbuf_addf(&buf, "trace2: unknown value for '%s': '%s'",
> - dst->env_var_name, tgt_value);
> + tr2_sysenv_display_name(dst->sysenv_var), tgt_value);
> warning("%s", buf.buf);
>
> strbuf_release(&buf);
> @@ -184,7 +183,7 @@ int tr2_dst_get_trace_fd(struct tr2_dst *dst)
>
> dst->initialized = 1;
>
> - tgt_value = getenv(dst->env_var_name);
> + tgt_value = tr2_sysenv_get(dst->sysenv_var);
>
> if (!tgt_value || !strcmp(tgt_value, "") || !strcmp(tgt_value, "0") ||
> !strcasecmp(tgt_value, "false")) {
> @@ -246,7 +245,8 @@ void tr2_dst_write_line(struct tr2_dst *dst, struct strbuf *buf_line)
> return;
>
> if (tr2_dst_want_warning())
> - warning("unable to write trace to '%s': %s", dst->env_var_name,
> + warning("unable to write trace to '%s': %s",
> + tr2_sysenv_display_name(dst->sysenv_var),
> strerror(errno));
> tr2_dst_trace_disable(dst);
> }
> diff --git a/trace2/tr2_dst.h b/trace2/tr2_dst.h
> index 9a64f05b02..3adf3bac13 100644
> --- a/trace2/tr2_dst.h
> +++ b/trace2/tr2_dst.h
> @@ -2,9 +2,10 @@
> #define TR2_DST_H
>
> struct strbuf;
> +#include "trace2/tr2_sysenv.h"
>
> struct tr2_dst {
> - const char *const env_var_name;
> + enum tr2_sysenv_variable sysenv_var;
> int fd;
> unsigned int initialized : 1;
> unsigned int need_close : 1;
> diff --git a/trace2/tr2_sysenv.c b/trace2/tr2_sysenv.c
> new file mode 100644
> index 0000000000..656613e371
> --- /dev/null
> +++ b/trace2/tr2_sysenv.c
> @@ -0,0 +1,125 @@
> +#include "cache.h"
> +#include "config.h"
> +#include "dir.h"
> +#include "tr2_sysenv.h"
> +
> +/*
> + * Each entry represents a trace2 setting.
> + * See Documentation/technical/api-trace2.txt
> + */
> +struct tr2_sysenv_entry {
> + const char *env_var_name;
> + const char *git_config_name;
> +
> + char *value;
> + unsigned int getenv_called : 1;
> +};
> +
> +/*
> + * This table must match "enum tr2_sysenv_variable" in tr2_sysenv.h.
> + * These strings are constant and must match the published names as
> + * described in the documentation.
> + *
> + * We do not define entries for the GIT_TR2_PARENT_* environment
> + * variables because they are transient and used to pass information
> + * from parent to child git processes, rather than settings.
> + */
> +/* clang-format off */
> +static struct tr2_sysenv_entry tr2_sysenv_settings[] = {
> + { "GIT_TR2_CONFIG_PARAMS", "trace2.configparams" },
> +
> + { "GIT_TR2_DST_DEBUG", "trace2.destinationdebug" },
> +
> + { "GIT_TR2", "trace2.normaltarget" },
> + { "GIT_TR2_BRIEF", "trace2.normalbrief" },
> +
> + { "GIT_TR2_EVENT", "trace2.eventtarget" },
> + { "GIT_TR2_EVENT_BRIEF", "trace2.eventbrief" },
> + { "GIT_TR2_EVENT_NESTING", "trace2.eventnesting" },
> +
> + { "GIT_TR2_PERF", "trace2.perftarget" },
> + { "GIT_TR2_PERF_BRIEF", "trace2.perfbrief" },
> +};
> +/* clang-format on */
> +
> +static int tr2_sysenv_cb(const char *key, const char *value, void *d)
> +{
> + int k;
> +
I added:
if (!starts_with(key, "trace2."))
return 0;
Here, and everything works as expected. I think that's a good
idea. Makes this O(n) over N config keys instead of O(n*x) where x = num
entries in tr2_sysenv_settings.
> + for (k = 0; k < ARRAY_SIZE(tr2_sysenv_settings); k++) {
> + if (!strcmp(key, tr2_sysenv_settings[k].git_config_name)) {
> + free(tr2_sysenv_settings[k].value);
> + tr2_sysenv_settings[k].value = xstrdup(value);
> + return 0;
> + }
> + }
> +
> + return 0;
> +}
> +
> +/*
> + * Load Trace2 settings from the system config (usually "/etc/gitconfig"
> + * unless we were built with a runtime-prefix). These are intended to
> + * define the default values for Trace2 as requested by the administrator.
> + */
> +void tr2_sysenv_load(void)
> +{
> + const char *system_config_pathname;
> + const char *test_pathname;
> +
> + system_config_pathname = git_etc_gitconfig();
> +
> + test_pathname = getenv("GIT_TEST_TR2_SYSTEM_CONFIG");
> + if (test_pathname) {
> + if (!*test_pathname || !strcmp(test_pathname, "0"))
> + return; /* disable use of system config */
> +
> + /* mock it with given test file */
> + system_config_pathname = test_pathname;
> + }
> +
> + if (file_exists(system_config_pathname))
> + git_config_from_file(tr2_sysenv_cb, system_config_pathname,
> + NULL);
Maybe this isn't worth it, but this "file_exists" thing is something we
could abstract in the config machinery (or maybe passing via
"config_options" makes more sense):
diff --git a/config.c b/config.c
index 0f0cdd8c0f..ea625a508f 100644
--- a/config.c
+++ b/config.c
@@ -1549,12 +1549,15 @@ static int git_config_from_stdin(config_fn_t fn, void *data)
int git_config_from_file_with_options(config_fn_t fn, const char *filename,
void *data,
- const struct config_options *opts)
+ const struct config_options *opts,
+ int or_warn)
{
int ret = -1;
FILE *f;
- f = fopen_or_warn(filename, "r");
+ f = or_warn
+ ? fopen_or_warn(filename, "r")
+ : fopen(filename, "r");
if (f) {
ret = do_config_from_file(fn, CONFIG_ORIGIN_FILE, filename,
filename, f, data, opts);
@@ -1565,7 +1568,7 @@ int git_config_from_file_with_options(config_fn_t fn, const char *filename,
int git_config_from_file(config_fn_t fn, const char *filename, void *data)
{
- return git_config_from_file_with_options(fn, filename, data, NULL);
+ return git_config_from_file_with_options(fn, filename, data, NULL, 1);
}
int git_config_from_mem(config_fn_t fn,
@@ -2787,7 +2790,7 @@ int git_config_set_multivar_in_file_gently(const char *config_filename,
*/
if (git_config_from_file_with_options(store_aux,
config_filename,
- &store, &opts)) {
+ &store, &opts, 1)) {
error(_("invalid config file %s"), config_filename);
ret = CONFIG_INVALID_FILE;
goto out_free;
diff --git a/config.h b/config.h
index ee5d3fa7b4..52e93e6cdc 100644
--- a/config.h
+++ b/config.h
@@ -72,7 +72,8 @@ extern int git_default_config(const char *, const char *, void *);
extern int git_config_from_file(config_fn_t fn, const char *, void *);
extern int git_config_from_file_with_options(config_fn_t fn, const char *,
void *,
- const struct config_options *);
+ const struct config_options *,
+ int);
extern int git_config_from_mem(config_fn_t fn,
const enum config_origin_type,
const char *name,
diff --git a/trace2/tr2_sysenv.c b/trace2/tr2_sysenv.c
index 656613e371..25a9c19d20 100644
--- a/trace2/tr2_sysenv.c
+++ b/trace2/tr2_sysenv.c
@@ -78,9 +81,9 @@ void tr2_sysenv_load(void)
system_config_pathname = test_pathname;
}
- if (file_exists(system_config_pathname))
- git_config_from_file(tr2_sysenv_cb, system_config_pathname,
- NULL);
+ git_config_from_file_with_options(tr2_sysenv_cb,
+ system_config_pathname, NULL, NULL,
+ 0);
}
/*
> +}
> +
> +/*
> + * Return the value for the requested setting. Start with the /etc/gitconfig
> + * value and allow the corresponding environment variable to override it.
> + */
> +const char *tr2_sysenv_get(enum tr2_sysenv_variable var)
> +{
> + if (var >= TR2_SYSENV_MUST_BE_LAST)
> + BUG("tr2_sysenv_get invalid var '%d'", var);
> +
> + if (!tr2_sysenv_settings[var].getenv_called) {
> + const char *v = getenv(tr2_sysenv_settings[var].env_var_name);
> + if (v && *v) {
> + free(tr2_sysenv_settings[var].value);
> + tr2_sysenv_settings[var].value = xstrdup(v);
> + }
> + tr2_sysenv_settings[var].getenv_called = 1;
> + }
> +
> + return tr2_sysenv_settings[var].value;
> +}
> +
> +/*
> + * Return a friendly name for this setting that is suitable for printing
> + * in an error messages.
> + */
> +const char *tr2_sysenv_display_name(enum tr2_sysenv_variable var)
> +{
> + if (var >= TR2_SYSENV_MUST_BE_LAST)
> + BUG("tr2_sysenv_get invalid var '%d'", var);
> +
> + return tr2_sysenv_settings[var].env_var_name;
> +}
> +
> +void tr2_sysenv_release(void)
> +{
> + int k;
> +
> + for (k = 0; k < ARRAY_SIZE(tr2_sysenv_settings); k++)
> + free(tr2_sysenv_settings[k].value);
> +}
> diff --git a/trace2/tr2_sysenv.h b/trace2/tr2_sysenv.h
> new file mode 100644
> index 0000000000..369b20bd87
> --- /dev/null
> +++ b/trace2/tr2_sysenv.h
> @@ -0,0 +1,36 @@
> +#ifndef TR2_SYSENV_H
> +#define TR2_SYSENV_H
> +
> +/*
> + * The Trace2 settings that can be loaded from /etc/gitconfig
> + * and/or user environment variables.
> + *
> + * Note that this set does not contain any of the transient
> + * environment variables used to pass information from parent
> + * to child git processes, such "GIT_TR2_PARENT_SID".
> + */
> +enum tr2_sysenv_variable {
> + TR2_SYSENV_CFG_PARAM = 0,
> +
> + TR2_SYSENV_DST_DEBUG,
> +
> + TR2_SYSENV_NORMAL,
> + TR2_SYSENV_NORMAL_BRIEF,
> +
> + TR2_SYSENV_EVENT,
> + TR2_SYSENV_EVENT_BRIEF,
> + TR2_SYSENV_EVENT_NESTING,
> +
> + TR2_SYSENV_PERF,
> + TR2_SYSENV_PERF_BRIEF,
> +
> + TR2_SYSENV_MUST_BE_LAST
> +};
> +
> +void tr2_sysenv_load(void);
> +
> +const char *tr2_sysenv_get(enum tr2_sysenv_variable);
> +const char *tr2_sysenv_display_name(enum tr2_sysenv_variable var);
> +void tr2_sysenv_release(void);
> +
> +#endif /* TR2_SYSENV_H */
> diff --git a/trace2/tr2_tgt_event.c b/trace2/tr2_tgt_event.c
> index 89a4d3ae9a..bb6e323953 100644
> --- a/trace2/tr2_tgt_event.c
> +++ b/trace2/tr2_tgt_event.c
> @@ -6,10 +6,11 @@
> #include "trace2/tr2_dst.h"
> #include "trace2/tr2_tbuf.h"
> #include "trace2/tr2_sid.h"
> +#include "trace2/tr2_sysenv.h"
> #include "trace2/tr2_tgt.h"
> #include "trace2/tr2_tls.h"
>
> -static struct tr2_dst tr2dst_event = { "GIT_TR2_EVENT", 0, 0, 0 };
> +static struct tr2_dst tr2dst_event = { TR2_SYSENV_EVENT, 0, 0, 0 };
>
> /*
> * The version number of the JSON data generated by the EVENT target
> @@ -28,17 +29,15 @@ static struct tr2_dst tr2dst_event = { "GIT_TR2_EVENT", 0, 0, 0 };
> * are primarily intended for the performance target during debugging.
> *
> * Some of the outer-most messages, however, may be of interest to the
> - * event target. Set this environment variable to a larger integer for
> - * more detail in the event target.
> + * event target. Use the TR2_SYSENV_EVENT_NESTING setting to increase
> + * region details in the event target.
> */
> -#define TR2_ENVVAR_EVENT_NESTING "GIT_TR2_EVENT_NESTING"
> static int tr2env_event_nesting_wanted = 2;
>
> /*
> - * Set this environment variable to true to omit the <time>, <file>, and
> + * Use the TR2_SYSENV_EVENT_BRIEF to omit the <time>, <file>, and
> * <line> fields from most events.
> */
> -#define TR2_ENVVAR_EVENT_BRIEF "GIT_TR2_EVENT_BRIEF"
> static int tr2env_event_brief;
>
> static int fn_init(void)
> @@ -46,17 +45,17 @@ static int fn_init(void)
> int want = tr2_dst_trace_want(&tr2dst_event);
> int want_nesting;
> int want_brief;
> - char *nesting;
> - char *brief;
> + const char *nesting;
> + const char *brief;
>
> if (!want)
> return want;
>
> - nesting = getenv(TR2_ENVVAR_EVENT_NESTING);
> + nesting = tr2_sysenv_get(TR2_SYSENV_EVENT_NESTING);
> if (nesting && ((want_nesting = atoi(nesting)) > 0))
> tr2env_event_nesting_wanted = want_nesting;
>
> - brief = getenv(TR2_ENVVAR_EVENT_BRIEF);
> + brief = tr2_sysenv_get(TR2_SYSENV_EVENT_BRIEF);
> if (brief && ((want_brief = atoi(brief)) > 0))
> tr2env_event_brief = want_brief;
A lot of this pre-dates this patch, but I wonder if the whole of trace2
couldn't make more use of config.c's bool parsing for things like
these. Maybe by having a "cfg_type" enum & parsed_value void* in
tr2_sysenv_entry?
> diff --git a/trace2/tr2_tgt_normal.c b/trace2/tr2_tgt_normal.c
> index 57f3e18f5b..3364223805 100644
> --- a/trace2/tr2_tgt_normal.c
> +++ b/trace2/tr2_tgt_normal.c
> @@ -4,19 +4,19 @@
> #include "quote.h"
> #include "version.h"
> #include "trace2/tr2_dst.h"
> +#include "trace2/tr2_sysenv.h"
> #include "trace2/tr2_tbuf.h"
> #include "trace2/tr2_tgt.h"
> #include "trace2/tr2_tls.h"
>
> -static struct tr2_dst tr2dst_normal = { "GIT_TR2", 0, 0, 0 };
> +static struct tr2_dst tr2dst_normal = { TR2_SYSENV_NORMAL, 0, 0, 0 };
>
> /*
> - * Set this environment variable to true to omit the "<time> <file>:<line>"
> + * Use the TR2_SYSENV_NORMAL_BRIEF setting to omit the "<time> <file>:<line>"
> * fields from each line written to the builtin normal target.
> *
> * Unit tests may want to use this to help with testing.
> */
> -#define TR2_ENVVAR_NORMAL_BRIEF "GIT_TR2_BRIEF"
> static int tr2env_normal_brief;
>
> #define TR2FMT_NORMAL_FL_WIDTH (50)
> @@ -25,12 +25,12 @@ static int fn_init(void)
> {
> int want = tr2_dst_trace_want(&tr2dst_normal);
> int want_brief;
> - char *brief;
> + const char *brief;
>
> if (!want)
> return want;
>
> - brief = getenv(TR2_ENVVAR_NORMAL_BRIEF);
> + brief = tr2_sysenv_get(TR2_SYSENV_NORMAL_BRIEF);
> if (brief && *brief &&
> ((want_brief = git_parse_maybe_bool(brief)) != -1))
> tr2env_normal_brief = want_brief;
> diff --git a/trace2/tr2_tgt_perf.c b/trace2/tr2_tgt_perf.c
> index 9c3b4d8a0f..1ad781c32e 100644
> --- a/trace2/tr2_tgt_perf.c
> +++ b/trace2/tr2_tgt_perf.c
> @@ -6,19 +6,19 @@
> #include "json-writer.h"
> #include "trace2/tr2_dst.h"
> #include "trace2/tr2_sid.h"
> +#include "trace2/tr2_sysenv.h"
> #include "trace2/tr2_tbuf.h"
> #include "trace2/tr2_tgt.h"
> #include "trace2/tr2_tls.h"
>
> -static struct tr2_dst tr2dst_perf = { "GIT_TR2_PERF", 0, 0, 0 };
> +static struct tr2_dst tr2dst_perf = { TR2_SYSENV_PERF, 0, 0, 0 };
>
> /*
> - * Set this environment variable to true to omit the "<time> <file>:<line>"
> + * Use TR2_SYSENV_PERF_BRIEF to omit the "<time> <file>:<line>"
> * fields from each line written to the builtin performance target.
> *
> * Unit tests may want to use this to help with testing.
> */
> -#define TR2_ENVVAR_PERF_BRIEF "GIT_TR2_PERF_BRIEF"
> static int tr2env_perf_brief;
>
> #define TR2FMT_PERF_FL_WIDTH (50)
> @@ -36,14 +36,14 @@ static int fn_init(void)
> {
> int want = tr2_dst_trace_want(&tr2dst_perf);
> int want_brief;
> - char *brief;
> + const char *brief;
>
> if (!want)
> return want;
>
> strbuf_addchars(&dots, '.', TR2_DOTS_BUFFER_SIZE);
>
> - brief = getenv(TR2_ENVVAR_PERF_BRIEF);
> + brief = tr2_sysenv_get(TR2_SYSENV_PERF_BRIEF);
> if (brief && *brief &&
> ((want_brief = git_parse_maybe_bool(brief)) != -1))
> tr2env_perf_brief = want_brief;
next prev parent reply other threads:[~2019-03-28 14:36 UTC|newest]
Thread overview: 68+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-03-28 13:30 [PATCH 0/4] trace2: load trace2 settings from system config Jeff Hostetler via GitGitGadget
2019-03-28 13:30 ` [PATCH 1/4] trace2: refactor setting process starting time Jeff Hostetler via GitGitGadget
2019-03-28 13:31 ` [PATCH 2/4] trace2: add absolute elapsed time to start event Jeff Hostetler via GitGitGadget
2019-03-28 13:31 ` [PATCH 3/4] trace2: find exec-dir before trace2 initialization Jeff Hostetler via GitGitGadget
2019-03-28 13:31 ` [PATCH 4/4] trace2: use system config for default trace2 settings Jeff Hostetler via GitGitGadget
2019-03-28 14:36 ` Ævar Arnfjörð Bjarmason [this message]
2019-03-28 18:50 ` Jeff Hostetler
2019-03-28 21:28 ` Josh Steadmon
2019-03-29 17:04 ` [PATCH v2 0/7] trace2: load trace2 settings from system config Jeff Hostetler via GitGitGadget
2019-03-29 17:04 ` [PATCH v2 1/7] trace2: refactor setting process starting time Jeff Hostetler via GitGitGadget
2019-03-29 17:04 ` [PATCH v2 2/7] trace2: add absolute elapsed time to start event Jeff Hostetler via GitGitGadget
2019-03-29 17:04 ` [PATCH v2 3/7] trace2: find exec-dir before trace2 initialization Jeff Hostetler via GitGitGadget
2019-03-29 17:04 ` [PATCH v2 4/7] trace2: use system config for default trace2 settings Jeff Hostetler via GitGitGadget
2019-04-01 21:00 ` Josh Steadmon
2019-04-01 21:06 ` Jeff Hostetler
2019-04-03 0:01 ` Jonathan Nieder
2019-04-03 0:00 ` Jonathan Nieder
2019-04-09 15:58 ` Jeff Hostetler
2019-03-29 17:04 ` [PATCH v2 5/7] trace2: report peak memory usage of the process Jeff Hostetler via GitGitGadget
2019-03-29 22:16 ` Ævar Arnfjörð Bjarmason
2019-04-01 21:05 ` Jeff Hostetler
2019-03-29 17:04 ` [PATCH v2 7/7] trace2: make SIDs more unique Jeff Hostetler via GitGitGadget
2019-03-29 22:12 ` Ævar Arnfjörð Bjarmason
2019-04-01 21:16 ` Jeff Hostetler
2019-03-29 17:04 ` [PATCH v2 6/7] trace2: clarify UTC datetime formatting Jeff Hostetler via GitGitGadget
2019-04-01 21:02 ` [PATCH v2 0/7] trace2: load trace2 settings from system config Josh Steadmon
2019-04-11 15:18 ` [PATCH v3 00/10] " Jeff Hostetler via GitGitGadget
2019-04-11 15:18 ` [PATCH v3 01/10] config: initialize opts structure in repo_read_config() Jeff Hostetler via GitGitGadget
2019-04-12 3:52 ` Jonathan Nieder
2019-04-15 14:34 ` Johannes Schindelin
2019-04-11 15:18 ` [PATCH v3 02/10] trace2: refactor setting process starting time Jeff Hostetler via GitGitGadget
2019-04-11 15:18 ` [PATCH v3 03/10] trace2: add absolute elapsed time to start event Jeff Hostetler via GitGitGadget
2019-04-11 15:18 ` [PATCH v3 04/10] trace2: find exec-dir before trace2 initialization Jeff Hostetler via GitGitGadget
2019-04-11 15:18 ` [PATCH v3 05/10] config: add read_very_early_config() Jeff Hostetler via GitGitGadget
2019-04-11 15:18 ` [PATCH v3 06/10] trace2: use system/global config for default trace2 settings Jeff Hostetler via GitGitGadget
2019-04-11 15:18 ` [PATCH v3 07/10] trace2: report peak memory usage of the process Jeff Hostetler via GitGitGadget
2019-04-11 15:18 ` [PATCH v3 08/10] trace2: clarify UTC datetime formatting Jeff Hostetler via GitGitGadget
2019-04-11 15:18 ` [PATCH v3 10/10] trace2: update docs to describe system/global config settings Jeff Hostetler via GitGitGadget
2019-04-11 15:18 ` [PATCH v3 09/10] trace2: make SIDs more unique Jeff Hostetler via GitGitGadget
2019-04-12 2:29 ` [PATCH v3 00/10] trace2: load trace2 settings from system config Junio C Hamano
2019-04-12 13:47 ` Jeff Hostetler
2019-04-15 20:39 ` [PATCH v4 " Jeff Hostetler via GitGitGadget
2019-04-15 20:39 ` [PATCH v4 01/10] config: initialize opts structure in repo_read_config() Jeff Hostetler via GitGitGadget
2019-04-15 20:39 ` [PATCH v4 02/10] trace2: refactor setting process starting time Jeff Hostetler via GitGitGadget
2019-04-15 20:39 ` [PATCH v4 03/10] trace2: add absolute elapsed time to start event Jeff Hostetler via GitGitGadget
2019-04-15 20:39 ` [PATCH v4 04/10] trace2: find exec-dir before trace2 initialization Jeff Hostetler via GitGitGadget
2019-04-15 20:39 ` [PATCH v4 05/10] config: add read_very_early_config() Jeff Hostetler via GitGitGadget
2019-04-15 20:39 ` [PATCH v4 06/10] trace2: use system/global config for default trace2 settings Jeff Hostetler via GitGitGadget
2019-04-27 13:43 ` SZEDER Gábor
2019-04-29 19:03 ` Jeff Hostetler
2019-04-15 20:39 ` [PATCH v4 08/10] trace2: clarify UTC datetime formatting Jeff Hostetler via GitGitGadget
2019-04-15 20:39 ` [PATCH v4 07/10] trace2: report peak memory usage of the process Jeff Hostetler via GitGitGadget
2019-04-15 20:39 ` [PATCH v4 09/10] trace2: make SIDs more unique Jeff Hostetler via GitGitGadget
2019-04-15 20:39 ` [PATCH v4 10/10] trace2: update docs to describe system/global config settings Jeff Hostetler via GitGitGadget
2019-04-29 20:14 ` [PATCH v5 00/11] trace2: load trace2 settings from system config Jeff Hostetler via GitGitGadget
2019-04-29 20:14 ` [PATCH v5 02/11] trace2: refactor setting process starting time Jeff Hostetler via GitGitGadget
2019-04-29 20:14 ` [PATCH v5 01/11] config: initialize opts structure in repo_read_config() Jeff Hostetler via GitGitGadget
2019-04-29 20:14 ` [PATCH v5 03/11] trace2: add absolute elapsed time to start event Jeff Hostetler via GitGitGadget
2019-04-29 20:14 ` [PATCH v5 04/11] trace2: find exec-dir before trace2 initialization Jeff Hostetler via GitGitGadget
2019-04-29 20:14 ` [PATCH v5 05/11] config: add read_very_early_config() Jeff Hostetler via GitGitGadget
2019-04-29 20:14 ` [PATCH v5 06/11] trace2: use system/global config for default trace2 settings Jeff Hostetler via GitGitGadget
2019-04-29 20:14 ` [PATCH v5 07/11] trace2: report peak memory usage of the process Jeff Hostetler via GitGitGadget
2019-04-29 20:14 ` [PATCH v5 08/11] trace2: clarify UTC datetime formatting Jeff Hostetler via GitGitGadget
2019-04-29 20:14 ` [PATCH v5 09/11] trace2: make SIDs more unique Jeff Hostetler via GitGitGadget
2019-04-29 20:14 ` [PATCH v5 10/11] trace2: update docs to describe system/global config settings Jeff Hostetler via GitGitGadget
2019-04-29 20:14 ` [PATCH v5 11/11] trace2: fixup access problem on /etc/gitconfig in read_very_early_config Jeff Hostetler via GitGitGadget
2019-04-29 20:21 ` [PATCH v5 00/11] trace2: load trace2 settings from system config Jeff Hostetler
2019-05-07 1:18 ` Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87wokj9ic1.fsf@evledraar.gmail.com \
--to=avarab@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitgitgadget@gmail.com \
--cc=gitster@pobox.com \
--cc=jeffhost@microsoft.com \
--cc=jrnieder@gmail.com \
--cc=peff@peff.net \
--cc=steadmon@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).