[PATCH] trace-cmd split: Only open one file descriptor per CPU

Steven Rostedt <[email protected]> Tue, 8 Jul 2025 14:38:19 -0400
Newsgroups org.kernel.vger.linux-trace-devel
Message-ID <[email protected]>
From: "Steven Rostedt (Google)" <[email protected]>

When splitting a trace.dat file, trace-cmd split will create a temp file
per CPU as it parse the trace.dat to store what to save in the new
trace.dat file into per CPU files.

After it finishes the creation of the CPU data files, it then calls
tracecmd_append_cpu_data() which will open each of these CPU files and
append them to the new trace.dat file.

The issue is when you have a trace.dat file that was created by a machine
with 512 CPUs. Because it doesn't close the file descriptors after
creating the files and before calling tracecmd_append_cpu_data() it has
1024 file descriptors open. With some distributions having a file
descriptor limit of 1024, this exceeds the limit because there's other
file descriptors open (for the trace.dat files themselves), and the
program fails.

There's no reason to keep the file descriptors open for the files that
were created before calling tracecmd_append_cpu_data(). Just close them
before calling that function. This keeps the number of file descriptors
open to that of the number of CPU buffers in the trace.dat file instead of
doubling them. There is a couple more file descriptors open as mentioned
before, but those are not an issue.

Reported-by: Julia Lawall <[email protected]>
Signed-off-by: Steven Rostedt (Google) <[email protected]>
---
 tracecmd/trace-split.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/tracecmd/trace-split.c b/tracecmd/trace-split.c
index 13a10c89590d..e037ab491ba0 100644
--- a/tracecmd/trace-split.c
+++ b/tracecmd/trace-split.c
@@ -571,6 +571,11 @@ static unsigned long long parse_file(struct tracecmd_input *handle,
 				  end, count, percpu, -1, type, &curr_end_reached);
 		}
 
+		for (cpu = 0; cpu < cpus; cpu++) {
+			close(cpu_data[cpu].fd);
+			cpu_data[cpu].fd = -1;
+		}
+
 		/* End is reached when all instances finished. */
 		all_end_reached &= curr_end_reached;
 
@@ -599,7 +604,6 @@ static unsigned long long parse_file(struct tracecmd_input *handle,
 		}
 
 		for (cpu = 0; cpu < cpus; cpu++) {
-			close(cpu_data[cpu].fd);
 			delete_temp_file(cpu_data[cpu].file);
 			put_temp_file(cpu_data[cpu].file);
 		}
-- 
2.47.2