| libtracefs(3) |
| ============= |
| |
| NAME |
| ---- |
| tracefs_snapshot_snap, tracefs_snapshot_clear, tracefs_snapshot_free - |
| API to create, clear and read snapshots |
| |
| SYNOPSIS |
| -------- |
| [verse] |
| -- |
| *#include <tracefs.h>* |
| |
| int *tracefs_snapshot_snap*(struct tracefs_instance pass:[*]instance); |
| int *tracefs_snapshot_clear*(struct tracefs_instance pass:[*]instance); |
| int *tracefs_snapshot_free*(struct tracefs_instance pass:[*]instance); |
| -- |
| |
| DESCRIPTION |
| ----------- |
| The Linux kernel tracing provides a "snapshot" feature. The kernel has two |
| ring buffers. One that is written to by the tracing system and another one that |
| is the "snapshot" buffer. When a snapshot happens, the two buffers are swapped, and |
| the current snapshot buffer becomes the one being written to, and the buffer |
| that was being written to becomes the saved snapshot. |
| |
| Note, the snapshot buffer is allocated the first time it is taken, so it is best |
| to take a snapshot at the start before one is needed so that it is allocated |
| and a snapshot is ready, then the snapshot will happen immediately. |
| |
| The *tracefs_snapshot_snap()* will allocate (if not already allocated) the snapshot |
| buffer and then take a "snapshot" (swap the main buffer that's being written to with |
| the allocated snapshot buffer). It will do this to the given _instance_ buffer or |
| the top instance if _instance_ is NULL. |
| |
| The *tracefs_snapshot_clear()* will erase the content of the snapshot buffer for |
| the given _instance_ or the top level instance if _instance_ is NULL. |
| |
| The *tracefs_snapshot_free()* will free the allocated snapshot for the given _instance_ |
| or the top level instance if _instance_ is NULL. That is, if another call to |
| *tracefs_snapshot_snap()* is done after this, then it will need to allocate |
| the snapshot buffer again before it can take a snapshot. This function should |
| be used to free up the kernel memory used by hte snapshot buffer when no longer in use. |
| |
| |
| RETURN VALUE |
| ------------ |
| The *tracefs_snapshot_snap()*, *tracefs_snapshot_clear()* and the *tracefs_snapshot_free()* |
| all return 0 on success and -1 on failure. |
| |
| EXAMPLE |
| ------- |
| [source,c] |
| -- |
| #include <stdlib.h> |
| #include <stdio.h> |
| #include <tracefs.h> |
| |
| static int callback(struct tep_event *event, struct tep_record *record, int cpu, void *data) |
| { |
| static struct trace_seq seq; |
| struct tep_handle *tep = event->tep; |
| |
| if (!seq.buffer) |
| trace_seq_init(&seq); |
| |
| trace_seq_reset(&seq); |
| |
| tep_print_event(tep, &seq, record, "[%03d] %s-%d %6.1000d\t%s: %s\n", |
| TEP_PRINT_CPU, |
| TEP_PRINT_COMM, |
| TEP_PRINT_PID, |
| TEP_PRINT_TIME, |
| TEP_PRINT_NAME, |
| TEP_PRINT_INFO); |
| trace_seq_do_printf(&seq); |
| return 0; |
| } |
| |
| int main (int argc, char **argv) |
| { |
| struct tracefs_instance *instance; |
| struct tep_handle *tep; |
| char *line = NULL; |
| size_t len = 0; |
| int ret; |
| |
| instance = tracefs_instance_create("my_snapshots"); |
| if (!instance) { |
| perror("creating instance"); |
| exit(-1); |
| } |
| |
| tep = tracefs_local_events(NULL); |
| if (!tep) { |
| perror("reading event formats"); |
| goto out; |
| } |
| |
| /* Make sure the snapshot buffer is allocated */ |
| ret = tracefs_snapshot_snap(instance); |
| if (ret < 0) |
| goto out; |
| |
| ret = tracefs_event_enable(instance, "sched", NULL); |
| if (ret < 0) { |
| perror("enabling event"); |
| goto out; |
| } |
| |
| for (;;) { |
| printf("Hit enter without text to take snapshot!\n"); |
| printf("Enter any text to display the snapshot\n"); |
| printf("Enter 'quit' to exit\n"); |
| getline(&line, &len, stdin); |
| ret = tracefs_snapshot_snap(instance); |
| if (ret < 0) { |
| perror("taking snapshot"); |
| goto out; |
| } |
| if (!line) |
| break; |
| if (strlen(line) < 2) |
| continue; |
| if (strncmp(line, "quit", 4) == 0) |
| break; |
| tracefs_iterate_snapshot_events(tep, instance, NULL, 0, callback, NULL); |
| } |
| |
| free(line); |
| |
| tracefs_instance_clear(instance); |
| |
| out: |
| tracefs_snapshot_free(instance); |
| tracefs_event_disable(instance, "sched", NULL); |
| tracefs_instance_destroy(instance); |
| tracefs_instance_free(instance); |
| |
| exit(0); |
| } |
| -- |
| FILES |
| ----- |
| [verse] |
| -- |
| *tracefs.h* |
| Header file to include in order to have access to the library APIs. |
| *-ltracefs* |
| Linker switch to add when building a program that uses the library. |
| -- |
| |
| SEE ALSO |
| -------- |
| *tracefs_iterate_snapshot_events*(3) |
| *libtracefs*(3), |
| *libtraceevent*(3), |
| *trace-cmd*(1) |
| |
| AUTHOR |
| ------ |
| [verse] |
| -- |
| *Steven Rostedt* <rostedt@goodmis.org> |
| -- |
| REPORTING BUGS |
| -------------- |
| Report bugs to <linux-trace-devel@vger.kernel.org> |
| |
| LICENSE |
| ------- |
| libtracefs is Free Software licensed under the GNU LGPL 2.1 |
| |
| RESOURCES |
| --------- |
| https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git/ |
| |
| COPYING |
| ------- |
| Copyright \(C) 2023 Google, LLC. Free use of this software is granted under |
| the terms of the GNU Public License (GPL). |