mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-03-05 05:09:02 +07:00
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:
parent
7335399a6a
commit
8d8c8e4cb3
@ -12,9 +12,9 @@ SYNOPSIS
|
|||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
-----------
|
-----------
|
||||||
This command manages the build-id cache. It can add and remove files to/from
|
This command manages the build-id cache. It can add, remove, update and purge
|
||||||
the cache. In the future it should as well purge older entries, set upper
|
files to/from the cache. In the future it should as well set upper limits for
|
||||||
limits for the space used by the cache, etc.
|
the space used by the cache, etc.
|
||||||
|
|
||||||
OPTIONS
|
OPTIONS
|
||||||
-------
|
-------
|
||||||
@ -36,7 +36,12 @@ OPTIONS
|
|||||||
actually made.
|
actually made.
|
||||||
-r::
|
-r::
|
||||||
--remove=::
|
--remove=::
|
||||||
Remove specified file from the cache.
|
Remove a cached binary which has same build-id of specified file
|
||||||
|
from the cache.
|
||||||
|
-p::
|
||||||
|
--purge=::
|
||||||
|
Purge all cached binaries including older caches which have specified
|
||||||
|
path from the cache.
|
||||||
-M::
|
-M::
|
||||||
--missing=::
|
--missing=::
|
||||||
List missing build ids in the cache for the specified file.
|
List missing build ids in the cache for the specified file.
|
||||||
|
@ -223,6 +223,33 @@ static int build_id_cache__remove_file(const char *filename)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int build_id_cache__purge_path(const char *pathname)
|
||||||
|
{
|
||||||
|
struct strlist *list;
|
||||||
|
struct str_node *pos;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = build_id_cache__list_build_ids(pathname, &list);
|
||||||
|
if (err)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
strlist__for_each(pos, list) {
|
||||||
|
err = build_id_cache__remove_s(pos->s);
|
||||||
|
if (verbose)
|
||||||
|
pr_info("Removing %s %s: %s\n", pos->s, pathname,
|
||||||
|
err ? "FAIL" : "Ok");
|
||||||
|
if (err)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
strlist__delete(list);
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (verbose)
|
||||||
|
pr_info("Purging %s: %s\n", pathname, err ? "FAIL" : "Ok");
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
static bool dso__missing_buildid_cache(struct dso *dso, int parm __maybe_unused)
|
static bool dso__missing_buildid_cache(struct dso *dso, int parm __maybe_unused)
|
||||||
{
|
{
|
||||||
char filename[PATH_MAX];
|
char filename[PATH_MAX];
|
||||||
@ -285,6 +312,7 @@ int cmd_buildid_cache(int argc, const char **argv,
|
|||||||
bool force = false;
|
bool force = false;
|
||||||
char const *add_name_list_str = NULL,
|
char const *add_name_list_str = NULL,
|
||||||
*remove_name_list_str = NULL,
|
*remove_name_list_str = NULL,
|
||||||
|
*purge_name_list_str = NULL,
|
||||||
*missing_filename = NULL,
|
*missing_filename = NULL,
|
||||||
*update_name_list_str = NULL,
|
*update_name_list_str = NULL,
|
||||||
*kcore_filename = NULL;
|
*kcore_filename = NULL;
|
||||||
@ -302,6 +330,8 @@ int cmd_buildid_cache(int argc, const char **argv,
|
|||||||
"file", "kcore file to add"),
|
"file", "kcore file to add"),
|
||||||
OPT_STRING('r', "remove", &remove_name_list_str, "file list",
|
OPT_STRING('r', "remove", &remove_name_list_str, "file list",
|
||||||
"file(s) to remove"),
|
"file(s) to remove"),
|
||||||
|
OPT_STRING('p', "purge", &purge_name_list_str, "path list",
|
||||||
|
"path(s) to remove (remove old caches too)"),
|
||||||
OPT_STRING('M', "missing", &missing_filename, "file",
|
OPT_STRING('M', "missing", &missing_filename, "file",
|
||||||
"to find missing build ids in the cache"),
|
"to find missing build ids in the cache"),
|
||||||
OPT_BOOLEAN('f', "force", &force, "don't complain, do it"),
|
OPT_BOOLEAN('f', "force", &force, "don't complain, do it"),
|
||||||
@ -368,6 +398,24 @@ int cmd_buildid_cache(int argc, const char **argv,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (purge_name_list_str) {
|
||||||
|
list = strlist__new(true, purge_name_list_str);
|
||||||
|
if (list) {
|
||||||
|
strlist__for_each(pos, list)
|
||||||
|
if (build_id_cache__purge_path(pos->s)) {
|
||||||
|
if (errno == ENOENT) {
|
||||||
|
pr_debug("%s wasn't in the cache\n",
|
||||||
|
pos->s);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
pr_warning("Couldn't remove %s: %s\n",
|
||||||
|
pos->s, strerror_r(errno, sbuf, sizeof(sbuf)));
|
||||||
|
}
|
||||||
|
|
||||||
|
strlist__delete(list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (missing_filename)
|
if (missing_filename)
|
||||||
ret = build_id_cache__fprintf_missing(session, stdout);
|
ret = build_id_cache__fprintf_missing(session, stdout);
|
||||||
|
|
||||||
|
@ -281,35 +281,93 @@ void disable_buildid_cache(void)
|
|||||||
no_buildid_cache = true;
|
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,
|
int build_id_cache__add_s(const char *sbuild_id, const char *name,
|
||||||
bool is_kallsyms, bool is_vdso)
|
bool is_kallsyms, bool is_vdso)
|
||||||
{
|
{
|
||||||
const size_t size = PATH_MAX;
|
const size_t size = PATH_MAX;
|
||||||
char *realname, *filename = zalloc(size),
|
char *realname = NULL, *filename = NULL, *dir_name = NULL,
|
||||||
*linkname = zalloc(size), *targetname, *tmp;
|
*linkname = zalloc(size), *targetname, *tmp;
|
||||||
int len, err = -1;
|
int err = -1;
|
||||||
bool slash = is_kallsyms || is_vdso;
|
|
||||||
|
|
||||||
if (is_kallsyms) {
|
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
|
|
||||||
realname = realpath(name, NULL);
|
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;
|
goto out_free;
|
||||||
|
|
||||||
len = scnprintf(filename, size, "%s%s%s",
|
if (mkdir_p(dir_name, 0755))
|
||||||
buildid_dir, slash ? "/" : "",
|
|
||||||
is_vdso ? DSO__NAME_VDSO : realname);
|
|
||||||
if (mkdir_p(filename, 0755))
|
|
||||||
goto out_free;
|
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 (access(filename, F_OK)) {
|
||||||
if (is_kallsyms) {
|
if (is_kallsyms) {
|
||||||
@ -337,6 +395,7 @@ int build_id_cache__add_s(const char *sbuild_id, const char *name,
|
|||||||
if (!is_kallsyms)
|
if (!is_kallsyms)
|
||||||
free(realname);
|
free(realname);
|
||||||
free(filename);
|
free(filename);
|
||||||
|
free(dir_name);
|
||||||
free(linkname);
|
free(linkname);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#define BUILD_ID_SIZE 20
|
#define BUILD_ID_SIZE 20
|
||||||
|
|
||||||
#include "tool.h"
|
#include "tool.h"
|
||||||
|
#include "strlist.h"
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
|
||||||
extern struct perf_tool build_id__mark_dso_hit_ops;
|
extern struct perf_tool build_id__mark_dso_hit_ops;
|
||||||
@ -22,6 +23,8 @@ bool perf_session__read_build_ids(struct perf_session *session, bool with_hits);
|
|||||||
int perf_session__write_buildid_table(struct perf_session *session, int fd);
|
int perf_session__write_buildid_table(struct perf_session *session, int fd);
|
||||||
int perf_session__cache_build_ids(struct perf_session *session);
|
int perf_session__cache_build_ids(struct perf_session *session);
|
||||||
|
|
||||||
|
int build_id_cache__list_build_ids(const char *pathname,
|
||||||
|
struct strlist **result);
|
||||||
bool build_id_cache__cached(const char *sbuild_id);
|
bool build_id_cache__cached(const char *sbuild_id);
|
||||||
int build_id_cache__add_s(const char *sbuild_id,
|
int build_id_cache__add_s(const char *sbuild_id,
|
||||||
const char *name, bool is_kallsyms, bool is_vdso);
|
const char *name, bool is_kallsyms, bool is_vdso);
|
||||||
|
Loading…
Reference in New Issue
Block a user