LIBTRACEFS(3)

πŸ¦‹ LIBTRACEFS πŸ¦‹

okay bestie, sit down, hydrate, and get comfy β€” this is libtracefs, the Linux kernel trace file system library, and it's literally the main character of tracing. this page is a lot, so we're doing it in parts, and you're gonna eat it up. πŸ’…

the header line says LIBTRACEFS(3) and it lives in the libtracefs Manual β€” that's the manual name, folded in right here so you never lose it. πŸŽ€


✨ NAME ✨

libtracefs β€” the Linux kernel trace file system library. no cap, that's the whole vibe. it's the C library that lets you poke at the kernel's tracing filesystem without crying. 🫢


✨ SYNOPSIS ✨

first things first, you gotta invite it in:

#include <tracefs.h>

then it's just a mountain of function declarations. and when I say mountain, I mean mountain. every single one is here, so let's go group by group, bestie β€” no skipping, no summarising, we're doing all of it. 😀


πŸ’– Locations of tracing files and directories:

these are your little map functions β€” they tell you where the tracing files and dirs actually live. πŸ”

char *tracefs_get_tracing_file(const char *name);
void tracefs_put_tracing_file(char *name);
const char *tracefs_tracing_dir(void);
const char *tracefs_debug_dir(void);
int tracefs_set_tracing_dir(char *tracing_dir)
int tracefs_tracing_dir_is_mounted(bool mount, const char **path);

(yes, tracefs_set_tracing_dir has no semicolon up there β€” that's how it's written in the page, and I am not touching it. respect the original, bestie. πŸ’€)


🧚 Trace instances:

instances are like little separate tracing worlds you can spin up. this is where the real main character energy lives. 🌈

struct tracefs_instance *tracefs_instance_create(const char *name);
int tracefs_instance_destroy(struct tracefs_instance *instance);
struct tracefs_instance *tracefs_instance_alloc(const char *tracing_dir, const char *name);
void tracefs_instance_free(struct tracefs_instance *instance);
char **tracefs_instances(const char *regex);
void tracefs_instance_clear(struct tracefs_instance *instance);
void tracefs_instance_reset(struct tracefs_instance *instance);
bool tracefs_instance_is_new(struct tracefs_instance *instance);
bool tracefs_file_exists(struct tracefs_instance *instance, char *name);
bool tracefs_dir_exists(struct tracefs_instance *instance, char *name);
char *tracefs_instance_get_file(struct tracefs_instance *instance, const char *file);
char *tracefs_instance_get_dir(struct tracefs_instance *instance);
int tracefs_instance_file_open(struct tracefs_instance *instance, const char *file, int mode);
int tracefs_instance_file_write(struct tracefs_instance *instance, const char *file, const char *str);
int tracefs_instance_file_write_number(struct tracefs_instance *instance, const char *file, size_t val);
int tracefs_instance_file_append(struct tracefs_instance *instance, const char *file, const char *str);
int tracefs_instance_file_clear(struct tracefs_instance *instance, const char *file);
char *tracefs_instance_file_read(struct tracefs_instance *instance, const char *file, int *psize);
int tracefs_instance_file_read_number(struct tracefs_instance *instance, const char *file, long long int *res);
const char *tracefs_instance_get_name(struct tracefs_instance *instance);
const char *tracefs_instance_get_trace_dir(struct tracefs_instance *instance);
int tracefs_instances_walk(int (*callback)(const char *, void *), void *context);
bool tracefs_instance_exists(const char *name);
int tracefs_instance_set_affinity(struct tracefs_instance *instance, const char *cpu_str);
int tracefs_instance_set_affinity_set(struct tracefs_instance *instance, cpu_set_t *set, size_t set_size);
int tracefs_instance_set_affinity_raw(struct tracefs_instance *instance, const char *mask);
char *tracefs_instance_get_affinity(struct tracefs_instance *instance);
int tracefs_instance_get_affinity_set(struct tracefs_instance *instance, cpu_set_t *set, size_t set_size);
char *tracefs_instance_get_affinity_raw(struct tracefs_instance *instance);
size_t tracefs_instance_get_buffer_size(struct tracefs_instance *instance, int cpu);
int tracefs_instance_set_buffer_size(struct tracefs_instance *instance, size_t size, int cpu);
int tracefs_instance_get_buffer_percent(struct tracefs_instance *instance);
int tracefs_instance_set_buffer_percent(struct tracefs_instance *instance, int val);

affinity, buffer sizes, buffer percentages, reading and writing files β€” it's giving full control, honestly. πŸ”₯


πŸ’œ Trace events:

events! the actual things happening in your kernel. this block is lowkey enormous, so buckle up. 🎒

char **tracefs_event_systems(const char *tracing_dir);
char **tracefs_system_events(const char *tracing_dir, const char *system);
int tracefs_event_enable(struct tracefs_instance *instance, const char *system,
                   const char *event);
int tracefs_event_disable(struct tracefs_instance *instance, const char *system,
                    const char *event);
enum tracefs_enable_state tracefs_event_is_enabled(struct tracefs_instance *instance,
                             const char *system, const char *event);
int tracefs_iterate_raw_events(struct tep_handle *tep, struct tracefs_instance *instance, cpu_set_t *cpus, int cpu_size, int (*callback)(struct tep_event *, struct tep_record *, int, void *), void *callback_context);
void tracefs_iterate_stop(struct tracefs_instance *instance);
int tracefs_follow_event(struct tep_handle *tep, struct tracefs_instance *instance,
                          const char *system, const char *event_name,
                          int (*callback)(struct tep_event *,
                                          struct tep_record *,
                                          int, void *),
                          void *callback_data);
int tracefs_follow_missed_events(struct tracefs_instance *instance,
                          int (*callback)(struct tep_event *,
                                          struct tep_record *,
                                          int, void *),
                          void *callback_data);
int tracefs_follow_event_clear(struct tracefs_instance *instance,
                  const char *system, const char *event_name);
int tracefs_follow_missed_events_clear(struct tracefs_instance *instance);
struct tep_handle *tracefs_local_events(const char *tracing_dir);
struct tep_handle *tracefs_local_events_system(const char *tracing_dir, const char * const *sys_names);
int tracefs_fill_local_events(const char *tracing_dir, struct tep_handle *tep, int *parsing_failures);
int tracefs_load_cmdlines(const char *tracing_dir, struct tep_handle *tep);
int tracefs_load_headers(const char *tracing_dir, struct tep_handle *tep);
char *tracefs_event_get_file(struct tracefs_instance *instance, const char *system, const char *event,
                     const char *file);
char *tracefs_event_file_read(struct tracefs_instance *instance, const char *system, const char *event,
                      const char *file, int *psize);
int tracefs_event_file_write(struct tracefs_instance *instance, const char *system, const char *event,
                     const char *file, const char *str);
int tracefs_event_file_append(struct tracefs_instance *instance, const char *system, const char *event,
                      const char *file, const char *str);
int tracefs_event_file_clear(struct tracefs_instance *instance, const char *system, const char *event,
                     const char *file);
bool tracefs_event_file_exists(struct tracefs_instance *instance, const char *system, const char *event,
                       const char *file);

the way there's a whole tracefs_follow_event / tracefs_follow_missed_events set with matching _clear versions β€” organized queen behaviour. πŸ‘‘


🌸 Snapshot buffer:

snapshot time!! grab the ring buffer exactly as it is right now, like a lil screenshot but for kernel events. πŸ“Έ

int tracefs_snapshot_snap(struct tracefs_instance *instance);
int tracefs_snapshot_clear(struct tracefs_instance *instance);
int tracefs_snapshot_free(struct tracefs_instance *instance);
int tracefs_iterate_snapshot_events(struct tep_handle *tep, struct tracefs_instance *instance,
                         cpu_set_t *cpus, int cpu_size,
                         int (*callback)(struct tep_event *, struct tep_record *, int, void *),
                         void *callback_context);
struct tracefs_cpu *tracefs_cpu_snapshot_open(struct tracefs_instance *instance,
                                     int cpu, bool nonblock);

πŸ“ Event filters:

filtering events so you only see the ones you care about β€” the curated feed of tracing, honestly. ⭐

int tracefs_filter_string_append(struct tep_event *event, char **filter,
                                 struct tracefs_filter type, const char *field,
                                 enum tracefs_synth_compare compare, const char *val);
int tracefs_filter_string_verify(struct tep_event *event, const char *filter, char **err);
int tracefs_event_filter_apply(struct tracefs_instance *instance, struct tep_event *event, const char *filter);
int tracefs_event_filter_clear(struct tracefs_instance *instance, struct tep_event *event);

πŸŽ€ Function filters:

same energy, but for functions. we love a consistent icon. πŸ’…

int tracefs_function_filter(struct tracefs_instance *instance, const char *filter, const char *module, int flags);
int tracefs_function_notrace(struct tracefs_instance *instance, const char *filter, const char *module, int flags);
int tracefs_filter_functions(const char *filter, const char *module, char ***list);

πŸ’– PID filters:

and now β€” filtering by process. get that pid outta here (or keep it, your call). πŸ™ˆ

int tracefs_filter_pid_function(struct tracefs_instance *instance, int pid,
                        bool reset, bool notrace);
int tracefs_filter_pid_function_clear(struct tracefs_instance *instance, bool notrace);
int tracefs_filter_pid_events(struct tracefs_instance *instance, int pid,
                        bool reset, bool notrace);
int tracefs_filter_pid_events_clear(struct tracefs_instance *instance, bool notrace);

πŸ¦‹ Trace helper functions:

the little helpers that make everything else bearable. lists, clocks, and turning tracing on and off. πŸ•

void tracefs_list_free(char **list);
char **tracefs_list_add(char *list, const char *string);
int *tracefs_list_size(char **list);
char *tracefs_get_clock(struct tracefs_instance *instance);
int tracefs_trace_is_on(struct tracefs_instance *instance);
int tracefs_trace_on(struct tracefs_instance *instance);
int tracefs_trace_off(struct tracefs_instance *instance);
int tracefs_trace_on_get_fd(struct tracefs_instance *instance);
int tracefs_trace_on_fd(int fd);
int tracefs_trace_off_fd(int fd);

(and yes, tracefs_list_size really does return int * in the page β€” not me, not my business, moving on. 😭)


🌈 Trace stream:

streaming the trace pipe β€” piping all that data around like it's nothing. 🌊

ssize_t tracefs_trace_pipe_stream(int fd, struct tracefs_instance *instance, int flags);
ssize_t tracefs_trace_pipe_print(struct tracefs_instance *instance, int flags);
void tracefs_trace_pipe_stop(struct tracefs_instance *instance);

πŸ”₯ Memory mapping the ring buffer:

mapping the ring buffer straight into memory. highkey the coolest block down here. 🧠✨

bool tracefs_cpu_is_mapped(struct tracefs_cpu *tcpu);
bool tracefs_mapped_is_supported(void);
int tracefs_cpu_map(struct tracefs_cpu *tcpu);
void tracefs_cpu_unmap(struct tracefs_cpu *tcpu);
struct tracefs_cpu *tracefs_cpu_open_mapped(struct tracefs_instance *instance,
                                        int cpu, bool nonblock);

and that's the whole synopsis, bestie β€” every single declaration, intact, exactly as written. we're only getting started though, because there's so much more coming. don't go anywhere. πŸ’œ

okay so the SYNOPSIS keeps going (this library has range πŸ’…) and here's the rest of it β€” every single prototype, grouped exactly how the page groups them. no skipping, no summarizing, because leaving stuff out would be a literal crime fr fr.

πŸŽ€ Trace options:

const struct tracefs_options_mask *tracefs_options_get_supported(struct tracefs_instance *instance);
bool tracefs_option_is_supported(struct tracefs_instance *instance, enum tracefs_option_id id);
const struct tracefs_options_mask *tracefs_options_get_enabled(struct tracefs_instance *instance);
bool tracefs_option_is_enabled(struct tracefs_instance *instance, enum tracefs_option_id id);
bool tracefs_option_mask_is_set(const struct tracefs_options_mask options, enum tracefs_option_id id);
int *tracefs_option_enable(struct tracefs_instance *instance, enum tracefs_option_id id);
int tracefs_option_disable(struct tracefs_instance *instance, enum tracefs_option_id id);
const char *tracefs_option_name(enum tracefs_option_id id);
enum tracefs_option_id tracefs_option_id(const char *name);

like get the supported ones, check if one is supported, get the enabled ones, check if one's enabled, check if a mask is set, enable, disable, then the little name↔id go-betweens so you can translate in both directions πŸ¦‹. main character energy, honestly.


🌸 Ftrace tracers:

char **tracefs_tracers(const char *tracing_dir);
char ** tracefs_instance_tracers(struct tracefs_instance *instance);
bool tracefs_tracer_available(const char *tracing_dir, const char *tracer);
int tracefs_tracer_set(struct tracefs_instance *instance, enum tracefs_tracers tracer);
int tracefs_tracer_set(struct tracefs_instance *instance, enum tracefs_tracers tracer, const char *name);
int tracefs_tracer_clear(struct tracefs_instance *instance);

so there's the list-everything one, the per-instance list, the "is this tracer even available" vibe check, two flavours of tracefs_tracer_set (yes bestie, it's the same name twice β€” the page says so, so it stays 🫢), and tracefs_tracer_clear to wipe it clean.


⭐ Writing data in the trace buffer:

int tracefs_print_init(struct tracefs_instance *instance);
int tracefs_printf(struct tracefs_instance *instance, const char *fmt, ...);
int tracefs_vprintf(struct tracefs_instance *instance, const char *fmt, va_list ap);
void tracefs_print_close(struct tracefs_instance *instance);
int tracefs_binary_init(struct tracefs_instance *instance);
int tracefs_binary_write(struct tracefs_instance *instance, void *data, int len);
void tracefs_binary_close(struct tracefs_instance *instance);

okay so there's a whole print era (init β†’ printf/vprintf β†’ close) and a whole binary era (init β†’ write β†’ close) β€” pick your lane, just don't forget the close, that's the rule 😭.


πŸ’œ Control library logs:

int tracefs_set_loglevel(enum tep_loglevel level);

one function, one job: set the log level. iconic minimalism.


🧚 Read the ring buffer statistics:

struct tracefs_buffer_stat *tracefs_instance_get_stat(struct tracefs_instance *instance, int cpu);
void tracefs_instance_put_stat(struct tracefs_buffer_stat *tstat);
ssize_t tracefs_buffer_stat_entries(struct tracefs_buffer_stat *tstat);
ssize_t tracefs_buffer_stat_overrun(struct tracefs_buffer_stat *tstat);
ssize_t tracefs_buffer_stat_commit_overrun(struct tracefs_buffer_stat *tstat);
ssize_t tracefs_buffer_stat_bytes(struct tracefs_buffer_stat *tstat);
long long tracefs_buffer_stat_event_timestamp(struct tracefs_buffer_stat *tstat);
long long tracefs_buffer_stat_timestamp(struct tracefs_buffer_stat *tstat);
ssize_t tracefs_buffer_stat_dropped_events(struct tracefs_buffer_stat *tstat);
ssize_t tracefs_buffer_stat_read_events(struct tracefs_buffer_stat *tstat);

grab the stats for a cpu, then get every little number out of it: entries, overrun, commit_overrun, bytes, the event_timestamp, the plain timestamp, dropped_events, read_events β€” and when you're done, tracefs_instance_put_stat it back. take care of your structs, bestie οΏ½


πŸ¦‹ Dynamic event generic APIs:

struct tracefs_dynevent;
enum tracefs_dynevent_type;
int tracefs_dynevent_create(struct tracefs_dynevent *devent);
int tracefs_dynevent_destroy(struct tracefs_dynevent *devent, bool force);
int tracefs_dynevent_destroy_all(unsigned int types, bool force);
void tracefs_dynevent_free(struct tracefs_dynevent *devent);
void tracefs_dynevent_list_free(struct tracefs_dynevent **events);
struct tracefs_dynevent *tracefs_dynevent_get(enum tracefs_dynevent_type type, const char *system, const char *event);
struct tracefs_dynevent **tracefs_dynevent_get_all(unsigned int types, const char *system);
enum tracefs_dynevent_type tracefs_dynevent_info(struct tracefs_dynevent *dynevent, char **system, char **event, char **prefix, char **addr, char **format);
struct tep_event *tracefs_dynevent_get_event(struct tep_handle *tep, struct tracefs_dynevent *dynevent);

the whole lifecycle fr: create it, destroy it (with a force flag πŸ‘€), or destroy_all the ones matching types (also with force), free the one, free the whole events list, get one by type/system/event, get_all by types/system, pull info out into system/event/prefix/addr/format, and grab the struct tep_event * via tracefs_dynevent_get_event. phew, she's thorough πŸ’…


πŸ”₯ Even probes (eprobes):

struct tracefs_dynevent * tracefs_eprobe_alloc(const char *system, const char *event, const char *target_system, const char *target_event, const char *fetchargs);

(yes the page really says "Even probes" and yes we're keeping it exactly like that, no cap 🫢) β€” one alloc, five args: system, event, target_system, target_event, fetchargs.


🐝 Uprobes, Kprobes and Kretprobes:

struct tracefs_dynevent * tracefs_kprobe_alloc(const char *system, const char *event, const char *addr, const char *format);
struct tracefs_dynevent * tracefs_kretprobe_alloc(const char *system, const char *event, const char *addr, const char *format, unsigned int max);
int tracefs_kprobe_raw(const char *system, const char *event, const char *addr, const char *format);
int tracefs_kretprobe_raw(const char *system, const char *event, const char *addr, const char *format);
tracefs_uprobe_alloc(const char *system, const char *event,
             const char *file, unsigned long long offset, const char *fetchargs)
tracefs_uretprobe_alloc(const char *system, const char *event,
             const char *file, unsigned long long offset, const char *fetchargs);
int tracefs_kprobe_destroy(const char *system, const char *event,
                   const char *addr, const char *format, bool force);

the whole probe fam is here πŸ‘‘ β€” kprobe_alloc, kretprobe_alloc (that one's got an extra unsigned int max), the raw kprobe_raw and kretprobe_raw, then uprobe_alloc and uretprobe_alloc (note: those two are written exactly as the page writes them, so keep them that way, don't "fix" them πŸ™ˆ), and kprobe_destroy with its force flag.


🌈 Synthetic events:

struct tracefs_synth *tracefs_sql(struct tep_handle *tep, const char *name,
                                const char *sql_buffer, char **err);
struct tracefs_synth *tracefs_synth_alloc(struct tep_handle *tep,
                                         const char *name,
                                         const char *start_system,
                                         const char *start_event,
                                         const char *end_system,
                                         const char *end_event,
                                         const char *start_match_field,
                                         const char *end_match_field,
                                         const char *match_name);
int tracefs_synth_add_match_field(struct tracefs_synth *synth,
                                  const char *start_match_field,
                                  const char *end_match_field,
                                  const char *name);
int tracefs_synth_add_compare_field(struct tracefs_synth *synth,
                                    const char *start_compare_field,
                                    const char *end_compare_field,
                                    enum tracefs_synth_calc calc,
                                    const char *name);
int tracefs_synth_add_start_field(struct tracefs_synth *synth,
                                  const char *start_field,
                                  const char *name);
int tracefs_synth_add_end_field(struct tracefs_synth *synth,
                                const char *end_field,
                                const char *name);
int tracefs_synth_append_start_filter(struct tracefs_synth *synth,
                                      struct tracefs_filter type,
                                      const char *field,
                                      enum tracefs_synth_compare compare,
                                      const char *val);
int tracefs_synth_append_end_filter(struct tracefs_synth *synth,
                                    struct tracefs_filter type,
                                    const char *field,
                                    enum tracefs_synth_compare compare,
                                    const char *val);
void tracefs_synth_free(struct tracefs_synth *synth);
int tracefs_synth_create(struct tracefs_synth *synth);
int tracefs_synth_destroy(struct tracefs_synth *synth);
int tracefs_synth_set_instance(struct tracefs_synth *synth, struct tracefs_instance *instance);
int tracefs_synth_echo_cmd(struct trace_seq *seq, struct tracefs_synth *synth);
bool tracefs_synth_complete(struct tracefs_synth *synth);
struct tracefs_hist *tracefs_synth_get_start_hist(struct tracefs_synth *synth);
int tracefs_synth_trace(struct tracefs_synth *synth,
                        enum tracefs_synth_handler type, const char *var);
int tracefs_synth_snapshot(struct tracefs_synth *synth,
                           enum tracefs_synth_handler type, const char *var);
int tracefs_synth_save(struct tracefs_synth *synth,
                       enum tracefs_synth_handler type, const char *var,
                       char **save_fields);
const char *tracefs_synth_get_name(struct tracefs_synth *synth);
int tracefs_synth_raw_fmt(struct trace_seq *seq, struct tracefs_synth *synth);
const char *tracefs_synth_show_event(struct tracefs_synth *synth);
const char *tracefs_synth_show_start_hist(struct tracefs_synth *synth);
const char *tracefs_synth_show_end_hist(struct tracefs_synth *synth);
struct tep_event *tracefs_synth_get_event(struct tep_handle *tep, struct tracefs_synth *synth);

okay this one is the big one, the synth era πŸ’–. tracefs_sql builds one straight from a SQL buffer (with err to catch the tea β˜•). then tracefs_synth_alloc with the full start/end setup, add_match_field, add_compare_field (that's the one with enum tracefs_synth_calc calc), add_start_field, add_end_field, append_start_filter and append_end_filter (both taking struct tracefs_filter type and enum tracefs_synth_compare compare), free, create, destroy, set_instance, the tracefs_synth_echo_cmd into a struct trace_seq *, tracefs_synth_complete returning bool, tracefs_synth_get_start_hist handing back a struct tracefs_hist *, then the triggers: tracefs_synth_trace, tracefs_synth_snapshot, and tracefs_synth_save (that one's got char **save_fields). plus getters: get_name, raw_fmt, show_event, show_start_hist, show_end_hist, and tracefs_synth_get_event for your struct tep_event *. she ate and left no crumbs πŸ‘‘


πŸ“ Ftrace errors reporting:

char *tracefs_error_last(struct tracefs_instance *instance);
char *tracefs_error_all(struct tracefs_instance *instance);
int tracefs_error_clear(struct tracefs_instance *instance);

the last error, all the errors, and a clean tracefs_error_clear to reset the slate. so valid, so needed 😭


and that's the entire synopsis bestie, like literally every single line πŸ’€ stay locked in, the actual explanations are up next 🫢✨

πŸŽ€ Histograms πŸŽ€

okay so the histogram girlies β€” this whole tracefs_hist_* crew β€” signatures straight up, exactly as written, no editing bestie:

struct tracefs_hist *tracefs_hist_alloc(struct tracefs_tep * tep,
                                        const char *system, const char *event,
                                        const char *key, enum tracefs_hist_key_type type);
struct tracefs_hist *tracefs_hist_alloc_2d(struct tracefs_tep * tep,
                                        const char *system, const char *event,
                                        const char *key1, enum tracefs_hist_key_type type1,
                                        const char *key2, enum tracefs_hist_key_type type2));
struct tracefs_hist *tracefs_hist_alloc_nd(struct tracefs_tep * tep,
                                        const char *system, const char *event,
                                        struct tracefs_hist_axis *axes);
struct tracefs_hist *tracefs_hist_alloc_nd_cnt(struct tep_handle *tep,
                                          const char *system, const char *event_name,
                                          struct tracefs_hist_axis_cnt *axes);
void tracefs_hist_free(struct tracefs_hist *hist);
int tracefs_hist_add_key(struct tracefs_hist *hist, const char *key,
                         enum tracefs_hist_key_type type);
int tracefs_hist_add_key_cnt(struct tracefs_hist *hist, const char *key,
                         enum tracefs_hist_key_type type, int cnt);
int tracefs_hist_add_value(struct tracefs_hist *hist, const char *value);
int tracefs_hist_add_sort_key(struct tracefs_hist *hist,
                              const char *sort_key);
int tracefs_hist_set_sort_key(struct tracefs_hist *hist,
                              const char *sort_key, ...);
int tracefs_hist_sort_key_direction(struct tracefs_hist *hist,
                                    const char *sort_key,
                                    enum tracefs_hist_sort_direction dir);
int tracefs_hist_add_name(struct tracefs_hist *hist, const char *name);
int tracefs_hist_append_filter(struct tracefs_hist *hist,
                               enum tracefs_filter type,
                               const char *field,
                               enum tracefs_compare compare,
                               const char *val);
int tracefs_hist_echo_cmd(struct trace_seq *s, struct tracefs_instance *instance,
                          struct tracefs_hist *hist,
                          enum tracefs_hist_command command);
int tracefs_hist_command(struct tracefs_instance *instance,
                         struct tracefs_hist *hist,
                         enum tracefs_hist_command command);
const char *tracefs_hist_get_name(struct tracefs_hist *hist);
const char *tracefs_hist_get_event(struct tracefs_hist *hist);
const char *tracefs_hist_get_system(struct tracefs_hist *hist);
int tracefs_hist_start(struct tracefs_instance *instance, struct tracefs_hist *hist);
int tracefs_hist_destroy(struct tracefs_instance *instance, struct tracefs_hist *hist);
int tracefs_hist_pause(struct tracefs_instance *instance, struct tracefs_hist *hist);
int tracefs_hist_continue(struct tracefs_instance *instance, struct tracefs_hist *hist);
int tracefs_hist_reset(struct tracefs_instance *instance, struct tracefs_hist *hist);

like, that's the whole roster πŸ’… alloc fam (tracefs_hist_alloc, tracefs_hist_alloc_2d, tracefs_hist_alloc_nd, tracefs_hist_alloc_nd_cnt), the free-er (tracefs_hist_free), the key/value/sort crew, the filter + command girlies, the three getters, and the lifecycle squad (tracefs_hist_start, tracefs_hist_destroy, tracefs_hist_pause, tracefs_hist_continue, tracefs_hist_reset). copy them character for character, i do not make the rules 🫢


🌈 Recording of trace_pipe_raw files 🌈

the tracefs_cpu_* besties β€” literally here for the raw pipe life:

struct tracefs_cpu *tracefs_cpu_open(struct tracefs_instance *instance,
                                     int cpu, bool nonblock);
struct tracefs_cpu *tracefs_cpu_alloc_fd(int fd, int subbuf_size, bool nonblock);
void tracefs_cpu_close(struct tracefs_cpu *tcpu);
void tracefs_cpu_free_fd(struct tracefs_cpu *tcpu);
int tracefs_cpu_read_size(struct tracefs_cpu *tcpu);
int tracefs_cpu_read(struct tracefs_cpu *tcpu, void *buffer, bool nonblock);
int tracefs_cpu_buffered_read(struct tracefs_cpu *tcpu, void *buffer, bool nonblock);
int tracefs_cpu_write(struct tracefs_cpu *tcpu, int wfd, bool nonblock);
int tracefs_cpu_stop(struct tracefs_cpu *tcpu);
int tracefs_cpu_flush(struct tracefs_cpu *tcpu, void *buffer);
int tracefs_cpu_flush_write(struct tracefs_cpu *tcpu, int wfd);
int tracefs_cpu_pipe(struct tracefs_cpu *tcpu, int wfd, bool nonblock);
struct kbuffer *tracefs_cpu_read_buf(struct tracefs_cpu *tcpu, bool nonblock);
struct kbuffer *tracefs_cpu_buffered_read_buf(struct tracefs_cpu *tcpu, bool nonblock);
struct kbuffer *tracefs_cpu_flush_buf(struct tracefs_cpu *tcpu);

notice the nonblock param showing up everywhere β€” she's consistent, she's committed 😌


πŸ¦‹ Helper functions for modifying the ring buffer sub-buffers πŸ¦‹

two little icons, get and set, for the sub-buffer size:

size_t tracefs_instance_get_subbuf_size(struct tracefs_instance *instance);
int tracefs_instance_set_subbuf_size(struct tracefs_instance *instance, size_t size);

🧚 Helper functions for guest tracing 🧚

the guest-tracing corner of the library, cid and pid and time conversion vibes:

char *tracefs_find_cid_pid(int cid);
char *tracefs_instance_find_cid_pid(struct tracefs_instance *instance, int cid);
int tracefs_time_conversion(int cpu, int *shift, int *multi, long long *offset);

✨ DESCRIPTION ✨

so what is libtracefs(3)? literally just this, no cap:

The libtracefs(3) library provides APIs to access kernel trace file system.

that's the whole pitch, bestie. APIs β†’ kernel trace file system. iconic behavior πŸ‘‘


πŸŽ€ FILES πŸŽ€

  • tracefs.h β€” the header file you gotta include to get access to the library APIs πŸ’–
  • -ltracefs β€” the linker switch you add when you're building a program that uses the library ✨

🌸 SEE ALSO 🌸

go read those too, iykyk 🫢


πŸ‘‘ AUTHOR πŸ‘‘

  • Steven Rostedt <rostedt@goodmis.org>
  • Tzvetomir Stoyanov <tz.stoyanov@gmail.com>

πŸ’€ REPORTING BUGS πŸ’€

found a bug? don't suffer in silence β€” report it to <linux-trace-devel@vger.kernel.org>. they wanna hear it fr fr πŸ›


πŸ“ LICENSE πŸ“

libtracefs is Free Software licensed under the GNU LGPL 2.1.


⭐ RESOURCES ⭐

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

that's the spot 🧚


πŸ’œ COPYING πŸ’œ

Copyright (C) 2020 VMware, Inc. Free use of this software is granted under the terms of the GNU Public License (GPL).


πŸ™ˆ NOTES πŸ™ˆ

  1. rostedt@goodmis.org β€” mailto:rostedt@goodmis.org
  2. tz.stoyanov@gmail.com β€” mailto:tz.stoyanov@gmail.com
  3. linux-trace-devel@vger.kernel.org β€” mailto:linux-trace-devel@vger.kernel.org

and that's the whole page, bestie β€” this was libtracefs 1.8.4, dated 10/21/2026, the LIBTRACEFS(3) of all time. go forth and trace ur little heart out πŸ’…βœ¨πŸŒΈ

πŸ“¦ where this page comes from