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 π
rostedt@goodmis.orgβmailto:rostedt@goodmis.orgtz.stoyanov@gmail.comβmailto:tz.stoyanov@gmail.comlinux-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
- arch rolling: libtracefs 1.8.4-1 Β· GPL-2.0-only AND LGPL-2.1-only
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms