aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTaeung Song <treeze.taeung@gmail.com>2016-06-23 10:14:31 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2016-06-23 16:20:04 -0400
commit8a0a9c7e9146781defc96f6743e7ee14ccc9ab23 (patch)
tree832a6c519cc5b76ff19a491ce9d85795fd4151b3
parente216708d982a1c262f411fee2fcac2bd9ec93a32 (diff)
perf config: Introduce new init() and exit()
Many sub-commands use perf_config() but everytime perf_config() is called, perf_config() always read config files. (i.e. user config '~/.perfconfig' and system config '$(sysconfdir)/perfconfig') But it is better to use the config set that already contains all config key-value pairs to avoid this repetitive work reading the config files in perf_config(). (the config set mean a static variable 'config_set') In other words, if new perf_config__init() is called, only first time 'config_set' is initialized collecting all configs from the config files. And then we could use new perf_config() like old perf_config(). When a sub-command finished, free the config set by perf_config__exit() at run_builtin(). If we do, 'config_set' can be reused wherever perf_config() is called and a feature of old perf_config() is the same as new perf_config() work without the repetitive work that read the config files. In summary, in order to use features about configuration, we can call the functions at perf.c and other source files as below. # initialize a config set perf_config__init() # configure actual variables from a config set perf_config() # eliminate allocated config set perf_config__exit() # destroy existing config set and initialize a new config set. perf_config__refresh() Signed-off-by: Taeung Song <treeze.taeung@gmail.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Masami Hiramatsu <mhiramat@kernel.org> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Wang Nan <wangnan0@huawei.com> Link: http://lkml.kernel.org/r/1466691272-24117-3-git-send-email-treeze.taeung@gmail.com [ 'init' counterpart is 'exit', not 'finish' ] Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/builtin-config.c4
-rw-r--r--tools/perf/perf.c2
-rw-r--r--tools/perf/util/config.c92
-rw-r--r--tools/perf/util/config.h29
4 files changed, 82 insertions, 45 deletions
diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c
index fe1b77fa21f9..cfd1036b1d24 100644
--- a/tools/perf/builtin-config.c
+++ b/tools/perf/builtin-config.c
@@ -80,6 +80,10 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
80 else if (use_user_config) 80 else if (use_user_config)
81 config_exclusive_filename = user_config; 81 config_exclusive_filename = user_config;
82 82
83 /*
84 * At only 'config' sub-command, individually use the config set
85 * because of reinitializing with options config file location.
86 */
83 set = perf_config_set__new(); 87 set = perf_config_set__new();
84 if (!set) { 88 if (!set) {
85 ret = -1; 89 ret = -1;
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index 66772dafa3ec..8f219223f305 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -355,6 +355,7 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
355 355
356 perf_env__set_cmdline(&perf_env, argc, argv); 356 perf_env__set_cmdline(&perf_env, argc, argv);
357 status = p->fn(argc, argv, prefix); 357 status = p->fn(argc, argv, prefix);
358 perf_config__exit();
358 exit_browser(status); 359 exit_browser(status);
359 perf_env__exit(&perf_env); 360 perf_env__exit(&perf_env);
360 bpf__clear(); 361 bpf__clear();
@@ -522,6 +523,7 @@ int main(int argc, const char **argv)
522 523
523 srandom(time(NULL)); 524 srandom(time(NULL));
524 525
526 perf_config__init();
525 perf_config(perf_default_config, NULL); 527 perf_config(perf_default_config, NULL);
526 set_buildid_dir(NULL); 528 set_buildid_dir(NULL);
527 529
diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c
index d15c59267644..18dae745034f 100644
--- a/tools/perf/util/config.c
+++ b/tools/perf/util/config.c
@@ -26,6 +26,7 @@ static FILE *config_file;
26static const char *config_file_name; 26static const char *config_file_name;
27static int config_linenr; 27static int config_linenr;
28static int config_file_eof; 28static int config_file_eof;
29static struct perf_config_set *config_set;
29 30
30const char *config_exclusive_filename; 31const char *config_exclusive_filename;
31 32
@@ -478,51 +479,6 @@ static int perf_config_global(void)
478 return !perf_env_bool("PERF_CONFIG_NOGLOBAL", 0); 479 return !perf_env_bool("PERF_CONFIG_NOGLOBAL", 0);
479} 480}
480 481
481int perf_config(config_fn_t fn, void *data)
482{
483 int ret = -1;
484 const char *home = NULL;
485
486 /* Setting $PERF_CONFIG makes perf read _only_ the given config file. */
487 if (config_exclusive_filename)
488 return perf_config_from_file(fn, config_exclusive_filename, data);
489 if (perf_config_system() && !access(perf_etc_perfconfig(), R_OK)) {
490 if (perf_config_from_file(fn, perf_etc_perfconfig(), data) < 0)
491 goto out;
492 }
493
494 home = getenv("HOME");
495 if (perf_config_global() && home) {
496 char *user_config = strdup(mkpath("%s/.perfconfig", home));
497 struct stat st;
498
499 if (user_config == NULL) {
500 warning("Not enough memory to process %s/.perfconfig, "
501 "ignoring it.", home);
502 goto out;
503 }
504
505 if (stat(user_config, &st) < 0)
506 goto out_free;
507
508 if (st.st_uid && (st.st_uid != geteuid())) {
509 warning("File %s not owned by current user or root, "
510 "ignoring it.", user_config);
511 goto out_free;
512 }
513
514 if (!st.st_size)
515 goto out_free;
516
517 ret = perf_config_from_file(fn, user_config, data);
518
519out_free:
520 free(user_config);
521 }
522out:
523 return ret;
524}
525
526static struct perf_config_section *find_section(struct list_head *sections, 482static struct perf_config_section *find_section(struct list_head *sections,
527 const char *section_name) 483 const char *section_name)
528{ 484{
@@ -706,6 +662,52 @@ struct perf_config_set *perf_config_set__new(void)
706 return set; 662 return set;
707} 663}
708 664
665int perf_config(config_fn_t fn, void *data)
666{
667 int ret = 0;
668 char key[BUFSIZ];
669 struct perf_config_section *section;
670 struct perf_config_item *item;
671
672 if (config_set == NULL)
673 return -1;
674
675 perf_config_set__for_each_entry(config_set, section, item) {
676 char *value = item->value;
677
678 if (value) {
679 scnprintf(key, sizeof(key), "%s.%s",
680 section->name, item->name);
681 ret = fn(key, value, data);
682 if (ret < 0) {
683 pr_err("Error: wrong config key-value pair %s=%s\n",
684 key, value);
685 break;
686 }
687 }
688 }
689
690 return ret;
691}
692
693void perf_config__init(void)
694{
695 if (config_set == NULL)
696 config_set = perf_config_set__new();
697}
698
699void perf_config__exit(void)
700{
701 perf_config_set__delete(config_set);
702 config_set = NULL;
703}
704
705void perf_config__refresh(void)
706{
707 perf_config__exit();
708 perf_config__init();
709}
710
709static void perf_config_item__delete(struct perf_config_item *item) 711static void perf_config_item__delete(struct perf_config_item *item)
710{ 712{
711 zfree(&item->name); 713 zfree(&item->name);
diff --git a/tools/perf/util/config.h b/tools/perf/util/config.h
index 155a441343e2..6f813d46045e 100644
--- a/tools/perf/util/config.h
+++ b/tools/perf/util/config.h
@@ -33,5 +33,34 @@ const char *perf_etc_perfconfig(void);
33 33
34struct perf_config_set *perf_config_set__new(void); 34struct perf_config_set *perf_config_set__new(void);
35void perf_config_set__delete(struct perf_config_set *set); 35void perf_config_set__delete(struct perf_config_set *set);
36void perf_config__init(void);
37void perf_config__exit(void);
38void perf_config__refresh(void);
39
40/**
41 * perf_config_sections__for_each - iterate thru all the sections
42 * @list: list_head instance to iterate
43 * @section: struct perf_config_section iterator
44 */
45#define perf_config_sections__for_each_entry(list, section) \
46 list_for_each_entry(section, list, node)
47
48/**
49 * perf_config_items__for_each - iterate thru all the items
50 * @list: list_head instance to iterate
51 * @item: struct perf_config_item iterator
52 */
53#define perf_config_items__for_each_entry(list, item) \
54 list_for_each_entry(item, list, node)
55
56/**
57 * perf_config_set__for_each - iterate thru all the config section-item pairs
58 * @set: evlist instance to iterate
59 * @section: struct perf_config_section iterator
60 * @item: struct perf_config_item iterator
61 */
62#define perf_config_set__for_each_entry(set, section, item) \
63 perf_config_sections__for_each_entry(&set->sections, section) \
64 perf_config_items__for_each_entry(&section->items, item)
36 65
37#endif /* __PERF_CONFIG_H */ 66#endif /* __PERF_CONFIG_H */