perf-buildid-cache: Cleanup, enhance --update and add --remove-all
cover perf-buildid-cache: Cleanup, enhance --update and add --remove-all
Hi,
Here is a sereis of patches for perf buildid-cache update. I'm moving ahead to integrated perf-cache, but before that current buildid-cache code should be cleaned up and change a bit.
The first 2 patches are cleanup code, just reducing the redundant code. The 3rd one modifies --update option not to fail but just add new binary if there is no cache entry which has same build-id of given binary. The 4th one adds --remove-all option which allows us to cleanup all caches which related to given path.
Thank you,
---
Masami Hiramatsu (4):
perf-buildid-cache: Remove unneeded debugdir parameters perf buildid-cache: Consolidate .build-id cache path generators perf buildid-cache: Add new buildid cache if update target is not cached perf buildid-cache: Add --remove-all FILE to remove all caches of FILE
tools/perf/Documentation/perf-buildid-cache.txt | 8 + tools/perf/builtin-buildid-cache.c | 85 ++++++++-- tools/perf/util/build-id.c | 187 ++++++++++++++++------- tools/perf/util/build-id.h | 6 - 4 files changed, 208 insertions(+), 78 deletions(-)
--
Masami HIRAMATSU
Software Platform Research Dpt. Linux Technology Center Hitachi, Ltd., Yokohama Research Laboratory
E-mail: [email protected]
PATCH 1/4 perf-buildid-cache: Remove unneeded debugdir parameters
Functions related to buildid-cache subcommand use debugdir parameters for passing buildid cache directory path. However all callers just pass buildid_dir global variable. Moreover, other functions which refer buildid cache use buildid_dir directly.
This removes unneeded debugdir parameters from those functions and use buildid_dir if needed.
--- tools/perf/builtin-buildid-cache.c | 37 +++++++++++++----------------- tools/perf/util/build-id.c | 44 ++++++++++++++++-------------------- tools/perf/util/build-id.h | 4 ++- 3 files changed, 38 insertions(+), 47 deletions(-)
tools/perf/builtin-buildid-cache.c +16 -21
@@ -125,8 +125,7 @@ static int build_id_cache__kcore_existing(const char *from_dir, char *to_dir,return ret; } -static int build_id_cache__add_kcore (const char *filename,const char *debugdir, -bool force) +static int build_id_cache__add_kcore (const char *filename,bool force) {char dir[32 ], sbuildid[BUILD_ID_SIZE *2 +1 ];char from_dir[PATH_MAX ], to_dir[PATH_MAX ];
@@ -143,7 +142,7 @@ static int build_id_cache__add_kcore(const char *filename, const char *debugdir,return -1 ;scnprintf (to_dir,sizeof (to_dir),"%s/[kernel.kcore]/%s" , - debugdir, sbuildid); + buildid_dir, sbuildid);if (!force && !build_id_cache__kcore_existing (from_dir, to_dir,sizeof (to_dir))) {
@@ -155,7 +154,7 @@ static int build_id_cache__add_kcore(const char *filename, const char *debugdir,return -1 ;scnprintf (to_dir,sizeof (to_dir),"%s/[kernel.kcore]/%s/%s" , - debugdir, sbuildid, dir); + buildid_dir, sbuildid, dir);if (mkdir_p (to_dir,0755 ))return -1 ;
@@ -183,7 +182,7 @@ static int build_id_cache__add_kcore(const char *filename, const char *debugdir,return 0 ; } -static int build_id_cache__add_file (const char *filename,const char *debugdir) +static int build_id_cache__add_file (const char *filename) {char sbuild_id[BUILD_ID_SIZE *2 +1 ];u8 build_id[BUILD_ID_SIZE ];
@@ -195,7 +194,7 @@ static int build_id_cache__add_file(const char *filename, const char *debugdir) }build_id__sprintf (build_id,sizeof (build_id), sbuild_id); - err =build_id_cache__add_s (sbuild_id, debugdir, filename, + err =build_id_cache__add_s (sbuild_id, filename, false, false);if (verbose) pr_info("Adding %s %s: %s\n", sbuild_id, filename,
@@ -203,8 +202,7 @@ static int build_id_cache__add_file(const char *filename, const char *debugdir)return err; } -static int build_id_cache__remove_file (const char *filename, -const char *debugdir) +static int build_id_cache__remove_file (const char *filename) {u8 build_id[BUILD_ID_SIZE ];char sbuild_id[BUILD_ID_SIZE *2 +1 ];
@@ -217,7 +215,7 @@ static int build_id_cache__remove_file(const char *filename, }build_id__sprintf (build_id,sizeof (build_id), sbuild_id); - err =build_id_cache__remove_s (sbuild_id, debugdir); + err =build_id_cache__remove_s (sbuild_id);if (verbose)pr_info ("Removing %s %s: %s\n" , sbuild_id, filename, err ?"FAIL" :"Ok" );
@@ -252,8 +250,7 @@ static int build_id_cache__fprintf_missing(struct perf_session *session, FILE *freturn 0 ; } -static int build_id_cache__update_file (const char *filename, -const char *debugdir) +static int build_id_cache__update_file (const char *filename) {u8 build_id[BUILD_ID_SIZE ];char sbuild_id[BUILD_ID_SIZE *2 +1 ];
@@ -266,11 +263,10 @@ static int build_id_cache__update_file(const char *filename, }build_id__sprintf (build_id,sizeof (build_id), sbuild_id); - err =build_id_cache__remove_s (sbuild_id, debugdir); -if (!err) { - err =build_id_cache__add_s (sbuild_id, debugdir, filename, - false, false); - } + err =build_id_cache__remove_s (sbuild_id); +if (!err) + err =build_id_cache__add_s (sbuild_id, filename, false, false); +if (verbose)pr_info ("Updating %s %s: %s\n" , sbuild_id, filename, err ?"FAIL" :"Ok" );
@@ -338,7 +334,7 @@ int cmd_buildid_cache(int argc, const char **argv, list =strlist__new (true, add_name_list_str);if (list) {strlist__for_each (pos, list) -if (build_id_cache__add_file (pos->s, buildid_dir)) { +if (build_id_cache__add_file (pos->s)) {if (errno ==EEXIST ) {pr_debug ("%s already in the cache\n" , pos->s);
@@ -356,7 +352,7 @@ int cmd_buildid_cache(int argc, const char **argv, list =strlist__new (true, remove_name_list_str);if (list) {strlist__for_each (pos, list) -if (build_id_cache__remove_file (pos->s, buildid_dir)) { +if (build_id_cache__remove_file (pos->s)) {if (errno ==ENOENT ) {pr_debug ("%s wasn't in the cache\n" , pos->s);
@@ -377,7 +373,7 @@ int cmd_buildid_cache(int argc, const char **argv, list =strlist__new (true, update_name_list_str);if (list) {strlist__for_each (pos, list) -if (build_id_cache__update_file (pos->s, buildid_dir)) { +if (build_id_cache__update_file (pos->s)) {if (errno ==ENOENT ) {pr_debug ("%s wasn't in the cache\n" , pos->s);
@@ -391,8 +387,7 @@ int cmd_buildid_cache(int argc, const char **argv, } } -if (kcore_filename && -build_id_cache__add_kcore (kcore_filename, buildid_dir, force)) +if (kcore_filename &&build_id_cache__add_kcore (kcore_filename, force))pr_warning ("Couldn't add %s\n" , kcore_filename); out:
tools/perf/util/build-id.c +20 -24
127 lines not on this page · raw message
tools/perf/util/build-id.h +2 -2
@@ -22,9 +22,9 @@ 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__cache_build_ids (struct perf_session *session); -int build_id_cache__add_s (const char *sbuild_id,const char *debugdir, +int build_id_cache__add_s (const char *sbuild_id,const char *name,bool is_kallsyms,bool is_vdso); -int build_id_cache__remove_s (const char *sbuild_id,const char *debugdir); +int build_id_cache__remove_s (const char *sbuild_id);void disable_buildid_cache (void );#endif
PATCH 2/4 perf buildid-cache: Consolidate .build-id cache path generators
In reply to Masami HiramatsuConsolidate .build-id cache path generating routines to build_id__filename() function. Other functions must use it to get the buildid cache path (link path) from build-id. This can reduce the risk of partial-update.
--- tools/perf/util/build-id.c | 58 +++++++++++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 17 deletions(-)
tools/perf/util/build-id.c +41 -17
@@ -93,6 +93,35 @@ int build_id__sprintf(const u8 *build_id, int len, char *bf)return raw - build_id; } +/* asnprintf consolidates asprintf and snprintf */ +static int asnprintf (char **strp,size_t size,const char *fmt, ...) +{ +va_list ap; +int ret; + +if (!strp) +return -EINVAL ; + +va_start (ap, fmt); +if (*strp) + ret =vsnprintf (*strp, size, fmt, ap); +else + ret =vasprintf (strp, fmt, ap); +va_end (ap); + +return ret; +} + +static char *build_id__filename (const char *sbuild_id,char *bf,size_t size) +{ +char *tmp = bf; +int ret =asnprintf (&bf, size,"%s/.build-id/%.2s/%s" , buildid_dir, + sbuild_id, sbuild_id +2 ); +if (ret <0 || (tmp && size < (unsigned int )ret)) +return NULL ; +return bf; +} +char *dso__build_id_filename (const struct dso *dso,char *bf,size_t size) {char build_id_hex[BUILD_ID_SIZE *2 +1 ];
@@ -101,14 +130,7 @@ char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size)return NULL ;build_id__sprintf (dso->build_id,sizeof (dso->build_id), build_id_hex); -if (bf ==NULL ) { -if (asprintf (&bf,"%s/.build-id/%.2s/%s" , buildid_dir, - build_id_hex, build_id_hex +2 ) <0 ) -return NULL ; - }else -snprintf (bf, size,"%s/.build-id/%.2s/%s" , buildid_dir, - build_id_hex, build_id_hex +2 ); -return bf; +return build_id__filename (build_id_hex, bf, size); }#define dsos__for_each_with_build_id (pos, head) \
@@ -264,7 +286,7 @@ int build_id_cache__add_s(const char *sbuild_id, const char *name, {const size_t size =PATH_MAX ;char *realname, *filename =zalloc (size), - *linkname =zalloc (size), *targetname; + *linkname =zalloc (size), *targetname, *tmp;int len, err =-1 ;bool slash = is_kallsyms || is_vdso;
@@ -297,13 +319,15 @@ int build_id_cache__add_s(const char *sbuild_id, const char *name, goto out_free; } - len =scnprintf (linkname, size,"%s/.build-id/%.2s" , - buildid_dir, sbuild_id); +if (!build_id__filename (sbuild_id, linkname, size)) + goto out_free; + tmp =strrchr (linkname,'/' ); + *tmp ='\0' ;if (access (linkname,X_OK ) &&mkdir_p (linkname,0755 )) goto out_free; -snprintf (linkname + len, size - len,"/%s" , sbuild_id +2 ); + *tmp ='/' ; targetname = filename +strlen (buildid_dir) -5 ;memcpy (targetname,"../.." ,5 );
@@ -332,14 +356,14 @@ int build_id_cache__remove_s(const char *sbuild_id) {const size_t size =PATH_MAX ;char *filename =zalloc (size), - *linkname =zalloc (size); + *linkname =zalloc (size), *tmp;int err =-1 ;if (filename ==NULL || linkname ==NULL ) goto out_free; -snprintf (linkname, size,"%s/.build-id/%.2s/%s" , - buildid_dir, sbuild_id, sbuild_id +2 ); +if (!build_id__filename (sbuild_id, linkname, size)) + goto out_free;if (access (linkname,F_OK )) goto out_free;
@@ -353,8 +377,8 @@ int build_id_cache__remove_s(const char *sbuild_id)/* * Since the link is relative, we must make it absolute: */ -snprintf (linkname, size,"%s/.build-id/%.2s/%s" , - buildid_dir, sbuild_id, filename); + tmp =strrchr (linkname,'/' ) +1 ; +snprintf (tmp, size - (tmp - linkname),"%s" , filename);if (unlink (linkname)) goto out_free;
PATCH 3/4 perf buildid-cache: Add new buildid cache if update target is not cached
In reply to Masami HiramatsuAdd new buildid cache if the update target file is not cached. This can happen when an old binary is replaced by new one after caching the old one. In this case, user sees his operation just failed. But it does not look straight, since user just pass the binary "path", not "build-id".
----
# ./perf buildid-cache --add ./perf (update ./perf to new binary) # ./perf buildid-cache --update ./perf ./perf wasn't in the cache # ----
This patch adds given new binary to cache if the new binary is not cached. So we'll not see the above error.
----
# ./perf buildid-cache --add ./perf (update ./perf to new binary) # ./perf buildid-cache --update ./perf # ----
--- tools/perf/Documentation/perf-buildid-cache.txt | 2 ++ tools/perf/builtin-buildid-cache.c | 6 ++++-- tools/perf/util/build-id.c | 12 ++++++++++++ tools/perf/util/build-id.h | 1 + 4 files changed, 19 insertions(+), 2 deletions(-)
tools/perf/Documentation/perf-buildid-cache.txt +2 -0
@@ -44,6 +44,8 @@ OPTIONS --update:: Update specified file of the cache. It can be used to update kallsyms kernel dso to vmlinux in order to support annotation. + If there is no cache which has given binary's build-id, this just adds + new one. -v:: --verbose:: Be more verbose.
tools/perf/builtin-buildid-cache.c +4 -2
@@ -255,7 +255,7 @@ static int build_id_cache__update_file(const char *filename)u8 build_id[BUILD_ID_SIZE ];char sbuild_id[BUILD_ID_SIZE *2 +1 ]; -int err; +int err =0 ;if (filename__read_build_id (filename, &build_id,sizeof (build_id)) <0 ) {pr_debug ("Couldn't read a build-id in %s\n" , filename);
@@ -263,7 +263,9 @@ static int build_id_cache__update_file(const char *filename) }build_id__sprintf (build_id,sizeof (build_id), sbuild_id); - err =build_id_cache__remove_s (sbuild_id); +if (build_id_cache__cached (sbuild_id)) + err =build_id_cache__remove_s (sbuild_id); +if (!err) err =build_id_cache__add_s (sbuild_id, filename, false, false);
tools/perf/util/build-id.c +12 -0
@@ -352,6 +352,18 @@ static int build_id_cache__add_b(const u8 *build_id, size_t build_id_size,return build_id_cache__add_s (sbuild_id, name, is_kallsyms, is_vdso); } +bool build_id_cache__cached (const char *sbuild_id) +{ +bool ret = false; +char *filename =build_id__filename (sbuild_id,NULL ,0 ); + +if (filename && !access (filename,F_OK )) + ret = true; +free (filename); + +return ret; +} +int build_id_cache__remove_s (const char *sbuild_id) {const size_t size =PATH_MAX ;
tools/perf/util/build-id.h +1 -0
@@ -22,6 +22,7 @@ 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__cache_build_ids (struct perf_session *session); +bool build_id_cache__cached (const char *sbuild_id);int build_id_cache__add_s (const char *sbuild_id,const char *name,bool is_kallsyms,bool is_vdso);int build_id_cache__remove_s (const char *sbuild_id);
PATCH 4/4 perf buildid-cache: Add --remove-all FILE to remove all caches of FILE
In reply to Masami HiramatsuAdd --remove-all 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 --remove-all FILE action for such usecase. perf buildid-cache --remove-all 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 --remove-all ./perf Removing 133b7b5486d987a5ab5c3ebf4ea14941f45d4d4f ./perf: Ok -----
--- tools/perf/Documentation/perf-buildid-cache.txt | 6 +- tools/perf/builtin-buildid-cache.c | 44 ++++++++++++ tools/perf/util/build-id.c | 81 ++++++++++++++++++----- tools/perf/util/build-id.h | 1 4 files changed, 115 insertions(+), 17 deletions(-)
tools/perf/Documentation/perf-buildid-cache.txt +5 -1
@@ -36,7 +36,11 @@ OPTIONS actually made. -r:: --remove=:: - Remove specified file from the cache. + Remove a cached binary which has same build-id of specified file + from the cache. +-R:: +--remove-all=:: + Remove all cached binary which has specified path from the cache. -M:: --missing=:: List missing build ids in the cache for the specified file.
tools/perf/builtin-buildid-cache.c +44 -0
68 lines not on this page · raw message
tools/perf/util/build-id.c +65 -16
100 lines not on this page · raw message
tools/perf/util/build-id.h +1 -0
@@ -22,6 +22,7 @@ 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__cache_build_ids (struct perf_session *session); +struct strlist *build_id_cache__list_build_ids (const char *pathname);bool build_id_cache__cached (const char *sbuild_id);int build_id_cache__add_s (const char *sbuild_id,const char *name,bool is_kallsyms,bool is_vdso);
Namhyung Kim
maintainerRe: [perf/core PATCH 4/4] perf buildid-cache: Add --remove-all FILE to remove all caches of FILE
Hi Masami,
Quoted 144 lines · Masami Hiramatsu
Add --remove-all 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 --remove-all FILE action for such usecase. perf buildid-cache --remove-all 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 --remove-all ./perf Removing 133b7b5486d987a5ab5c3ebf4ea14941f45d4d4f ./perf: Ok -----Signed-off-by Masami Hiramatsu <[email protected]>--- tools/perf/Documentation/perf-buildid-cache.txt | 6 +- tools/perf/builtin-buildid-cache.c | 44 ++++++++++++ tools/perf/util/build-id.c | 81 ++++++++++++++++++----- tools/perf/util/build-id.h | 1 4 files changed, 115 insertions(+), 17 deletions(-)tools/perf/Documentation/perf-buildid-cache.txt +5
-1@@ -36,7 +36,11 @@ OPTIONS actually made. -r:: --remove=:: - Remove specified file from the cache. + Remove a cached binary which has same build-id of specified file + from the cache. +-R:: +--remove-all=:: + Remove all cached binary which has specified path from the cache. -M:: --missing=:: List missing build ids in the cache for the specified file.tools/perf/builtin-buildid-cache.c +44
-0@@ -223,6 +223,29 @@ static int build_id_cache__remove_file(const char *filename)return err; } +static int build_id_cache__remove_path (const char *pathname) +{ +struct strlist *list; +struct str_node *pos; +int err; + + list =build_id_cache__list_build_ids (pathname); +if (!list) +return 0 ; + +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); + +return err; +} +static bool dso__missing_buildid_cache (struct dso *dso,int parm__maybe_unused ) {char filename[PATH_MAX ];@@ -285,6 +308,7 @@ int cmd_buildid_cache(int argc, const char **argv,bool force = false;char const *add_name_list_str =NULL , *remove_name_list_str =NULL , + *remove_all_name_list_str =NULL , *missing_filename =NULL , *update_name_list_str =NULL , *kcore_filename =NULL ;@@ -302,6 +326,8 @@ int cmd_buildid_cache(int argc, const char **argv, "file", "kcore file to add"),OPT_STRING ('r' ,"remove" , &remove_name_list_str,"file list" ,"file(s) to remove" ), +OPT_STRING ('R' ,"remove-all" , &remove_all_name_list_str,"path list" , +"path(s) to remove (remove old caches too)" ),OPT_STRING ('M' ,"missing" , &missing_filename,"file" ,"to find missing build ids in the cache" ), OPT_BOOLEAN('f', "force", &force, "don't complain, do it"),@@ -368,6 +394,24 @@ int cmd_buildid_cache(int argc, const char **argv, } } +if (remove_all_name_list_str) { + list =strlist__new (true, remove_all_name_list_str); +if (list) { +strlist__for_each (pos, list) +if (build_id_cache__remove_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) ret =build_id_cache__fprintf_missing (session, stdout);tools/perf/util/build-id.c +6
-0@@ -281,35 +281,84 @@ 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; +
tools/perf/util/build-id.c void disable_buildid_cache(void) · line 299
Quoted 10 lines
tools/perf/util/build-id.c +10
-0+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 ; +free (realname);
Shouldn't it be:
if (!slash) free(realname);
?
Thanks,
Namhyung
Quoted 99 lines
tools/perf/util/build-id.c +49
-16+ +return filename; +} + +struct strlist *build_id_cache__list_build_ids (const char *pathname) +{ +struct strlist *list; +char *dirname; +DIR *dir; +struct dirent *d; + + list =strlist__new (true,NULL ); + dirname =build_id_cache__dirname_from_path (pathname, false, false); +if (!list || !dirname) + goto error_free; + +/* List up all dirents */ + dir =opendir (dirname); +if (!dir) + goto error_free; +while ((d =readdir (dir)) !=NULL ) { +if (!strcmp (d->d_name,"." ) || !strcmp (d->d_name,".." )) +continue ; +strlist__add (list, d->d_name); + } +closedir (dir); + +free (dirname); +return list; + +error_free: +free (dirname); +if (list) +strlist__delete (list); +return NULL ; +} +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 , *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 ) + filename =build_id_cache__dirname_from_path (name, is_kallsyms, is_vdso); +if (!filename) goto out_free; - len =scnprintf (filename, size,"%s%s%s" , - buildid_dir, slash ?"/" :"" , - is_vdso ?DSO__NAME_VDSO : realname);if (mkdir_p (filename,0755 )) goto out_free; -snprintf (filename + len, size - len,"/%s" , sbuild_id); +if (asprintf (&filename,"%s/%s" , filename, sbuild_id) <0 ) { + filename =NULL ; + goto out_free; + }if (access (filename,F_OK )) {if (is_kallsyms) {tools/perf/util/build-id.h +1
-1@@ -22,6 +22,7 @@ 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__cache_build_ids (struct perf_session *session); +struct strlist *build_id_cache__list_build_ids (const char *pathname);bool build_id_cache__cached (const char *sbuild_id);int build_id_cache__add_s (const char *sbuild_id,const char *name,bool is_kallsyms,bool is_vdso); --To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Re: Re: [perf/core PATCH 4/4] perf buildid-cache: Add --remove-all FILE to remove all caches of FILE
Quoted 160 lines · Namhyung Kim
Hi Masami,
Quoted 144 lines · Masami Hiramatsu
Add --remove-all 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 --remove-all FILE action for such usecase. perf buildid-cache --remove-all 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 --remove-all ./perf Removing 133b7b5486d987a5ab5c3ebf4ea14941f45d4d4f ./perf: Ok -----Signed-off-by Masami Hiramatsu <[email protected]>--- tools/perf/Documentation/perf-buildid-cache.txt | 6 +- tools/perf/builtin-buildid-cache.c | 44 ++++++++++++ tools/perf/util/build-id.c | 81 ++++++++++++++++++----- tools/perf/util/build-id.h | 1 4 files changed, 115 insertions(+), 17 deletions(-)tools/perf/Documentation/perf-buildid-cache.txt +5
-1@@ -36,7 +36,11 @@ OPTIONS actually made. -r:: --remove=:: - Remove specified file from the cache. + Remove a cached binary which has same build-id of specified file + from the cache. +-R:: +--remove-all=:: + Remove all cached binary which has specified path from the cache. -M:: --missing=:: List missing build ids in the cache for the specified file.tools/perf/builtin-buildid-cache.c +44
-0@@ -223,6 +223,29 @@ static int build_id_cache__remove_file(const char *filename)return err; } +static int build_id_cache__remove_path (const char *pathname) +{ +struct strlist *list; +struct str_node *pos; +int err; + + list =build_id_cache__list_build_ids (pathname); +if (!list) +return 0 ; + +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); + +return err; +} +static bool dso__missing_buildid_cache (struct dso *dso,int parm__maybe_unused ) {char filename[PATH_MAX ];@@ -285,6 +308,7 @@ int cmd_buildid_cache(int argc, const char **argv,bool force = false;char const *add_name_list_str =NULL , *remove_name_list_str =NULL , + *remove_all_name_list_str =NULL , *missing_filename =NULL , *update_name_list_str =NULL , *kcore_filename =NULL ;@@ -302,6 +326,8 @@ int cmd_buildid_cache(int argc, const char **argv, "file", "kcore file to add"),OPT_STRING ('r' ,"remove" , &remove_name_list_str,"file list" ,"file(s) to remove" ), +OPT_STRING ('R' ,"remove-all" , &remove_all_name_list_str,"path list" , +"path(s) to remove (remove old caches too)" ),OPT_STRING ('M' ,"missing" , &missing_filename,"file" ,"to find missing build ids in the cache" ), OPT_BOOLEAN('f', "force", &force, "don't complain, do it"),@@ -368,6 +394,24 @@ int cmd_buildid_cache(int argc, const char **argv, } } +if (remove_all_name_list_str) { + list =strlist__new (true, remove_all_name_list_str); +if (list) { +strlist__for_each (pos, list) +if (build_id_cache__remove_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) ret =build_id_cache__fprintf_missing (session, stdout);tools/perf/util/build-id.c +6
-0@@ -281,35 +281,84 @@ 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; +tools/perf/util/build-id.c void disable_buildid_cache(void) · line 299
Quoted 10 lines
tools/perf/util/build-id.c +10
-0+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 ; +free (realname);Shouldn't it be:
Quoted 2 lines
if (!slash) free(realname);
Ah! right:)
Thank you
Signature · 4 lines
Masami HIRAMATSU Software Platform Research Dept. Linux Technology Research Center Hitachi, Ltd., Yokohama Research Laboratory E-mail: [email protected]