I wanted to try splice syscall, which trace-cmd uses to zero copy raw files of off ftrace.
Here is the partial list of ftrace raw files splice fails to read:
/sys/kernel/debug/tracing/per_cpu/cpo0/trace_pipe_raw
/sys/kernel/debug/tracing/per_cpu/cpo0/snapshot_raw
/sys/kernel/debug/tracing/per_cpu/cpo1/trace_pipe_raw
/sys/kernel/debug/tracing/per_cpu/cpo1/snapshot_raw
And here are some other files (that splice handles just fine):
/sys/kernel/debug/tracing/per_cpu/cpo0/trace_pipe
/sys/kernel/debug/tracing/per_cpu/cpo0/snapshot
/sys/kernel/debug/tracing/per_cpu/cpo1/trace_pipe
/sys/kernel/debug/tracing/per_cpu/cpo1/snapshot
What works:
- using the read() system call works great to read from raw ftrace files.
- using the cat() system call will display raw ftrace files.
- using the trace-cmd tool which is a CLI front end for ftrace.
This is my code:
static void unit_test_x(void){ int buffer_pipe[2]; pipe(buffer_pipe); std::string source_path = "/sys/kernel/debug/tracing/per_cpu/cpu1/trace_pipe_raw"; int trace_fd = open(source_path.c_str(), O_RDONLY); std::string destination_path = "foo"; int dest_fd = open (destination_path.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE, 0644); int actually_read = splice(trace_fd, NULL, buffer_pipe[1], NULL, 1000, SPLICE_F_MORE | SPLICE_F_MOVE ); if (0 > actually_read ) { printf("Oh dear, something went wrong %s\n", s trerror(errno)); throw std::runtime_error("writing from source to pipe failed"); } actually_read = splice(buffer_pipe[0], NULL, dest_fd, NULL, actually_read, SPLICE_F_MORE | SPLICE_F_MOVE);}
note:
All accsess to /sys/kernel/debug/tracing is done with sudo