summaryrefslogtreecommitdiff
path: root/tools/tracing/rtla/src
diff options
context:
space:
mode:
authorWander Lairson Costa <wander@redhat.com>2026-03-09 16:46:29 -0300
committerTomas Glozar <tglozar@redhat.com>2026-03-11 15:29:50 +0100
commit47dd74f68c0c068fdd29cdf9fe1860a19209bc1f (patch)
tree949a857dca865bde8ffb7d1d25aa784fd8601d89 /tools/tracing/rtla/src
parent4bf4ef5292b9253d8607c61a875d9f6b14129976 (diff)
rtla/trace: Fix I/O handling in save_trace_to_file()
The read/write loop in save_trace_to_file() does not correctly handle errors from the read() and write() system calls. If either call is interrupted by a signal, it returns -1 with errno set to EINTR, but the code treats this as a fatal error and aborts the save operation. Additionally, write() may perform a partial write, returning fewer bytes than requested, which the code does not handle. Fix the I/O loop by introducing proper error handling. The return value of read() is now stored in a ssize_t variable and checked for errors, with EINTR causing a retry. For write(), an inner loop ensures all bytes are written, handling both EINTR and partial writes. Error messages now include strerror() output for better debugging. This follows the same pattern established in the previous commit that fixed trace_event_save_hist(), ensuring consistent and robust I/O handling throughout the trace saving code. Signed-off-by: Wander Lairson Costa <wander@redhat.com> Link: https://lore.kernel.org/r/20260309195040.1019085-17-wander@redhat.com Signed-off-by: Tomas Glozar <tglozar@redhat.com>
Diffstat (limited to 'tools/tracing/rtla/src')
-rw-r--r--tools/tracing/rtla/src/trace.c31
1 files changed, 24 insertions, 7 deletions
diff --git a/tools/tracing/rtla/src/trace.c b/tools/tracing/rtla/src/trace.c
index fed3362527b0..e407447773d0 100644
--- a/tools/tracing/rtla/src/trace.c
+++ b/tools/tracing/rtla/src/trace.c
@@ -73,6 +73,8 @@ int save_trace_to_file(struct tracefs_instance *inst, const char *filename)
char buffer[4096];
int out_fd, in_fd;
int retval = -1;
+ ssize_t n_read;
+ ssize_t n_written;
if (!inst || !filename)
return 0;
@@ -90,15 +92,30 @@ int save_trace_to_file(struct tracefs_instance *inst, const char *filename)
goto out_close_in;
}
- do {
- retval = read(in_fd, buffer, sizeof(buffer));
- if (retval <= 0)
+ for (;;) {
+ n_read = read(in_fd, buffer, sizeof(buffer));
+ if (n_read < 0) {
+ if (errno == EINTR)
+ continue;
+ err_msg("Error reading trace file: %s\n", strerror(errno));
goto out_close;
+ }
+ if (n_read == 0)
+ break;
- retval = write(out_fd, buffer, retval);
- if (retval < 0)
- goto out_close;
- } while (retval > 0);
+ n_written = 0;
+ while (n_written < n_read) {
+ const ssize_t w = write(out_fd, buffer + n_written, n_read - n_written);
+
+ if (w < 0) {
+ if (errno == EINTR)
+ continue;
+ err_msg("Error writing trace file: %s\n", strerror(errno));
+ goto out_close;
+ }
+ n_written += w;
+ }
+ }
retval = 0;
out_close: