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 <masami.hiramatsu.pt@hitachi.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: Hemant Kumar <hemant@linux.vnet.ibm.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
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 <acme@redhat.com>
This commit is contained in:
Masami Hiramatsu
2015-02-27 13:50:26 +09:00
committed by Arnaldo Carvalho de Melo
parent 7335399a6a
commit 8d8c8e4cb3
4 changed files with 136 additions and 21 deletions

View File

@@ -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;
}