1 /* 2 * builtin-buildid-cache.c 3 * 4 * Builtin buildid-cache command: Manages build-id cache 5 * 6 * Copyright (C) 2010, Red Hat Inc. 7 * Copyright (C) 2010, Arnaldo Carvalho de Melo <acme@redhat.com> 8 */ 9 #include "builtin.h" 10 #include "perf.h" 11 #include "util/cache.h" 12 #include "util/debug.h" 13 #include "util/header.h" 14 #include "util/parse-options.h" 15 #include "util/strlist.h" 16 #include "util/build-id.h" 17 #include "util/symbol.h" 18 19 static int build_id_cache__add_file(const char *filename, const char *debugdir) 20 { 21 char sbuild_id[BUILD_ID_SIZE * 2 + 1]; 22 u8 build_id[BUILD_ID_SIZE]; 23 int err; 24 25 if (filename__read_build_id(filename, &build_id, sizeof(build_id)) < 0) { 26 pr_debug("Couldn't read a build-id in %s\n", filename); 27 return -1; 28 } 29 30 build_id__sprintf(build_id, sizeof(build_id), sbuild_id); 31 err = build_id_cache__add_s(sbuild_id, debugdir, filename, 32 false, false); 33 if (verbose) 34 pr_info("Adding %s %s: %s\n", sbuild_id, filename, 35 err ? "FAIL" : "Ok"); 36 return err; 37 } 38 39 static int build_id_cache__remove_file(const char *filename, 40 const char *debugdir) 41 { 42 u8 build_id[BUILD_ID_SIZE]; 43 char sbuild_id[BUILD_ID_SIZE * 2 + 1]; 44 45 int err; 46 47 if (filename__read_build_id(filename, &build_id, sizeof(build_id)) < 0) { 48 pr_debug("Couldn't read a build-id in %s\n", filename); 49 return -1; 50 } 51 52 build_id__sprintf(build_id, sizeof(build_id), sbuild_id); 53 err = build_id_cache__remove_s(sbuild_id, debugdir); 54 if (verbose) 55 pr_info("Removing %s %s: %s\n", sbuild_id, filename, 56 err ? "FAIL" : "Ok"); 57 58 return err; 59 } 60 61 int cmd_buildid_cache(int argc, const char **argv, 62 const char *prefix __maybe_unused) 63 { 64 struct strlist *list; 65 struct str_node *pos; 66 char debugdir[PATH_MAX]; 67 char const *add_name_list_str = NULL, 68 *remove_name_list_str = NULL; 69 const struct option buildid_cache_options[] = { 70 OPT_STRING('a', "add", &add_name_list_str, 71 "file list", "file(s) to add"), 72 OPT_STRING('r', "remove", &remove_name_list_str, "file list", 73 "file(s) to remove"), 74 OPT_INCR('v', "verbose", &verbose, "be more verbose"), 75 OPT_END() 76 }; 77 const char * const buildid_cache_usage[] = { 78 "perf buildid-cache [<options>]", 79 NULL 80 }; 81 82 argc = parse_options(argc, argv, buildid_cache_options, 83 buildid_cache_usage, 0); 84 85 if (symbol__init() < 0) 86 return -1; 87 88 setup_pager(); 89 90 snprintf(debugdir, sizeof(debugdir), "%s", buildid_dir); 91 92 if (add_name_list_str) { 93 list = strlist__new(true, add_name_list_str); 94 if (list) { 95 strlist__for_each(pos, list) 96 if (build_id_cache__add_file(pos->s, debugdir)) { 97 if (errno == EEXIST) { 98 pr_debug("%s already in the cache\n", 99 pos->s); 100 continue; 101 } 102 pr_warning("Couldn't add %s: %s\n", 103 pos->s, strerror(errno)); 104 } 105 106 strlist__delete(list); 107 } 108 } 109 110 if (remove_name_list_str) { 111 list = strlist__new(true, remove_name_list_str); 112 if (list) { 113 strlist__for_each(pos, list) 114 if (build_id_cache__remove_file(pos->s, debugdir)) { 115 if (errno == ENOENT) { 116 pr_debug("%s wasn't in the cache\n", 117 pos->s); 118 continue; 119 } 120 pr_warning("Couldn't remove %s: %s\n", 121 pos->s, strerror(errno)); 122 } 123 124 strlist__delete(list); 125 } 126 } 127 128 return 0; 129 } 130