Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751578AbbGLL63 (ORCPT ); Sun, 12 Jul 2015 07:58:29 -0400 Received: from mail-pa0-f44.google.com ([209.85.220.44]:34269 "EHLO mail-pa0-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751280AbbGLL62 (ORCPT ); Sun, 12 Jul 2015 07:58:28 -0400 From: Taeung Song To: Arnaldo Carvalho de Melo Cc: linux-kernel@vger.kernel.org, jolsa@redhat.com, namhyung@kernel.org, Ingo Molnar , Taeung Song Subject: [PATCH v3 5/5] perf config: Add '--system' and '--global' options to be able to select which config file to be used. Date: Sun, 12 Jul 2015 14:17:31 +0900 Message-Id: <1436678251-19359-1-git-send-email-treeze.taeung@gmail.com> X-Mailer: git-send-email 1.9.1 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 9011 Lines: 284 Which config file is used is decided at only perf_config(). That's why a config file to be used can't be selected among system and global config file when perf-config commands get or set it. So add '--system' and '--global' options to select which config file to be used when getting, setting or etc. Signed-off-by: Taeung Song --- tools/perf/Documentation/perf-config.txt | 20 ++++++++-- tools/perf/builtin-config.c | 24 +++++++++-- tools/perf/util/cache.h | 5 ++- tools/perf/util/config.c | 68 +++++++++++++++++++------------- 4 files changed, 80 insertions(+), 37 deletions(-) diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt index a543e1b..b798112 100644 --- a/tools/perf/Documentation/perf-config.txt +++ b/tools/perf/Documentation/perf-config.txt @@ -8,13 +8,13 @@ perf-config - Get and set variables in a configuration file. SYNOPSIS -------- [verse] -'perf config' [section.name[=value] ...] +'perf config' [] [section.name[=value] ...] or -'perf config' -l | --list +'perf config' [] -l | --list or -'perf config' -a | --list-all +'perf config' [] -a | --list-all or -'perf config' -r | --remove [section.name ...] +'perf config' [] -r | --remove [section.name ...] DESCRIPTION ----------- @@ -35,6 +35,14 @@ OPTIONS --remove:: Remove specific config variables. +--global:: + For writing and reading options: write to global + '$HOME/.perfconfig' file or read it. + +--system:: + For writing and reading options: write to system-wide + '$(sysconfdir)/perfconfig' or read it. + CONFIGURATION FILE ------------------ @@ -47,6 +55,10 @@ store a system-wide default configuration. The variables are divided into sections. In each section, the variables can are composed of a key and value. +When reading or writing, the values are read from the system and global +configuration files by default, and options '--system' and '--global' +can be used to tell the command to read from or write to only that location. + Syntax ~~~~~~ diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c index 857e121..d8fa566 100644 --- a/tools/perf/builtin-config.c +++ b/tools/perf/builtin-config.c @@ -14,6 +14,8 @@ #include "util/debug.h" static int actions; +static bool use_system_config, use_global_config; +static const char *config_file_name; static const char * const config_usage[] = { "perf config [options] [section.name[=value] ...]", @@ -25,6 +27,9 @@ static const char * const config_usage[] = { #define ACTION_REMOVE (1<<2) static const struct option config_options[] = { + OPT_GROUP("Config file location"), + OPT_BOOLEAN(0, "system", &use_system_config, "use system config file"), + OPT_BOOLEAN(0, "global", &use_global_config, "use global config file"), OPT_GROUP("Action"), OPT_BIT('l', "list", &actions, "show current config variables", ACTION_LIST), OPT_BIT('a', "list-all", &actions, @@ -508,7 +513,7 @@ static int set_config(const char *section_name, const char *name, char *value) } } - return perf_configset_write_in_full(); + return perf_configset_write_in_full(config_file_name); } static int collect_current_config(const char *var, const char *value, @@ -635,13 +640,24 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused) else has_option = false; + if (use_system_config && use_global_config) { + pr_err("Error: only one config file at a time."); + usage_with_options(config_usage, config_options); + return -1; + } else if (use_global_config || (!use_system_config && !use_global_config)) { + config_file_name = perf_user_perfconfig(getenv("HOME")); + if (!config_file_name) + return -1; + } else if (use_system_config) + config_file_name = perf_etc_perfconfig(); + INIT_LIST_HEAD(§ions); - perf_config(collect_current_config, NULL); + perf_config_from_file(collect_current_config, config_file_name, NULL); switch (actions) { case ACTION_LIST: if (argc == 0) - ret = perf_config(show_config, NULL); + ret = perf_config_from_file(show_config, config_file_name, NULL); else goto out_err; goto out; @@ -665,7 +681,7 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused) goto out; default: if (!has_option && argc == 0) { - ret = perf_config(show_config, NULL); + ret = perf_config_from_file(show_config, config_file_name, NULL); goto out; } else if (argc > 0) { for (i = 0; argv[i]; i++) { diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h index 36d7839..079a3846 100644 --- a/tools/perf/util/cache.h +++ b/tools/perf/util/cache.h @@ -35,15 +35,18 @@ struct config_section { struct list_head sections; typedef int (*configset_fn_t)(const char *, const char *, char*); -extern int perf_configset_write_in_full(void); +extern int perf_configset_write_in_full(const char *file_name); typedef int (*config_fn_t)(const char *, const char *, void *); extern int perf_default_config(const char *, const char *, void *); extern int perf_config(config_fn_t fn, void *); +extern int perf_config_from_file(config_fn_t fn, const char *filename, void *data); extern int perf_config_int(const char *, const char *); extern u64 perf_config_u64(const char *, const char *); extern int perf_config_bool(const char *, const char *); extern int config_error_nonbool(const char *); extern const char *perf_config_dirname(const char *, const char *); +extern const char *perf_etc_perfconfig(void); +extern const char *perf_user_perfconfig(const char *home); /* pager.c */ extern void setup_pager(void); diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c index b6c0d2c..333c2ee 100644 --- a/tools/perf/util/config.c +++ b/tools/perf/util/config.c @@ -21,7 +21,7 @@ char buildid_dir[MAXPATHLEN]; /* root dir for buildid, binary cache */ static FILE *config_file; -static char *config_file_name; +static const char *config_file_name; static int config_linenr; static int config_file_eof; @@ -412,7 +412,7 @@ int perf_default_config(const char *var, const char *value, return 0; } -static int perf_config_from_file(config_fn_t fn, const char *filename, void *data) +int perf_config_from_file(config_fn_t fn, const char *filename, void *data) { int ret; FILE *f = fopen(filename, "r"); @@ -420,16 +420,48 @@ static int perf_config_from_file(config_fn_t fn, const char *filename, void *dat ret = -1; if (f) { config_file = f; - config_file_name = strdup(filename); + config_file_name = filename; config_linenr = 1; config_file_eof = 0; ret = perf_parse_file(fn, data); fclose(f); + config_file_name = NULL; } return ret; } -static const char *perf_etc_perfconfig(void) +const char *perf_user_perfconfig(const char *home) +{ + char *user_config = strdup(mkpath("%s/.perfconfig", home)); + struct stat st; + + if (user_config == NULL) { + warning("Not enough memory to process %s/.perfconfig, " + "ignoring it.", home); + goto out; + } + + if (stat(user_config, &st) < 0) + goto out_free; + + if (st.st_uid && (st.st_uid != geteuid())) { + warning("File %s not owned by current user or root, " + "ignoring it.", user_config); + goto out_free; + } + + if (!st.st_size) + goto out_free; + + return user_config; + +out_free: + free(user_config); +out: + return NULL; +} + +const char *perf_etc_perfconfig(void) { static const char *system_wide; if (!system_wide) @@ -469,31 +501,11 @@ int perf_config(config_fn_t fn, void *data) home = getenv("HOME"); if (perf_config_global() && home) { - char *user_config = strdup(mkpath("%s/.perfconfig", home)); - struct stat st; - - if (user_config == NULL) { - warning("Not enough memory to process %s/.perfconfig, " - "ignoring it.", home); + const char *user_config = perf_user_perfconfig(home); + if (user_config == NULL) goto out; - } - - if (stat(user_config, &st) < 0) - goto out_free; - - if (st.st_uid && (st.st_uid != geteuid())) { - warning("File %s not owned by current user or root, " - "ignoring it.", user_config); - goto out_free; - } - - if (!st.st_size) - goto out_free; - ret += perf_config_from_file(fn, user_config, data); found += 1; -out_free: - free(user_config); } out: if (found == 0) @@ -501,12 +513,12 @@ out: return ret; } -int perf_configset_write_in_full(void) +int perf_configset_write_in_full(const char *file_name) { struct config_section *section_node; struct config_element *element_node; const char *first_line = "# this file is auto-generated."; - FILE *fp = fopen(config_file_name, "w"); + FILE *fp = fopen(file_name, "w"); if (!fp) return -1; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/