[PATCH v1 09/11] perf tools: Remove redundant chroot handling

From: Namhyung Kim

Date: Fri Oct 23 2026 - 03:21:41 EST


Now that nsinfo__mountns_enter() enters the target process's chroot
alongside its mount namespace, callers inside a mountns context no
longer need to manually prepend the target's root directory path via
dso__filename_with_chroot() or filename_with_chroot().

Remove dso__filename_with_chroot() and filename_with_chroot() and use
the DSO path directly within the mountns scope.

Assisted-by: LLM
Signed-off-by: Namhyung Kim <namhyung@xxxxxxxxxx>
---
tools/perf/util/dso.c | 29 ++---------------------------
tools/perf/util/dso.h | 2 --
tools/perf/util/symbol.c | 8 --------
tools/perf/util/util.c | 31 -------------------------------
tools/perf/util/util.h | 2 --
5 files changed, 2 insertions(+), 70 deletions(-)

diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index ce98613868e7d371..4331b48505b2b10e 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -585,11 +585,6 @@ static int do_open(char *name) EXCLUSIVE_LOCKS_REQUIRED(_dso__data_open_lock)
return -1;
}

-char *dso__filename_with_chroot(const struct dso *dso, const char *filename)
-{
- return filename_with_chroot(nsinfo__pid(dso__nsinfo_const(dso)), filename);
-}
-
char *dso__get_filename(struct dso *dso, const char *root_dir, bool *decomp,
enum dso_binary_type type)
{
@@ -603,28 +598,8 @@ char *dso__get_filename(struct dso *dso, const char *root_dir, bool *decomp,
if (dso__read_binary_type_filename(dso, type, root_dir, name, PATH_MAX))
goto out;

- if (!is_regular_file(name)) {
- struct stat st;
- char *new_name;
-
- /*
- * errno only reflects the failure reason when stat() itself
- * failed: a successful stat() on a non-regular file (e.g. a
- * directory) leaves a stale errno, which a previous failed
- * iteration of the try_to_open_dso() fallback loop may have
- * set to ENOENT.
- */
- if (stat(name, &st) == 0 || errno != ENOENT ||
- dso__nsinfo(dso) == NULL)
- goto out;
-
- new_name = dso__filename_with_chroot(dso, name);
- if (!new_name)
- goto out;
-
- free(name);
- name = new_name;
- }
+ if (!is_regular_file(name))
+ goto out;

if (dso__needs_decompress(dso)) {
char newpath[KMOD_DECOMP_LEN];
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
index 3329f417810c25a4..e53c83c23c578918 100644
--- a/tools/perf/util/dso.h
+++ b/tools/perf/util/dso.h
@@ -826,8 +826,6 @@ static inline bool dso__has_symbols(const struct dso *dso)
return !RB_EMPTY_ROOT(&RC_CHK_ACCESS(dso)->symbols.rb_root);
}

-char *dso__filename_with_chroot(const struct dso *dso, const char *filename);
-
bool dso__sorted_by_name(const struct dso *dso);
void dso__set_sorted_by_name(struct dso *dso);
void dso__sort_by_name(struct dso *dso);
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index b61a574ce9a30721..807e433c770812a4 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1902,14 +1902,6 @@ int dso__load(struct dso *dso, struct map *map)
nsinfo__mountns_exit(&nsc);

is_reg = is_regular_file(name);
- if (!is_reg && errno == ENOENT && dso__nsinfo(dso)) {
- char *new_name = dso__filename_with_chroot(dso, name);
- if (new_name) {
- is_reg = is_regular_file(new_name);
- strlcpy(name, new_name, PATH_MAX);
- free(new_name);
- }
- }

#ifdef HAVE_LIBBFD_SUPPORT
if (is_reg)
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index 8f7cd32f524dc10e..443b1d2b4748bfe4 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -451,37 +451,6 @@ void perf_debuginfod_setup(struct perf_debuginfod *di)
#endif
}

-/*
- * Return a new filename prepended with task's root directory if it's in
- * a chroot. Callers should free the returned string.
- */
-char *filename_with_chroot(int pid, const char *filename)
-{
- char buf[PATH_MAX];
- char proc_root[32];
- char *new_name = NULL;
- int ret;
-
- scnprintf(proc_root, sizeof(proc_root), "/proc/%d/root", pid);
- ret = readlink(proc_root, buf, sizeof(buf) - 1);
- if (ret <= 0)
- return NULL;
-
- /* readlink(2) does not append a null byte to buf */
- buf[ret] = '\0';
-
- if (!strcmp(buf, "/"))
- return NULL;
-
- if (strstr(buf, "(deleted)"))
- return NULL;
-
- if (asprintf(&new_name, "%s/%s", buf, filename) < 0)
- return NULL;
-
- return new_name;
-}
-
/*
* Reallocate an array *arr of size *arr_sz so that it is big enough to contain
* x elements of size msz, initializing new entries to *init_val or zero if
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index f8f1ff603c728086..b9adb58df976f29e 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -84,8 +84,6 @@ void perf_debuginfod_setup(struct perf_debuginfod *di);

const char *perf_basename(const char *path);

-char *filename_with_chroot(int pid, const char *filename);
-
int do_realloc_array_as_needed(void **arr, size_t *arr_sz, size_t x,
size_t msz, const void *init_val);

--
2.56.0.257.gf7497c7d27-goog