Linux Perf
builtin-config.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * builtin-config.c
4  *
5  * Copyright (C) 2015, Taeung Song <treeze.taeung@gmail.com>
6  *
7  */
8 #include "builtin.h"
9 
10 #include "perf.h"
11 
12 #include "util/cache.h"
13 #include <subcmd/parse-options.h>
14 #include "util/util.h"
15 #include "util/debug.h"
16 #include "util/config.h"
17 #include <linux/string.h>
18 
20 
21 static const char * const config_usage[] = {
22  "perf config [<file-option>] [options] [section.name[=value] ...]",
23  NULL
24 };
25 
26 enum actions {
28 } actions;
29 
30 static struct option config_options[] = {
31  OPT_SET_UINT('l', "list", &actions,
32  "show current config variables", ACTION_LIST),
33  OPT_BOOLEAN(0, "system", &use_system_config, "use system config file"),
34  OPT_BOOLEAN(0, "user", &use_user_config, "use user config file"),
35  OPT_END()
36 };
37 
38 static int set_config(struct perf_config_set *set, const char *file_name)
39 {
40  struct perf_config_section *section = NULL;
41  struct perf_config_item *item = NULL;
42  const char *first_line = "# this file is auto-generated.";
43  FILE *fp;
44 
45  if (set == NULL)
46  return -1;
47 
48  fp = fopen(file_name, "w");
49  if (!fp)
50  return -1;
51 
52  fprintf(fp, "%s\n", first_line);
53 
54  /* overwrite configvariables */
55  perf_config_items__for_each_entry(&set->sections, section) {
56  if (!use_system_config && section->from_system_config)
57  continue;
58  fprintf(fp, "[%s]\n", section->name);
59 
60  perf_config_items__for_each_entry(&section->items, item) {
62  continue;
63  if (item->value)
64  fprintf(fp, "\t%s = %s\n",
65  item->name, item->value);
66  }
67  }
68  fclose(fp);
69 
70  return 0;
71 }
72 
73 static int show_spec_config(struct perf_config_set *set, const char *var)
74 {
75  struct perf_config_section *section;
76  struct perf_config_item *item;
77 
78  if (set == NULL)
79  return -1;
80 
81  perf_config_items__for_each_entry(&set->sections, section) {
82  if (!strstarts(var, section->name))
83  continue;
84 
85  perf_config_items__for_each_entry(&section->items, item) {
86  const char *name = var + strlen(section->name) + 1;
87 
88  if (strcmp(name, item->name) == 0) {
89  char *value = item->value;
90 
91  if (value) {
92  printf("%s=%s\n", var, value);
93  return 0;
94  }
95  }
96 
97  }
98  }
99 
100  return 0;
101 }
102 
103 static int show_config(struct perf_config_set *set)
104 {
105  struct perf_config_section *section;
106  struct perf_config_item *item;
107 
108  if (set == NULL)
109  return -1;
110 
111  perf_config_set__for_each_entry(set, section, item) {
112  char *value = item->value;
113 
114  if (value)
115  printf("%s.%s=%s\n", section->name,
116  item->name, value);
117  }
118 
119  return 0;
120 }
121 
122 static int parse_config_arg(char *arg, char **var, char **value)
123 {
124  const char *last_dot = strchr(arg, '.');
125 
126  /*
127  * Since "var" actually contains the section name and the real
128  * config variable name separated by a dot, we have to know where the dot is.
129  */
130  if (last_dot == NULL || last_dot == arg) {
131  pr_err("The config variable does not contain a section name: %s\n", arg);
132  return -1;
133  }
134  if (!last_dot[1]) {
135  pr_err("The config variable does not contain a variable name: %s\n", arg);
136  return -1;
137  }
138 
139  *value = strchr(arg, '=');
140  if (*value == NULL)
141  *var = arg;
142  else if (!strcmp(*value, "=")) {
143  pr_err("The config variable does not contain a value: %s\n", arg);
144  return -1;
145  } else {
146  *value = *value + 1; /* excluding a first character '=' */
147  *var = strsep(&arg, "=");
148  if (*var[0] == '\0') {
149  pr_err("invalid config variable: %s\n", arg);
150  return -1;
151  }
152  }
153 
154  return 0;
155 }
156 
157 int cmd_config(int argc, const char **argv)
158 {
159  int i, ret = -1;
160  struct perf_config_set *set;
161  char *user_config = mkpath("%s/.perfconfig", getenv("HOME"));
162  const char *config_filename;
163  bool changed = false;
164 
165  argc = parse_options(argc, argv, config_options, config_usage,
166  PARSE_OPT_STOP_AT_NON_OPTION);
167 
169  pr_err("Error: only one config file at a time\n");
170  parse_options_usage(config_usage, config_options, "user", 0);
171  parse_options_usage(NULL, config_options, "system", 0);
172  return -1;
173  }
174 
175  if (use_system_config)
177  else if (use_user_config)
178  config_exclusive_filename = user_config;
179 
181  config_filename = user_config;
182  else
183  config_filename = config_exclusive_filename;
184 
185  /*
186  * At only 'config' sub-command, individually use the config set
187  * because of reinitializing with options config file location.
188  */
189  set = perf_config_set__new();
190  if (!set)
191  goto out_err;
192 
193  switch (actions) {
194  case ACTION_LIST:
195  if (argc) {
196  pr_err("Error: takes no arguments\n");
197  parse_options_usage(config_usage, config_options, "l", 1);
198  } else {
199  if (show_config(set) < 0) {
200  pr_err("Nothing configured, "
201  "please check your %s \n", config_filename);
202  goto out_err;
203  }
204  }
205  break;
206  default:
207  if (!argc) {
208  usage_with_options(config_usage, config_options);
209  break;
210  }
211 
212  for (i = 0; argv[i]; i++) {
213  char *var, *value;
214  char *arg = strdup(argv[i]);
215 
216  if (!arg) {
217  pr_err("%s: strdup failed\n", __func__);
218  goto out_err;
219  }
220 
221  if (parse_config_arg(arg, &var, &value) < 0) {
222  free(arg);
223  goto out_err;
224  }
225 
226  if (value == NULL) {
227  if (show_spec_config(set, var) < 0) {
228  pr_err("%s is not configured: %s\n",
229  var, config_filename);
230  free(arg);
231  goto out_err;
232  }
233  } else {
234  if (perf_config_set__collect(set, config_filename,
235  var, value) < 0) {
236  pr_err("Failed to add '%s=%s'\n",
237  var, value);
238  free(arg);
239  goto out_err;
240  }
241  changed = true;
242  }
243  free(arg);
244  }
245 
246  if (!changed)
247  break;
248 
249  if (set_config(set, config_filename) < 0) {
250  pr_err("Failed to set the configs on %s\n",
251  config_filename);
252  goto out_err;
253  }
254  }
255 
256  ret = 0;
257 out_err:
259  return ret;
260 }
int value
Definition: python.c:1143
char * name
Definition: config.h:9
void perf_config_set__delete(struct perf_config_set *set)
Definition: config.c:792
static int parse_config_arg(char *arg, char **var, char **value)
static int set_config(struct perf_config_set *set, const char *file_name)
static bool use_system_config
static int show_spec_config(struct perf_config_set *set, const char *var)
static const char *const config_usage[]
static struct option config_options[]
#define pr_err(fmt,...)
Definition: json.h:21
#define perf_config_items__for_each_entry(list, item)
Definition: config.h:57
struct perf_config_set * perf_config_set__new(void)
Definition: config.c:698
const char * name
char * value
Definition: config.h:10
bool from_system_config
Definition: config.h:18
struct list_head items
Definition: config.h:17
const char * config_exclusive_filename
Definition: config.c:40
bool from_system_config
Definition: config.h:11
static int show_config(struct perf_config_set *set)
const char * perf_etc_perfconfig(void)
Definition: config.c:478
actions
void free(void *)
static bool use_user_config
#define perf_config_set__for_each_entry(set, section, item)
Definition: config.h:66
int cmd_config(int argc, const char **argv)
int perf_config_set__collect(struct perf_config_set *set, const char *file_name, const char *var, const char *value)
Definition: config.c:638
char * mkpath(const char *fmt,...) __printf(1