Re: Extracting data from tracepoints (and anything else)


Tristan Mayfield
 

I've spent a few days trying to solve this issue I've had, and I've learned a lot about both the past BPF APIs, and the new CO-RE API. I do have a couple questions though.
  • Once a CO-RE program is compiled and tested with the verifier, can it be run on a kernel of the same version that isn't compiled with BTF?
  • The CO-RE API is very nice, but in case that ends up only being able to run on kernels with BTF support enabled, I've been trying to solve the original issue found in this topic without the CO-RE approach. I'm still not able to read the arguments from a given tracepoint. I'll put my code below. I'm sure there are still plenty of issues and appreciate any time given to nudge me in the right direction.
#include <linux/bpf.h>
#include "bpf_helpers.h"

// To get kernel datatypes. Haven't figured out how to do this
// without cloning the kernel source tree yet.
#include "/kernel-src/tools/include/linux/types.h"
#include <linux/version.h>
#include <asm/ptrace.h>
#include <unistd.h>
#define MAX_CPUS 4

struct bpf_map_def SEC("maps") events = {
  .type = BPF_MAP_TYPE_PERF_EVENT_ARRAY,
  .key_size = sizeof(int),
  .value_size = sizeof(u32),
  .max_entries = MAX_CPUS,
};

// Struct to pass data via perf buffer
struct data_t {
    u32 pid;
    u32 tgid;
    char program_name[16]; // max comm length is arbitrary
    char file[255];
};

struct sys_enter_openat_args {
    // struct fields obtained from tplist.py output
    long long pad;
    int __syscall_nr;
    int dfd;
    const char * filename;
    int flags;
    __mode_t mode;  // used __mode_t instead of umode_t
};

SEC("tracepoint/syscalls/sys_enter_openat")
int bpf_prog(struct sys_enter_openat_args *ctx)
{
  struct data_t data = {};

  data.pid = bpf_get_current_pid_tgid() >> 32;
  data.tgid = bpf_get_current_pid_tgid();
  bpf_get_current_comm(&data.program_name, sizeof(data.program_name));

  int err = bpf_probe_read_str(data.file, sizeof(data.file), ctx->filename);

  // debugging
  char msg[] = "Probe read results: %d\n";
  bpf_trace_printk(msg, sizeof(msg), ctx->err);

  bpf_perf_event_output(ctx, &events, 0, &data, sizeof(data));

  return 0;
}
char _license[] SEC("license") = "GPL";
u32 _version SEC("version") = LINUX_VERSION_CODE;

With the above code, err = -14 and ctx->filename = -100.
I took a look at an article written by

Join iovisor-dev@lists.iovisor.org to automatically receive all group messages.