-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Introducing libbpf to systemd #12151
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
Conversation
|
I don't think it makes much sense to add a library to the codebase without actually using it for anything. |
|
We could use libbpf to eventually replace libseccomp, which can't express some logic operations we'd like to do. Also I'm not so happy how system call names map to actual system call numbers. The downside is that we would have to do everything in systemd instead of relying on a bit higher level interface which libseccomp provides, but at least it would be C (-ish). But this is just an additional potential side benefit of using libbpf. |
|
systemd does not usually use submodules for it's dependency and that's something that linux distro usually don't want anyway is there a particular reason why libpf needs to be used that way ? |
|
@boucman this is actually mentioned in the commit message. |
|
right, my bad... |
|
It might be OK to link against libbpf, but this PR only adds the dependency, and doesn't do anything with it. Unless there's actually code that uses the new dep I don't think we should add the dep... |
|
Thank you for your comments. |
|
(So, to say this clearly: in generally agree with using libbpf instead of our handgrown BPF code. Would love to review a patch. Though I generally prefer shared lib deps over drop-in deps like the current version). |
|
Looks like libbpf is not a standalone library (yet) and built from src:linux which bumps the soname on each new major kernel release. |
Well, this PR added it as git submodule, which pins the release at some git commit, and links against the thing statically, so that we get around the .so instability. |
|
@mbiebl Actually there were a lot of changes in the last months to make libbpf API/ABI stable and versioned:
I'm not sure what is Please let me know if you think something else should be fixed in libbpf to consider its API/ABI stable (in addition to git submodule approach used here). |
|
Libbpf would introduce a dependency on LLVM, so for architectures (if any) where only GCC is available, features using BPF would have to be disabled. |
|
@rdna I see, thanks. |
|
hmm, if libbpf indeed introduces an llvm runtime dependency this would be less than ideal. @rdna do you know the story there? |
|
@poettering libbpf does not introduce llvm runtime dependency. Workflow here may look like this:
By talking about run time llvm dependency people usually have tracing in mind. In tracing case BPF programs should currently be built on target host since they may depend on specific kernel configuration (e.g. field offsets in a kernel struct that is used by tracing program and those offsets e.g. depend on some
|
|
I started to experiment with this PR because I was wondering if Anyway, so far it has been relatively easy for people who don't care much about bpf filters to just basically ignore them. With I also opened libbpf/libbpf#27 and libbpf/libbpf#28, that were uncovered here. I'm not sure whether it's the right place to report bugs in libbpf though. |
dc79478 to
49f1021
Compare
|
Interestingly, turns out that currently only Travis CI is aware of submodules in general. I'm not saying it's hard to tweak the build scripts a little to make it work but are we sure we can't wait for Plus, my understanding is that this PR is supposed to make it easier to add new eBPF programs in the future, which is great, but I'm wondering if anyone is going to add something new in the foreseeable future. Wouldn't it be better to start to rely on |
|
Before I forget, in https://discuss.lgtm.com/t/lgtm-seems-to-be-failing-to-extract-the-systemd-project-due-to-a-submodule/1994 I reported the LGTM failure so in theory LGTM should be able to analyze the PR soon. |
|
@evverx |
|
Turns out it was me who broke the part of semaphoreci dealing with submodules a couple of months ago. I've just fixed it and judging by https://semaphoreci.com/systemd/systemd/branches/pull-request-12151/builds/7 it got past @wat-ze-hex
Can't argue with that and I also agree that it's useful to have the infrastructure in place and I wouldn't say that I'm strongly opposed to the change. It's just that there're places (the fuzzers for example) where it would be useful to turn everything related to eBPF off so I guess I'm fine as long as the fuzzers are intact (right now they are failing to compile). |
Make it possible to include libbpf into projects built by Meson build system as a subproject. This is the case e.g. for systemd. meson.build declares dependencies which may be used in parent projects: `libbpf_static_dep` for static library `libbpf_shared_dep` for shared library `bpf_includes` provides the location of bpf.h, btf.h and libbpf.h Parent projects need to introduce git wrap to build libbpf: https://github.com/mesonbuild/meson/blob/master/docs/markdown/Wrap-dependency-system-manual.md#wrap-git An alternative approach is applying a patch with meson.build for libbpf while building a parent project: https://github.com/mesonbuild/meson/blob/master/docs/markdown/Wrap-dependency-system-manual.md#wrap-file Imo it's less transparent and would add more headache. meson.build is placed in the source root because that's how Meson expects it to be placed. The related discussion is in systemd/systemd#12151
I'm glad it turned out to be possible to find a reasonable compromise. @boucman I'm wondering if anybody is willing to bring |
Make it possible to include libbpf into projects built by Meson build system as a subproject. This is the case e.g. for systemd. meson.build declares dependencies which may be used in parent projects: `libbpf_static_dep` for static library `libbpf_shared_dep` for shared library `bpf_includes` provides the location of bpf.h, btf.h and libbpf.h Parent projects need to introduce git wrap to build libbpf: https://github.com/mesonbuild/meson/blob/master/docs/markdown/Wrap-dependency-system-manual.md#wrap-git An alternative approach is applying a patch with meson.build for libbpf while building a parent project: https://github.com/mesonbuild/meson/blob/master/docs/markdown/Wrap-dependency-system-manual.md#wrap-file Imo it's less transparent and would add more headache. meson.build is placed in the source root because that's how Meson expects it to be placed. The related discussion is in systemd/systemd#12151
|
@evverx adding |
|
@michaelolbrich so, maybe, it would make sense to delay shipping the compiled code until the library is added. At this point, it seems to me that we are trying to complicate things to cover theoretical use cases. |
|
Just to clarify, while it's important to come up with something that will hopefully work everywhere, this PR seems to be a proof of concept (unless I'm mistaken) and it would be great to keep things simple to get the code working at least (currently LLVM isn't necessary at all because the macro assembly hasn't been replaced yet and libbpf is failing to compile on i386: libbpf/libbpf#34). |
I'll add it to our buildroot todo list... |
The choice of having the library as a git submodule allows us to iterate faster in bringing eBPF capabilities due to the package for Red Hat does not exist yet. Github mirror of of bpf-next linux tree: https://github.com/libbpf/libbpf The package for Debian can be found in https://packages.debian.org/sid/libbpf-dev Meanwhile, there is an ongoing discussion for .rpm: https://lore.kernel.org/bpf/CAADnVQKvRz-EMPqB5oMiG=6N1-QwAhMGnpnQsgSyQuUcrA781A@mail.gmail.com/T/#m89f1546f20062d39a27fc7d7a12b4af5b6325c2a Once there is an availible RPM we'll replace the git submodule with a proper external dependency.
Since libbpf presents as a git submodule, subprojects/libbpf.wrap is introduced. It temporary points to https://github.com/wat-ze-hex/libbpf to test with Ubuntu CI.
In order to rewrite src/core/bpf-devices.{c|h},
src/core/bpf-devices/bpf-firewall.{c|h} from macro-assembly to eBPF, libbpf
library must be linked to libcore.a.
Replace
int bpf_map_new(enum bpf_map_type type, size_t key_size, size_t value_size, size_t max_entries, uint32_t flags);
int bpf_map_update_element(int fd, const void *key, void *value);
int bpf_map_lookup_element(int fd, const void *key, void *value);
with functions from libbpf.
Replace BPF_PROG_LOAD and BPF_PROG_LOAD syscalls.
Further steps include introducing a template meson.build and llvm/clang
dependency to compile eBPF programs.
845c95f to
423f7f1
Compare
Just having |
|
Regarding the actual BPF programs, rather than stack commits here, I'd prefer to open another PR once this PR have broken through the wall of failing tests. We have a lot of trouble with submodule and that's a poor man's problem because RPM package is not available in Fedora. But we have RPM spec: https://github.com/facebookincubator/rpm-backports/tree/master/rpms/libbpf |
In order to libbpf to be used in systemd some testing is required, see related discussions in systemd/systemd#12151 and libbpf#29 The tests introduced here mirrors the tests of systemd: For Debian: build with gcc, gcc + asan, clang, clang + asan Debian tests use `docker` virtualization Fror Ubuntu Xenial: build with gcc The differences: Install only libelf and it's dependencies. Instead of Meson build system `make` is used, so `make` remains the preferred method of building and `meson.build` doesn't get rooted in `libbpf`. `travis_wait.bash` is kept as a workaround for travis-ci/travis-ci#9979 An example of testing UI: https://travis-ci.org/wat-ze-hex/libbpf
In order to libbpf to be used in systemd some testing is required, see related discussions in systemd/systemd#12151 and libbpf#29 The tests introduced here mirrors the tests of systemd: For Debian: build with gcc, gcc + asan, clang, clang + asan Debian tests use `docker` virtualization Fror Ubuntu Xenial: build with gcc The differences: Install only libelf and it's dependencies. Instead of Meson build system `make` is used, so `make` remains the preferred method of building and `meson.build` doesn't get rooted in `libbpf`. `travis_wait.bash` is kept as a workaround for travis-ci/travis-ci#9979 An example of testing UI: https://travis-ci.org/wat-ze-hex/libbpf
In order to libbpf to be used in systemd some testing is required, see related discussions in systemd/systemd#12151 and #29 The tests introduced here mirrors the tests of systemd: For Debian: build with gcc, gcc + asan, clang, clang + asan Debian tests use `docker` virtualization Fror Ubuntu Xenial: build with gcc The differences: Install only libelf and it's dependencies. Instead of Meson build system `make` is used, so `make` remains the preferred method of building and `meson.build` doesn't get rooted in `libbpf`. `travis_wait.bash` is kept as a workaround for travis-ci/travis-ci#9979 An example of testing UI: https://travis-ci.org/wat-ze-hex/libbpf
Using %ld for printing out value of ptrdiff_t type is not portable between 32-bit and 64-bit archs. This is causing compilation errors for libbpf on 32-bit platform (discovered as part of an effort to integrate libbpf into systemd ([0])). Proper formatter is %td, which is used in this patch. v2->v1: - add Reported-by - provide more context on how this issue was discovered [0] systemd/systemd#12151 Reported-by: Evgeny Vereshchagin <evvers@ya.ru> Cc: Daniel Borkmann <daniel@iogearbox.net> Cc: Alexei Starovoitov <ast@fb.com> Cc: Yonghong Song <yhs@fb.com> Signed-off-by: Andrii Nakryiko <andriin@fb.com> Acked-by: Song Liu <songliubraving@fb.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Using %ld for printing out value of ptrdiff_t type is not portable between 32-bit and 64-bit archs. This is causing compilation errors for libbpf on 32-bit platform (discovered as part of an effort to integrate libbpf into systemd ([0])). Proper formatter is %td, which is used in this patch. v2->v1: - add Reported-by - provide more context on how this issue was discovered [0] systemd/systemd#12151 Reported-by: Evgeny Vereshchagin <evvers@ya.ru> Cc: Daniel Borkmann <daniel@iogearbox.net> Cc: Alexei Starovoitov <ast@fb.com> Cc: Yonghong Song <yhs@fb.com> Signed-off-by: Andrii Nakryiko <andriin@fb.com> Acked-by: Song Liu <songliubraving@fb.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
|
So I think it's OK to commit both BE and LE versions of the bytecode. And yes, it's OK if it changes over time. It would be like the hwdb stuff which we regenerate before each release too and commit. So I am on board with adding the libbpf dep as long as the llvm thing doesn't become a hard dep and people can use the pre-generated bytecode. |
|
Could this wait until we have a BPF compiler in GCC (which is supposedly coming in GCC 10 next year)? That way an LLVM dependency isn't required at all. |
Make it possible to include libbpf into projects built by Meson build system as a subproject. This is the case e.g. for systemd. meson.build declares dependencies which may be used in parent projects: `libbpf_static_dep` for static library `libbpf_shared_dep` for shared library `bpf_includes` provides the location of bpf.h, btf.h and libbpf.h Parent projects need to introduce git wrap to build libbpf: https://github.com/mesonbuild/meson/blob/master/docs/markdown/Wrap-dependency-system-manual.md#wrap-git An alternative approach is applying a patch with meson.build for libbpf while building a parent project: https://github.com/mesonbuild/meson/blob/master/docs/markdown/Wrap-dependency-system-manual.md#wrap-file Imo it's less transparent and would add more headache. meson.build is placed in the source root because that's how Meson expects it to be placed. The related discussion is in systemd/systemd#12151
In order to libbpf to be used in systemd some testing is required, see related discussions in systemd/systemd#12151 and libbpf/libbpf#29 The tests introduced here mirrors the tests of systemd: For Debian: build with gcc, gcc + asan, clang, clang + asan Debian tests use `docker` virtualization Fror Ubuntu Xenial: build with gcc The differences: Install only libelf and it's dependencies. Instead of Meson build system `make` is used, so `make` remains the preferred method of building and `meson.build` doesn't get rooted in `libbpf`. `travis_wait.bash` is kept as a workaround for travis-ci/travis-ci#9979 An example of testing UI: https://travis-ci.org/wat-ze-hex/libbpf
Using %ld for printing out value of ptrdiff_t type is not portable between 32-bit and 64-bit archs. This is causing compilation errors for libbpf on 32-bit platform (discovered as part of an effort to integrate libbpf into systemd ([0])). Proper formatter is %td, which is used in this patch. v2->v1: - add Reported-by - provide more context on how this issue was discovered [0] systemd/systemd#12151 Reported-by: Evgeny Vereshchagin <evvers@ya.ru> Cc: Daniel Borkmann <daniel@iogearbox.net> Cc: Alexei Starovoitov <ast@fb.com> Cc: Yonghong Song <yhs@fb.com> Signed-off-by: Andrii Nakryiko <andriin@fb.com> Acked-by: Song Liu <songliubraving@fb.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
jira LE-1907 Rebuild_History Non-Buildable kernel-4.18.0-193.el8 commit-author Andrii Nakryiko <andriin@fb.com> commit e1d1dc4 Using %ld for printing out value of ptrdiff_t type is not portable between 32-bit and 64-bit archs. This is causing compilation errors for libbpf on 32-bit platform (discovered as part of an effort to integrate libbpf into systemd ([0])). Proper formatter is %td, which is used in this patch. v2->v1: - add Reported-by - provide more context on how this issue was discovered [0] systemd/systemd#12151 Reported-by: Evgeny Vereshchagin <evvers@ya.ru> Cc: Daniel Borkmann <daniel@iogearbox.net> Cc: Alexei Starovoitov <ast@fb.com> Cc: Yonghong Song <yhs@fb.com> Signed-off-by: Andrii Nakryiko <andriin@fb.com> Acked-by: Song Liu <songliubraving@fb.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> (cherry picked from commit e1d1dc4) Signed-off-by: Jonathan Maple <jmaple@ciq.com>
This is required to be able to write eBPF programs in C instead of macro-assembly. BPF instruction macro are already used in systemd, e.g.in src/core/bpf-devices.{h|c} and src/core/bpf-firewall.{h|c}. That code is not
reader friendly and hard to extend / maintain, e.g. jump offsets have to be calculated manually, also it complicates bringing new features such as BTF. So the idea is to replace micro-assembly with eBPF programs written in C. Having libbpf will make it easier to use BPF infrastructure in systemd in future, e.g. by introducing new eBPF programs and get new features for free, such as BTF, static variables and whatever else is implemented in libbpf.
Extensive BPF documentation https://cilium.readthedocs.io/en/v1.4/bpf/