1#include "cache.h" 2#include "config.h" 3#include "dir.h" 4#include "tr2_sysenv.h" 5 6/* 7 * Each entry represents a trace2 setting. 8 * See Documentation/technical/api-trace2.txt 9 */ 10struct tr2_sysenv_entry { 11 const char *env_var_name; 12 const char *git_config_name; 13 14 char *value; 15 unsigned int getenv_called : 1; 16}; 17 18/* 19 * This table must match "enum tr2_sysenv_variable" in tr2_sysenv.h. 20 * 21 * The strings in this table are constant and must match the published 22 * config and environment variable names as described in the documentation. 23 * 24 * We do not define entries for the GIT_TR2_PARENT_* environment 25 * variables because they are transient and used to pass information 26 * from parent to child git processes, rather than settings. 27 */ 28/* clang-format off */ 29static struct tr2_sysenv_entry tr2_sysenv_settings[] = { 30 [TR2_SYSENV_CFG_PARAM] = { "GIT_TR2_CONFIG_PARAMS", 31 "trace2.configparams" }, 32 33 [TR2_SYSENV_DST_DEBUG] = { "GIT_TR2_DST_DEBUG", 34 "trace2.destinationdebug" }, 35 36 [TR2_SYSENV_NORMAL] = { "GIT_TR2", 37 "trace2.normaltarget" }, 38 [TR2_SYSENV_NORMAL_BRIEF] = { "GIT_TR2_BRIEF", 39 "trace2.normalbrief" }, 40 41 [TR2_SYSENV_EVENT] = { "GIT_TR2_EVENT", 42 "trace2.eventtarget" }, 43 [TR2_SYSENV_EVENT_BRIEF] = { "GIT_TR2_EVENT_BRIEF", 44 "trace2.eventbrief" }, 45 [TR2_SYSENV_EVENT_NESTING] = { "GIT_TR2_EVENT_NESTING", 46 "trace2.eventnesting" }, 47 48 [TR2_SYSENV_PERF] = { "GIT_TR2_PERF", 49 "trace2.perftarget" }, 50 [TR2_SYSENV_PERF_BRIEF] = { "GIT_TR2_PERF_BRIEF", 51 "trace2.perfbrief" }, 52}; 53/* clang-format on */ 54 55static int tr2_sysenv_cb(const char *key, const char *value, void *d) 56{ 57 int k; 58 59 if (!starts_with(key, "trace2.")) 60 return 0; 61 62 for (k = 0; k < ARRAY_SIZE(tr2_sysenv_settings); k++) { 63 if (!strcmp(key, tr2_sysenv_settings[k].git_config_name)) { 64 free(tr2_sysenv_settings[k].value); 65 tr2_sysenv_settings[k].value = xstrdup(value); 66 return 0; 67 } 68 } 69 70 return 0; 71} 72 73/* 74 * Load Trace2 settings from the system config (usually "/etc/gitconfig" 75 * unless we were built with a runtime-prefix). These are intended to 76 * define the default values for Trace2 as requested by the administrator. 77 * 78 * Then override with the Trace2 settings from the global config. 79 */ 80void tr2_sysenv_load(void) 81{ 82 if (ARRAY_SIZE(tr2_sysenv_settings) != TR2_SYSENV_MUST_BE_LAST) 83 BUG("tr2_sysenv_settings size is wrong"); 84 85 read_very_early_config(tr2_sysenv_cb, NULL); 86} 87 88/* 89 * Return the value for the requested Trace2 setting from these sources: 90 * the system config, the global config, and the environment. 91 */ 92const char *tr2_sysenv_get(enum tr2_sysenv_variable var) 93{ 94 if (var >= TR2_SYSENV_MUST_BE_LAST) 95 BUG("tr2_sysenv_get invalid var '%d'", var); 96 97 if (!tr2_sysenv_settings[var].getenv_called) { 98 const char *v = getenv(tr2_sysenv_settings[var].env_var_name); 99 if (v && *v) { 100 free(tr2_sysenv_settings[var].value); 101 tr2_sysenv_settings[var].value = xstrdup(v); 102 } 103 tr2_sysenv_settings[var].getenv_called = 1; 104 } 105 106 return tr2_sysenv_settings[var].value; 107} 108 109/* 110 * Return a friendly name for this setting that is suitable for printing 111 * in an error messages. 112 */ 113const char *tr2_sysenv_display_name(enum tr2_sysenv_variable var) 114{ 115 if (var >= TR2_SYSENV_MUST_BE_LAST) 116 BUG("tr2_sysenv_get invalid var '%d'", var); 117 118 return tr2_sysenv_settings[var].env_var_name; 119} 120 121void tr2_sysenv_release(void) 122{ 123 int k; 124 125 for (k = 0; k < ARRAY_SIZE(tr2_sysenv_settings); k++) 126 free(tr2_sysenv_settings[k].value); 127}