Andrii Nakryiko wrote: > On Tue, Apr 6, 2021 at 9:49 PM Rafael David Tinoco > <rafaeldtinoco@xxxxxxxxxx> wrote: > > > > Sorry taking so long for replying on this… have been working in: > > https://github.com/rafaeldtinoco/conntracker/tree/main/ebpf > > as a consumer for the work being proposed by this patch. > > > > Current working version at: > > https://github.com/rafaeldtinoco/conntracker/blob/main/ebpf/patches/libbpf-introduce-legacy-kprobe-events-support.patch > > About to be changed with suggestions from this thread. > > Just catching up on this thread now. > > > don't get why you need this function either... > > > > Because of /sys/kernel/debug/tracing/events/kprobes/%s/enable. I’m > > toggling it to OFF before removing the kprobe in kprobe_events, like > > showed above. > > Alright, see above about enable files, it doesn't seem necessary, > actually. You use poke_kprobe_events() to add or remove kprobe to the > kernel. That gives you event_name and its id (from > /sys/kernel/debug/tracing/events/kprobes/%s/id). You then use that id > to create perf_event and activate BPF program: > > struct perf_event_attr attr; > struct bpf_link* link; > int fd = -1, err, id; > FILE* f = NULL; > > err = poke_kprobe_events(true /*add*/, func_name, is_kretprobe); > if (err) { > fprintf(stderr, "failed to create kprobe event: %d\n", err); > return NULL; > } > > snprintf( > fname, > sizeof(fname), > "/sys/kernel/debug/tracing/events/kprobes/%s/id", > func_name); > f = fopen(fname, "r"); > if (!f) { > fprintf(stderr, "failed to open kprobe id file '%s': %d\n", fname, -errno); > goto err_out; > } > > if (fscanf(f, "%d\n", &id) != 1) { > fprintf(stderr, "failed to read kprobe id from '%s': %d\n", fname, -errno); > goto err_out; > } > > fclose(f); > f = NULL; > > memset(&attr, 0, sizeof(attr)); > attr.size = sizeof(attr); > attr.config = id; > attr.type = PERF_TYPE_TRACEPOINT; > attr.sample_period = 1; > attr.wakeup_events = 1; > > fd = syscall(__NR_perf_event_open, &attr, -1, 0, -1, PERF_FLAG_FD_CLOEXEC); > if (fd < 0) { > fprintf( > stderr, > "failed to create perf event for kprobe ID %d: %d\n", > id, > -errno); > goto err_out; > } > > link = bpf_program__attach_perf_event(prog, fd); > > And that should be it. It doesn't seem like either BCC or my example > (which I'm sure worked last time) does anything with /enable files and > I'm sure all that works. FWIW I also have a similar patch on my stack that does this and was working fine for us. I've got a note here to submit it, but its been stuck on the todo list. I'll post it here maybe its helpful, +static int write_to_kprobe_events(const char *name, + uint64_t offset, int pid, bool retprobe) +{ + const char *kprobe_events = "/sys/kernel/debug/tracing/kprobe_events"; + int fd = open(kprobe_events, O_WRONLY | O_APPEND, 0); + char buf[PATH_MAX]; + int err; + + if (fd < 0) { + err = -errno; + pr_warn("Failed open kprobe_events: %s\n", strerror(errno)); + return err; + } + snprintf(buf, sizeof(buf), "%c:kprobes/%s %s", + retprobe ? 'r' : 'p', name, name); + err = write(fd, buf, strlen(buf)); + close(fd); + if (err < 0) { + err = -errno; + pr_warn("Failed write kprobe_events: %s\n", strerror(errno)); + return err; + } + return 0; +} + +/* If we do not have an event_source/../kprobes then we can try to use + * kprobe-base event tracing, for details see documentation kprobetrace.rst + */ +static int perf_event_open_probe_debugfs(bool uprobe, bool retprobe, const char *name, + uint64_t offset, int pid) +{ + const char *kprobes_dir = "/sys/kernel/debug/tracing/events/kprobes/"; + struct perf_event_attr attr = {}; + char errmsg[STRERR_BUFSIZE]; + char file[PATH_MAX]; + int pfd, err, id; + + if (uprobe) { + return -EOPNOTSUPP; + } else { + err = write_to_kprobe_events(name, offset, pid, retprobe); + if (err < 0) + return err; + err = snprintf(file, sizeof(file), "%s/%s/id", kprobes_dir, name); + if (err < 0) + return -errno; + id = parse_uint_from_file(file, "%d\n"); + if (id < 0) + return err; + attr.size = sizeof(attr); + attr.type = PERF_TYPE_TRACEPOINT; + attr.config = id; + } + + /* pid filter is meaningful only for uprobes */ + pfd = syscall(__NR_perf_event_open, &attr, + pid < 0 ? -1 : pid /* pid */, + pid == -1 ? 0 : -1 /* cpu */, + -1 /* group_fd */, PERF_FLAG_FD_CLOEXEC); + if (pfd < 0) { + err = -errno; + pr_warn("%s perf_event_open_probe_debugfs() failed: %s\n", + uprobe ? "uprobe" : "kprobe", + libbpf_strerror_r(err, errmsg, sizeof(errmsg))); + return err; + } + return pfd; +} > > [...] > > > >>> return bpf_program__attach_kprobe(prog, retprobe, func_name);