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