-
Notifications
You must be signed in to change notification settings - Fork 190
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Load ebpf module without host kernel header dependency #716
Comments
Package pre-compiled ebpf moduleIn bcc module https://github.com/sustainable-computing-io/kepler/blob/main/vendor/github.com/iovisor/gobpf/bcc/module.go#L83 func newModule(code string, cflags []string) *Module {
cflagsC := make([]*C.char, len(defaultCflags)+len(cflags))
defer func() {
for _, cflag := range cflagsC {
C.free(unsafe.Pointer(cflag))
}
}()
for i, cflag := range cflags {
cflagsC[i] = C.CString(cflag)
}
for i, cflag := range defaultCflags {
cflagsC[len(cflags)+i] = C.CString(cflag)
}
cs := C.CString(code)
defer C.free(unsafe.Pointer(cs))
c := C.bpf_module_create_c_from_string(cs, 2, (**C.char)(&cflagsC[0]), C.int(len(cflagsC)), (C.bool)(true), nil)
if c == nil {
return nil
}
return &Module{
p: c,
funcs: make(map[string]int),
kprobes: make(map[string]int),
uprobes: make(map[string]int),
tracepoints: make(map[string]int),
rawTracepoints: make(map[string]int),
perfEvents: make(map[string][]int),
}
} Similarly, an ebpf pre-compiler can call This pre-compiled module, however, has to have fixed cflags. Pre-packaged Kernel SourceIf the target kernel is known, kepler can be built into a container image that has the kernel headers pre-installed and |
do we want to build by our own or seems we should provide a tool to help create the module? |
for pre-compiled, yes, new tools are needed. The pre-installed kernel headers way will need kepler to compile against the pre-installed headers. |
This is related to BPF CO-RE (Compile Once – Run Everywhere) The cilium ebpf library has overcome this issue: cilium/ebpf#114. |
@marceloamaral yes, eventually that's the solution to go if we can get perf event work |
I think the right thing to do here is to drop BCC and dynamic compilation entirely, and go for fully pre-compiled BPF programs with CO-RE. There's some discussion on how to achieve this from Go in this Cilium discussion: cilium/ebpf#548 (Side note: cool project! Hadn't heard about it before :) ) |
For pre-compiled module, we can use the same compilation flags as bcc. This can be done by setting DEBUG_PREPROCESSOR flag in bpf_module_create_c_from_string, i.e. setting to Below is the clang command to generate the module clang -cc1 -triple x86_64-unknown-linux-gnu -emit-llvm-bc -emit-llvm-uselists -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name main.c -mrelocation-model static -fno-jump-tables -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -target-cpu x86-64 -tune-cpu generic -mllvm -treat-scalable-fixed-error-as-warning -debug-info-kind=constructor -dwarf-version=5 -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/kernels/4.18.0-425.3.1.el8.x86_64 -nostdsysteminc -nobuiltininc -resource-dir lib/clang/14.0.6 -isystem /virtual/lib/clang/include -include ./include/linux/kconfig.h -include /virtual/include/bcc/bpf.h -include /virtual/include/bcc/bpf_workaround.h -include /virtual/include/bcc/helpers.h -isystem /virtual/include -I /home/hchen/src/github.com/sustainable-computing-io/kepler -D __BPF_TRACING__ -I arch/x86/include/ -I /lib/modules/4.18.0-425.3.1.el8.x86_64/build/arch/x86/include/generated -I include -I /lib/modules/4.18.0-425.3.1.el8.x86_64/build/include -I arch/x86/include/uapi -I /lib/modules/4.18.0-425.3.1.el8.x86_64/build/arch/x86/include/generated/uapi -I include/uapi -I /lib/modules/4.18.0-425.3.1.el8.x86_64/build/include/generated/uapi -D __KERNEL__ -D KBUILD_MODNAME="bcc" -D MAP_SIZE=10240 -D NUM_CPUS=12 -D SET_GROUP_ID -D NUMCPUS=12 -O2 -Wno-deprecated-declarations -Wno-gnu-variable-sized-type-not-at-end -Wno-pragma-once-outside-header -Wno-address-of-packed-member -Wno-unknown-warning-option -Wno-unused-value -Wno-pointer-sign -fdebug-compilation-dir=/usr/src/kernels/4.18.0-425.3.1.el8.x86_64 -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o main.bc -x c /virtual/main.c Note, some of the headers are from bcc and bcc-devel. If the module can be compiled, we can load it into kepler without having to compile from source |
That seems a bit long. I'd suggest modelling the precompiled BPF modules on the libbpf-tools in BCC instead: https://github.com/iovisor/bcc/tree/master/libbpf-tools/ There is also the bpf-examples repo you can borrow code from: https://github.com/xdp-project/bpf-examples In both cases, it should be possible to get rid of the BCC header dependencies completely, and just have a relatively simple Makefile rule that builds the BPF objects... |
@tohojo thanks! that's a good pointer! |
You're welcome :)
|
Using libbpf might be a more general solution that will work in different environments. We just need to make sure that we will compile the bpf code in the system that has BTF. Here is a code with example to load a pre-compiled libbpf code in golang: Cilium has ported to golang many libbpf functions and can also be a source of inspiration. |
I believe most Go people prefer to use the native (Cilium) go-bpf library over the libbpf bindings, partly because the FFI linking to libbpf for libbpfgo is a bit of a hassle (not sure of the details, not a Go person, really). There are some features that are supported by libbpf that are not in the go-bpf library, but if you don't need those go-bpf may be easier to use and integrate... |
sounds good. The bare minimum is to remove the BCC macros from bpf code to stay framework neural, we can then choose which library we can use next. |
Update: I can now load pre-compiled eBPF program (.bpf.o) to the go program using only libbpf library based on Makefile in libbpfgo-beginners. fmt.Printf("%d: %s, %d, %d, %d\n", ct.PID, ct.Command, ct.ProcessRunTime, ct.CPUCycles, ct.CacheMisses)
Will merge to Kepler code and push PR soon. |
Shouldn't this be closed since it was fixed by PR 733? |
Is your feature request related to a problem? Please describe.
Currently kepler dynamically compiles the ebpf program when started. This compilation requires kernel headers. If kernel headers are missing, the compilation will fail.
Describe the solution you'd like
The text was updated successfully, but these errors were encountered: