From: Ilya Leoshkevich <iii@linux.ibm.com>
To: Steven Rostedt <rostedt@goodmis.org>
Cc: linux-trace-devel@vger.kernel.org,
Heiko Carstens <hca@linux.ibm.com>,
Vasily Gorbik <gor@linux.ibm.com>,
Alexander Gordeev <agordeev@linux.ibm.com>,
Ilya Leoshkevich <iii@linux.ibm.com>
Subject: [PATCH] libtracecmd: Support changing /proc/kallsyms
Date: Thu, 17 Apr 2025 01:13:00 +0200 [thread overview]
Message-ID: <20250416231325.14113-1-iii@linux.ibm.com> (raw)
Running BPF selftests under trace-cmd intermittently fails with:
error in size of file '/proc/kallsyms'
This is because these selftests load and unload BPF programs.
bpf_prog_put() uses workqueues and RCU, so these programs disappear
from /proc/kallsyms after a delay.
trace-cmd reads /proc/kallsyms twice: the first time to compute its
size, and the second time to copy it into the trace file. If the
resulting sizes don't match, which is what happens in this case,
recording fails.
Fix by first copying /proc/kallsyms into a temporary file, and then
into the trace file. An alternative would be to read it into a
malloc()-ed buffer, but this would increase trace-cmd memory usage,
since /proc/kallsyms can be a few dozen megabytes large. In case
/tmp is tmpfs, both solutions are almost equivalent.
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
lib/trace-cmd/trace-output.c | 66 ++++++++++++++++++++++++++++--------
1 file changed, 52 insertions(+), 14 deletions(-)
diff --git a/lib/trace-cmd/trace-output.c b/lib/trace-cmd/trace-output.c
index 00b87a19..d85021be 100644
--- a/lib/trace-cmd/trace-output.c
+++ b/lib/trace-cmd/trace-output.c
@@ -1129,14 +1129,52 @@ err:
tracecmd_warning("can't set kptr_restrict");
}
+static int copy_to_temp_fd(const char *path, tsize_t *size)
+{
+ char temp_path[] = "/tmp/trace_XXXXXX";
+ char buf[BUFSIZ];
+ int fd, temp_fd;
+ stsize_t r;
+
+ fd = open(path, O_RDONLY);
+ if (fd < 0)
+ goto fail;
+
+ temp_fd = mkstemp(temp_path);
+ if (temp_fd < 0)
+ goto fail_close;
+ unlink(temp_path);
+
+ *size = 0;
+ for (;;) {
+ r = read(fd, buf, sizeof(buf));
+ if (r == 0)
+ break;
+ if (r < 0 || __do_write_check(temp_fd, buf, r))
+ goto fail_close_temp;
+ *size += r;
+ }
+
+ if (lseek(temp_fd, 0, SEEK_SET) == (off_t)-1)
+ goto fail_close_temp;
+
+ close(fd);
+ return temp_fd;
+
+fail_close_temp:
+ close(temp_fd);
+fail_close:
+ close(fd);
+fail:
+ return -1;
+}
+
static int read_proc_kallsyms(struct tracecmd_output *handle, bool compress)
{
enum tracecmd_section_flags flags = 0;
- unsigned int size, check_size, endian4;
const char *path = "/proc/kallsyms";
- tsize_t offset;
- struct stat st;
- int ret;
+ tsize_t check_size, offset, size;
+ int endian4, fd, ret;
if (!tcmd_check_out_state(handle, TRACECMD_FILE_KALLSYMS)) {
tracecmd_warning("Cannot read kallsyms, unexpected state 0x%X",
@@ -1155,36 +1193,36 @@ static int read_proc_kallsyms(struct tracecmd_output *handle, bool compress)
return -1;
tcmd_out_compression_start(handle, compress);
- ret = stat(path, &st);
- if (ret < 0) {
+ set_proc_kptr_restrict(0);
+ fd = copy_to_temp_fd(path, &size);
+ set_proc_kptr_restrict(1);
+ if (fd < 0) {
/* not found */
size = 0;
endian4 = convert_endian_4(handle, size);
ret = tcmd_do_write_check(handle, &endian4, 4);
goto out;
}
- size = get_size(path);
endian4 = convert_endian_4(handle, size);
ret = tcmd_do_write_check(handle, &endian4, 4);
if (ret)
- goto out;
+ goto out_close;
- set_proc_kptr_restrict(0);
- check_size = copy_file(handle, path);
+ check_size = copy_file_fd(handle, fd, 0);
if (size != check_size) {
errno = EINVAL;
tracecmd_warning("error in size of file '%s'", path);
- set_proc_kptr_restrict(1);
ret = -1;
- goto out;
+ goto out_close;
}
- set_proc_kptr_restrict(1);
ret = tcmd_out_compression_end(handle, compress);
if (ret)
- goto out;
+ goto out_close;
ret = tcmd_out_update_section_header(handle, offset);
+out_close:
+ close(fd);
out:
if (!ret)
handle->file_state = TRACECMD_FILE_KALLSYMS;
--
2.49.0
next reply other threads:[~2025-04-16 23:13 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-04-16 23:13 Ilya Leoshkevich [this message]
2025-05-14 7:51 ` [PATCH] libtracecmd: Support changing /proc/kallsyms Ilya Leoshkevich
2025-05-14 13:45 ` Steven Rostedt
2025-05-30 20:45 ` Steven Rostedt
2025-06-02 15:05 ` Ilya Leoshkevich
2025-06-02 15:19 ` Steven Rostedt
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250416231325.14113-1-iii@linux.ibm.com \
--to=iii@linux.ibm.com \
--cc=agordeev@linux.ibm.com \
--cc=gor@linux.ibm.com \
--cc=hca@linux.ibm.com \
--cc=linux-trace-devel@vger.kernel.org \
--cc=rostedt@goodmis.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).