From 8d8c8e4cb3014fcc51f0e127b4316043306f5bb0 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Fri, 27 Feb 2015 13:50:26 +0900 Subject: perf buildid-cache: Add --purge FILE to remove all caches of FILE Add --purge FILE to remove all caches of FILE. Since the current --remove FILE removes a cache which has same build-id of given FILE. Since the command takes a FILE path, it can confuse user who tries to remove cache about FILE path. ----- # ./perf buildid-cache -v --add ./perf Adding 133b7b5486d987a5ab5c3ebf4ea14941f45d4d4f ./perf: Ok # (update the ./perf binary) # ./perf buildid-cache -v --remove ./perf Removing 305bbd1be68f66eca7e2d78db294653031edfa79 ./perf: FAIL ./perf wasn't in the cache ----- Actually, the --remove's FAIL is not shown, it just silently fails. So, this patch adds --purge FILE action for such usecase. perf buildid-cache --purge FILE removes all caches which has same FILE path. In other words, it removes all caches including old binaries. ----- # ./perf buildid-cache -v --add ./perf Adding 133b7b5486d987a5ab5c3ebf4ea14941f45d4d4f ./perf: Ok # (update the ./perf binary) # ./perf buildid-cache -v --purge ./perf Removing 133b7b5486d987a5ab5c3ebf4ea14941f45d4d4f ./perf: Ok ----- BTW, if you want to purge all the caches, remove ~/.debug/* . Signed-off-by: Masami Hiramatsu Cc: Adrian Hunter Cc: Borislav Petkov Cc: Hemant Kumar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20150227045026.1999.64084.stgit@localhost.localdomain [ s/dirname/dir_name/g to fix build on fedora14, where dirname is a global ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/build-id.c | 93 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 76 insertions(+), 17 deletions(-) (limited to 'tools/perf/util/build-id.c') diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index 0bc33be5a78c..ffdc338df925 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -281,35 +281,93 @@ void disable_buildid_cache(void) no_buildid_cache = true; } +static char *build_id_cache__dirname_from_path(const char *name, + bool is_kallsyms, bool is_vdso) +{ + char *realname = (char *)name, *filename; + bool slash = is_kallsyms || is_vdso; + + if (!slash) { + realname = realpath(name, NULL); + if (!realname) + return NULL; + } + + if (asprintf(&filename, "%s%s%s", buildid_dir, slash ? "/" : "", + is_vdso ? DSO__NAME_VDSO : realname) < 0) + filename = NULL; + + if (!slash) + free(realname); + + return filename; +} + +int build_id_cache__list_build_ids(const char *pathname, + struct strlist **result) +{ + struct strlist *list; + char *dir_name; + DIR *dir; + struct dirent *d; + int ret = 0; + + list = strlist__new(true, NULL); + dir_name = build_id_cache__dirname_from_path(pathname, false, false); + if (!list || !dir_name) { + ret = -ENOMEM; + goto out; + } + + /* List up all dirents */ + dir = opendir(dir_name); + if (!dir) { + ret = -errno; + goto out; + } + + while ((d = readdir(dir)) != NULL) { + if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, "..")) + continue; + strlist__add(list, d->d_name); + } + closedir(dir); + +out: + free(dir_name); + if (ret) + strlist__delete(list); + else + *result = list; + + return ret; +} + int build_id_cache__add_s(const char *sbuild_id, const char *name, bool is_kallsyms, bool is_vdso) { const size_t size = PATH_MAX; - char *realname, *filename = zalloc(size), + char *realname = NULL, *filename = NULL, *dir_name = NULL, *linkname = zalloc(size), *targetname, *tmp; - int len, err = -1; - bool slash = is_kallsyms || is_vdso; + int err = -1; - if (is_kallsyms) { - if (symbol_conf.kptr_restrict) { - pr_debug("Not caching a kptr_restrict'ed /proc/kallsyms\n"); - err = 0; - goto out_free; - } - realname = (char *) name; - } else + if (!is_kallsyms) { realname = realpath(name, NULL); + if (!realname) + goto out_free; + } - if (realname == NULL || filename == NULL || linkname == NULL) + dir_name = build_id_cache__dirname_from_path(name, is_kallsyms, is_vdso); + if (!dir_name) goto out_free; - len = scnprintf(filename, size, "%s%s%s", - buildid_dir, slash ? "/" : "", - is_vdso ? DSO__NAME_VDSO : realname); - if (mkdir_p(filename, 0755)) + if (mkdir_p(dir_name, 0755)) goto out_free; - snprintf(filename + len, size - len, "/%s", sbuild_id); + if (asprintf(&filename, "%s/%s", dir_name, sbuild_id) < 0) { + filename = NULL; + goto out_free; + } if (access(filename, F_OK)) { if (is_kallsyms) { @@ -337,6 +395,7 @@ out_free: if (!is_kallsyms) free(realname); free(filename); + free(dir_name); free(linkname); return err; } -- cgit v1.2.3-59-g8ed1b