Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1261133 > unrolled thread
| Started by | Taeung Song <treeze.taeung@gmail.com> |
|---|---|
| First post | 2015-11-03 03:00 +0100 |
| Last post | 2015-11-03 13:20 +0100 |
| Articles | 12 — 2 participants |
Back to article view | Back to linux.kernel
[PATCH v9 0/9] perf tools: Add 'perf-config' command Taeung Song <treeze.taeung@gmail.com> - 2015-11-03 03:00 +0100
[PATCH v9 7/9] perf config: Add 'set' feature Taeung Song <treeze.taeung@gmail.com> - 2015-11-03 03:00 +0100
[PATCH v9 3/9] perf config: Collect configs to handle config variables Taeung Song <treeze.taeung@gmail.com> - 2015-11-03 03:00 +0100
Re: [PATCH v9 3/9] perf config: Collect configs to handle config variables Namhyung Kim <namhyung@kernel.org> - 2015-11-03 13:20 +0100
[PATCH v9 2/9] perf config: Add '--system' and '--user' options to select which config file is used Taeung Song <treeze.taeung@gmail.com> - 2015-11-03 03:00 +0100
Re: [PATCH v9 2/9] perf config: Add '--system' and '--user' options to select which config file is used Namhyung Kim <namhyung@kernel.org> - 2015-11-03 12:50 +0100
[PATCH v9 5/9] perf config: Add a option 'list-all' to perf-config Taeung Song <treeze.taeung@gmail.com> - 2015-11-03 03:00 +0100
Re: [PATCH v9 5/9] perf config: Add a option 'list-all' to perf-config Namhyung Kim <namhyung@kernel.org> - 2015-11-03 13:40 +0100
[PATCH v9 6/9] perf config: Add 'get' functionaliy Taeung Song <treeze.taeung@gmail.com> - 2015-11-03 03:00 +0100
[PATCH v9 9/9] perf config: Add a option 'remove' to perf-config Taeung Song <treeze.taeung@gmail.com> - 2015-11-03 03:00 +0100
[PATCH v9 4/9] perf config: Add comparing name treating '_' and '-' as being the same thing. Taeung Song <treeze.taeung@gmail.com> - 2015-11-03 03:00 +0100
Re: [PATCH v9 4/9] perf config: Add comparing name treating '_' and '-' as being the same thing. Namhyung Kim <namhyung@kernel.org> - 2015-11-03 13:20 +0100
| From | Taeung Song <treeze.taeung@gmail.com> |
|---|---|
| Date | 2015-11-03 03:00 +0100 |
| Subject | [PATCH v9 0/9] perf tools: Add 'perf-config' command |
| Message-ID | <qqz3c-4xe-9@gated-at.bofh.it> |
So far, it is difficult that the state of perf configs is looked through
and there's no knowing what kind of other variables except variables in perfconfig.example.
Also perf configs can't be changed without manually modifying $HOME/.perfconfig or
$(sysconfdir)/perfconfig file. So I suggest this patchset of the perf-config command
which can list, get, set, remove perf configs or list with default config values as below.
Taeung Song (9):
[PATCH v9 1/9] perf tools: Add 'perf-config' command
[PATCH v9 2/9] perf config: Add '--system' and '--user' options to select which
config file is used
[PATCH v9 3/9] perf config: Collect configs to handle config variables
[PATCH v9 4/9] perf config: Add comparing name treating '_' and '-' as
being the same thing.
[PATCH v9 5/9] perf config: Add a option 'list-all' to perf-config
[PATCH v9 6/9] perf config: Add 'get' functionaliy
[PATCH v9 7/9] perf config: Add 'set' feature
[PATCH v9 8/9] perf config: normalize a value depending on default type of it
[PATCH v9 9/9] perf config: Add a option 'remove' to perf-config
Changes in v9:
- Add the compare name functionality treating '-' and '-' as being the same thing
for usability (PATCH v9 4/9)
Changes in v8:
- Correct small typing errors in a perf-config documention (PATCH v8 1/8)
- Split the collecting configs part into a separate patch (PATCH v8 3/8)
- Use new enum and struct for default configs instead of hard-coded value
as suggested by Namhyung (PATCH v8 4/8)
Changes in v7:
- Modify explanations of syntax and options(color, gtk, tui, buildid, annotate)
to be better proper descriptions as suggested by Arnaldo (PATCH v7 1/7)
Changes in v6:
- Split a 'set' feature patch into two patch to separate normalize_value() from it.
(PATCH v6 5/7, PATCH v6 6/7)
- Bug fix : 'remove' and 'set' malfunctions when without a specific file-option.
(If file-option isn't used, 'remove' feature had to use both user and system
config file and 'set' feature had to only handle user config file.)
(PATCH v6 5/7, PATCH v6 7/7)
Changes in v5:
- Simplify the switch statement in cmd_config()
- Set a config file path with '--system' or '--user'
instead of '--global' or '--system' as suggested by Namhyung. (PATCH v5 2/6)
- The patch about 'get' and 'set 'split into two patchs
as suggested by Namhyung. (PATCH v5 4/6, PATCH v5 5/6)
Changes in v4:
- If some config value is default value, notice it is '(default)'
as suggested by Jirka. (PATCH v4 3/5)
- If there wasn't any perfconfig file, perf-config malfunctioned like
Jirka pointed out. So add exception routine with '--global' and '--system'
option which can select perf config file path. (PATCH v4 2/5)
Changes in v3:
- Add a config variable 'kmem.default' with a default value as suggested by Namhyung.
(PATCH v3 2/5, PATCH v4 3/5)
Changes in v2:
- Change option name of listing all configs as '--list-all' instead of '--all'
as suggested by Namhyung. (PATCH v2 3/4, PATCH v4 4/5)
- Correct small infelicities or typing errors in a perf-config documention
as suggested by Arnaldo. (PATCH v2 1/4, PATCH v4 1/5)
- Declaration a global variable 'static struct default_configsets' has config variables
with default values instead of using a 'util/PERFCONFIG-DEFAULT' file.
(PATCH v2 3/4, PATCH v4 3/5)
- Add a function to normalize a value and check data type of it.
(PATCH v2 2/4, PATCH v4 3/5)
- Simplify parsing arguments as arguments is just divided by '=' and then
in front of '.' is a section, between '.' and '=' is a name, and behind '=' is a value.
(PATCH v2 2/4, PATCH v4 3/5)
- If run perf-config command without any option, perf-config work as '--list'.
(PATCH v2 1/4, PATCH v4 1/5)
tools/perf/Build | 1 +
tools/perf/Documentation/perf-config.txt | 422 +++++++++++++++++++
tools/perf/builtin-config.c | 677 +++++++++++++++++++++++++++++++
tools/perf/builtin.h | 1 +
tools/perf/command-list.txt | 1 +
tools/perf/perf.c | 1 +
tools/perf/util/cache.h | 20 +
tools/perf/util/config.c | 31 +-
8 files changed, 1151 insertions(+), 3 deletions(-)
create mode 100644 tools/perf/Documentation/perf-config.txt
create mode 100644 tools/perf/builtin-config.c
--
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/
[toc] | [next] | [standalone]
| From | Taeung Song <treeze.taeung@gmail.com> |
|---|---|
| Date | 2015-11-03 03:00 +0100 |
| Subject | [PATCH v9 7/9] perf config: Add 'set' feature |
| Message-ID | <qqz3c-4xe-15@gated-at.bofh.it> |
| In reply to | #1261133 |
This patch consists of functions
which can set specific config variables.
For the syntax examples,
perf config [<file-option>] [options] [section.name[=value] ...]
set specific config variables
# perf config report.queue-size=100M report.children=true
Signed-off-by: Taeung Song <treeze.taeung@gmail.com>
---
tools/perf/Documentation/perf-config.txt | 2 +-
tools/perf/builtin-config.c | 126 +++++++++++++++++++++++++------
tools/perf/util/cache.h | 5 +-
tools/perf/util/config.c | 27 ++++++-
4 files changed, 134 insertions(+), 26 deletions(-)
diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
index c7dd65e..3caa1d1 100644
--- a/tools/perf/Documentation/perf-config.txt
+++ b/tools/perf/Documentation/perf-config.txt
@@ -8,7 +8,7 @@ perf-config - Get and set variables in a configuration file.
SYNOPSIS
--------
[verse]
-'perf config' [<file-option>] [section.name ...]
+'perf config' [<file-option>] [section.name[=value] ...]
or
'perf config' [<file-option>] -l | --list
or
diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c
index 16d81ae..6ac28af 100644
--- a/tools/perf/builtin-config.c
+++ b/tools/perf/builtin-config.c
@@ -16,7 +16,7 @@
static bool use_system_config, use_user_config;
static const char * const config_usage[] = {
- "perf config [<file-option>] [options] [section.name ...]",
+ "perf config [<file-option>] [options] [section.name[=value] ...]",
NULL
};
@@ -338,7 +338,9 @@ static int show_all_config(struct list_head *sections)
}
static int show_spec_config(struct list_head *sections,
- const char *section_name, const char *name)
+ const char *config_file_name __maybe_unused,
+ const char *section_name, const char *name,
+ char *value __maybe_unused)
{
int i;
struct config_section *section = NULL;
@@ -366,6 +368,39 @@ static int show_spec_config(struct list_head *sections,
return -1;
}
+static int set_config(struct list_head *sections, const char *config_file_name,
+ const char *section_name, const char *name, char *value)
+{
+ struct config_section *section = NULL;
+ struct config_element *element = NULL;
+
+ find_config(sections, §ion, &element, section_name, name);
+ if (value != NULL) {
+ value = strdup(value);
+ if (!value) {
+ pr_err("%s: strdup failed\n", __func__);
+ return -1;
+ }
+
+ /* if there isn't existent section, add a new section */
+ if (!section) {
+ section = init_section(section_name);
+ if (!section)
+ return -1;
+ list_add_tail(§ion->list, sections);
+ }
+ /* if nothing to replace, add a new element which contains key-value pair. */
+ if (!element) {
+ add_element(§ion->element_head, name, value);
+ } else {
+ free(element->value);
+ element->value = value;
+ }
+ }
+
+ return perf_configset_write_in_full(sections, config_file_name);
+}
+
static int collect_current_config(const char *var, const char *value,
void *spec_sections __maybe_unused)
{
@@ -415,8 +450,10 @@ out_err:
return ret;
}
-static int perf_configset_with_option(configset_fn_t fn, struct list_head *sections,
- const char *var)
+static int perf_configset_with_option(configset_fn_t fn,
+ struct list_head *sections,
+ const char *config_file_name,
+ const char *var, char *value)
{
int ret = -1;
char *ptr, *key;
@@ -443,10 +480,24 @@ static int perf_configset_with_option(configset_fn_t fn, struct list_head *secti
}
section_name = strsep(&ptr, ".");
- name = ptr;
- fn(sections, section_name, name);
- ret = 0;
+ name = strsep(&ptr, "=");
+ if (!value) {
+ /* do nothing */
+ } else if (!strcmp(value, "=")) {
+ pr_err("The config variable does not contain a value: %s.%s\n",
+ section_name, name);
+ goto out_err;
+ } else {
+ value++;
+ name = strsep(&name, "=");
+ if (name[0] == '\0') {
+ pr_err("invalid key: %s\n", var);
+ goto out_err;
+ }
+ }
+ fn(sections, config_file_name, section_name, name, value);
+ ret = 0;
out_err:
free(key);
return ret;
@@ -470,7 +521,10 @@ static int show_config(struct list_head *sections)
int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
{
int i, ret = 0;
- struct list_head sections;
+ struct list_head *sections;
+ struct list_head all_sections, user_sections, system_sections;
+ const char *system_config = perf_etc_perfconfig();
+ char *user_config = mkpath("%s/.perfconfig", getenv("HOME"));
set_option_flag(config_options, 'l', "list", PARSE_OPT_EXCLUSIVE);
set_option_flag(config_options, 'a', "list-all", PARSE_OPT_EXCLUSIVE);
@@ -485,19 +539,27 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
return -1;
}
- INIT_LIST_HEAD(§ions);
-
- if (use_system_config)
- config_exclusive_filename = perf_etc_perfconfig();
- else if (use_user_config)
- config_exclusive_filename = mkpath("%s/.perfconfig", getenv("HOME"));
-
- perf_config(collect_current_config, §ions);
+ INIT_LIST_HEAD(&user_sections);
+ INIT_LIST_HEAD(&system_sections);
+ perf_config_from_file(collect_current_config, user_config, &user_sections);
+ perf_config_from_file(collect_current_config, system_config, &system_sections);
+
+ if (use_system_config) {
+ sections = &system_sections;
+ config_exclusive_filename = system_config;
+ } else if (use_user_config) {
+ sections = &user_sections;
+ config_exclusive_filename = user_config;
+ } else {
+ sections = &all_sections;
+ INIT_LIST_HEAD(&all_sections);
+ perf_config(collect_current_config, &all_sections);
+ }
switch (actions) {
case ACTION_LIST_ALL:
if (argc == 0) {
- ret = show_all_config(§ions);
+ ret = show_all_config(sections);
break;
}
case ACTION_LIST:
@@ -510,12 +572,30 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
return -1;
}
default:
- if (argc)
- for (i = 0; argv[i]; i++)
- ret = perf_configset_with_option(show_spec_config, §ions,
- argv[i]);
- else
- ret = show_config(§ions);
+
+ if (argc) {
+ for (i = 0; argv[i]; i++) {
+ char *value = strchr(argv[i], '=');
+
+ if (value == NULL)
+ ret = perf_configset_with_option(show_spec_config,
+ sections, NULL,
+ argv[i], value);
+ else {
+ if (!use_system_config && !use_user_config)
+ ret = perf_configset_with_option(set_config,
+ &user_sections,
+ user_config,
+ argv[i], value);
+ else
+ ret = perf_configset_with_option(set_config,
+ sections,
+ config_exclusive_filename,
+ argv[i], value);
+ }
+ }
+ } else
+ ret = show_config(sections);
}
return ret;
diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h
index 71aefed..2ec958e 100644
--- a/tools/perf/util/cache.h
+++ b/tools/perf/util/cache.h
@@ -35,9 +35,12 @@ struct config_section {
extern const char *config_exclusive_filename;
typedef int (*config_fn_t)(const char *, const char *, void *);
-typedef int (*configset_fn_t)(struct list_head *, const char *, const char *);
+typedef int (*configset_fn_t)(struct list_head *, const char *,
+ const char *, const char *, char *);
+extern int perf_configset_write_in_full(struct list_head *sections, const char *file_name);
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 *);
diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c
index 55ef373..2111695 100644
--- a/tools/perf/util/config.c
+++ b/tools/perf/util/config.c
@@ -416,7 +416,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");
@@ -506,6 +506,31 @@ out:
return ret;
}
+int perf_configset_write_in_full(struct list_head *sections, const char *file_name)
+{
+ struct config_section *section;
+ struct config_element *element;
+ const char *first_line = "# this file is auto-generated.";
+ FILE *fp = fopen(file_name, "w");
+
+ if (!fp)
+ return -1;
+
+ fprintf(fp, "%s\n", first_line);
+ /* overwrite configvariables */
+ list_for_each_entry(section, sections, list) {
+ fprintf(fp, "[%s]\n", section->name);
+ list_for_each_entry(element, §ion->element_head, list) {
+ if (element->value)
+ fprintf(fp, "\t%s = %s\n",
+ element->name, element->value);
+ }
+ }
+ fclose(fp);
+
+ return 0;
+}
+
/*
* Call this to report error for your variable that should not
* get a boolean value (i.e. "[my] var" means "true").
--
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/
[toc] | [prev] | [next] | [standalone]
| From | Taeung Song <treeze.taeung@gmail.com> |
|---|---|
| Date | 2015-11-03 03:00 +0100 |
| Subject | [PATCH v9 3/9] perf config: Collect configs to handle config variables |
| Message-ID | <qqz3d-4xe-27@gated-at.bofh.it> |
| In reply to | #1261133 |
Collecting configs into list because of two reason.
First of all, if there are same variables both user
and system config file, they all will be printed
when 'list' command work. But if config variables are
duplicated, user config variables should only be printed
because it has priority.
Lastly, list into which configs is collected
will be required to keep and handle config variables
and values in the near furture. For example,
getting or setting functionality.
And change show_config() function.
Old show_config() worked depending on perf_config().
New show_config() work using collected configs list.
Signed-off-by: Taeung Song <treeze.taeung@gmail.com>
---
tools/perf/builtin-config.c | 148 ++++++++++++++++++++++++++++++++++++++++++--
tools/perf/util/cache.h | 13 ++++
2 files changed, 156 insertions(+), 5 deletions(-)
diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c
index 68e105a..f99c39d 100644
--- a/tools/perf/builtin-config.c
+++ b/tools/perf/builtin-config.c
@@ -32,13 +32,146 @@ static struct option config_options[] = {
OPT_END()
};
-static int show_config(const char *key, const char *value,
- void *cb __maybe_unused)
+static struct config_section *find_section(struct list_head *sections,
+ const char *section_name)
{
+ struct config_section *section;
+
+ list_for_each_entry(section, sections, list)
+ if (!strcmp(section->name, section_name))
+ return section;
+
+ return NULL;
+}
+
+static struct config_element *find_element(const char *name,
+ struct config_section *section)
+{
+ struct config_element *element;
+
+ list_for_each_entry(element, §ion->element_head, list)
+ if (!strcmp(element->name, name))
+ return element;
+
+ return NULL;
+}
+
+static void find_config(struct list_head *sections,
+ struct config_section **section,
+ struct config_element **element,
+ const char *section_name, const char *name)
+{
+ *section = find_section(sections, section_name);
+
+ if (*section != NULL)
+ *element = find_element(name, *section);
+ else
+ *element = NULL;
+}
+
+static struct config_section *init_section(const char *section_name)
+{
+ struct config_section *section;
+
+ section = zalloc(sizeof(*section));
+ if (!section)
+ return NULL;
+
+ INIT_LIST_HEAD(§ion->element_head);
+ section->name = strdup(section_name);
+ if (!section->name) {
+ pr_err("%s: strdup failed\n", __func__);
+ free(section);
+ return NULL;
+ }
+
+ return section;
+}
+
+static int add_element(struct list_head *head,
+ const char *name, const char *value)
+{
+ struct config_element *element;
+
+ element = zalloc(sizeof(*element));
+ if (!element)
+ return -1;
+
+ element->name = strdup(name);
+ if (!element->name) {
+ pr_err("%s: strdup failed\n", __func__);
+ free(element);
+ return -1;
+ }
if (value)
- printf("%s=%s\n", key, value);
+ element->value = (char *)value;
else
- printf("%s\n", key);
+ element->value = NULL;
+
+ list_add_tail(&element->list, head);
+ return 0;
+}
+
+static int collect_current_config(const char *var, const char *value,
+ void *spec_sections __maybe_unused)
+{
+ int ret = -1;
+ char *ptr, *key;
+ char *section_name, *name;
+ struct config_section *section = NULL;
+ struct config_element *element = NULL;
+ struct list_head *sections = (struct list_head *)spec_sections;
+
+ key = ptr = strdup(var);
+ if (!key) {
+ pr_err("%s: strdup failed\n", __func__);
+ return -1;
+ }
+
+ section_name = strsep(&ptr, ".");
+ name = ptr;
+ if (name == NULL || value == NULL)
+ goto out_err;
+
+ find_config(sections, §ion, &element, section_name, name);
+
+ if (!section) {
+ section = init_section(section_name);
+ if (!section)
+ goto out_err;
+ list_add_tail(§ion->list, sections);
+ }
+
+ value = strdup(value);
+ if (!value) {
+ pr_err("%s: strdup failed\n", __func__);
+ goto out_err;
+ }
+
+ if (!element)
+ add_element(§ion->element_head, name, value);
+ else {
+ free(element->value);
+ element->value = (char *)value;
+ }
+
+ ret = 0;
+out_err:
+ free(key);
+ return ret;
+}
+
+static int show_config(struct list_head *sections)
+{
+ struct config_section *section;
+ struct config_element *element;
+
+ list_for_each_entry(section, sections, list) {
+ list_for_each_entry(element, §ion->element_head, list) {
+ printf("%s.%s=%s\n", section->name,
+ element->name, element->value);
+ }
+ }
return 0;
}
@@ -46,6 +179,7 @@ static int show_config(const char *key, const char *value,
int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
{
int ret = 0;
+ struct list_head sections;
argc = parse_options(argc, argv, config_options, config_usage,
PARSE_OPT_STOP_AT_NON_OPTION);
@@ -57,11 +191,15 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
return -1;
}
+ INIT_LIST_HEAD(§ions);
+
if (use_system_config)
config_exclusive_filename = perf_etc_perfconfig();
else if (use_user_config)
config_exclusive_filename = mkpath("%s/.perfconfig", getenv("HOME"));
+ perf_config(collect_current_config, §ions);
+
switch (actions) {
case ACTION_LIST:
default:
@@ -70,7 +208,7 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
parse_options_usage(config_usage, config_options, "l", 1);
return -1;
} else
- ret = perf_config(show_config, NULL);
+ ret = show_config(§ions);
}
return ret;
diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h
index d1eb75f..e503371 100644
--- a/tools/perf/util/cache.h
+++ b/tools/perf/util/cache.h
@@ -1,6 +1,7 @@
#ifndef __PERF_CACHE_H
#define __PERF_CACHE_H
+#include <linux/list.h>
#include <stdbool.h>
#include "util.h"
#include "strbuf.h"
@@ -19,6 +20,18 @@
#define PERF_DEBUGFS_ENVIRONMENT "PERF_DEBUGFS_DIR"
#define PERF_TRACEFS_ENVIRONMENT "PERF_TRACEFS_DIR"
+struct config_element {
+ char *name;
+ char *value;
+ struct list_head list;
+};
+
+struct config_section {
+ char *name;
+ struct list_head element_head;
+ struct list_head list;
+};
+
extern const char *config_exclusive_filename;
typedef int (*config_fn_t)(const char *, const char *, void *);
--
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/
[toc] | [prev] | [next] | [standalone]
| From | Namhyung Kim <namhyung@kernel.org> |
|---|---|
| Date | 2015-11-03 13:20 +0100 |
| Subject | Re: [PATCH v9 3/9] perf config: Collect configs to handle config variables |
| Message-ID | <qqIJb-2zy-11@gated-at.bofh.it> |
| In reply to | #1261138 |
On Tue, Nov 03, 2015 at 10:50:14AM +0900, Taeung Song wrote:
> Collecting configs into list because of two reason.
>
> First of all, if there are same variables both user
> and system config file, they all will be printed
> when 'list' command work. But if config variables are
> duplicated, user config variables should only be printed
> because it has priority.
>
> Lastly, list into which configs is collected
> will be required to keep and handle config variables
> and values in the near furture. For example,
> getting or setting functionality.
>
> And change show_config() function.
> Old show_config() worked depending on perf_config().
> New show_config() work using collected configs list.
>
> Signed-off-by: Taeung Song <treeze.taeung@gmail.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
One nitpick again..
[SNIP]
> +static int collect_current_config(const char *var, const char *value,
> + void *spec_sections __maybe_unused)
The spec_sections is actually used, so "__maybe_unused" is not necessary.
Thanks,
Namhyung
> +{
> + int ret = -1;
> + char *ptr, *key;
> + char *section_name, *name;
> + struct config_section *section = NULL;
> + struct config_element *element = NULL;
> + struct list_head *sections = (struct list_head *)spec_sections;
> +
> + key = ptr = strdup(var);
> + if (!key) {
> + pr_err("%s: strdup failed\n", __func__);
> + return -1;
> + }
> +
> + section_name = strsep(&ptr, ".");
> + name = ptr;
> + if (name == NULL || value == NULL)
> + goto out_err;
> +
> + find_config(sections, §ion, &element, section_name, name);
> +
> + if (!section) {
> + section = init_section(section_name);
> + if (!section)
> + goto out_err;
> + list_add_tail(§ion->list, sections);
> + }
> +
> + value = strdup(value);
> + if (!value) {
> + pr_err("%s: strdup failed\n", __func__);
> + goto out_err;
> + }
> +
> + if (!element)
> + add_element(§ion->element_head, name, value);
> + else {
> + free(element->value);
> + element->value = (char *)value;
> + }
> +
> + ret = 0;
> +out_err:
> + free(key);
> + return ret;
> +}
--
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/
[toc] | [prev] | [next] | [standalone]
| From | Taeung Song <treeze.taeung@gmail.com> |
|---|---|
| Date | 2015-11-03 03:00 +0100 |
| Subject | [PATCH v9 2/9] perf config: Add '--system' and '--user' options to select which config file is used |
| Message-ID | <qqz3d-4xe-39@gated-at.bofh.it> |
| In reply to | #1261133 |
The file-options '--system' means $(sysconfdir)/perfconfig and
'--user' means $HOME/.perfconfig. If file-option isn't used,
both system and user config file is read.
The syntax examples are like below.
perf config [<file-option>] [options]
a specific config file.
# perf config --user | --system
or
both user and system config file.
# perf config
Signed-off-by: Taeung Song <treeze.taeung@gmail.com>
---
tools/perf/Documentation/perf-config.txt | 14 +++++++++++++-
tools/perf/builtin-config.c | 18 +++++++++++++++++-
tools/perf/util/cache.h | 3 +++
tools/perf/util/config.c | 4 ++--
4 files changed, 35 insertions(+), 4 deletions(-)
diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
index a590319..2188722 100644
--- a/tools/perf/Documentation/perf-config.txt
+++ b/tools/perf/Documentation/perf-config.txt
@@ -8,7 +8,7 @@ perf-config - Get and set variables in a configuration file.
SYNOPSIS
--------
[verse]
-'perf config' -l | --list
+'perf config' [<file-option>] -l | --list
DESCRIPTION
-----------
@@ -21,6 +21,14 @@ OPTIONS
--list::
Show current config variables, name and value, for all sections.
+--user::
+ For writing and reading options: write to user
+ '$HOME/.perfconfig' file or read it.
+
+--system::
+ For writing and reading options: write to system-wide
+ '$(sysconfdir)/perfconfig' or read it.
+
CONFIGURATION FILE
------------------
@@ -33,6 +41,10 @@ store a system-wide default configuration.
The variables are divided into sections. In each section, the variables
that are composed of a name and value.
+When reading or writing, the values are read from the system and user
+configuration files by default, and options '--system' and '--user'
+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 2d16150..68e105a 100644
--- a/tools/perf/builtin-config.c
+++ b/tools/perf/builtin-config.c
@@ -13,8 +13,10 @@
#include "util/util.h"
#include "util/debug.h"
+static bool use_system_config, use_user_config;
+
static const char * const config_usage[] = {
- "perf config [options]",
+ "perf config [<file-option>] [options]",
NULL
};
@@ -25,6 +27,8 @@ enum actions {
static struct option config_options[] = {
OPT_SET_UINT('l', "list", &actions,
"show current config variables", ACTION_LIST),
+ OPT_BOOLEAN(0, "system", &use_system_config, "use system config file"),
+ OPT_BOOLEAN(0, "user", &use_user_config, "use user config file"),
OPT_END()
};
@@ -46,6 +50,18 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
argc = parse_options(argc, argv, config_options, config_usage,
PARSE_OPT_STOP_AT_NON_OPTION);
+ if (use_system_config && use_user_config) {
+ pr_err("Error: only one config file at a time\n");
+ parse_options_usage(config_usage, config_options, "user", 0);
+ parse_options_usage(NULL, config_options, "system", 0);
+ return -1;
+ }
+
+ if (use_system_config)
+ config_exclusive_filename = perf_etc_perfconfig();
+ else if (use_user_config)
+ config_exclusive_filename = mkpath("%s/.perfconfig", getenv("HOME"));
+
switch (actions) {
case ACTION_LIST:
default:
diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h
index c861373..d1eb75f 100644
--- a/tools/perf/util/cache.h
+++ b/tools/perf/util/cache.h
@@ -19,6 +19,8 @@
#define PERF_DEBUGFS_ENVIRONMENT "PERF_DEBUGFS_DIR"
#define PERF_TRACEFS_ENVIRONMENT "PERF_TRACEFS_DIR"
+extern const char *config_exclusive_filename;
+
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 *);
@@ -27,6 +29,7 @@ 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);
/* pager.c */
extern void setup_pager(void);
diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c
index 2e452ac..55ef373 100644
--- a/tools/perf/util/config.c
+++ b/tools/perf/util/config.c
@@ -26,7 +26,7 @@ static const char *config_file_name;
static int config_linenr;
static int config_file_eof;
-static const char *config_exclusive_filename;
+const char *config_exclusive_filename;
static int get_next_char(void)
{
@@ -434,7 +434,7 @@ static int perf_config_from_file(config_fn_t fn, const char *filename, void *dat
return ret;
}
-static const char *perf_etc_perfconfig(void)
+const char *perf_etc_perfconfig(void)
{
static const char *system_wide;
if (!system_wide)
--
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/
[toc] | [prev] | [next] | [standalone]
| From | Namhyung Kim <namhyung@kernel.org> |
|---|---|
| Date | 2015-11-03 12:50 +0100 |
| Subject | Re: [PATCH v9 2/9] perf config: Add '--system' and '--user' options to select which config file is used |
| Message-ID | <qqIga-2a9-7@gated-at.bofh.it> |
| In reply to | #1261139 |
On Tue, Nov 03, 2015 at 10:50:13AM +0900, Taeung Song wrote:
> The file-options '--system' means $(sysconfdir)/perfconfig and
> '--user' means $HOME/.perfconfig. If file-option isn't used,
> both system and user config file is read.
> The syntax examples are like below.
>
> perf config [<file-option>] [options]
>
> a specific config file.
> # perf config --user | --system
> or
> both user and system config file.
> # perf config
>
> Signed-off-by: Taeung Song <treeze.taeung@gmail.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Thanks,
Namhyung
> ---
> tools/perf/Documentation/perf-config.txt | 14 +++++++++++++-
> tools/perf/builtin-config.c | 18 +++++++++++++++++-
> tools/perf/util/cache.h | 3 +++
> tools/perf/util/config.c | 4 ++--
> 4 files changed, 35 insertions(+), 4 deletions(-)
>
> diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
> index a590319..2188722 100644
> --- a/tools/perf/Documentation/perf-config.txt
> +++ b/tools/perf/Documentation/perf-config.txt
> @@ -8,7 +8,7 @@ perf-config - Get and set variables in a configuration file.
> SYNOPSIS
> --------
> [verse]
> -'perf config' -l | --list
> +'perf config' [<file-option>] -l | --list
>
> DESCRIPTION
> -----------
> @@ -21,6 +21,14 @@ OPTIONS
> --list::
> Show current config variables, name and value, for all sections.
>
> +--user::
> + For writing and reading options: write to user
> + '$HOME/.perfconfig' file or read it.
> +
> +--system::
> + For writing and reading options: write to system-wide
> + '$(sysconfdir)/perfconfig' or read it.
> +
> CONFIGURATION FILE
> ------------------
>
> @@ -33,6 +41,10 @@ store a system-wide default configuration.
> The variables are divided into sections. In each section, the variables
> that are composed of a name and value.
>
> +When reading or writing, the values are read from the system and user
> +configuration files by default, and options '--system' and '--user'
> +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 2d16150..68e105a 100644
> --- a/tools/perf/builtin-config.c
> +++ b/tools/perf/builtin-config.c
> @@ -13,8 +13,10 @@
> #include "util/util.h"
> #include "util/debug.h"
>
> +static bool use_system_config, use_user_config;
> +
> static const char * const config_usage[] = {
> - "perf config [options]",
> + "perf config [<file-option>] [options]",
> NULL
> };
>
> @@ -25,6 +27,8 @@ enum actions {
> static struct option config_options[] = {
> OPT_SET_UINT('l', "list", &actions,
> "show current config variables", ACTION_LIST),
> + OPT_BOOLEAN(0, "system", &use_system_config, "use system config file"),
> + OPT_BOOLEAN(0, "user", &use_user_config, "use user config file"),
> OPT_END()
> };
>
> @@ -46,6 +50,18 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
> argc = parse_options(argc, argv, config_options, config_usage,
> PARSE_OPT_STOP_AT_NON_OPTION);
>
> + if (use_system_config && use_user_config) {
> + pr_err("Error: only one config file at a time\n");
> + parse_options_usage(config_usage, config_options, "user", 0);
> + parse_options_usage(NULL, config_options, "system", 0);
> + return -1;
> + }
> +
> + if (use_system_config)
> + config_exclusive_filename = perf_etc_perfconfig();
> + else if (use_user_config)
> + config_exclusive_filename = mkpath("%s/.perfconfig", getenv("HOME"));
> +
> switch (actions) {
> case ACTION_LIST:
> default:
> diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h
> index c861373..d1eb75f 100644
> --- a/tools/perf/util/cache.h
> +++ b/tools/perf/util/cache.h
> @@ -19,6 +19,8 @@
> #define PERF_DEBUGFS_ENVIRONMENT "PERF_DEBUGFS_DIR"
> #define PERF_TRACEFS_ENVIRONMENT "PERF_TRACEFS_DIR"
>
> +extern const char *config_exclusive_filename;
> +
> 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 *);
> @@ -27,6 +29,7 @@ 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);
>
> /* pager.c */
> extern void setup_pager(void);
> diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c
> index 2e452ac..55ef373 100644
> --- a/tools/perf/util/config.c
> +++ b/tools/perf/util/config.c
> @@ -26,7 +26,7 @@ static const char *config_file_name;
> static int config_linenr;
> static int config_file_eof;
>
> -static const char *config_exclusive_filename;
> +const char *config_exclusive_filename;
>
> static int get_next_char(void)
> {
> @@ -434,7 +434,7 @@ static int perf_config_from_file(config_fn_t fn, const char *filename, void *dat
> return ret;
> }
>
> -static const char *perf_etc_perfconfig(void)
> +const char *perf_etc_perfconfig(void)
> {
> static const char *system_wide;
> if (!system_wide)
> --
> 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/
[toc] | [prev] | [next] | [standalone]
| From | Taeung Song <treeze.taeung@gmail.com> |
|---|---|
| Date | 2015-11-03 03:00 +0100 |
| Subject | [PATCH v9 5/9] perf config: Add a option 'list-all' to perf-config |
| Message-ID | <qqz3d-4xe-41@gated-at.bofh.it> |
| In reply to | #1261133 |
A option 'list-all' is to display both current config variables and
all possible config variables with default values.
The syntax examples are like below
perf config [<file-option>] [options]
display all perf config with default values.
# perf config -a | --list-all
Signed-off-by: Taeung Song <treeze.taeung@gmail.com>
---
tools/perf/Documentation/perf-config.txt | 6 +
tools/perf/builtin-config.c | 219 ++++++++++++++++++++++++++++++-
2 files changed, 223 insertions(+), 2 deletions(-)
diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
index 2188722..6141b1f 100644
--- a/tools/perf/Documentation/perf-config.txt
+++ b/tools/perf/Documentation/perf-config.txt
@@ -9,6 +9,8 @@ SYNOPSIS
--------
[verse]
'perf config' [<file-option>] -l | --list
+or
+'perf config' [<file-option>] -a | --list-all
DESCRIPTION
-----------
@@ -29,6 +31,10 @@ OPTIONS
For writing and reading options: write to system-wide
'$(sysconfdir)/perfconfig' or read it.
+-a::
+--list-all::
+ Show current and all possible config variables with default values.
+
CONFIGURATION FILE
------------------
diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c
index d4e2899..bba93bd 100644
--- a/tools/perf/builtin-config.c
+++ b/tools/perf/builtin-config.c
@@ -21,17 +21,154 @@ static const char * const config_usage[] = {
};
enum actions {
- ACTION_LIST = 1
+ ACTION_LIST = 1,
+ ACTION_LIST_ALL
} actions;
static struct option config_options[] = {
OPT_SET_UINT('l', "list", &actions,
"show current config variables", ACTION_LIST),
+ OPT_SET_UINT('a', "list-all", &actions,
+ "show current and all possible config variables with default values",
+ ACTION_LIST_ALL),
OPT_BOOLEAN(0, "system", &use_system_config, "use system config file"),
OPT_BOOLEAN(0, "user", &use_user_config, "use user config file"),
OPT_END()
};
+enum config_idx {
+ CONFIG_COLORS_TOP,
+ CONFIG_COLORS_MEDIUM,
+ CONFIG_COLORS_NORMAL,
+ CONFIG_COLORS_SELECTED,
+ CONFIG_COLORS_CODE,
+ CONFIG_COLORS_ADDR,
+ CONFIG_COLORS_ROOT,
+ CONFIG_TUI_REPORT,
+ CONFIG_TUI_ANNOTATE,
+ CONFIG_TUI_TOP,
+ CONFIG_BUILDID_DIR,
+ CONFIG_ANNOTATE_HIDE_SRC_CODE,
+ CONFIG_ANNOTATE_USE_OFFSET,
+ CONFIG_ANNOTATE_JUMP_ARROWS,
+ CONFIG_ANNOTATE_SHOW_NR_JUMPS,
+ CONFIG_GTK_ANNOTATE,
+ CONFIG_GTK_REPORT,
+ CONFIG_GTK_TOP,
+ CONFIG_PAGER_CMD,
+ CONFIG_PAGER_REPORT,
+ CONFIG_PAGER_ANNOTATE,
+ CONFIG_PAGER_TOP,
+ CONFIG_PAGER_DIFF,
+ CONFIG_HELP_FORMAT,
+ CONFIG_HELP_AUTOCORRECT,
+ CONFIG_HIST_PERCENTAGE,
+ CONFIG_UI_SHOW_HEADERS,
+ CONFIG_CALL_GRAPH_RECORD_MODE,
+ CONFIG_CALL_GRAPH_DUMP_SIZE,
+ CONFIG_CALL_GRAPH_PRINT_TYPE,
+ CONFIG_CALL_GRAPH_ORDER,
+ CONFIG_CALL_GRAPH_SORT_KEY,
+ CONFIG_CALL_GRAPH_THRESHOLD,
+ CONFIG_CALL_GRAPH_PRINT_LIMIT,
+ CONFIG_REPORT_CHILDREN,
+ CONFIG_REPORT_PERCENT_LIMIT,
+ CONFIG_REPORT_QUEUE_SIZE,
+ CONFIG_TOP_CHILDREN,
+ CONFIG_MAN_VIEWER,
+ CONFIG_KMEM_DEFAULT,
+};
+
+enum config_type {
+ CONFIG_TYPE_BOOL,
+ CONFIG_TYPE_INT,
+ CONFIG_TYPE_LONG,
+ CONFIG_TYPE_U64,
+ CONFIG_TYPE_FLOAT,
+ CONFIG_TYPE_DOUBLE,
+ CONFIG_TYPE_STRING,
+ /* special type */
+ CONFIG_END
+};
+
+struct config_item {
+ const char *section;
+ const char *name;
+ union {
+ bool b;
+ int i;
+ u32 l;
+ u64 ll;
+ float f;
+ double d;
+ const char *s;
+ } value;
+ enum config_type type;
+};
+
+#define CONF_VAR(_sec, _name, _field, _val, _type) \
+ { .section = _sec, .name = _name, .value._field = _val, .type = _type }
+
+#define CONF_BOOL_VAR(_idx, _sec, _name, _val) \
+ [CONFIG_##_idx] = CONF_VAR(_sec, _name, b, _val, CONFIG_TYPE_BOOL)
+#define CONF_INT_VAR(_idx, _sec, _name, _val) \
+ [CONFIG_##_idx] = CONF_VAR(_sec, _name, i, _val, CONFIG_TYPE_INT)
+#define CONF_LONG_VAR(_idx, _sec, _name, _val) \
+ [CONFIG_##_idx] = CONF_VAR(_sec, _name, l, _val, CONFIG_TYPE_LONG)
+#define CONF_U64_VAR(_idx, _sec, _name, _val) \
+ [CONFIG_##_idx] = CONF_VAR(_sec, _name, ll, _val, CONFIG_TYPE_U64)
+#define CONF_FLOAT_VAR(_idx, _sec, _name, _val) \
+ [CONFIG_##_idx] = CONF_VAR(_sec, _name, f, _val, CONFIG_TYPE_FLOAT)
+#define CONF_DOUBLE_VAR(_idx, _sec, _name, _val) \
+ [CONFIG_##_idx] = CONF_VAR(_sec, _name, d, _val, CONFIG_TYPE_DOUBLE)
+#define CONF_STR_VAR(_idx, _sec, _name, _val) \
+ [CONFIG_##_idx] = CONF_VAR(_sec, _name, s, _val, CONFIG_TYPE_STRING)
+#define CONF_END() { .type = CONFIG_END }
+
+struct config_item default_configs[] = {
+ CONF_STR_VAR(COLORS_TOP, "colors", "top", "red, default"),
+ CONF_STR_VAR(COLORS_MEDIUM, "colors", "medium", "green, default"),
+ CONF_STR_VAR(COLORS_NORMAL, "colors", "normal", "lightgray, default"),
+ CONF_STR_VAR(COLORS_SELECTED, "colors", "selected", "white, lightgray"),
+ CONF_STR_VAR(COLORS_CODE, "colors", "code", "blue, default"),
+ CONF_STR_VAR(COLORS_ADDR, "colors", "addr", "magenta, default"),
+ CONF_STR_VAR(COLORS_ROOT, "colors", "root", "white, blue"),
+ CONF_BOOL_VAR(TUI_REPORT, "tui", "report", true),
+ CONF_BOOL_VAR(TUI_ANNOTATE, "tui", "annotate", true),
+ CONF_BOOL_VAR(TUI_TOP, "tui", "top", true),
+ CONF_STR_VAR(BUILDID_DIR, "buildid", "dir", "~/.debug"),
+ CONF_BOOL_VAR(ANNOTATE_HIDE_SRC_CODE, "annotate", "hide_src_code", false),
+ CONF_BOOL_VAR(ANNOTATE_USE_OFFSET, "annotate", "use_offset", true),
+ CONF_BOOL_VAR(ANNOTATE_JUMP_ARROWS, "annotate", "jump_arrows", true),
+ CONF_BOOL_VAR(ANNOTATE_SHOW_NR_JUMPS, "annotate", "show_nr_jumps", false),
+ CONF_BOOL_VAR(GTK_ANNOTATE, "gtk", "annotate", false),
+ CONF_BOOL_VAR(GTK_REPORT, "gtk", "report", false),
+ CONF_BOOL_VAR(GTK_TOP, "gtk", "top", false),
+ CONF_BOOL_VAR(PAGER_CMD, "pager", "cmd", true),
+ CONF_BOOL_VAR(PAGER_REPORT, "pager", "report", true),
+ CONF_BOOL_VAR(PAGER_ANNOTATE, "pager", "annotate", true),
+ CONF_BOOL_VAR(PAGER_TOP, "pager", "top", true),
+ CONF_BOOL_VAR(PAGER_DIFF, "pager", "diff", true),
+ CONF_STR_VAR(HELP_FORMAT, "help", "format", "man"),
+ CONF_INT_VAR(HELP_AUTOCORRECT, "help", "autocorrect", 0),
+ CONF_STR_VAR(HIST_PERCENTAGE, "hist", "percentage", "absolute"),
+ CONF_BOOL_VAR(UI_SHOW_HEADERS, "ui", "show-headers", true),
+ CONF_STR_VAR(CALL_GRAPH_RECORD_MODE, "call-graph", "record-mode", "fp"),
+ CONF_LONG_VAR(CALL_GRAPH_DUMP_SIZE, "call-graph", "dump-size", 8192),
+ CONF_STR_VAR(CALL_GRAPH_PRINT_TYPE, "call-graph", "print-type", "fractal"),
+ CONF_STR_VAR(CALL_GRAPH_ORDER, "call-graph", "order", "caller"),
+ CONF_STR_VAR(CALL_GRAPH_SORT_KEY, "call-graph", "sort-key", "function"),
+ CONF_DOUBLE_VAR(CALL_GRAPH_THRESHOLD, "call-graph", "threshold", 0.5),
+ CONF_LONG_VAR(CALL_GRAPH_PRINT_LIMIT, "call-graph", "print-limit", 0),
+ CONF_BOOL_VAR(REPORT_CHILDREN, "report", "children", false),
+ CONF_FLOAT_VAR(REPORT_PERCENT_LIMIT, "report", "percent-limit", 0),
+ CONF_U64_VAR(REPORT_QUEUE_SIZE, "report", "queue-size", 0),
+ CONF_BOOL_VAR(TOP_CHILDREN, "top", "children", false),
+ CONF_STR_VAR(MAN_VIEWER, "man", "viewer", "man"),
+ CONF_STR_VAR(KMEM_DEFAULT, "kmem", "default", "slab"),
+ CONF_END()
+};
+
static int compare_name(const char *name1, const char *name2)
{
while (true) {
@@ -133,6 +270,73 @@ static int add_element(struct list_head *head,
return 0;
}
+static char *get_value(struct config_item *config)
+{
+ int ret = 0;
+ char *value;
+
+ if (config->type == CONFIG_TYPE_BOOL)
+ ret = asprintf(&value, "%s",
+ config->value.b ? "true" : "false");
+ else if (config->type == CONFIG_TYPE_INT)
+ ret = asprintf(&value, "%d", config->value.i);
+ else if (config->type == CONFIG_TYPE_LONG)
+ ret = asprintf(&value, "%u", config->value.l);
+ else if (config->type == CONFIG_TYPE_U64)
+ ret = asprintf(&value, "%"PRId64, config->value.ll);
+ else if (config->type == CONFIG_TYPE_FLOAT)
+ ret = asprintf(&value, "%f", config->value.f);
+ else if (config->type == CONFIG_TYPE_DOUBLE)
+ ret = asprintf(&value, "%f", config->value.d);
+ else
+ value = (char *)config->value.s;
+
+ if (ret < 0)
+ return NULL;
+
+ return value;
+}
+
+static int show_all_config(struct list_head *sections)
+{
+ int i;
+ bool has_config;
+ struct config_section *section;
+ struct config_element *element;
+
+ for (i = 0; default_configs[i].type != CONFIG_END; i++) {
+ struct config_item *config = &default_configs[i];
+ find_config(sections, §ion, &element,
+ config->section, config->name);
+
+ if (!element)
+ printf("%s.%s=%s\n", config->section, config->name,
+ get_value(config));
+ else
+ printf("%s.%s=%s\n", section->name,
+ element->name, element->value);
+ }
+
+ /* Print config variables the default configsets haven't */
+ list_for_each_entry(section, sections, list) {
+ list_for_each_entry(element, §ion->element_head, list) {
+ has_config = false;
+ for (i = 0; default_configs[i].type != CONFIG_END; i++) {
+ if (!strcmp(default_configs[i].section, section->name)
+ && !compare_name(default_configs[i].name, element->name)) {
+ has_config = true;
+ break;
+ }
+ }
+ if (!has_config)
+ printf("%s.%s=%s\n", section->name,
+ element->name, element->value);
+ }
+ }
+
+ return 0;
+}
+
static int collect_current_config(const char *var, const char *value,
void *spec_sections __maybe_unused)
{
@@ -202,6 +406,9 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
int ret = 0;
struct list_head sections;
+ set_option_flag(config_options, 'l', "list", PARSE_OPT_EXCLUSIVE);
+ set_option_flag(config_options, 'a', "list-all", PARSE_OPT_EXCLUSIVE);
+
argc = parse_options(argc, argv, config_options, config_usage,
PARSE_OPT_STOP_AT_NON_OPTION);
@@ -222,11 +429,19 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
perf_config(collect_current_config, §ions);
switch (actions) {
+ case ACTION_LIST_ALL:
+ if (argc == 0) {
+ ret = show_all_config(§ions);
+ break;
+ }
case ACTION_LIST:
default:
if (argc) {
pr_err("Error: takes no arguments\n");
- parse_options_usage(config_usage, config_options, "l", 1);
+ if (actions == ACTION_LIST_ALL)
+ parse_options_usage(config_usage, config_options, "a", 1);
+ else
+ parse_options_usage(config_usage, config_options, "l", 1);
return -1;
} else
ret = show_config(§ions);
--
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/
[toc] | [prev] | [next] | [standalone]
| From | Namhyung Kim <namhyung@kernel.org> |
|---|---|
| Date | 2015-11-03 13:40 +0100 |
| Subject | Re: [PATCH v9 5/9] perf config: Add a option 'list-all' to perf-config |
| Message-ID | <qqJ2x-2Hl-3@gated-at.bofh.it> |
| In reply to | #1261144 |
On Tue, Nov 03, 2015 at 10:50:16AM +0900, Taeung Song wrote:
> A option 'list-all' is to display both current config variables and
> all possible config variables with default values.
> The syntax examples are like below
>
> perf config [<file-option>] [options]
>
> display all perf config with default values.
> # perf config -a | --list-all
>
> Signed-off-by: Taeung Song <treeze.taeung@gmail.com>
> ---
> tools/perf/Documentation/perf-config.txt | 6 +
> tools/perf/builtin-config.c | 219 ++++++++++++++++++++++++++++++-
> 2 files changed, 223 insertions(+), 2 deletions(-)
>
> diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
> index 2188722..6141b1f 100644
> --- a/tools/perf/Documentation/perf-config.txt
> +++ b/tools/perf/Documentation/perf-config.txt
> @@ -9,6 +9,8 @@ SYNOPSIS
> --------
> [verse]
> 'perf config' [<file-option>] -l | --list
> +or
> +'perf config' [<file-option>] -a | --list-all
>
> DESCRIPTION
> -----------
> @@ -29,6 +31,10 @@ OPTIONS
> For writing and reading options: write to system-wide
> '$(sysconfdir)/perfconfig' or read it.
>
> +-a::
> +--list-all::
> + Show current and all possible config variables with default values.
> +
> CONFIGURATION FILE
> ------------------
>
> diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c
> index d4e2899..bba93bd 100644
> --- a/tools/perf/builtin-config.c
> +++ b/tools/perf/builtin-config.c
> @@ -21,17 +21,154 @@ static const char * const config_usage[] = {
> };
>
> enum actions {
> - ACTION_LIST = 1
> + ACTION_LIST = 1,
> + ACTION_LIST_ALL
> } actions;
>
> static struct option config_options[] = {
> OPT_SET_UINT('l', "list", &actions,
> "show current config variables", ACTION_LIST),
> + OPT_SET_UINT('a', "list-all", &actions,
> + "show current and all possible config variables with default values",
> + ACTION_LIST_ALL),
> OPT_BOOLEAN(0, "system", &use_system_config, "use system config file"),
> OPT_BOOLEAN(0, "user", &use_user_config, "use user config file"),
> OPT_END()
> };
>
> +enum config_idx {
> + CONFIG_COLORS_TOP,
> + CONFIG_COLORS_MEDIUM,
> + CONFIG_COLORS_NORMAL,
> + CONFIG_COLORS_SELECTED,
> + CONFIG_COLORS_CODE,
> + CONFIG_COLORS_ADDR,
> + CONFIG_COLORS_ROOT,
> + CONFIG_TUI_REPORT,
> + CONFIG_TUI_ANNOTATE,
> + CONFIG_TUI_TOP,
> + CONFIG_BUILDID_DIR,
> + CONFIG_ANNOTATE_HIDE_SRC_CODE,
> + CONFIG_ANNOTATE_USE_OFFSET,
> + CONFIG_ANNOTATE_JUMP_ARROWS,
> + CONFIG_ANNOTATE_SHOW_NR_JUMPS,
> + CONFIG_GTK_ANNOTATE,
> + CONFIG_GTK_REPORT,
> + CONFIG_GTK_TOP,
> + CONFIG_PAGER_CMD,
> + CONFIG_PAGER_REPORT,
> + CONFIG_PAGER_ANNOTATE,
> + CONFIG_PAGER_TOP,
> + CONFIG_PAGER_DIFF,
> + CONFIG_HELP_FORMAT,
> + CONFIG_HELP_AUTOCORRECT,
> + CONFIG_HIST_PERCENTAGE,
> + CONFIG_UI_SHOW_HEADERS,
> + CONFIG_CALL_GRAPH_RECORD_MODE,
> + CONFIG_CALL_GRAPH_DUMP_SIZE,
> + CONFIG_CALL_GRAPH_PRINT_TYPE,
> + CONFIG_CALL_GRAPH_ORDER,
> + CONFIG_CALL_GRAPH_SORT_KEY,
> + CONFIG_CALL_GRAPH_THRESHOLD,
> + CONFIG_CALL_GRAPH_PRINT_LIMIT,
> + CONFIG_REPORT_CHILDREN,
> + CONFIG_REPORT_PERCENT_LIMIT,
> + CONFIG_REPORT_QUEUE_SIZE,
> + CONFIG_TOP_CHILDREN,
> + CONFIG_MAN_VIEWER,
> + CONFIG_KMEM_DEFAULT,
> +};
> +
> +enum config_type {
> + CONFIG_TYPE_BOOL,
> + CONFIG_TYPE_INT,
> + CONFIG_TYPE_LONG,
> + CONFIG_TYPE_U64,
> + CONFIG_TYPE_FLOAT,
> + CONFIG_TYPE_DOUBLE,
> + CONFIG_TYPE_STRING,
> + /* special type */
> + CONFIG_END
> +};
> +
> +struct config_item {
> + const char *section;
> + const char *name;
> + union {
> + bool b;
> + int i;
> + u32 l;
> + u64 ll;
> + float f;
> + double d;
> + const char *s;
> + } value;
> + enum config_type type;
> +};
> +
> +#define CONF_VAR(_sec, _name, _field, _val, _type) \
> + { .section = _sec, .name = _name, .value._field = _val, .type = _type }
> +
> +#define CONF_BOOL_VAR(_idx, _sec, _name, _val) \
> + [CONFIG_##_idx] = CONF_VAR(_sec, _name, b, _val, CONFIG_TYPE_BOOL)
> +#define CONF_INT_VAR(_idx, _sec, _name, _val) \
> + [CONFIG_##_idx] = CONF_VAR(_sec, _name, i, _val, CONFIG_TYPE_INT)
> +#define CONF_LONG_VAR(_idx, _sec, _name, _val) \
> + [CONFIG_##_idx] = CONF_VAR(_sec, _name, l, _val, CONFIG_TYPE_LONG)
> +#define CONF_U64_VAR(_idx, _sec, _name, _val) \
> + [CONFIG_##_idx] = CONF_VAR(_sec, _name, ll, _val, CONFIG_TYPE_U64)
> +#define CONF_FLOAT_VAR(_idx, _sec, _name, _val) \
> + [CONFIG_##_idx] = CONF_VAR(_sec, _name, f, _val, CONFIG_TYPE_FLOAT)
> +#define CONF_DOUBLE_VAR(_idx, _sec, _name, _val) \
> + [CONFIG_##_idx] = CONF_VAR(_sec, _name, d, _val, CONFIG_TYPE_DOUBLE)
> +#define CONF_STR_VAR(_idx, _sec, _name, _val) \
> + [CONFIG_##_idx] = CONF_VAR(_sec, _name, s, _val, CONFIG_TYPE_STRING)
> +#define CONF_END() { .type = CONFIG_END }
> +
> +struct config_item default_configs[] = {
> + CONF_STR_VAR(COLORS_TOP, "colors", "top", "red, default"),
> + CONF_STR_VAR(COLORS_MEDIUM, "colors", "medium", "green, default"),
> + CONF_STR_VAR(COLORS_NORMAL, "colors", "normal", "lightgray, default"),
> + CONF_STR_VAR(COLORS_SELECTED, "colors", "selected", "white, lightgray"),
> + CONF_STR_VAR(COLORS_CODE, "colors", "code", "blue, default"),
> + CONF_STR_VAR(COLORS_ADDR, "colors", "addr", "magenta, default"),
> + CONF_STR_VAR(COLORS_ROOT, "colors", "root", "white, blue"),
> + CONF_BOOL_VAR(TUI_REPORT, "tui", "report", true),
> + CONF_BOOL_VAR(TUI_ANNOTATE, "tui", "annotate", true),
> + CONF_BOOL_VAR(TUI_TOP, "tui", "top", true),
> + CONF_STR_VAR(BUILDID_DIR, "buildid", "dir", "~/.debug"),
> + CONF_BOOL_VAR(ANNOTATE_HIDE_SRC_CODE, "annotate", "hide_src_code", false),
> + CONF_BOOL_VAR(ANNOTATE_USE_OFFSET, "annotate", "use_offset", true),
> + CONF_BOOL_VAR(ANNOTATE_JUMP_ARROWS, "annotate", "jump_arrows", true),
> + CONF_BOOL_VAR(ANNOTATE_SHOW_NR_JUMPS, "annotate", "show_nr_jumps", false),
> + CONF_BOOL_VAR(GTK_ANNOTATE, "gtk", "annotate", false),
> + CONF_BOOL_VAR(GTK_REPORT, "gtk", "report", false),
> + CONF_BOOL_VAR(GTK_TOP, "gtk", "top", false),
> + CONF_BOOL_VAR(PAGER_CMD, "pager", "cmd", true),
> + CONF_BOOL_VAR(PAGER_REPORT, "pager", "report", true),
> + CONF_BOOL_VAR(PAGER_ANNOTATE, "pager", "annotate", true),
> + CONF_BOOL_VAR(PAGER_TOP, "pager", "top", true),
> + CONF_BOOL_VAR(PAGER_DIFF, "pager", "diff", true),
> + CONF_STR_VAR(HELP_FORMAT, "help", "format", "man"),
> + CONF_INT_VAR(HELP_AUTOCORRECT, "help", "autocorrect", 0),
> + CONF_STR_VAR(HIST_PERCENTAGE, "hist", "percentage", "absolute"),
> + CONF_BOOL_VAR(UI_SHOW_HEADERS, "ui", "show-headers", true),
> + CONF_STR_VAR(CALL_GRAPH_RECORD_MODE, "call-graph", "record-mode", "fp"),
> + CONF_LONG_VAR(CALL_GRAPH_DUMP_SIZE, "call-graph", "dump-size", 8192),
> + CONF_STR_VAR(CALL_GRAPH_PRINT_TYPE, "call-graph", "print-type", "fractal"),
It's changed to "graph" recently.
> + CONF_STR_VAR(CALL_GRAPH_ORDER, "call-graph", "order", "caller"),
Default is "callee" (with some exception regarding --children).
> + CONF_STR_VAR(CALL_GRAPH_SORT_KEY, "call-graph", "sort-key", "function"),
> + CONF_DOUBLE_VAR(CALL_GRAPH_THRESHOLD, "call-graph", "threshold", 0.5),
> + CONF_LONG_VAR(CALL_GRAPH_PRINT_LIMIT, "call-graph", "print-limit", 0),
> + CONF_BOOL_VAR(REPORT_CHILDREN, "report", "children", false),
I believe the default is "true".
> + CONF_FLOAT_VAR(REPORT_PERCENT_LIMIT, "report", "percent-limit", 0),
> + CONF_U64_VAR(REPORT_QUEUE_SIZE, "report", "queue-size", 0),
> + CONF_BOOL_VAR(TOP_CHILDREN, "top", "children", false),
Ditto - default is "true".
> + CONF_STR_VAR(MAN_VIEWER, "man", "viewer", "man"),
> + CONF_STR_VAR(KMEM_DEFAULT, "kmem", "default", "slab"),
> + CONF_END()
> +};
> +
> static int compare_name(const char *name1, const char *name2)
> {
> while (true) {
> @@ -133,6 +270,73 @@ static int add_element(struct list_head *head,
> return 0;
> }
>
> +static char *get_value(struct config_item *config)
> +{
> + int ret = 0;
> + char *value;
> +
> + if (config->type == CONFIG_TYPE_BOOL)
> + ret = asprintf(&value, "%s",
> + config->value.b ? "true" : "false");
> + else if (config->type == CONFIG_TYPE_INT)
> + ret = asprintf(&value, "%d", config->value.i);
> + else if (config->type == CONFIG_TYPE_LONG)
> + ret = asprintf(&value, "%u", config->value.l);
> + else if (config->type == CONFIG_TYPE_U64)
> + ret = asprintf(&value, "%"PRId64, config->value.ll);
> + else if (config->type == CONFIG_TYPE_FLOAT)
> + ret = asprintf(&value, "%f", config->value.f);
> + else if (config->type == CONFIG_TYPE_DOUBLE)
> + ret = asprintf(&value, "%f", config->value.d);
> + else
> + value = (char *)config->value.s;
> +
> + if (ret < 0)
> + return NULL;
> +
> + return value;
> +}
> +
> +static int show_all_config(struct list_head *sections)
> +{
> + int i;
> + bool has_config;
> + struct config_section *section;
> + struct config_element *element;
> +
> + for (i = 0; default_configs[i].type != CONFIG_END; i++) {
> + struct config_item *config = &default_configs[i];
> + find_config(sections, §ion, &element,
> + config->section, config->name);
> +
> + if (!element)
> + printf("%s.%s=%s\n", config->section, config->name,
> + get_value(config));
You need to free the value string.
> + else
> + printf("%s.%s=%s\n", section->name,
> + element->name, element->value);
> + }
> +
> + /* Print config variables the default configsets haven't */
> + list_for_each_entry(section, sections, list) {
> + list_for_each_entry(element, §ion->element_head, list) {
> + has_config = false;
> + for (i = 0; default_configs[i].type != CONFIG_END; i++) {
> + if (!strcmp(default_configs[i].section, section->name)
> + && !compare_name(default_configs[i].name, element->name)) {
> + has_config = true;
> + break;
> + }
> + }
> + if (!has_config)
> + printf("%s.%s=%s\n", section->name,
> + element->name, element->value);
> + }
> + }
> +
> + return 0;
> +}
> +
> static int collect_current_config(const char *var, const char *value,
> void *spec_sections __maybe_unused)
> {
> @@ -202,6 +406,9 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
> int ret = 0;
> struct list_head sections;
>
> + set_option_flag(config_options, 'l', "list", PARSE_OPT_EXCLUSIVE);
> + set_option_flag(config_options, 'a', "list-all", PARSE_OPT_EXCLUSIVE);
> +
> argc = parse_options(argc, argv, config_options, config_usage,
> PARSE_OPT_STOP_AT_NON_OPTION);
>
> @@ -222,11 +429,19 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
> perf_config(collect_current_config, §ions);
>
> switch (actions) {
> + case ACTION_LIST_ALL:
> + if (argc == 0) {
> + ret = show_all_config(§ions);
> + break;
> + }
In this case, you should add something like following, otherwise
people can be confused..
/* fall through */
Thanks,
Namhyung
> case ACTION_LIST:
> default:
> if (argc) {
> pr_err("Error: takes no arguments\n");
> - parse_options_usage(config_usage, config_options, "l", 1);
> + if (actions == ACTION_LIST_ALL)
> + parse_options_usage(config_usage, config_options, "a", 1);
> + else
> + parse_options_usage(config_usage, config_options, "l", 1);
> return -1;
> } else
> ret = show_config(§ions);
> --
> 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/
[toc] | [prev] | [next] | [standalone]
| From | Taeung Song <treeze.taeung@gmail.com> |
|---|---|
| Date | 2015-11-03 03:00 +0100 |
| Subject | [PATCH v9 6/9] perf config: Add 'get' functionaliy |
| Message-ID | <qqz3e-4xe-49@gated-at.bofh.it> |
| In reply to | #1261133 |
This patch consists of functions
which can get specific config variables.
For the syntax examples,
perf config [<file-option>] [section.name ...]
display key-value pairs of specific config variables
# perf config report.queue-size report.children
Signed-off-by: Taeung Song <treeze.taeung@gmail.com>
---
tools/perf/Documentation/perf-config.txt | 2 +
tools/perf/builtin-config.c | 79 ++++++++++++++++++++++++++++++--
tools/perf/util/cache.h | 1 +
3 files changed, 78 insertions(+), 4 deletions(-)
diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
index 6141b1f..c7dd65e 100644
--- a/tools/perf/Documentation/perf-config.txt
+++ b/tools/perf/Documentation/perf-config.txt
@@ -8,6 +8,8 @@ perf-config - Get and set variables in a configuration file.
SYNOPSIS
--------
[verse]
+'perf config' [<file-option>] [section.name ...]
+or
'perf config' [<file-option>] -l | --list
or
'perf config' [<file-option>] -a | --list-all
diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c
index bba93bd..16d81ae 100644
--- a/tools/perf/builtin-config.c
+++ b/tools/perf/builtin-config.c
@@ -16,7 +16,7 @@
static bool use_system_config, use_user_config;
static const char * const config_usage[] = {
- "perf config [<file-option>] [options]",
+ "perf config [<file-option>] [options] [section.name ...]",
NULL
};
@@ -337,6 +337,35 @@ static int show_all_config(struct list_head *sections)
return 0;
}
+static int show_spec_config(struct list_head *sections,
+ const char *section_name, const char *name)
+{
+ int i;
+ struct config_section *section = NULL;
+ struct config_element *element = NULL;
+
+ find_config(sections, §ion, &element, section_name, name);
+
+ if (section && element) {
+ printf("%s.%s=%s\n", section->name,
+ element->name, element->value);
+ return 0;
+ }
+
+ for (i = 0; default_configs[i].type != CONFIG_END; i++) {
+ struct config_item *config = &default_configs[i];
+
+ if (!strcmp(config->section, section_name) &&
+ !compare_name(config->name, name)) {
+ printf("%s.%s=%s (default)\n", config->section,
+ config->name, get_value(config));
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
static int collect_current_config(const char *var, const char *value,
void *spec_sections __maybe_unused)
{
@@ -386,6 +415,43 @@ out_err:
return ret;
}
+static int perf_configset_with_option(configset_fn_t fn, struct list_head *sections,
+ const char *var)
+{
+ int ret = -1;
+ char *ptr, *key;
+ const char *last_dot;
+ char *section_name, *name;
+
+ key = ptr = strdup(var);
+ if (!key) {
+ pr_err("%s: strdup failed\n", __func__);
+ return -1;
+ }
+ last_dot = strchr(key, '.');
+ /*
+ * Since "key" actually contains the section name and the real
+ * key name separated by a dot, we have to know where the dot is.
+ */
+ if (last_dot == NULL || last_dot == key) {
+ pr_err("The config variable does not contain a section: %s\n", key);
+ goto out_err;
+ }
+ if (!last_dot[1]) {
+ pr_err("The config varible does not contain variable name: %s\n", key);
+ goto out_err;
+ }
+
+ section_name = strsep(&ptr, ".");
+ name = ptr;
+ fn(sections, section_name, name);
+ ret = 0;
+
+out_err:
+ free(key);
+ return ret;
+}
+
static int show_config(struct list_head *sections)
{
struct config_section *section;
@@ -403,7 +469,7 @@ static int show_config(struct list_head *sections)
int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
{
- int ret = 0;
+ int i, ret = 0;
struct list_head sections;
set_option_flag(config_options, 'l', "list", PARSE_OPT_EXCLUSIVE);
@@ -435,7 +501,6 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
break;
}
case ACTION_LIST:
- default:
if (argc) {
pr_err("Error: takes no arguments\n");
if (actions == ACTION_LIST_ALL)
@@ -443,7 +508,13 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
else
parse_options_usage(config_usage, config_options, "l", 1);
return -1;
- } else
+ }
+ default:
+ if (argc)
+ for (i = 0; argv[i]; i++)
+ ret = perf_configset_with_option(show_spec_config, §ions,
+ argv[i]);
+ else
ret = show_config(§ions);
}
diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h
index e503371..71aefed 100644
--- a/tools/perf/util/cache.h
+++ b/tools/perf/util/cache.h
@@ -35,6 +35,7 @@ struct config_section {
extern const char *config_exclusive_filename;
typedef int (*config_fn_t)(const char *, const char *, void *);
+typedef int (*configset_fn_t)(struct list_head *, const char *, const char *);
extern int perf_default_config(const char *, const char *, void *);
extern int perf_config(config_fn_t fn, void *);
extern int perf_config_int(const char *, const char *);
--
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/
[toc] | [prev] | [next] | [standalone]
| From | Taeung Song <treeze.taeung@gmail.com> |
|---|---|
| Date | 2015-11-03 03:00 +0100 |
| Subject | [PATCH v9 9/9] perf config: Add a option 'remove' to perf-config |
| Message-ID | <qqz3e-4xe-55@gated-at.bofh.it> |
| In reply to | #1261133 |
A option 'remove' is to remove specific config variables.
For the syntax examples,
# perf config [<file-option>] -r | --remove [section.name ...]
Signed-off-by: Taeung Song <treeze.taeung@gmail.com>
---
tools/perf/Documentation/perf-config.txt | 6 +++++
tools/perf/builtin-config.c | 38 ++++++++++++++++++++++++++++++--
2 files changed, 42 insertions(+), 2 deletions(-)
diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt
index 3caa1d1..a32e0c2 100644
--- a/tools/perf/Documentation/perf-config.txt
+++ b/tools/perf/Documentation/perf-config.txt
@@ -13,6 +13,8 @@ or
'perf config' [<file-option>] -l | --list
or
'perf config' [<file-option>] -a | --list-all
+or
+'perf config' [<file-option>] -r | --remove [section.name ...]
DESCRIPTION
-----------
@@ -37,6 +39,10 @@ OPTIONS
--list-all::
Show current and all possible config variables with default values.
+-r::
+--remove::
+ Remove specific config variables.
+
CONFIGURATION FILE
------------------
diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c
index 04884fd..bc47b65 100644
--- a/tools/perf/builtin-config.c
+++ b/tools/perf/builtin-config.c
@@ -22,7 +22,8 @@ static const char * const config_usage[] = {
enum actions {
ACTION_LIST = 1,
- ACTION_LIST_ALL
+ ACTION_LIST_ALL,
+ ACTION_REMOVE
} actions;
static struct option config_options[] = {
@@ -31,6 +32,8 @@ static struct option config_options[] = {
OPT_SET_UINT('a', "list-all", &actions,
"show current and all possible config variables with default values",
ACTION_LIST_ALL),
+ OPT_SET_UINT('r', "remove", &actions,
+ "remove specific variables: [section.name ...]", ACTION_REMOVE),
OPT_BOOLEAN(0, "system", &use_system_config, "use system config file"),
OPT_BOOLEAN(0, "user", &use_user_config, "use user config file"),
OPT_END()
@@ -423,7 +426,14 @@ static int set_config(struct list_head *sections, const char *config_file_name,
struct config_element *element = NULL;
find_config(sections, §ion, &element, section_name, name);
- if (value != NULL) {
+ if (!value) {
+ /* value == NULL means remove the variable */
+ if (section && element) {
+ if (!element->value)
+ free(element->value);
+ element->value = NULL;
+ }
+ } else {
value = normalize_value(section_name, name, value);
/* if there isn't existent section, add a new section */
@@ -572,6 +582,7 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
set_option_flag(config_options, 'l', "list", PARSE_OPT_EXCLUSIVE);
set_option_flag(config_options, 'a', "list-all", PARSE_OPT_EXCLUSIVE);
+ set_option_flag(config_options, 'r', "remove", PARSE_OPT_EXCLUSIVE);
argc = parse_options(argc, argv, config_options, config_usage,
PARSE_OPT_STOP_AT_NON_OPTION);
@@ -601,6 +612,29 @@ int cmd_config(int argc, const char **argv, const char *prefix __maybe_unused)
}
switch (actions) {
+ case ACTION_REMOVE:
+ if (argc) {
+ for (i = 0; argv[i]; i++) {
+ if (!use_system_config && !use_user_config) {
+ ret = perf_configset_with_option(set_config,
+ &system_sections,
+ system_config,
+ argv[i], NULL);
+ ret = perf_configset_with_option(set_config,
+ &user_sections,
+ user_config,
+ argv[i], NULL);
+ } else
+ ret = perf_configset_with_option(set_config, sections,
+ config_exclusive_filename,
+ argv[i], NULL);
+ }
+ } else {
+ pr_err("Error: Missing arguments\n");
+ parse_options_usage(config_usage, config_options, "r", 1);
+ return -1;
+ }
+ break;
case ACTION_LIST_ALL:
if (argc == 0) {
ret = show_all_config(sections);
--
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/
[toc] | [prev] | [next] | [standalone]
| From | Taeung Song <treeze.taeung@gmail.com> |
|---|---|
| Date | 2015-11-03 03:00 +0100 |
| Subject | [PATCH v9 4/9] perf config: Add comparing name treating '_' and '-' as being the same thing. |
| Message-ID | <qqz3e-4xe-57@gated-at.bofh.it> |
| In reply to | #1261133 |
The comparing name functionality is that
two config name are compared treating '-' or '_' as
being the same thing. For example, both 'print_percent'
and 'print-percent' in 'call-graph' section
are regarded as the same thing.
Signed-off-by: Taeung Song <treeze.taeung@gmail.com>
---
tools/perf/builtin-config.c | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c
index f99c39d..d4e2899 100644
--- a/tools/perf/builtin-config.c
+++ b/tools/perf/builtin-config.c
@@ -32,6 +32,27 @@ static struct option config_options[] = {
OPT_END()
};
+static int compare_name(const char *name1, const char *name2)
+{
+ while (true) {
+ /*
+ * If two names have '-' or '_', them are treated
+ * as being the same thing.
+ */
+ if ((*name1 == '-' || *name1 == '_')
+ && (*name2 == '-' || *name2 == '_')) {
+ name1++, name2++;
+ continue;
+ }
+
+ if (*name1 && (*name1 == *name2))
+ name1++, name2++;
+ else
+ break;
+ }
+ return *(const unsigned char *)name1-*(const unsigned char *)name2;
+}
+
static struct config_section *find_section(struct list_head *sections,
const char *section_name)
{
@@ -50,7 +71,7 @@ static struct config_element *find_element(const char *name,
struct config_element *element;
list_for_each_entry(element, §ion->element_head, list)
- if (!strcmp(element->name, name))
+ if (!compare_name(element->name, name))
return element;
return NULL;
--
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/
[toc] | [prev] | [next] | [standalone]
| From | Namhyung Kim <namhyung@kernel.org> |
|---|---|
| Date | 2015-11-03 13:20 +0100 |
| Subject | Re: [PATCH v9 4/9] perf config: Add comparing name treating '_' and '-' as being the same thing. |
| Message-ID | <qqIJb-2zy-1@gated-at.bofh.it> |
| In reply to | #1261150 |
On Tue, Nov 03, 2015 at 10:50:15AM +0900, Taeung Song wrote:
> The comparing name functionality is that
> two config name are compared treating '-' or '_' as
> being the same thing. For example, both 'print_percent'
> and 'print-percent' in 'call-graph' section
> are regarded as the same thing.
Hmm.. but this code only does it for 'perf config' command, right?
What we want is treating them in all other commands which use
perf_config() callbacks. I think it'd be better to convert the
character when parsing the config files..
Thanks,
Namhyung
>
> Signed-off-by: Taeung Song <treeze.taeung@gmail.com>
> ---
> tools/perf/builtin-config.c | 23 ++++++++++++++++++++++-
> 1 file changed, 22 insertions(+), 1 deletion(-)
>
> diff --git a/tools/perf/builtin-config.c b/tools/perf/builtin-config.c
> index f99c39d..d4e2899 100644
> --- a/tools/perf/builtin-config.c
> +++ b/tools/perf/builtin-config.c
> @@ -32,6 +32,27 @@ static struct option config_options[] = {
> OPT_END()
> };
>
> +static int compare_name(const char *name1, const char *name2)
> +{
> + while (true) {
> + /*
> + * If two names have '-' or '_', them are treated
> + * as being the same thing.
> + */
> + if ((*name1 == '-' || *name1 == '_')
> + && (*name2 == '-' || *name2 == '_')) {
> + name1++, name2++;
> + continue;
> + }
> +
> + if (*name1 && (*name1 == *name2))
> + name1++, name2++;
> + else
> + break;
> + }
> + return *(const unsigned char *)name1-*(const unsigned char *)name2;
> +}
> +
> static struct config_section *find_section(struct list_head *sections,
> const char *section_name)
> {
> @@ -50,7 +71,7 @@ static struct config_element *find_element(const char *name,
> struct config_element *element;
>
> list_for_each_entry(element, §ion->element_head, list)
> - if (!strcmp(element->name, name))
> + if (!compare_name(element->name, name))
> return element;
>
> return NULL;
> --
> 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/
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web