From: taeung <treeze.taeung@gmail.com>
To: Namhyung Kim <namhyung@kernel.org>
Cc: linux-perf-users@vger.kernel.org
Subject: How do you think about a time when selecting perf config file path ?
Date: Thu, 14 May 2015 15:29:44 +0900 [thread overview]
Message-ID: <555440D8.6040201@gmail.com> (raw)
Hi, Namhyung
How do you think about a time when selecting perf config file path ?
At this present, perfconfig file path can be selected as
'/etc/perfconfig' or '$(HOME)/.perfconfig'.
And the config file path is selected when calling a function
'perf_config()'.
If you see functions 1,2,3,4 as below, you can understand what I
agonize. I think that the part which perf config path is selected must
be separated as other function to also use the function in
'cmd_config()' in new builtin-config.c.
For example,
If adding a option '--global' or '--local' for config file path,
the perf config file name have to selected in 'cmd_config()' before
'perf_config()' is called.
How do you think about this ?
Thanks,
Taeung
1. a function 'perf_config()' in util/config.c
========
int perf_config(config_fn_t fn, void *data)
{
int ret = 0, found = 0;
const char *home = NULL;
/* Setting $PERF_CONFIG makes perf read _only_ the given config file. */
if (config_exclusive_filename)
return perf_config_from_file(fn, config_exclusive_filename, data);
if (perf_config_system() && !access(perf_etc_perfconfig(), R_OK)) {
ret += perf_config_from_file(fn, perf_etc_perfconfig(),
data);
found += 1;
}
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);
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)
return -1;
return ret;
}
========
2. 'perf_config_from_file()' in util/config.c I modified
========
int perf_config_from_file(config_fn_t fn, const char *filename, void *data)
{
int ret;
FILE *f = fopen(filename, "r");
ret = -1;
if (f) {
config_file = f;
- config_file_name = filename;
+ config_file_name = strdup(filename);
config_linenr = 1;
config_file_eof = 0;
ret = perf_parse_file(fn, data);
fclose(f);
- config_file_name = NULL;
}
return ret;
}
========
3. 'perf_configset_write_in_full()' in util/config.c that I added as new
a function because of new 'perf config' command. And this function use a
global variable 'config_file_name' to rewrite config file with new
config contents.
(To add new command 'perf-config', I try to modify this file
'util/config.c')
========
+int perf_configset_write_in_full(void)
+{
+ 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");
+
+ if (!fp)
+ return -1;
+
+ fprintf(fp, "%s\n", first_line);
+ /* overwrite configvariables */
+ list_for_each_entry(section_node, sections, list) {
+ fprintf(fp, "[%s]\n", section_node->name);
+ list_for_each_entry(element_node, §ion_node->element_head, list) {
+ if (element_node->value)
+ fprintf(fp, "\t%s = %s\n",
+ element_node->subkey, element_node->value);
+ }
+ }
+ fclose(fp);
+
+ return 0;
+}
========
4. a new function 'cmd_config()' in new file builtin-config.c.
(If working a command as '$ perf config', cmd_config() is firstly
called. This function is also added by me.)
========
+int cmd_config(int argc, const char **argv, const char *prefix
__maybe_unused)
+{
+ int i, ret = 0;
+ int origin_argc = argc - 1;
+ char *value;
+ bool is_option;
+
+ argc = parse_options(argc, argv, config_options, config_usage,
+ PARSE_OPT_STOP_AT_NON_OPTION);
+ if (origin_argc > argc)
+ is_option = true;
+ else
+ is_option = false;
+
+ if (!is_option && argc >= 0) {
+ switch (argc) {
+ case 0:
+ break;
+ default:
+ for (i = 0; argv[i]; i++) {
+ value = strrchr(argv[i], '=');
+ if (value == NULL || value == argv[i])
+ ret = perf_configset_with_option(show_spec_config, argv[i]);
+ else
+ ret = perf_configset_with_option(set_spec_config, argv[i]);
+ if (ret < 0)
+ break;
+ }
+ goto out;
+ }
+ }
+ if (params.list_action && argc == 0)
+ ret = perf_config(show_config, NULL);
+ else {
+ pr_warning("Error: Unknown argument.\n");
+ usage_with_options(config_usage, config_options);
+ }
+
+ return ret;
+}
========
next reply other threads:[~2015-05-14 6:29 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-05-14 6:29 taeung [this message]
2015-05-15 12:40 ` How do you think about a time when selecting perf config file path ? Namhyung Kim
2015-05-18 20:50 ` Arnaldo Carvalho de Melo
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
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=555440D8.6040201@gmail.com \
--to=treeze.taeung@gmail.com \
--cc=linux-perf-users@vger.kernel.org \
--cc=namhyung@kernel.org \
/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.
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 NNTP newsgroup(s).