1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * config.c 4 * 5 * Helper functions for parsing config items. 6 * Originally copied from GIT source. 7 * 8 * Copyright (C) Linus Torvalds, 2005 9 * Copyright (C) Johannes Schindelin, 2005 10 * 11 */ 12 #include "config.h" 13 14 #include <errno.h> 15 #include <limits.h> 16 #include <stdbool.h> 17 #include <stdio.h> 18 #include <stdlib.h> 19 #include <string.h> 20 21 #include <linux/ctype.h> 22 #include <linux/string.h> 23 #include <linux/zalloc.h> 24 #include <sys/param.h> 25 #include <sys/stat.h> 26 #include <unistd.h> 27 28 #include <subcmd/exec-cmd.h> 29 30 #include "build-id.h" 31 #include "callchain.h" 32 #include "debug.h" 33 #include "header.h" 34 #include "mutex.h" 35 #include "path.h" 36 #include "srcline.h" 37 #include "unwind.h" 38 #include "util/event.h" /* proc_map_timeout */ 39 #include "util/evsel.h" /* evsel__hw_names, evsel__use_bpf_counters */ 40 #include "util/hist.h" /* perf_hist_config */ 41 #include "util/stat.h" /* perf_stat__set_big_num */ 42 43 #define MAXNAME (256) 44 45 #define DEBUG_CACHE_DIR ".debug" 46 47 #define METRIC_ONLY_LEN 20 48 49 static struct stats walltime_nsecs_stats; 50 51 struct perf_stat_config stat_config = { 52 .aggr_mode = AGGR_GLOBAL, 53 .aggr_level = MAX_CACHE_LVL + 1, 54 .scale = true, 55 .unit_width = 4, /* strlen("unit") */ 56 .run_count = 1, 57 .metric_only_len = METRIC_ONLY_LEN, 58 .walltime_nsecs_stats = &walltime_nsecs_stats, 59 .big_num = true, 60 .ctl_fd = -1, 61 .ctl_fd_ack = -1, 62 .iostat_run = false, 63 }; 64 65 char buildid_dir[MAXPATHLEN]; /* root dir for buildid, binary cache */ 66 67 static FILE *config_file; 68 static const char *config_file_name; 69 static int config_linenr; 70 static int config_file_eof; 71 static struct perf_config_set *config_set; 72 73 const char *config_exclusive_filename; 74 75 static int get_next_char(void) 76 { 77 int c; 78 FILE *f; 79 80 c = '\n'; 81 if ((f = config_file) != NULL) { 82 c = fgetc(f); 83 if (c == '\r') { 84 /* DOS like systems */ 85 c = fgetc(f); 86 if (c != '\n') { 87 ungetc(c, f); 88 c = '\r'; 89 } 90 } 91 if (c == '\n') 92 config_linenr++; 93 if (c == EOF) { 94 config_file_eof = 1; 95 c = '\n'; 96 } 97 } 98 return c; 99 } 100 101 static char *parse_value(void) 102 { 103 static char value[1024]; 104 int quote = 0, comment = 0, space = 0; 105 size_t len = 0; 106 107 for (;;) { 108 int c = get_next_char(); 109 110 if (len >= sizeof(value) - 1) 111 return NULL; 112 if (c == '\n') { 113 if (quote) 114 return NULL; 115 value[len] = 0; 116 return value; 117 } 118 if (comment) 119 continue; 120 if (isspace(c) && !quote) { 121 space = 1; 122 continue; 123 } 124 if (!quote) { 125 if (c == ';' || c == '#') { 126 comment = 1; 127 continue; 128 } 129 } 130 if (space) { 131 if (len) 132 value[len++] = ' '; 133 space = 0; 134 } 135 if (c == '\\') { 136 c = get_next_char(); 137 switch (c) { 138 case '\n': 139 continue; 140 case 't': 141 c = '\t'; 142 break; 143 case 'b': 144 c = '\b'; 145 break; 146 case 'n': 147 c = '\n'; 148 break; 149 /* Some characters escape as themselves */ 150 case '\\': case '"': 151 break; 152 /* Reject unknown escape sequences */ 153 default: 154 return NULL; 155 } 156 value[len++] = c; 157 continue; 158 } 159 if (c == '"') { 160 quote = 1-quote; 161 continue; 162 } 163 value[len++] = c; 164 } 165 } 166 167 static inline int iskeychar(int c) 168 { 169 return isalnum(c) || c == '-' || c == '_'; 170 } 171 172 static int get_value(config_fn_t fn, void *data, char *name, unsigned int len) 173 { 174 int c; 175 char *value; 176 177 /* Get the full name */ 178 for (;;) { 179 c = get_next_char(); 180 if (config_file_eof) 181 break; 182 if (!iskeychar(c)) 183 break; 184 name[len++] = c; 185 if (len >= MAXNAME) 186 return -1; 187 } 188 name[len] = 0; 189 while (c == ' ' || c == '\t') 190 c = get_next_char(); 191 192 value = NULL; 193 if (c != '\n') { 194 if (c != '=') 195 return -1; 196 value = parse_value(); 197 if (!value) 198 return -1; 199 } 200 return fn(name, value, data); 201 } 202 203 static int get_extended_base_var(char *name, int baselen, int c) 204 { 205 do { 206 if (c == '\n') 207 return -1; 208 c = get_next_char(); 209 } while (isspace(c)); 210 211 /* We require the format to be '[base "extension"]' */ 212 if (c != '"') 213 return -1; 214 name[baselen++] = '.'; 215 216 for (;;) { 217 int ch = get_next_char(); 218 219 if (ch == '\n') 220 return -1; 221 if (ch == '"') 222 break; 223 if (ch == '\\') { 224 ch = get_next_char(); 225 if (ch == '\n') 226 return -1; 227 } 228 name[baselen++] = ch; 229 if (baselen > MAXNAME / 2) 230 return -1; 231 } 232 233 /* Final ']' */ 234 if (get_next_char() != ']') 235 return -1; 236 return baselen; 237 } 238 239 static int get_base_var(char *name) 240 { 241 int baselen = 0; 242 243 for (;;) { 244 int c = get_next_char(); 245 if (config_file_eof) 246 return -1; 247 if (c == ']') 248 return baselen; 249 if (isspace(c)) 250 return get_extended_base_var(name, baselen, c); 251 if (!iskeychar(c) && c != '.') 252 return -1; 253 if (baselen > MAXNAME / 2) 254 return -1; 255 name[baselen++] = tolower(c); 256 } 257 } 258 259 static int perf_parse_file(config_fn_t fn, void *data) 260 { 261 int comment = 0; 262 int baselen = 0; 263 static char var[MAXNAME]; 264 265 /* U+FEFF Byte Order Mark in UTF8 */ 266 static const unsigned char *utf8_bom = (unsigned char *) "\xef\xbb\xbf"; 267 const unsigned char *bomptr = utf8_bom; 268 269 for (;;) { 270 int line, c = get_next_char(); 271 272 if (bomptr && *bomptr) { 273 /* We are at the file beginning; skip UTF8-encoded BOM 274 * if present. Sane editors won't put this in on their 275 * own, but e.g. Windows Notepad will do it happily. */ 276 if ((unsigned char) c == *bomptr) { 277 bomptr++; 278 continue; 279 } else { 280 /* Do not tolerate partial BOM. */ 281 if (bomptr != utf8_bom) 282 break; 283 /* No BOM at file beginning. Cool. */ 284 bomptr = NULL; 285 } 286 } 287 if (c == '\n') { 288 if (config_file_eof) 289 return 0; 290 comment = 0; 291 continue; 292 } 293 if (comment || isspace(c)) 294 continue; 295 if (c == '#' || c == ';') { 296 comment = 1; 297 continue; 298 } 299 if (c == '[') { 300 baselen = get_base_var(var); 301 if (baselen <= 0) 302 break; 303 var[baselen++] = '.'; 304 var[baselen] = 0; 305 continue; 306 } 307 if (!isalpha(c)) 308 break; 309 var[baselen] = tolower(c); 310 311 /* 312 * The get_value function might or might not reach the '\n', 313 * so saving the current line number for error reporting. 314 */ 315 line = config_linenr; 316 if (get_value(fn, data, var, baselen+1) < 0) { 317 config_linenr = line; 318 break; 319 } 320 } 321 pr_err("bad config file line %d in %s\n", config_linenr, config_file_name); 322 return -1; 323 } 324 325 static int parse_unit_factor(const char *end, unsigned long *val) 326 { 327 if (!*end) 328 return 1; 329 else if (!strcasecmp(end, "k")) { 330 *val *= 1024; 331 return 1; 332 } 333 else if (!strcasecmp(end, "m")) { 334 *val *= 1024 * 1024; 335 return 1; 336 } 337 else if (!strcasecmp(end, "g")) { 338 *val *= 1024 * 1024 * 1024; 339 return 1; 340 } 341 return 0; 342 } 343 344 static int perf_parse_llong(const char *value, long long *ret) 345 { 346 if (value && *value) { 347 char *end; 348 long long val = strtoll(value, &end, 0); 349 unsigned long factor = 1; 350 351 if (!parse_unit_factor(end, &factor)) 352 return 0; 353 *ret = val * factor; 354 return 1; 355 } 356 return 0; 357 } 358 359 static int perf_parse_long(const char *value, long *ret) 360 { 361 if (value && *value) { 362 char *end; 363 long val = strtol(value, &end, 0); 364 unsigned long factor = 1; 365 if (!parse_unit_factor(end, &factor)) 366 return 0; 367 *ret = val * factor; 368 return 1; 369 } 370 return 0; 371 } 372 373 static void bad_config(const char *name) 374 { 375 /* config_file_name is owned by the parsing thread, under config_mutex. */ 376 pr_warning("bad config value for '%s', ignoring...\n", name); 377 } 378 379 int perf_config_u64(u64 *dest, const char *name, const char *value) 380 { 381 long long ret = 0; 382 383 if (!perf_parse_llong(value, &ret)) { 384 bad_config(name); 385 return -1; 386 } 387 388 *dest = ret; 389 return 0; 390 } 391 392 int perf_config_int(int *dest, const char *name, const char *value) 393 { 394 long ret = 0; 395 if (!perf_parse_long(value, &ret)) { 396 bad_config(name); 397 return -1; 398 } 399 *dest = ret; 400 return 0; 401 } 402 403 int perf_config_u8(u8 *dest, const char *name, const char *value) 404 { 405 long ret = 0; 406 407 if (!perf_parse_long(value, &ret)) { 408 bad_config(name); 409 return -1; 410 } 411 *dest = ret; 412 return 0; 413 } 414 415 static int perf_config_bool_or_int(const char *name, const char *value, int *is_bool) 416 { 417 int ret; 418 419 *is_bool = 1; 420 if (!value) 421 return 1; 422 if (!*value) 423 return 0; 424 if (!strcasecmp(value, "true") || !strcasecmp(value, "yes") || !strcasecmp(value, "on")) 425 return 1; 426 if (!strcasecmp(value, "false") || !strcasecmp(value, "no") || !strcasecmp(value, "off")) 427 return 0; 428 *is_bool = 0; 429 return perf_config_int(&ret, name, value) < 0 ? -1 : ret; 430 } 431 432 int perf_config_bool(const char *name, const char *value) 433 { 434 int discard; 435 return !!perf_config_bool_or_int(name, value, &discard); 436 } 437 438 static const char *perf_config_dirname(const char *name, const char *value) 439 { 440 if (!name) 441 return NULL; 442 return value; 443 } 444 445 static int perf_buildid_config(const char *var, const char *value) 446 { 447 /* same dir for all commands */ 448 if (!strcmp(var, "buildid.dir")) { 449 const char *dir = perf_config_dirname(var, value); 450 451 if (!dir) { 452 pr_err("Invalid buildid directory!\n"); 453 return -1; 454 } 455 strncpy(buildid_dir, dir, MAXPATHLEN-1); 456 buildid_dir[MAXPATHLEN-1] = '\0'; 457 } 458 459 return 0; 460 } 461 462 static int perf_default_core_config(const char *var, const char *value) 463 { 464 if (!strcmp(var, "core.proc-map-timeout")) 465 proc_map_timeout = strtoul(value, NULL, 10); 466 467 if (!strcmp(var, "core.addr2line-timeout")) 468 symbol_conf.addr2line_timeout_ms = strtoul(value, NULL, 10); 469 470 if (!strcmp(var, "core.addr2line-disable-warn")) 471 symbol_conf.addr2line_disable_warn = perf_config_bool(var, value); 472 473 if (!strcmp(var, "core.hybrid-merge")) { 474 /* 475 * Note, this is for sampling tools like perf report and top. 476 * perf stat has its own merging options and the 477 * stat_config.hybrid_merge of "perf stat --hybrid-merge" is 478 * deliberately not set here. 479 */ 480 symbol_conf.hybrid_merge = perf_config_bool(var, value); 481 } 482 483 /* Add other config variables here. */ 484 return 0; 485 } 486 487 static int perf_ui_config(const char *var, const char *value) 488 { 489 /* Add other config variables here. */ 490 if (!strcmp(var, "ui.show-headers")) 491 symbol_conf.show_hist_headers = perf_config_bool(var, value); 492 493 return 0; 494 } 495 496 void perf_stat__set_big_num(int set) 497 { 498 stat_config.big_num = (set != 0); 499 } 500 501 static void perf_stat__set_no_csv_summary(int set) 502 { 503 stat_config.no_csv_summary = (set != 0); 504 } 505 506 static int perf_stat_config(const char *var, const char *value) 507 { 508 if (!strcmp(var, "stat.big-num")) 509 perf_stat__set_big_num(perf_config_bool(var, value)); 510 511 if (!strcmp(var, "stat.no-csv-summary")) 512 perf_stat__set_no_csv_summary(perf_config_bool(var, value)); 513 514 if (!strcmp(var, "stat.bpf-counter-events")) 515 evsel__bpf_counter_events = strdup(value); 516 517 /* Add other config variables here. */ 518 return 0; 519 } 520 521 int perf_default_config(const char *var, const char *value, 522 void *dummy __maybe_unused) 523 { 524 if (strstarts(var, "core.")) 525 return perf_default_core_config(var, value); 526 527 if (strstarts(var, "hist.")) 528 return perf_hist_config(var, value); 529 530 if (strstarts(var, "ui.")) 531 return perf_ui_config(var, value); 532 533 if (strstarts(var, "call-graph.")) 534 return perf_callchain_config(var, value); 535 536 if (strstarts(var, "buildid.")) 537 return perf_buildid_config(var, value); 538 539 if (strstarts(var, "stat.")) 540 return perf_stat_config(var, value); 541 542 if (strstarts(var, "addr2line.")) 543 return addr2line_configure(var, value, dummy); 544 545 if (strstarts(var, "unwind.")) 546 return unwind__configure(var, value, dummy); 547 548 /* Add other config variables here. */ 549 return 0; 550 } 551 552 /* Parsing and rewriting share the static parser state. */ 553 static DEFINE_MUTEX(config_mutex); 554 555 /* Serializes whole perf_config__set_variable() updates. */ 556 static DEFINE_MUTEX(config_update_mutex); 557 558 static int perf_config_from_file(config_fn_t fn, const char *filename, void *data) 559 { 560 int ret; 561 FILE *f = fopen(filename, "r"); 562 563 mutex_lock(&config_mutex); 564 ret = -1; 565 if (f) { 566 config_file = f; 567 config_file_name = filename; 568 config_linenr = 1; 569 config_file_eof = 0; 570 ret = perf_parse_file(fn, data); 571 fclose(f); 572 config_file_name = NULL; 573 } 574 mutex_unlock(&config_mutex); 575 return ret; 576 } 577 578 /* system_path() allocates, so it is computed once. */ 579 static const char *etc_perfconfig; 580 581 static void perf_etc_perfconfig__init(void) 582 { 583 etc_perfconfig = system_path(ETC_PERFCONFIG); 584 if (!etc_perfconfig) 585 etc_perfconfig = ETC_PERFCONFIG; 586 } 587 588 const char *perf_etc_perfconfig(void) 589 { 590 DO_ONCE(perf_etc_perfconfig__init); 591 return etc_perfconfig; 592 } 593 594 static int perf_env_bool(const char *k, int def) 595 { 596 const char *v = getenv(k); 597 return v ? perf_config_bool(k, v) : def; 598 } 599 600 int perf_config_system(void) 601 { 602 return !perf_env_bool("PERF_CONFIG_NOSYSTEM", 0); 603 } 604 605 int perf_config_global(void) 606 { 607 return !perf_env_bool("PERF_CONFIG_NOGLOBAL", 0); 608 } 609 610 static char *home_perfconfig(void) 611 { 612 const char *home = NULL; 613 char *config; 614 struct stat st; 615 char path[PATH_MAX]; 616 617 home = getenv("HOME"); 618 619 /* 620 * Skip reading user config if: 621 * - there is no place to read it from (HOME) 622 * - we are asked not to (PERF_CONFIG_NOGLOBAL=1) 623 */ 624 if (!home || !*home || !perf_config_global()) 625 return NULL; 626 627 config = strdup(mkpath(path, sizeof(path), "%s/.perfconfig", home)); 628 if (config == NULL) { 629 pr_warning("Not enough memory to process %s/.perfconfig, ignoring it.\n", home); 630 return NULL; 631 } 632 633 if (stat(config, &st) < 0) 634 goto out_free; 635 636 if (st.st_uid && (st.st_uid != geteuid())) { 637 pr_warning("File %s not owned by current user or root, ignoring it.\n", config); 638 goto out_free; 639 } 640 641 if (st.st_size) 642 return config; 643 644 out_free: 645 free(config); 646 return NULL; 647 } 648 649 /* home_perfconfig() allocates and warns, so it is computed once. */ 650 static const char *home_config; 651 652 static void perf_home_perfconfig__init(void) 653 { 654 home_config = home_perfconfig(); 655 } 656 657 const char *perf_home_perfconfig(void) 658 { 659 DO_ONCE(perf_home_perfconfig__init); 660 return home_config; 661 } 662 663 static struct perf_config_section *find_section(struct list_head *sections, 664 const char *section_name) 665 { 666 struct perf_config_section *section; 667 668 list_for_each_entry(section, sections, node) 669 if (!strcmp(section->name, section_name)) 670 return section; 671 672 return NULL; 673 } 674 675 static struct perf_config_item *find_config_item(const char *name, 676 struct perf_config_section *section) 677 { 678 struct perf_config_item *item; 679 680 list_for_each_entry(item, §ion->items, node) 681 if (!strcmp(item->name, name)) 682 return item; 683 684 return NULL; 685 } 686 687 static struct perf_config_section *add_section(struct list_head *sections, 688 const char *section_name) 689 { 690 struct perf_config_section *section = zalloc(sizeof(*section)); 691 692 if (!section) 693 return NULL; 694 695 INIT_LIST_HEAD(§ion->items); 696 section->name = strdup(section_name); 697 if (!section->name) { 698 pr_debug("%s: strdup failed\n", __func__); 699 free(section); 700 return NULL; 701 } 702 703 list_add_tail(§ion->node, sections); 704 return section; 705 } 706 707 static struct perf_config_item *add_config_item(struct perf_config_section *section, 708 const char *name) 709 { 710 struct perf_config_item *item = zalloc(sizeof(*item)); 711 712 if (!item) 713 return NULL; 714 715 item->name = strdup(name); 716 if (!item->name) { 717 pr_debug("%s: strdup failed\n", __func__); 718 free(item); 719 return NULL; 720 } 721 722 list_add_tail(&item->node, §ion->items); 723 return item; 724 } 725 726 static int set_value(struct perf_config_item *item, const char *value) 727 { 728 char *val = strdup(value); 729 730 if (!val) 731 return -1; 732 733 zfree(&item->value); 734 item->value = val; 735 return 0; 736 } 737 738 static int collect_config(const char *var, const char *value, 739 void *perf_config_set) 740 { 741 int ret = -1; 742 char *ptr, *key; 743 char *section_name, *name; 744 struct perf_config_section *section = NULL; 745 struct perf_config_item *item = NULL; 746 struct perf_config_set *set = perf_config_set; 747 struct list_head *sections; 748 749 if (set == NULL) 750 return -1; 751 752 sections = &set->sections; 753 key = ptr = strdup(var); 754 if (!key) { 755 pr_debug("%s: strdup failed\n", __func__); 756 return -1; 757 } 758 759 section_name = strsep(&ptr, "."); 760 name = ptr; 761 if (name == NULL || value == NULL) 762 goto out_free; 763 764 section = find_section(sections, section_name); 765 if (!section) { 766 section = add_section(sections, section_name); 767 if (!section) 768 goto out_free; 769 } 770 771 item = find_config_item(name, section); 772 if (!item) { 773 item = add_config_item(section, name); 774 if (!item) 775 goto out_free; 776 } 777 778 /* perf_config_set can contain both user and system config items. 779 * So we should know where each value is from. 780 * The classification would be needed when a particular config file 781 * is overwritten by setting feature i.e. set_config(). 782 */ 783 if (strcmp(config_file_name, perf_etc_perfconfig()) == 0) { 784 section->from_system_config = true; 785 item->from_system_config = true; 786 } else { 787 section->from_system_config = false; 788 item->from_system_config = false; 789 } 790 791 ret = set_value(item, value); 792 793 out_free: 794 free(key); 795 return ret; 796 } 797 798 int perf_config_set__collect(struct perf_config_set *set, const char *file_name, 799 const char *var, const char *value) 800 { 801 int ret; 802 803 mutex_lock(&config_mutex); 804 config_file_name = file_name; 805 ret = collect_config(var, value, set); 806 /* Don't leave the static parser state pointing at the caller's buffer. */ 807 config_file_name = NULL; 808 mutex_unlock(&config_mutex); 809 return ret; 810 } 811 812 static int perf_config_set__init(struct perf_config_set *set) 813 { 814 int ret = -1; 815 816 /* Setting $PERF_CONFIG makes perf read _only_ the given config file. */ 817 if (config_exclusive_filename) 818 return perf_config_from_file(collect_config, config_exclusive_filename, set); 819 if (perf_config_system() && !access(perf_etc_perfconfig(), R_OK)) { 820 if (perf_config_from_file(collect_config, perf_etc_perfconfig(), set) < 0) 821 goto out; 822 } 823 if (perf_config_global() && perf_home_perfconfig()) { 824 if (perf_config_from_file(collect_config, perf_home_perfconfig(), set) < 0) 825 goto out; 826 } 827 828 out: 829 return ret; 830 } 831 832 struct perf_config_set *perf_config_set__new(void) 833 { 834 struct perf_config_set *set = zalloc(sizeof(*set)); 835 836 if (set) { 837 INIT_LIST_HEAD(&set->sections); 838 perf_config_set__init(set); 839 } 840 841 return set; 842 } 843 844 struct perf_config_set *perf_config_set__load_file(const char *file) 845 { 846 struct perf_config_set *set = zalloc(sizeof(*set)); 847 848 if (set) { 849 INIT_LIST_HEAD(&set->sections); 850 perf_config_from_file(collect_config, file, set); 851 } 852 853 return set; 854 } 855 856 /* Not config_mutex: building the set parses the config files, which takes it. */ 857 static DEFINE_MUTEX(config_set_mutex); 858 859 /* Called with config_set_mutex held. */ 860 static int perf_config__init(void) 861 { 862 if (config_set == NULL) 863 config_set = perf_config_set__new(); 864 865 return config_set == NULL; 866 } 867 868 int perf_config_set(struct perf_config_set *set, 869 config_fn_t fn, void *data) 870 { 871 int ret = 0; 872 char key[BUFSIZ]; 873 struct perf_config_section *section; 874 struct perf_config_item *item; 875 876 perf_config_set__for_each_entry(set, section, item) { 877 char *value = item->value; 878 879 if (value) { 880 scnprintf(key, sizeof(key), "%s.%s", 881 section->name, item->name); 882 ret = fn(key, value, data); 883 if (ret < 0) { 884 pr_err("Error in the given config file: wrong config key-value pair %s=%s\n", 885 key, value); 886 /* 887 * Can't be just a 'break', as perf_config_set__for_each_entry() 888 * expands to two nested for() loops. 889 */ 890 goto out; 891 } 892 } 893 } 894 out: 895 return ret; 896 } 897 898 int perf_config(config_fn_t fn, void *data) 899 { 900 struct perf_config_set *set; 901 902 /* Not held across the dispatch: a callback can call perf_config() again. */ 903 mutex_lock(&config_set_mutex); 904 if (perf_config__init()) { 905 mutex_unlock(&config_set_mutex); 906 return -1; 907 } 908 set = config_set; 909 mutex_unlock(&config_set_mutex); 910 911 return perf_config_set(set, fn, data); 912 } 913 914 void perf_config__exit(void) 915 { 916 mutex_lock(&config_set_mutex); 917 perf_config_set__delete(config_set); 918 config_set = NULL; 919 mutex_unlock(&config_set_mutex); 920 } 921 922 int perf_config_set__write(struct perf_config_set *set, 923 const char *file_name, bool system_config) 924 { 925 struct perf_config_section *section = NULL; 926 struct perf_config_item *item = NULL; 927 int ret = 0; 928 FILE *fp; 929 930 mutex_lock(&config_mutex); 931 fp = fopen(file_name, "w"); 932 if (!fp) { 933 mutex_unlock(&config_mutex); 934 return -1; 935 } 936 937 if (fprintf(fp, "# this file is auto-generated.\n") < 0) 938 ret = -1; 939 940 /* overwrite configvariables */ 941 perf_config_sections__for_each_entry(&set->sections, section) { 942 if (!system_config && section->from_system_config) 943 continue; 944 if (fprintf(fp, "[%s]\n", section->name) < 0) 945 ret = -1; 946 947 perf_config_items__for_each_entry(§ion->items, item) { 948 if (!system_config && item->from_system_config) 949 continue; 950 if (item->value && 951 fprintf(fp, "\t%s = %s\n", item->name, item->value) < 0) 952 ret = -1; 953 } 954 } 955 if (fclose(fp) != 0) 956 ret = -1; 957 mutex_unlock(&config_mutex); 958 959 return ret; 960 } 961 962 /* 963 * Set @var=@value in the config file perf is using: ~/.perfconfig or the 964 * file named by PERF_CONFIG. Same rewrite 'perf config' does, comments 965 * are not preserved. 966 */ 967 int perf_config__set_variable(const char *var, const char *value) 968 { 969 const char *config_filename; 970 bool system_config; 971 struct perf_config_set *set = NULL; 972 int ret = -1; 973 974 mutex_lock(&config_update_mutex); 975 976 /* Static: the parser publishes it as config_file_name. */ 977 { 978 static char path[PATH_MAX]; 979 char *user_config = mkpath(path, sizeof(path), "%s/.perfconfig", getenv("HOME")); 980 981 config_filename = config_exclusive_filename ?: user_config; 982 } 983 984 /* Rewriting the system wide file keeps its entries, or it is truncated. */ 985 system_config = strcmp(config_filename, perf_etc_perfconfig()) == 0; 986 987 set = perf_config_set__new(); 988 if (!set) 989 goto out_err; 990 991 if (perf_config_set__collect(set, config_filename, var, value) < 0) { 992 pr_err("Failed to add '%s=%s'\n", var, value); 993 goto out_err; 994 } 995 996 if (perf_config_set__write(set, config_filename, system_config) < 0) { 997 pr_err("Failed to set the configs on %s\n", config_filename); 998 goto out_err; 999 } 1000 1001 ret = 0; 1002 out_err: 1003 perf_config_set__delete(set); 1004 mutex_unlock(&config_update_mutex); 1005 return ret; 1006 } 1007 1008 static void perf_config_item__delete(struct perf_config_item *item) 1009 { 1010 zfree(&item->name); 1011 zfree(&item->value); 1012 free(item); 1013 } 1014 1015 static void perf_config_section__purge(struct perf_config_section *section) 1016 { 1017 struct perf_config_item *item, *tmp; 1018 1019 list_for_each_entry_safe(item, tmp, §ion->items, node) { 1020 list_del_init(&item->node); 1021 perf_config_item__delete(item); 1022 } 1023 } 1024 1025 static void perf_config_section__delete(struct perf_config_section *section) 1026 { 1027 perf_config_section__purge(section); 1028 zfree(§ion->name); 1029 free(section); 1030 } 1031 1032 static void perf_config_set__purge(struct perf_config_set *set) 1033 { 1034 struct perf_config_section *section, *tmp; 1035 1036 list_for_each_entry_safe(section, tmp, &set->sections, node) { 1037 list_del_init(§ion->node); 1038 perf_config_section__delete(section); 1039 } 1040 } 1041 1042 void perf_config_set__delete(struct perf_config_set *set) 1043 { 1044 if (set == NULL) 1045 return; 1046 1047 perf_config_set__purge(set); 1048 free(set); 1049 } 1050 1051 /* 1052 * Call this to report error for your variable that should not 1053 * get a boolean value (i.e. "[my] var" means "true"). 1054 */ 1055 int config_error_nonbool(const char *var) 1056 { 1057 pr_err("Missing value for '%s'", var); 1058 return -1; 1059 } 1060 1061 void set_buildid_dir(const char *dir) 1062 { 1063 if (dir) 1064 scnprintf(buildid_dir, MAXPATHLEN, "%s", dir); 1065 1066 /* default to $HOME/.debug */ 1067 if (buildid_dir[0] == '\0') { 1068 char *home = getenv("HOME"); 1069 1070 if (home) { 1071 snprintf(buildid_dir, MAXPATHLEN, "%s/%s", 1072 home, DEBUG_CACHE_DIR); 1073 } else { 1074 strncpy(buildid_dir, DEBUG_CACHE_DIR, MAXPATHLEN-1); 1075 } 1076 buildid_dir[MAXPATHLEN-1] = '\0'; 1077 } 1078 /* for communicating with external commands */ 1079 setenv("PERF_BUILDID_DIR", buildid_dir, 1); 1080 } 1081 1082 struct perf_config_scan_data { 1083 const char *name; 1084 const char *fmt; 1085 const char *value; 1086 va_list args; 1087 int ret; 1088 }; 1089 1090 static int perf_config_scan_cb(const char *var, const char *value, void *data) 1091 { 1092 struct perf_config_scan_data *d = data; 1093 1094 if (!strcmp(var, d->name)) 1095 d->ret = vsscanf(value, d->fmt, d->args); 1096 1097 return 0; 1098 } 1099 1100 int perf_config_scan(const char *name, const char *fmt, ...) 1101 { 1102 struct perf_config_scan_data d = { 1103 .name = name, 1104 .fmt = fmt, 1105 }; 1106 1107 va_start(d.args, fmt); 1108 perf_config(perf_config_scan_cb, &d); 1109 va_end(d.args); 1110 1111 return d.ret; 1112 } 1113 1114 static int perf_config_get_cb(const char *var, const char *value, void *data) 1115 { 1116 struct perf_config_scan_data *d = data; 1117 1118 if (!strcmp(var, d->name)) 1119 d->value = value; 1120 1121 return 0; 1122 } 1123 1124 const char *perf_config_get(const char *name) 1125 { 1126 struct perf_config_scan_data d = { 1127 .name = name, 1128 .value = NULL, 1129 }; 1130 1131 perf_config(perf_config_get_cb, &d); 1132 return d.value; 1133 } 1134