Provided by: libtraceevent-doc_1.8.2-1ubuntu2_all bug

NAME

       kbuffer_alloc, kbuffer_dup, kbuffer_free, kbuffer_load_subbuffer, kbuffer_subbuffer,
       kbuffer_refresh, kbuffer_subbuffer_size, kbuffer_start_of_data - Creating of kbuffer
       element to parse the Linux kernel tracing ring buffer

SYNOPSIS

       #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 *kbuffer_alloc(enum kbuffer_long_size size, enum kbuffer_endian endian);
       struct kbuffer *kbuffer_dup(struct kbuffer *kbuf);
       void kbuffer_free(struct kbuffer *kbuf);
       int kbuffer_load_subbuffer(struct kbuffer *kbuf, void *subbuffer);
       int kbuffer_subbuffer_size(struct kbuffer *kbuf);
       int kbuffer_refresh(struct kbuffer *kbuf);
       int kbuffer_start_of_data(struct kbuffer *kbuf);
       void *kbuffer_subbuffer(struct kbuffer *_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_dup() function will duplicate an existing kbuffer structure with an allocated
       new one. It will have all the properties of the passed in kbuf, including pointing to the
       same subbuffer that was loaded in the kbuf. It must be freed with kbuffer_free().

       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_refresh() is to be used if more writes were done on the loaded kbuffer where
       the size of the kbuffer needs to be refreshed to be able to read the new events that were
       written since the last kbuffer_load_subbuffer() was called on it.

       Note, no memory barriers are implemented with this function and any synchronization with
       the writer is the responsibility of the application.

       The kbuffer_start_of_data() function returns the offset of where the actual data load of
       the sub-buffer begins.

       The kbuffer_subbuffer() function returns the pointer to the currently loaded subbuffer.
       That is, the last subbuffer that was loaded by kbuffer_load_subbuffer(). If no subbuffer
       was loaded NULL is returned.

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.

       kbuffer_subbuffer() returns the last loaded subbuffer to kbuf that was loaded by
       kbuffer_load_subbuffer() or NULL if none was loaded.

       kbuffer_refresh() returns 0 on success and -1 if kbuf is NULL or it does not have a
       subbuffer loaded via kbuffer_load_subbuffer().

EXAMPLE

           #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

           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

           Steven Rostedt <rostedt@goodmis.org[1]>, author of libtraceevent.

REPORTING BUGS

       Report bugs to <linux-trace-devel@vger.kernel.org[2]>

LICENSE

       libtraceevent is Free Software licensed under the GNU LGPL 2.1

RESOURCES

       https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/

NOTES

        1. rostedt@goodmis.org
           mailto:rostedt@goodmis.org

        2. linux-trace-devel@vger.kernel.org
           mailto:linux-trace-devel@vger.kernel.org