diff options
Diffstat (limited to 'tools/perf/util')
-rw-r--r-- | tools/perf/util/build-id.c | 47 | ||||
-rw-r--r-- | tools/perf/util/build-id.h | 9 | ||||
-rw-r--r-- | tools/perf/util/dso.c | 12 | ||||
-rw-r--r-- | tools/perf/util/parse-events.c | 2 | ||||
-rw-r--r-- | tools/perf/util/probe-event.c | 6 | ||||
-rw-r--r-- | tools/perf/util/probe-file.c | 19 | ||||
-rw-r--r-- | tools/perf/util/probe-file.h | 4 | ||||
-rw-r--r-- | tools/perf/util/python-ext-sources | 1 | ||||
-rw-r--r-- | tools/perf/util/symbol.c | 19 | ||||
-rw-r--r-- | tools/perf/util/util.c | 34 | ||||
-rw-r--r-- | tools/perf/util/util.h | 2 |
11 files changed, 110 insertions, 45 deletions
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index e0148b081bdf..f7bfd90a7388 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -534,13 +534,14 @@ char *build_id_cache__complement(const char *incomplete_sbuild_id) } char *build_id_cache__cachedir(const char *sbuild_id, const char *name, - bool is_kallsyms, bool is_vdso) + struct nsinfo *nsi, bool is_kallsyms, + bool is_vdso) { char *realname = (char *)name, *filename; bool slash = is_kallsyms || is_vdso; if (!slash) { - realname = realpath(name, NULL); + realname = nsinfo__realpath(name, nsi); if (!realname) return NULL; } @@ -556,13 +557,13 @@ char *build_id_cache__cachedir(const char *sbuild_id, const char *name, return filename; } -int build_id_cache__list_build_ids(const char *pathname, +int build_id_cache__list_build_ids(const char *pathname, struct nsinfo *nsi, struct strlist **result) { char *dir_name; int ret = 0; - dir_name = build_id_cache__cachedir(NULL, pathname, false, false); + dir_name = build_id_cache__cachedir(NULL, pathname, nsi, false, false); if (!dir_name) return -ENOMEM; @@ -576,16 +577,20 @@ int build_id_cache__list_build_ids(const char *pathname, #if defined(HAVE_LIBELF_SUPPORT) && defined(HAVE_GELF_GETNOTE_SUPPORT) static int build_id_cache__add_sdt_cache(const char *sbuild_id, - const char *realname) + const char *realname, + struct nsinfo *nsi) { struct probe_cache *cache; int ret; + struct nscookie nsc; - cache = probe_cache__new(sbuild_id); + cache = probe_cache__new(sbuild_id, nsi); if (!cache) return -1; + nsinfo__mountns_enter(nsi, &nsc); ret = probe_cache__scan_sdt(cache, realname); + nsinfo__mountns_exit(&nsc); if (ret >= 0) { pr_debug4("Found %d SDTs in %s\n", ret, realname); if (probe_cache__commit(cache) < 0) @@ -595,11 +600,11 @@ static int build_id_cache__add_sdt_cache(const char *sbuild_id, return ret; } #else -#define build_id_cache__add_sdt_cache(sbuild_id, realname) (0) +#define build_id_cache__add_sdt_cache(sbuild_id, realname, nsi) (0) #endif int build_id_cache__add_s(const char *sbuild_id, const char *name, - bool is_kallsyms, bool is_vdso) + struct nsinfo *nsi, bool is_kallsyms, bool is_vdso) { const size_t size = PATH_MAX; char *realname = NULL, *filename = NULL, *dir_name = NULL, @@ -607,13 +612,16 @@ int build_id_cache__add_s(const char *sbuild_id, const char *name, int err = -1; if (!is_kallsyms) { - realname = realpath(name, NULL); + if (!is_vdso) + realname = nsinfo__realpath(name, nsi); + else + realname = realpath(name, NULL); if (!realname) goto out_free; } - dir_name = build_id_cache__cachedir(sbuild_id, name, - is_kallsyms, is_vdso); + dir_name = build_id_cache__cachedir(sbuild_id, name, nsi, is_kallsyms, + is_vdso); if (!dir_name) goto out_free; @@ -634,7 +642,10 @@ int build_id_cache__add_s(const char *sbuild_id, const char *name, if (access(filename, F_OK)) { if (is_kallsyms) { - if (copyfile("/proc/kallsyms", filename)) + if (copyfile("/proc/kallsyms", filename)) + goto out_free; + } else if (nsi && nsi->need_setns) { + if (copyfile_ns(name, filename, nsi)) goto out_free; } else if (link(realname, filename) && errno != EEXIST && copyfile(name, filename)) @@ -657,7 +668,8 @@ int build_id_cache__add_s(const char *sbuild_id, const char *name, err = 0; /* Update SDT cache : error is just warned */ - if (realname && build_id_cache__add_sdt_cache(sbuild_id, realname) < 0) + if (realname && + build_id_cache__add_sdt_cache(sbuild_id, realname, nsi) < 0) pr_debug4("Failed to update/scan SDT cache for %s\n", realname); out_free: @@ -670,14 +682,15 @@ out_free: } static int build_id_cache__add_b(const u8 *build_id, size_t build_id_size, - const char *name, bool is_kallsyms, - bool is_vdso) + const char *name, struct nsinfo *nsi, + bool is_kallsyms, bool is_vdso) { char sbuild_id[SBUILD_ID_SIZE]; build_id__sprintf(build_id, build_id_size, sbuild_id); - return build_id_cache__add_s(sbuild_id, name, is_kallsyms, is_vdso); + return build_id_cache__add_s(sbuild_id, name, nsi, is_kallsyms, + is_vdso); } bool build_id_cache__cached(const char *sbuild_id) @@ -743,7 +756,7 @@ static int dso__cache_build_id(struct dso *dso, struct machine *machine) name = nm; } return build_id_cache__add_b(dso->build_id, sizeof(dso->build_id), name, - is_kallsyms, is_vdso); + dso->nsinfo, is_kallsyms, is_vdso); } static int __dsos__cache_build_ids(struct list_head *head, diff --git a/tools/perf/util/build-id.h b/tools/perf/util/build-id.h index 96690a55c62c..23970847d4c4 100644 --- a/tools/perf/util/build-id.h +++ b/tools/perf/util/build-id.h @@ -5,6 +5,7 @@ #define SBUILD_ID_SIZE (BUILD_ID_SIZE * 2 + 1) #include "tool.h" +#include "namespaces.h" #include <linux/types.h> extern struct perf_tool build_id__mark_dso_hit_ops; @@ -31,17 +32,19 @@ int perf_session__cache_build_ids(struct perf_session *session); char *build_id_cache__origname(const char *sbuild_id); char *build_id_cache__linkname(const char *sbuild_id, char *bf, size_t size); char *build_id_cache__cachedir(const char *sbuild_id, const char *name, - bool is_kallsyms, bool is_vdso); + struct nsinfo *nsi, bool is_kallsyms, + bool is_vdso); struct strlist; struct strlist *build_id_cache__list_all(bool validonly); char *build_id_cache__complement(const char *incomplete_sbuild_id); -int build_id_cache__list_build_ids(const char *pathname, +int build_id_cache__list_build_ids(const char *pathname, struct nsinfo *nsi, struct strlist **result); 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); + const char *name, struct nsinfo *nsi, + bool is_kallsyms, bool is_vdso); int build_id_cache__remove_s(const char *sbuild_id); extern char buildid_dir[]; diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index beda40ed63b0..dc9b49533a8f 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -504,7 +504,14 @@ static void check_data_close(void); */ static int open_dso(struct dso *dso, struct machine *machine) { - int fd = __open_dso(dso, machine); + int fd; + struct nscookie nsc; + + if (dso->binary_type != DSO_BINARY_TYPE__BUILD_ID_CACHE) + nsinfo__mountns_enter(dso->nsinfo, &nsc); + fd = __open_dso(dso, machine); + if (dso->binary_type != DSO_BINARY_TYPE__BUILD_ID_CACHE) + nsinfo__mountns_exit(&nsc); if (fd >= 0) { dso__list_add(dso); @@ -1302,6 +1309,7 @@ bool __dsos__read_build_ids(struct list_head *head, bool with_hits) { bool have_build_id = false; struct dso *pos; + struct nscookie nsc; list_for_each_entry(pos, head, node) { if (with_hits && !pos->hit && !dso__is_vdso(pos)) @@ -1310,11 +1318,13 @@ bool __dsos__read_build_ids(struct list_head *head, bool with_hits) have_build_id = true; continue; } + nsinfo__mountns_enter(pos->nsinfo, &nsc); if (filename__read_build_id(pos->long_name, pos->build_id, sizeof(pos->build_id)) > 0) { have_build_id = true; pos->has_build_id = true; } + nsinfo__mountns_exit(&nsc); } return have_build_id; diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 01e779b91c8e..84e301073885 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -2124,7 +2124,7 @@ void print_sdt_events(const char *subsys_glob, const char *event_glob, return; } strlist__for_each_entry(nd, bidlist) { - pcache = probe_cache__new(nd->s); + pcache = probe_cache__new(nd->s, NULL); if (!pcache) continue; list_for_each_entry(ent, &pcache->entries, node) { diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index a80895a7e611..d7cd1142f4c6 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -2769,7 +2769,7 @@ static int __add_probe_trace_events(struct perf_probe_event *pev, if (ret == -EINVAL && pev->uprobes) warn_uprobe_event_compat(tev); if (ret == 0 && probe_conf.cache) { - cache = probe_cache__new(pev->target); + cache = probe_cache__new(pev->target, pev->nsi); if (!cache || probe_cache__add_entry(cache, pev, tevs, ntevs) < 0 || probe_cache__commit(cache) < 0) @@ -3119,7 +3119,7 @@ static int find_cached_events(struct perf_probe_event *pev, int ntevs = 0; int ret = 0; - cache = probe_cache__new(target); + cache = probe_cache__new(target, pev->nsi); /* Return 0 ("not found") if the target has no probe cache. */ if (!cache) return 0; @@ -3209,7 +3209,7 @@ static int find_probe_trace_events_from_cache(struct perf_probe_event *pev, else return find_cached_events(pev, tevs, pev->target); } - cache = probe_cache__new(pev->target); + cache = probe_cache__new(pev->target, pev->nsi); if (!cache) return 0; diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c index d679389e627c..cdf8d83a484c 100644 --- a/tools/perf/util/probe-file.c +++ b/tools/perf/util/probe-file.c @@ -412,13 +412,15 @@ int probe_cache_entry__get_event(struct probe_cache_entry *entry, } /* For the kernel probe caches, pass target = NULL or DSO__NAME_KALLSYMS */ -static int probe_cache__open(struct probe_cache *pcache, const char *target) +static int probe_cache__open(struct probe_cache *pcache, const char *target, + struct nsinfo *nsi) { char cpath[PATH_MAX]; char sbuildid[SBUILD_ID_SIZE]; char *dir_name = NULL; bool is_kallsyms = false; int ret, fd; + struct nscookie nsc; if (target && build_id_cache__cached(target)) { /* This is a cached buildid */ @@ -431,8 +433,11 @@ static int probe_cache__open(struct probe_cache *pcache, const char *target) target = DSO__NAME_KALLSYMS; is_kallsyms = true; ret = sysfs__sprintf_build_id("/", sbuildid); - } else + } else { + nsinfo__mountns_enter(nsi, &nsc); ret = filename__sprintf_build_id(target, sbuildid); + nsinfo__mountns_exit(&nsc); + } if (ret < 0) { pr_debug("Failed to get build-id from %s.\n", target); @@ -441,7 +446,7 @@ static int probe_cache__open(struct probe_cache *pcache, const char *target) /* If we have no buildid cache, make it */ if (!build_id_cache__cached(sbuildid)) { - ret = build_id_cache__add_s(sbuildid, target, + ret = build_id_cache__add_s(sbuildid, target, nsi, is_kallsyms, NULL); if (ret < 0) { pr_debug("Failed to add build-id cache: %s\n", target); @@ -449,7 +454,7 @@ static int probe_cache__open(struct probe_cache *pcache, const char *target) } } - dir_name = build_id_cache__cachedir(sbuildid, target, is_kallsyms, + dir_name = build_id_cache__cachedir(sbuildid, target, nsi, is_kallsyms, false); found: if (!dir_name) { @@ -554,7 +559,7 @@ void probe_cache__delete(struct probe_cache *pcache) free(pcache); } -struct probe_cache *probe_cache__new(const char *target) +struct probe_cache *probe_cache__new(const char *target, struct nsinfo *nsi) { struct probe_cache *pcache = probe_cache__alloc(); int ret; @@ -562,7 +567,7 @@ struct probe_cache *probe_cache__new(const char *target) if (!pcache) return NULL; - ret = probe_cache__open(pcache, target); + ret = probe_cache__open(pcache, target, nsi); if (ret < 0) { pr_debug("Cache open error: %d\n", ret); goto out_err; @@ -974,7 +979,7 @@ int probe_cache__show_all_caches(struct strfilter *filter) return -EINVAL; } strlist__for_each_entry(nd, bidlist) { - pcache = probe_cache__new(nd->s); + pcache = probe_cache__new(nd->s, NULL); if (!pcache) continue; if (!list_empty(&pcache->entries)) { diff --git a/tools/perf/util/probe-file.h b/tools/perf/util/probe-file.h index 5ecc9d3925db..2ca4163abafe 100644 --- a/tools/perf/util/probe-file.h +++ b/tools/perf/util/probe-file.h @@ -51,7 +51,7 @@ int probe_file__del_strlist(int fd, struct strlist *namelist); int probe_cache_entry__get_event(struct probe_cache_entry *entry, struct probe_trace_event **tevs); -struct probe_cache *probe_cache__new(const char *target); +struct probe_cache *probe_cache__new(const char *target, struct nsinfo *nsi); int probe_cache__add_entry(struct probe_cache *pcache, struct perf_probe_event *pev, struct probe_trace_event *tevs, int ntevs); @@ -69,7 +69,7 @@ int probe_cache__show_all_caches(struct strfilter *filter); bool probe_type_is_available(enum probe_type type); bool kretprobe_offset_is_supported(void); #else /* ! HAVE_LIBELF_SUPPORT */ -static inline struct probe_cache *probe_cache__new(const char *tgt __maybe_unused) +static inline struct probe_cache *probe_cache__new(const char *tgt __maybe_unused, struct nsinfo *nsi __maybe_unused) { return NULL; } diff --git a/tools/perf/util/python-ext-sources b/tools/perf/util/python-ext-sources index 9f3b0d9754a8..e66dc495809a 100644 --- a/tools/perf/util/python-ext-sources +++ b/tools/perf/util/python-ext-sources @@ -10,6 +10,7 @@ util/ctype.c util/evlist.c util/evsel.c util/cpumap.c +util/namespaces.c ../lib/bitmap.c ../lib/find_bit.c ../lib/hweight.c diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 21c97cc41cfc..8c7bae545617 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1464,7 +1464,6 @@ static int dso__find_perf_map(char *filebuf, size_t bufsz, return rc; } - int dso__load(struct dso *dso, struct map *map) { char *name; @@ -1565,6 +1564,8 @@ int dso__load(struct dso *dso, struct map *map) for (i = 0; i < DSO_BINARY_TYPE__SYMTAB_CNT; i++) { struct symsrc *ss = &ss_[ss_pos]; bool next_slot = false; + bool is_reg; + int sirc; enum dso_binary_type symtab_type = binary_type_symtab[i]; @@ -1575,12 +1576,20 @@ int dso__load(struct dso *dso, struct map *map) root_dir, name, PATH_MAX)) continue; - if (!is_regular_file(name)) - continue; + if (symtab_type == DSO_BINARY_TYPE__BUILD_ID_CACHE) + nsinfo__mountns_exit(&nsc); + + is_reg = is_regular_file(name); + sirc = symsrc__init(ss, dso, name, symtab_type); - /* Name is now the name of the next image to try */ - if (symsrc__init(ss, dso, name, symtab_type) < 0) + if (symtab_type == DSO_BINARY_TYPE__BUILD_ID_CACHE) + nsinfo__mountns_enter(dso->nsinfo, &nsc); + + if (!is_reg || sirc < 0) { + if (sirc >= 0) + symsrc__destroy(ss); continue; + } if (!syms_ss && symsrc__has_symtab(ss)) { syms_ss = ss; diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index 988111e0bab5..9e4ea852f636 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c @@ -143,13 +143,17 @@ out: return list; } -static int slow_copyfile(const char *from, const char *to) +static int slow_copyfile(const char *from, const char *to, struct nsinfo *nsi) { int err = -1; char *line = NULL; size_t n; - FILE *from_fp = fopen(from, "r"), *to_fp; + FILE *from_fp, *to_fp; + struct nscookie nsc; + nsinfo__mountns_enter(nsi, &nsc); + from_fp = fopen(from, "r"); + nsinfo__mountns_exit(&nsc); if (from_fp == NULL) goto out; @@ -198,15 +202,21 @@ int copyfile_offset(int ifd, loff_t off_in, int ofd, loff_t off_out, u64 size) return size ? -1 : 0; } -int copyfile_mode(const char *from, const char *to, mode_t mode) +static int copyfile_mode_ns(const char *from, const char *to, mode_t mode, + struct nsinfo *nsi) { int fromfd, tofd; struct stat st; - int err = -1; + int err; char *tmp = NULL, *ptr = NULL; + struct nscookie nsc; - if (stat(from, &st)) + nsinfo__mountns_enter(nsi, &nsc); + err = stat(from, &st); + nsinfo__mountns_exit(&nsc); + if (err) goto out; + err = -1; /* extra 'x' at the end is to reserve space for '.' */ if (asprintf(&tmp, "%s.XXXXXXx", to) < 0) { @@ -227,11 +237,13 @@ int copyfile_mode(const char *from, const char *to, mode_t mode) goto out_close_to; if (st.st_size == 0) { /* /proc? do it slowly... */ - err = slow_copyfile(from, tmp); + err = slow_copyfile(from, tmp, nsi); goto out_close_to; } + nsinfo__mountns_enter(nsi, &nsc); fromfd = open(from, O_RDONLY); + nsinfo__mountns_exit(&nsc); if (fromfd < 0) goto out_close_to; @@ -248,6 +260,16 @@ out: return err; } +int copyfile_ns(const char *from, const char *to, struct nsinfo *nsi) +{ + return copyfile_mode_ns(from, to, 0755, nsi); +} + +int copyfile_mode(const char *from, const char *to, mode_t mode) +{ + return copyfile_mode_ns(from, to, mode, NULL); +} + int copyfile(const char *from, const char *to) { return copyfile_mode(from, to, 0755); diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 1e5fe1d9ec32..062dd20437f7 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -12,6 +12,7 @@ #include <stdarg.h> #include <linux/compiler.h> #include <linux/types.h> +#include "namespaces.h" /* General helper functions */ void usage(const char *err) __noreturn; @@ -33,6 +34,7 @@ struct strlist *lsdir(const char *name, bool (*filter)(const char *, struct dire bool lsdir_no_dot_filter(const char *name, struct dirent *d); int copyfile(const char *from, const char *to); int copyfile_mode(const char *from, const char *to, mode_t mode); +int copyfile_ns(const char *from, const char *to, struct nsinfo *nsi); int copyfile_offset(int fromfd, loff_t from_ofs, int tofd, loff_t to_ofs, u64 size); ssize_t readn(int fd, void *buf, size_t n); |