'\" t .\" Title: libtracefs .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets vsnapshot .\" Date: 01/13/2024 .\" Manual: libtracefs Manual .\" Source: libtracefs 1.8.0 .\" Language: English .\" .TH "LIBTRACEFS" "3" "01/13/2024" "libtracefs 1\&.8\&.0" "libtracefs Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" tracefs_cpu_read_size, tracefs_cpu_read, tracefs_cpu_buffered_read, tracefs_cpu_write, tracefs_cpu_stop, tracefs_cpu_flush, tracefs_cpu_flush_write, tracefs_cpu_pipe \- Reading trace_pipe_raw data .SH "SYNOPSIS" .sp .nf \fB#include \fR int \fBtracefs_cpu_read_size\fR(struct tracefs_cpu *\fItcpu\fR); int \fBtracefs_cpu_read\fR(struct tracefs_cpu *\fItcpu\fR, void *\fIbuffer\fR, bool \fInonblock\fR); int \fBtracefs_cpu_buffered_read\fR(struct tracefs_cpu *\fItcpu\fR, void *\fIbuffer\fR, bool \fInonblock\fR); int \fBtracefs_cpu_write\fR(struct tracefs_cpu *\fItcpu\fR, int \fIwfd\fR, bool \fInonblock\fR); int \fBtracefs_cpu_stop\fR(struct tracefs_cpu *\fItcpu\fR); int \fBtracefs_cpu_flush\fR(struct tracefs_cpu *\fItcpu\fR, void *\fIbuffer\fR); int \fBtracefs_cpu_flush_write\fR(struct tracefs_cpu *\fItcpu\fR, int \fIwfd\fR); int \fBtracefs_cpu_pipe\fR(struct tracefs_cpu *\fItcpu\fR, int \fIwfd\fR, bool \fInonblock\fR); .fi .SH "DESCRIPTION" .sp This set of APIs can be used to read the raw data from the trace_pipe_raw files in the tracefs file system\&. .sp The \fBtracefs_cpu_read_size()\fR returns the subbuffer size of the trace_pipe_raw\&. This returns the minimum size of the buffer that is passed to the below functions\&. .sp The \fBtracefs_cpu_read()\fR reads the trace_pipe_raw files associated to \fItcpu\fR into \fIbuffer\fR\&. \fIbuffer\fR must be at least the size of the sub buffer of the ring buffer, which is returned by \fBtracefs_cpu_read_size()\fR\&. If \fInonblock\fR is set, and there\(cqs no data available, it will return immediately\&. Otherwise depending on how \fItcpu\fR was opened, it will block\&. If \fItcpu\fR was opened with nonblock set, then this \fInonblock\fR will make no difference\&. .sp The \fBtracefs_cpu_buffered_read()\fR is basically the same as \fBtracefs_cpu_read()\fR except that it uses a pipe through splice to buffer reads\&. This will batch reads keeping the reading from the ring buffer less intrusive to the system, as just reading all the time can cause quite a disturbance\&. Note, one difference between this and \fBtracefs_cpu_read()\fR is that it will read only in sub buffer pages\&. If the ring buffer has not filled a page, then it will not return anything, even with \fInonblock\fR set\&. Calls to \fBtracefs_cpu_flush()\fR should be done to read the rest of the file at the end of the trace\&. .sp The \fBtracefs_cpu_write()\fR will pipe the data from the trace_pipe_raw file associated with \fItcpu\fR into the \fIwfd\fR file descriptor\&. If \fInonblock\fR is set, then it will not block on if there\(cqs nothing to write\&. Note, it will only write sub buffer size data to \fIwfd\fR\&. Calls to tracefs_cpu_flush_write() are needed to write out the rest\&. .sp The \fBtracefs_cpu_stop()\fR will attempt to unblock a task blocked on \fItcpu\fR reading it\&. On older kernels, it may not do anything for the pipe reads, as older kernels do not wake up tasks waiting on the ring buffer\&. Returns 0 if it definitely woke up any possible waiters, but returns 1 if it is not sure it worked and waiters may need to have a signal sent to them\&. .sp The \fBtracefs_cpu_flush()\fR reads the trace_pipe_raw file associated by the \fItcpu\fR and puts it into \fIbuffer\fR, which must be the size of the sub buffer which is retrieved\&. by \fBtracefs_cpu_read_size()\fR\&. This should be called at the end of tracing to get the rest of the data\&. This call will convert the file descriptor of trace_pipe_raw into non\-blocking mode\&. .sp The \fBtracefs_cpu_flush_write()\fR same as \fBtrace_cpu_flush()\fR except it takes a file descriptor \fIwfd\fR to flush the data into\&. .sp The \fBtracefs_cpu_pipe()\fR is similar to \fBtracefs_cpu_write()\fR but the \fIwfd\fR file descriptor must be a pipe\&. This call is an optimization of \fBtracefs_cpu_write()\fR that uses two calls to \fBsplice\fR(2) in order to connect the trace_pipe_raw file descriptor with the write file descriptor\&. \fBsplice\fR(2) requires that one of the passed in file descriptors is a pipe\&. If the application wants to pass the data to an existing pipe, there\(cqs no reason for there to be two \fBsplice\fR(2) system calls and \fBtracefs_cpu_pipe()\fR can simply use a single call to \fIwfd\fR\&. .SH "RETURN VALUE" .sp The \fBtracefs_cpu_open()\fR returns a struct tracefs_cpu descriptor that can be used by the other functions or NULL on error\&. .sp The \fBtracefs_cpu_read_size()\fR returns the minimum size of the buffers to be used with \fBtracefs_cpu_read()\fR, \fBtracefs_cpu_buffered_read()\fR and \fBtracefs_cpu_flush()\fR\&. Returns negative on error\&. .sp The \fBtracefs_cpu_read()\fR returns the number of bytes read, or negative on error\&. .sp The \fBtracefs_cpu_buffered_read()\fR returns the number of bytes read or negative on error\&. .sp The \fBtracefs_cpu_write()\fR returns the number of bytes written to the file or negative on error\&. .sp The \fBtracefs_cpu_stop()\fR returns zero if any waiters were guaranteed to be woken up from waiting on input, or returns one if this is an older kernel that does not supply that guarantee, and a signal may need to be sent to any waiters\&. Returns negative on error\&. .sp The \fBtracefs_cpu_flush()\fR returns the number of bytes read or negative on error\&. .sp The \fBtracefs_cpu_flush_write()\fR returns the number of bytes written to the file or negative on error\&. .SH "EXAMPLE" .sp .if n \{\ .RS 4 .\} .nf #define _LARGEFILE64_SOURCE #include #include #include #include #include struct thread_data { struct tracefs_cpu *tcpu; int done; int fd; }; static void *thread_run(void *arg) { struct thread_data *data = arg; struct tracefs_cpu *tcpu = data\->tcpu; int fd = data\->fd; int ret; while (!data\->done) { ret = tracefs_cpu_write(tcpu, fd, false); printf("wrote %d\en", ret); } return NULL; } int main (int argc, char **argv) { struct tracefs_instance *instance; struct thread_data data; pthread_t thread; char *file; int secs = 10; int cpu; int ret; if (argc < 3 || !isdigit(argv[1][0])) { printf("usage: %s cpu file_destination [sleep secs]\en\en", argv[0]); exit(\-1); } cpu = atoi(argv[1]); file = argv[2]; if (argc > 3) secs = atoi(argv[3]); instance = tracefs_instance_create("cpu_write"); if (!instance) { perror("create instance"); exit(\-1); } memset(&data, 0, sizeof(data)); data\&.tcpu = tracefs_cpu_open(instance, cpu, 0); if (!data\&.tcpu) { perror("Open instance"); exit(\-1); } data\&.fd = open(file, O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE, 0644); if (data\&.fd < 0) { perror(file); exit(\-1); } pthread_create(&thread, NULL, thread_run, &data); sleep(secs); data\&.done = 1; printf("stopping\en"); ret = tracefs_cpu_stop(data\&.tcpu); printf("joining %d\en", ret); pthread_join(thread, NULL); tracefs_trace_off(instance); do { ret = tracefs_cpu_flush_write(data\&.tcpu, data\&.fd); printf("flushed %d\en", ret); } while (ret > 0); tracefs_trace_on(instance); tracefs_cpu_close(data\&.tcpu); close(data\&.fd); return 0; } .fi .if n \{\ .RE .\} .SH "FILES" .sp .if n \{\ .RS 4 .\} .nf \fBtracefs\&.h\fR Header file to include in order to have access to the library APIs\&. \fB\-ltracefs\fR Linker switch to add when building a program that uses the library\&. .fi .if n \{\ .RE .\} .SH "SEE ALSO" .sp \fBtracefs_cpu_open\fR(3) \fBtracefs_cpu_close\fR(3) \fBtracefs_cpu_read_buf\fR(3) \fBtracefs_cpu_buffered_read_buf\fR(3) \fBtracefs_cpu_flush_buf\fR(3) \fBlibtracefs\fR(3), \fBlibtraceevent\fR(3), \fBtrace\-cmd\fR(1) .SH "AUTHOR" .sp .if n \{\ .RS 4 .\} .nf \fBSteven Rostedt\fR <\m[blue]\fBrostedt@goodmis\&.org\fR\m[]\&\s-2\u[1]\d\s+2> .fi .if n \{\ .RE .\} .SH "REPORTING BUGS" .sp Report bugs to <\m[blue]\fBlinux\-trace\-devel@vger\&.kernel\&.org\fR\m[]\&\s-2\u[2]\d\s+2> .SH "LICENSE" .sp libtracefs is Free Software licensed under the GNU LGPL 2\&.1 .SH "RESOURCES" .sp \m[blue]\fBhttps://git\&.kernel\&.org/pub/scm/libs/libtrace/libtracefs\&.git/\fR\m[] .SH "COPYING" .sp Copyright (C) 2022 Google, Inc\&. Free use of this software is granted under the terms of the GNU Public License (GPL)\&. .SH "NOTES" .IP " 1." 4 rostedt@goodmis.org .RS 4 \%mailto:rostedt@goodmis.org .RE .IP " 2." 4 linux-trace-devel@vger.kernel.org .RS 4 \%mailto:linux-trace-devel@vger.kernel.org .RE