diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 07:25:46 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 07:25:46 +0000 |
commit | 5277429a362a9cf4ce649557bf4c8fe0e20c05c0 (patch) | |
tree | 52cc97728c6fbb7393984dc3db05c5836107fe44 /Documentation/libtraceevent-kbuffer-create.txt | |
parent | Initial commit. (diff) | |
download | libtraceevent-upstream.tar.xz libtraceevent-upstream.zip |
Adding upstream version 1:1.7.1.upstream/1%1.7.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'Documentation/libtraceevent-kbuffer-create.txt')
-rw-r--r-- | Documentation/libtraceevent-kbuffer-create.txt | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/Documentation/libtraceevent-kbuffer-create.txt b/Documentation/libtraceevent-kbuffer-create.txt new file mode 100644 index 0000000..12e5d6c --- /dev/null +++ b/Documentation/libtraceevent-kbuffer-create.txt @@ -0,0 +1,207 @@ +libtraceevent(3) +================ + +NAME +---- +kbuffer_alloc, kbuffer_free, kbuffer_load_subbuffer, kbuffer_subbuffer_size, kbuffer_start_of_data - Creating of kbuffer element to parse +the Linux kernel tracing ring buffer + +SYNOPSIS +-------- +[verse] +-- +*#include <kbuffer.h>* + +enum kbuffer_endian { + KBUFFER_ENDIAN_BIG, + KBUFFER_ENDIAN_LITTLE, + KBUFFER_ENDIAN_SAME_AS_HOST, +}; + +enum kbuffer_long_size { + KBUFFER_LSIZE_4, + KBUFFER_LSIZE_8, + KBUFFER_LSIZE_SAME_AS_HOST, +}; + +struct kbuffer; +struct tep_handle; + +struct kbuffer pass:[*]*kbuffer_alloc*(enum kbuffer_long_size _size_, enum kbuffer_endian _endian_); +void *kbuffer_free*(struct kbuffer pass:[*]_kbuf_); +int *kbuffer_load_subbuffer*(struct kbuffer pass:[*]_kbuf_, void pass:[*]_subbuffer_); +int *kbuffer_subbuffer_size*(struct kbuffer pass:[*]_kbuf); +int *kbuffer_start_of_data*(struct kbuffer pass:[*]_kbuf_); +-- + +DESCRIPTION +----------- +These functions create a _kbuffer_ handle that can be used to parse the raw sub buffers +of the Linux kernel tracing ring buffer. The ring buffer is found in the tracefs +directory, and can be retrieved by *tracefs_instance_get_file(3)* at +*per_cpu/cpuX/trace_pipe_raw* where *X* is replaced by the per CPU number of +the specified ring buffer. The ring buffer inside the kernel is split up per +CPU, such that the raw ring buffer must be retrieved per CPU as well. + +The *kbuffer_alloc()* will create a descriptor that can be used to manage a sub buffer +read by the ring buffer. The _size_ parameter denotes what the word size is +for the given buffer (note, this works from reading raw data from machines other +than the machine that is calling this function). The _endian_ denotes the endian +for the machine. + +If _endian_ is set to _KBUFFER_ENDIAN_SAME_AS_HOST_ the endian will be set to the same +as the host endianess, which is useful when the application is reading the +ring buffer data directly from the same machine it is running on. + +If _size_ is set to _KBUFFER_LSIZE_SAME_AS_HOST_, if the word size is 8, it will +set the kbuffer descriptor to long size of 8. But if the size is 4, then it +will then perform a *uname(2)* call, and if the _machine_ field has the string "64" +in it, it will be set to 8 byte long size and not 4 byte. This is because the +ring buffer long size is dependent on the kernel and not user space. + +The *kbuffer_free()* function will free the resources created by *kbuffer_alloc()*. + +The *kbuffer_load_subbuffer()* will take a _subbuffer_ which is a raw data blob +from the tracefs *trace_pipe_raw* file. The Linux tracing ring buffer is broken up +into sub buffers. Each sub buffer is as stand alone data segment that has all the +information to split out the individual events and time stamps. This sub buffer +is what kbuffer uses to walk the events. + +The *kbuffer_subbuffer_size()* returns the location of the end of the last event +on the sub-buffer. It does not return the size of the sub-buffer itself. + +The *kbuffer_start_of_data()* function returns the offset of where the actual +data load of the sub-buffer begins. + +RETURN VALUE +------------ +*kbuffer_alloc()* returns an allocated kbuffer descriptor or NULL on error. +The returned descriptor must be freed with *kbuffer_free()* + +*kbuffer_load_subbuffer()* returns 0 on success and -1 on error. + +*kbuffer_subbuffer_size()* returns the index on the subbuffer where the end +of the last event is located. + +*kbuffer_start_of_data()* returns the offset of where the data begins on the +sub-buffer loaded in _kbuf_. + +EXAMPLE +------- +[source,c] +-- +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/stat.h> + +#include <kbuffer.h> + +int main (int argc, char **argv) +{ + unsigned long long ts; + struct kbuffer *kbuf; + struct stat st; + char *buf; + void *event; + int ret; + int fd; + int i = 0; + + if (argc < 2) { + printf("usage: %s raw-subbuffer-page\n", argv[0]); + printf(" Try: dd count=1 bs=4096 if=/sys/kernel/tracing/per_cpu/cpu0/trace_pipe_raw of=/tmp/file\n"); + exit(0); + } + + if (stat(argv[1], &st) < 0) { + perror("stat"); + exit(-1); + } + + buf = malloc(st.st_size); + if (!buf) { + perror("Allocating buffer"); + exit(-1); + } + + fd = open(argv[1], O_RDONLY); + if (fd < 0) { + perror(argv[1]); + exit(-1); + } + + ret = read(fd, buf, st.st_size); + if (ret < 0) { + perror("Reading buffer"); + exit(-1); + } + close(fd); + + kbuf = kbuffer_alloc(KBUFFER_ENDIAN_SAME_AS_HOST, + KBUFFER_LSIZE_SAME_AS_HOST); + if (!kbuf) { + perror("Creating kbuffer"); + exit(-1); + } + ret = kbuffer_load_subbuffer(kbuf, buf); + if (ret < 0) { + perror("Loading sub bufer"); + exit(-1); + } + + if (kbuffer_subbuffer_size(kbuf) > st.st_size) { + fprintf(stderr, "kbuffer is bigger than raw size %d > %ld\n", + kbuffer_subbuffer_size(kbuf), st.st_size); + exit(-1); + } + + printf("Kbuffer data starts at %d\n", kbuffer_start_of_data(kbuf)); + do { + event = kbuffer_read_event(kbuf, &ts); + if (event) { + printf(" event %3d ts:%lld\n", i++, ts); + event = kbuffer_next_event(kbuf, NULL); + } + } while (event); + + if (!event) + printf("Finished sub buffer\n"); + + kbuffer_free(kbuf); + + return 0; +} +-- +FILES +----- +[verse] +-- +*event-parse.h* + Header file to include in order to have access to the library APIs. +*-ltraceevent* + Linker switch to add when building a program that uses the library. +-- + +SEE ALSO +-------- +*libtraceevent*(3), *trace-cmd*(1) + +AUTHOR +------ +[verse] +-- +*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*. +-- +REPORTING BUGS +-------------- +Report bugs to <linux-trace-devel@vger.kernel.org> + +LICENSE +------- +libtraceevent is Free Software licensed under the GNU LGPL 2.1 + +RESOURCES +--------- +https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/ |