Re: Building BPF programs and kernel persistence
Andrii Nakryiko
On Mon, May 11, 2020 at 10:06 AM <mayfieldtristan@...> wrote:
Hi! For the future, I think cc'ing bpf@... would be a good idea, there are a lot of folks who are probably not watching iovisor mailing list, but could help with issues like this. I'd start with actually specifying what compilation errors you run into. Also check out https://github.com/iovisor/bcc/blob/master/libbpf-tools/Makefile to see how BPF programs can be compiled properly outside of kernel tree. Though that one pretty much assumes vmlinux.h, which simplifies a bunch of compilation issues, probably. Right, pinning map or program doesn't ensure that program is still attached to whatever BPF hook you attached to it. As you mentioned, XDP, tc, cgroup-bpf programs are persistent. We are actually moving towards the model of auto-detachment for those as well. See recent activity around bpf_link. The solution with bpf_link to make such attachments persistent is through pinning **link** itself, not program or map. bpf_link is relatively recent addition, so on older kernels you'd have to make sure you still have some process around that would keep BPF attachment FD around.
Hope above helped. Please cc bpf@... (and ideally send plain-text emails, kernel mailing lists don't accept HTML emails). |
|
Re: eBPF map - Control and Data plane concurrency
#bcc
Simone Magnani
Thanks for the suggestion, now I feel more confident about this solution. However, I have still problems with the map-in-map type: is it possible to use a map which has as key the 4 tcp-session identifier {srcIp, dstIp, srcPort, dstPort} and as value a BPF_ARRAY which is a list of some packets' headers belonging to that session? |
|
Building BPF programs and kernel persistence
Tristan Mayfield
Hi all, hope everyone is staying healthy out there. I've been working on building BPF programs, and have run into a few issues that I think might be clang (vs gcc) based. It seems that either clang isn't the most friendly of compilers when it comes to building Linux-native programs, or my lack of experience makes it seem so. I've been trying to build the simple BPF program below:
#include "bpf_helpers.h" #include <linux/bpf.h> #include <linux/version.h> #include <linux/types.h> #include <linux/tcp.h> #include <net/sock.h> struct inet_sock_set_state_args { long long pad; const void * skaddr; int oldstate; int newstate; u16 sport; u16 dport; u16 family; u8 protocol; u8 saddr[4]; u8 daddr[4]; u8 saddr_v6[16]; u8 daddr_v6[16]; }; SEC("tracepoint/sock/inet_sock_set_state") int bpf_prog(struct inet_sock_set_state_args *args) { struct sock *sk = (struct sock *)args->skaddr; short lport = args->sport; char msg[] = "lport: %d\n"; bpf_trace_printk(msg, sizeof(msg), lport); return 0; } char _license[] SEC("license") = "GPL"; I've been looking through selftests/bpf/, samples/bpf/, and examples on various blogs and articles.
From this, I've come up with the following makefile:
## Build tools LLC := llc CC := clang HOSTCC := clang CLANGINC := /usr/lib/llvm-10/lib/clang/10.0.0/include ## Some useful flags INC_FLAGS := -nostdinc -isystem $(CLANGINC) EXTRA_FLAGS := -O3 -emit-llvm ## Includes linuxhdrs := /usr/src/linux-headers-$(shell uname -r) LINUXINCLUDE := -include $(linuxhdrs)/include/linux/kconfig.h \ -include /usr/include/linux/bpf.h \ -I$(linuxhdrs)/arch/x86/include/ \ -I$(linuxhdrs)/arch/x86/include/uapi \ -I$(linuxhdrs)/arch/x86/include/generated \ -I$(linuxhdrs)/arch/x86/include/generated/uapi \ -I$(linuxhdrs)/include \ -I$(linuxhdrs)/include/uapi \ -I$(linuxhdrs)/include/generated/uapi \ LIBBPF := -I/home/vagrant/libbpf/src/ OBJS := tcptest.bpf.o $(OBJS): %.o:%.c $(CC) $(INC_FLAGS) \ -target bpf -D__KERNEL__ -D __ASM_SYSREG_H \ -D__BPF_TRACING__ -D__TARGET_ARCH_$(ARCH) \ -Wno-unused-value -Wno-pointer-sign \ -Wno-compare-distinct-pointer-types \ -Wno-gnu-variable-sized-type-not-at-end \ -Wno-address-of-packed-member \ -Wno-tautological-compare \ -Wno-unknown-warning-option \ -Wall -v \ $(LINUXINCLUDE) $(LIBBPF) \ $(EXTRA_FLAGS) -c $< -o - | $(LLC) -march=bpf -filetype obj -o $ Unfortunately, I keep running into what seems to be asm errors. I've tried reorganizing the list of include statements, taking out "-target bpf", not including some files, including other files, etc etc.
This stackoverflow post suggests that it's a kconfig.h error, but I seem to be including the file just fine (https://stackoverflow.com/questions/56975861/error-compiling-ebpf-c-code-out-of-kernel-tree/56990939#56990939).
I'm not really sure where to go from here with building BPF programs and including files that have the kernel datatypes. Maybe I'm missing something that's obvious that I'm just ignorant of?
As additional information, and regarding kernel persistence, I am working on a monitoring project that uses BPF programs to continuously monitor the system without the bulky dependencies that BCC includes. I'm concurrently working on a BTF/CO-RE solution but I'm emphasizing a non-CO-RE approach at the moment. I can load and run BPF programs but upon termination of my userspace loader the BPF programs themselves also terminate.
I would like to have the BPF program persist in the kernel even after the user space loader has completed its execution. I read in various documentation and in a 2015 LWN article that persistent BPF programs can be created by pinning programs and maps to the BPF vfs so as to keep the fds open. I have attempted pinning the entire BPF object, various programs and various maps, and no matter what I've tried the kernel BPF program terminates when the userspace process terminates. Using bpftool I have verified that the BPF files are pinned to the location and that BPF programs themselves all work. I know that persistent BPF programs are a part of projects like XDP and tc. Is there a way to do this for a generic BPF loader without having to implement customized kernel functions? Below I have included a simplified version of my code. In which I outline the basic steps I take to load the compiled bpf programs and attempt to make persistent instances of them.
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <getopt.h> #include <dirent.h> #include <sys/stat.h> #include <unistd.h> #include <assert.h> #include <linux/version.h>
#include "libbpf.h" #include "bpf.h" #include "loader_helpers.h"
#include <stdbool.h> #include <fcntl.h> #include <poll.h> #include <linux/perf_event.h> #include <assert.h> #include <sys/syscall.h> #include <sys/ioctl.h> #include <sys/mman.h> #include <time.h> #include <signal.h> #include <linux/ptrace.h>
int main(int argc, char **argv) {
struct bpf_object *bpf_obj; struct bpf_program *bpf_prog; struct bpf_map *map; char * license = "GPL"; __u32 kernelvers = LINUX_VERSION_CODE; struct bpf_link * link; int err; int prog_fd;
bpf_obj = bpf_object__open("test_file.bpf.o");
bpf_prog = bpf_program__next(NULL, bpf_obj);
err = bpf_program__set_tracepoint(bpf_prog); if(err) { fprintf(stderr, "ERR couldn't setup program type\n"); return -1; } err = bpf_program__load(bpf_prog, license, kernelvers); if(err) { fprintf(stderr, "ERR couldn't setup program phase\n"); return -1; } prog_fd = bpf_program__fd(bpf_prog);
link = bpf_program__attach_tracepoint(bpf_prog, "syscalls", "sys_enter_openat"); if(!link) { fprintf(stderr, "ERROR ATTACHING TRACEPOINT\n"); return -1; }
assert(bpf_program__is_tracepoint(bpf_prog));
pin: err = bpf_program__pin(bpf_prog, "/sys/fs/bpf/tpprogram"); if(err) { if(err == -17) { printf("Program exists...trying to unpin and retry!\n"); err = bpf_program__unpin(bpf_prog, "/sys/fs/bpf/tpprogram"); if(!err) { goto pin; } printf("The pining already exists but it couldn't be removed...\n"); return -1; } printf("We couldn't pin...%d\n", err); return -1; }
printf("Program pinned and working...\n");
return 0; } Thanks for having a look and I hope these issues can be cleared up. Seems like building is the last major hurdle I have to get rolling with better engineering solutions than manually including structs in my files. Hope everyone stays well! |
|
Re: eBPF map - Control and Data plane concurrency
#bcc
Yonghong Song
Your approach seems okay. You can use two maps or use map-in-map.
toggle quoted message
Show quoted text
Using batch operation from user space should speedup the deletion operation. On Sat, May 9, 2020 at 5:31 AM <simonemagnani.96@...> wrote:
|
|
eBPF map - Control and Data plane concurrency
#bcc
Simone Magnani
Hi everybody,
I am writing this email to ask for an opinion about how to address the following problem. Lately, I have been trying to develop an eBPF program that extracts some per-flow values and stores them into an eBPF HASH_MAP, which is then read by the user-space that extracts the stored information. When I start reading the map from user-space, all the entries should be deleted at the same time, and the data plane should keep storing the incoming data. The solution that I have found is to use two maps (and programs) that are continuously swapped when the user-space read is triggered. In this way, when we read the 'old' map, the 'new' map keeps storing the new data. At the same time, to speed up the lookup and delete operation, I could use the recently added "bpf_map_lookup_and_delete_batch" function to read and clear the map. Do you think this could be an optimal solution, or are there other more efficient methods? Thanks in advance for all the suggestions Best Regards, Simone |
|
Re: #bcc - skb_network_header crashes in a BPF Kernel trace function
#bcc
Yonghong Song
On Wed, May 6, 2020 at 11:00 PM Yonghong Song via lists.iovisor.org
<ys114321=gmail.com@...> wrote: I see the issue now. ip_hdr(skb) eventually transforms to static inline unsigned char *skb_network_header(const struct sk_buff *skb) { return skb->head + skb->network_header; } The above two pointer dereferences need bpf probe read. Unfortunately, you may need put the above function in your bpf program so you could use bpf_probe_read to access skb->head and skb->network_header.
|
|
Re: #bcc - skb_network_header crashes in a BPF Kernel trace function
#bcc
Yonghong Song
On Wed, May 6, 2020 at 9:26 AM <vigs.prof@...> wrote:
You did not show the code which actually caused the problem. bpf_probe_read(&ip_Hdr, sizeof(ip_Hdr), (void*)ip_hdr(skb));There must be code after "if ( (ip_Hdr.protocol != IPPROTO_TCP)) return 0;" . You may need bpf_probe_read() for memory accesses there.
|
|
#bcc - skb_network_header crashes in a BPF Kernel trace function
#bcc
vigs.prof@...
Hello - I am looking to trace ip_forward_finish. The intent is to trace latency of all TCP connections going through a linux based gateway router. Hence thought of tracing ip_forward_finish kernel function. And capture the time-stamp of SYN, SYN-ACK and ACK messages at the router.
The issue is accessing iphdr inside the trace function crashes with the below error:
bpf: Failed to load program: Permission denied
0: (79) r6 = *(u64 *)(r1 +96)
1: (b7) r1 = 0
2: (6b) *(u16 *)(r10 -24) = r1
3: (bf) r3 = r6
4: (07) r3 += 192
5: (bf) r1 = r10
6: (07) r1 += -24
7: (b7) r2 = 2
8: (85) call bpf_probe_read#4
9: (69) r1 = *(u16 *)(r10 -24)
10: (55) if r1 != 0x8 goto pc+7
R0=inv(id=0) R1=inv8 R6=inv(id=0) R10=fp0
11: (69) r1 = *(u16 *)(r6 +196)
R6 invalid mem access 'inv'
HINT: The invalid mem access 'inv' error can happen if you try to dereference memory without first using bpf_probe_read() to copy it to the BPF stack. Sometimes the bpf_probe_read is automatic by the bcc rewriter, other times you'll need to be explicit.
The code fragment I originally had was as below and the crash occurs when an access to ip_Hdr->protocol is made. And I also checked that ip_Hdr is not null.
int trace_forward_finish(struct pt_regs *ctx,struct net *net, struct sock *sk, struct sk_buff *skb)
{
if (skb->protocol != htons(ETH_P_IP)) return 0;
struct iphdr* ip_Hdr = (struct iphdr *) skb_network_header(skb);
if (ip_Hdr->protocol != IPPROTO_TCP)
return 0;
/// Other code
}
Per the HINT in the message, I did try to change to bpf_probe_read but still the same outcome
int trace_forward_finish(struct pt_regs *ctx,struct net *net, struct sock *sk, struct sk_buff *skb)
{
if (skb->protocol != htons(ETH_P_IP)) return 0;
struct iphdr ip_Hdr;
bpf_probe_read(&ip_Hdr, sizeof(ip_Hdr), (void*)ip_hdr(skb));
if ( (ip_Hdr.protocol != IPPROTO_TCP))
return 0;
return 0;
}
Any help would be appreciated. |
|
Seeking candidates for PhD position related to XDP/eBPF
Hi Potential PhD student,
Reminder: Application deadline 15.May 2020 is really soon for our PhD position located in Sweden, at Karlstads University. See: "PhD position in Computer Science, programmable networks" https://kau.varbi.com/en/what:job/jobID:315513 This PhD position is related to XDP/eBPF. The Red Hat engineers you will be cooperating with are Toke and I. Red Hat is funding the position, but employment happens under University terms, with the exception the work should be released under an Open Source license. -- Best regards, Jesper Dangaard Brouer MSc.CS, Principal Kernel Engineer at Red Hat LinkedIn: http://www.linkedin.com/in/brouer |
|
Re: Extracting data from tracepoints (and anything else)
Andrii Nakryiko
On Thu, Apr 16, 2020 at 8:42 AM <mayfieldtristan@...> wrote:
You are not really accessing CPU registers, but you access their values before the program was interrupted. Those values are stored in pt_regs struct. It's a technicality in this case, but you can't access CPU registers directly in BPF. BTW, raw_tracepoints are completely different, but you should be able to find examples in selftests for those. For example, if I'm porting Brenden Gregg's bpftrace tool "elfsnoop" to libbpf, I'd want to trace "load_elf_binary()." load_elf_binary() only has one argument: "struct linux_binrprm *bprm." So if I want to read that struct, I'd have to access the register with that argument. I think in bpf_tracing.h that macro would be PT_REGS_PARAM1(x). I don't have the greatest understanding of asm and cpu registers, but I believe that would be the %rdi register?Yes, rdi register, which is accesed from pt_regs using PT_REGS_PARM1() With that in mind, here's my code and build.So <linux/ptrace.h> in your case is taken from UAPI headers, not kernel internal headers. They have different names for field. Drop -D__KERNEL__ part and it should work. kretprobes can only safely access return value, which you would use PT_REGS_RC(ctx) to get. Input arguments are clobbered by the time kretprobe fires, so using PT_REGS_PARM1(ctx) would return you something, but most probably it won't be a correct value of first input argument. raw_tracepoints are similar to fentry/fexit in that each input argument is 8-byte long. See progs/test_vmlinux.c in selftests/bpf for an example of getting a syscall number on sys_entry. BPF_PROG is useful macro for such use cases.
|
|
Re: Extracting data from tracepoints (and anything else)
Tristan Mayfield
I've waited to reply, not wanting to clog the mailing list, but I thought it would be beneficial to follow up on the same topic with kprobes in addition to tracepoints. The main issue I had with tracepoints was not understanding the 8-byte alignment in the arguments. Once that was sorted, getting information was actually really simple.
At this point I've moved to kprobes, kretprobes, and raw tracepoints. From what I understand, if not using CO-RE or vmlinux.h, to access data from kprobes or kretprobes you must access the cpu registers in which those values live? For example, if I'm porting Brenden Gregg's bpftrace tool "elfsnoop" to libbpf, I'd want to trace "load_elf_binary()." load_elf_binary() only has one argument: "struct linux_binrprm *bprm." So if I want to read that struct, I'd have to access the register with that argument. I think in bpf_tracing.h that macro would be PT_REGS_PARAM1(x). I don't have the greatest understanding of asm and cpu registers, but I believe that would be the %rdi register? With that in mind, here's my code and build. #include <linux/bpf.h> Unfortunately, as Andrii mentioned previously in this topic, I think there are different definitions of pt_regs and my /usr/include/linux/ptrace.h does not have the correct one, as evidenced by the error I get when trying to build. elfsnoop.bpf.c:89:54: error: no member named 'di' in 'struct pt_regs' struct linux_binprm *arg = (struct linux_binprm *) PT_REGS_PARM1(ctx); ^~~~~~~~~~~~~~~~~~ /home/vagrant/libbpf/src/bpf_tracing.h:54:32: note: expanded from macro 'PT_REGS_PARM1' #define PT_REGS_PARM1(x) ((x)->di) Is this the correct way to access data in kprobes? Most of the information I've found explicitly talking about accessing kprobe data is pretty old (2012-2015). selftests/bpf/ seems to not have examples of accessing kprobe data, and, from my understanding, libbpf-tools is CO-RE dependent which I'm trying to avoid for now just because most default kernels aren't BTF enabled yet (I will definitely be voicing my opinion to distros that this should change since the average user likely isn't keen on recompiling and installing a kernel). I also looked at the brief C Appendix of "BPF Performace Tools" and "Linux Observability with BPF" to try and understand, but I still haven't been able to extract data from the kprobes or raw tracepoints yet. I think the final question that may (or may not) solve this issue is which pt_regs should be used? Also, assuming this is the correct way, is this generalizable to raw tracepoints and kretprobes as well? After I have these things figured out with some working examples, I think I will publish a github repo with a tutorial as discussed with Andrii in a few messages above. Appreciate any feedback and help. |
|
Re: Extracting data from tracepoints (and anything else)
Andrii Nakryiko
adding back mailing list
On Mon, Apr 6, 2020 at 7:58 AM <mayfieldtristan@...> wrote: Notice offsets, they are all (except for first 4 fields which fit in first 8 bytes) 8-byte aligned. You can do that in your struct definitions as: int __syscall_nr __attribute__((aligned(8))); OR just use long. The other issue I've been confused about, is __syscall_nr has an offset of 8 and size 4, but dfd has an offset 16 where I'd expect 12.Not sure which part do you mean? Field alignment, sizes, and padding are all part of standard C. As for tracepoint, selftests in kernel and various BCC and libbpf examples should be a good starting point. You can use libbpf-tools/Makefile for inspiration on how to do this: https://github.com/iovisor/bcc/blob/master/libbpf-tools/Makefile You might need to define __TARGET_ARCH_x86 and __KERNEL__ explicitly otherwise. It's easier with vmlinux.h, though. BPF is still rapidly evolving, so yeah, that's a concern. It definitely requires dedication and time to maintain good up-to-date documentation. No way around that, unfortunately. Sure, you are welcome. |
|
Re: Extracting data from tracepoints (and anything else)
Andrii Nakryiko
On Wed, Apr 1, 2020 at 12:52 PM <mayfieldtristan@...> wrote:
Just answered on another Github issue (https://github.com/iovisor/bcc/issues/2855#issuecomment-609532793), please check it there as well. Short answer: no. Unless you can pretty much guarantee that it will be exactly the same **binary** compiled version of the kernel (not just same version). 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.These should come from kernel-devel packages. #include <linux/version.h>nit: this is deprecated form of declaring maps, please see kernel selftests for better examples. It's not arbitrary, it's set at 16 in kernel. char file[255];I haven't checked the order of fields, but each field has to be long in size (so 8 bytes on 64-bit arch). BPF is 64-bit arch, so long is 64-bit there. I'm not sure how this plays out on 32-bit target architecture, but assuming you are on x86-64, all switch int to long and make __mode_t also long. ctx->err doesn't exist according to definition above? 0 is not right here, use BPF_F_CURRENT_CPU (0xffffffffULL). Otherwise you'll get data only on CPU #0 (if you get tracepoint triggered on that CPU). _version is not necessary with modern libbpf and kernel. This is due to invalid memory layour of struct sys_enter_openat_args, you are reading wrong pointer. But sometimes filename might not be in memory and you will get -EFAULT (-14), but that should not happen all the time for sure. I took a look at an article written by Gianluca Borello (https://sysdig.com/blog/the-art-of-writing-ebpf-programs-a-primer/) for Sysdig's approach, and thought that using a raw tracepoint would be easier to get the filename arg than the above approach. I tried it out, but couldn't get it to compile.better include bpf_tracing.h header from libbpf and use PT_REGS_PARM2_CORE(regs) instead of directly referencing fields of pt_regs. This is due to different definitions of struct pt_regs in user-space and kernel-space. Using libbpf's bpf_tracing.h header and PT_REGS macros should eliminate a lot of those. Sticking to vmlinux.h also helps, but requires BPF CO-RE. If CO-RE compiled programs can run on non-BTF supported kernels, then I would be more than happy to shift to that approach. Otherwise, it's nice to have non-BTF reliant code.No, unfortunately, it can't. As a final note, I was working through some examples for XDP in https://github.com/xdp-project/xdp-tutorial and was thinking that something similar would be helpful for general BPF programming. The API may be too volatile at this point, but if people who have the technical expertise are interested, I'm willing to donate some of my own time to help build something similar. BCC's libbpf-tools has been extremely helpful, but it seems that there's not any resources (I've found) that are as in-depth and cohesive as the tutorial linked above. Again, I don't know if it's completely appropriate at this stage of development, but I know there's a lot of interest out there in using BPF at a more granular level and with less overhead than what is offered with BCC.I agree that such tutorial is sorely missing. libbpf-tools and kernel selftests (not so much samples/bpf, though) are probably the best way to see usage of all the newer features. It would be awesome for someone to prepare an approachable and comprehensive set of tutorials, of course. Please do give it a try and community will certainly help you with answering questions you have! |
|
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.
#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 |
|
Re: Extracting data from tracepoints (and anything else)
Andrii Nakryiko
On Wed, Mar 25, 2020 at 11:39 AM <mayfieldtristan@...> wrote:
Yes. A lot of newer functionality relies on kernel BTF as well. But to compile portable BPF program you also need kernel BTF (for BPF CO-RE stuff). |
|
Re: Extracting data from tracepoints (and anything else)
Tristan Mayfield
Take a closer look. libbpf-tools do not use bpf_load.h, that one is Will do. Does this mean that, going forward, BPF development will be encouraged to use kernels compiled with "CONFIG_DEBUG_INFO_BTF=y"? I've been using a default build up to now. |
|
Re: Extracting data from tracepoints (and anything else)
Andrii Nakryiko
On Wed, Mar 25, 2020 at 6:45 AM <mayfieldtristan@...> wrote:
Take a closer look. libbpf-tools do not use bpf_load.h, that one is deprecated and its use is discouraged. libbpf-tools rely on code-generated BPF skeleton. But really, get a close look at libbpf-tools, it has everything you need to get started.
|
|
Re: Extracting data from tracepoints (and anything else)
Tristan Mayfield
bpf_probe_read_str() has been there for a long time, at least 4.12 orI found out that the cloned the kernel tree from the Ubuntu repo (i.e. "git clone --depth 1 git://kernel.ubuntu.com/ubuntu/ubuntu-bionic.git") for Bionic was the issue. For some reason it doesn't have an up to date libbpf library and so doesn't have bpf_probe_read_str(). I think going forward, getting the API from the repo you recommended or from the official kernel source is the way to go. I appreciate the pointers for my BPF program. If using github.com/libbpf/libbpf, should I just plan on loading and attaching programs manually instead of using bpf_load.h? I've been looking through the bcc/libbpf-tools/ directory and it looks like they're making use of bpf_load.h and BTF/CO-RE. I've tried using bpf_load.h/c with the standalone libbpf, but I've gotten some difficult linking issues I haven't been able to resolve. Please keep this discussion on mailing list, though, it might benefitAgreed, the last message I replied to just you accidentally. Thanks again for the help. |
|
Re: Extracting data from tracepoints (and anything else)
Andrii Nakryiko
Adding back mailing list.
On Mon, Mar 23, 2020 at 12:33 PM <mayfieldtristan@...> wrote: bpf_probe_read_str() has been there for a long time, at least 4.12 or even older. samples/bpf are part of kernel, so yes, they are using libbpf from kernel sources. For stand-alone application I'd go with github.com/libbpf/libbpf comm is 16 and unlikely to ever change. No need to waste 256 bytes here. char *file;data has to be initialized here: struct data_t data = {}; struct sys_enter_openat_args args;data is not completely initialized, see above. Please keep this discussion on mailing list, though, it might benefit someone else. |
|
Re: Array brace-enclosed initialization
Yonghong Song
On Mon, Mar 23, 2020 at 10:05 AM Federico Parola <fede.parola@...> wrote:
The init list is too long. The compiler puts {0, 1, 2, ..., 9} in a readonly section. That is why you got the failure below. If you use native clang compilation and a recent kernel, libbpf should be able to automatically create a map for you so your code will work.
|
|