Skip to content

Commit

Permalink
Documentation fixups & additions (#274)
Browse files Browse the repository at this point in the history
* cleanup a bunch of existing docs.

* docs: more code cleanup & add tools details.

* docs: add smth small on centos support.

* docs: address review.

* Update README.md

Co-authored-by: Vladimir Kobal <vlad@prokk.net>

Co-authored-by: thiagoftsm <thiagoftsm@gmail.com>
Co-authored-by: Vladimir Kobal <vlad@prokk.net>
  • Loading branch information
3 people authored Nov 30, 2021
1 parent 8ec9a19 commit ea08cdf
Show file tree
Hide file tree
Showing 12 changed files with 205 additions and 161 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
# Builds and Releases packages for eBPF to be consumed by NetData Agent
# Builds and Releases packages for eBPF to be consumed by Netdata Agent
name: CD
on:
push:
Expand Down
130 changes: 74 additions & 56 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,89 +9,104 @@ Linux Kernel eBPF Collectors

The respository has the following directory structure:

- `artifacts`: Directory that will have the eBPF programs when the compilation
- `artifacts`: directory that will have the eBPF programs when the compilation
process ends.
- `includes`: Common headers
- `kernel`: The eBPF programs source code
- `co-re`: contains all eBPF programs that utilize eBPF CO-RE (Compile Once -
Run Everywhere) technology.
- `tests`: contains test cases for our eBPF CO-RE programs.
- `docs`: contains an assortment of documentation related to this repository.
- `includes`: headers used throughout the project.
- `kernel`: contains all eBPF programs that don't utilize eBPF CO-RE
technology; these may be considered legacy more and more as time progresses
and we shift fully to CO-RE.
- `kernel-patches`: contains patches needed to properly compile our legacy
`kernel/` eBPF programs on some kernel versions.
- `libbpf`: this is a submodule'd fork of
[netdata/libbpf](https://github.com/netdata/libbpf) which is itself a fork of
the official `libbpf` package, the user-space side of eBPF system calls.
- `tools`: scripts used to verify system status before installing eBPF code.

## Necessary packages
## Requirements

To compile the eBPF programs, it will be necessary to have the following packages:
#### Packages

- Libelf headers
- llvm/clang, because GCC prior to 10.0 cannot compile eBPF code.
To compile the eBPF programs, it will be necessary to have the following
packages:

- libelf headers
- LLVM/Clang; this is because GCC prior to 10.0 cannot compile eBPF code.
- Kernel headers

The last group of files can be extracted directly from kernel source doing the
following steps:
#### Generating Headers

Kernel headers can be extracted directly from the kernel source doing the
following steps (assumes your kernel source is accessible at `/usr/src/linux`):

```bash
# go into your official linux kernel source code
cd /usr/src/linux
make defconfig
make scripts
make prepare
make headers_install
```

In case you are using the kernel `5.4` or newer, it is necessary to comment out
the following line inside the file `generated/autoconf.h`:
#### Misc

In case you are using the kernel `5.4` or newer, please comment out the
following line inside the file `generated/autoconf.h`:

```c
#define CONFIG_CC_HAS_ASM_INLINE 1
```
## Necessary changes
#### Makefiles
Before compilation of this repository, it is necessary to change the Makefiles
according your environment. The original files were adjusted to compile on
Slackware Linux Current.
It's also possible that you'll need to change the `Makefile`s in this
repository according your environment. The original files were adjusted to
compile on Slackware Linux Current.
### `kernel/Makefile`
Inside this file probably it will be necessary to change the following variable:
Inside `kernel/Makefile`, you may need to change the following variables:
- `KERNELSOURCE`: Where is your kernel-source? This variable was set initially
to work on Slackware, Fedora and Ubuntu
- `LINUXINCLUDE`: Depending of the Linux distribution, it is necessary to add
or remove directories from this variable.
- `LLVM_INCLUDES`: Depending of the kernel version, it will be necessary to
change this path
to work on Slackware, Fedora and Ubuntu.
- `LINUXINCLUDE`: Depending on the Linux distribution, it may be necessary to
add or remove directories from this variable.
- `LLVM_INCLUDES`: Depending on the kernel version, it may be necessary to
change this path.
## Building (with Docker)
## Building with Docker
There are two build environments that produce different builds different
variants of libc and the Linux Kernel.
There are two build environments that produce different variants of libc and
the Linux Kernel.
The build environments are:
- `musl` => `Dockerfile.musl` (_based on Alpine 3.11_)
- `glibc` => `Dockerfile.glibc` (_based on Ubuntu 20.04_)
### Building for glibc
### glibc
```sh
$ docker build -f Dodkcerfile.glibc -t kernel-collector:glibc ./
$ docker build -f Dockerfile.glibc -t kernel-collector:glibc ./
$ docker run --rm -v $PWD:/kernel-collector kernel-collector:glibc
```

### Building for musl
### musl

```sh
$ docker build -f Dodkcerfile.musl -t kernel-collector:musl ./
$ docker build -f Dockerfile.musl -t kernel-collector:musl ./
$ docker run --rm -v $PWD:/kernel-collector kernel-collector:musl
```

### Building for a Kernel
### Different Kernel

To build for a different Kernel version other than the default just pass the
To build for a different Kernel version rather than the default just pass the
`--build-arg KERNEL_VERSION=<kernel_version>` argument to the `docker build`.

For example:

```sh
$ docker build -f Dodkcerfile.musl -t kernel-collector:musl_5_4 --build--arg KERNEL_VERSION=5.4.18 ./
$ docker build -f Dockerfile.musl -t kernel-collector:musl_5_4 --build--arg KERNEL_VERSION=5.4.18 ./
$ docker run --rm -v $PWD:/kernel-collector kernel-collector:musl_5_4
```

Expand All @@ -103,29 +118,31 @@ when running the build image.
For example:

```sh
$ docker build -f Dodkcerfile.musl -t kernel-collector:musl ./
$ docker build -f Dockerfile.musl -t kernel-collector:musl ./
$ docker run --rm -e DEBUG=1 -v $PWD:/kernel-collector kernel-collector:musl
```

This sets `EXTRA_CFLAGS=-g` up before building.
This sets `EXTRA_CFLAGS=-g` before building.

## Compilation (manually)
## Manual Compilation

After the necessary changes have been done inside the `kernel/Makefille` file,
you need to run the following command to compile the eBPF programs:
After you've got your `kernel/Makefille` properly setup, you can run the
following command to compile all the eBPF programs:

```bash
$ make
# build in parallel jobs equal to `nproc` (number of processors)
$ make -j`nproc`
```

When the compilation finishes, you will have a file inside `artifacts` directory with the following
content:
When compilation finishes, you will have a file inside the `artifacts`
directory with contents like the following:

```
pnetdata_ebpf_process.<kernel version>.o
pnetdata_ebpf_socket.<kernel version>.o
rnetdata_ebpf_process.<kernel version>.o
rnetdata_ebpf_socket.<kernel version>.o
...
```

`p*.o`: eBPF programs used with entry mode, this is the default mode.
Expand All @@ -141,32 +158,33 @@ To release a new version and create a Github Release:

1. Create a Git tag like so:

```sh
$ TAG="v0.0.1"; git tag -a -s -m "Release ${TAG}" "${TAG}" && git push origin "${TAG}"
```
```sh
$ TAG="v0.0.1"; git tag -a -s -m "Release ${TAG}" "${TAG}" && git push origin "${TAG}"
```

Replace `v0.0.1` with the next desired tag. SemVer is not strictly being followed
here at this time so the specific tagged versions is not so important.
Replace `v0.0.1` with the next desired tag. SemVer is not strictly being
followed here at this time so the specific tagged versions is not so
important.

This will kick off a Github Action Workflow that will Rebuild the NetData eBPF
Kernel Collector for all Kernel and LIBC variants, create a Github Release and
upload all assets to the release to be consumed by anyone or the NetData Installer.
This will kick off a Github Action Workflow that will Rebuild the Netdata
eBPF Kernel Collector for all Kernel and LIBC variants, create a Github
Release and upload all assets to the release to be consumed by anyone or the
Netdata Installer.

2. Wait for the CD pipeline to finish in the Github Actions UI.
3. Review the Release, Updates Release Notes, etc in the Github Releases UI.
4. Push the "Publish Release" button in the Github Releases UI.

## Contribution

Netdata is an open-software software and we are always open for contributions that
Netdata is open-source software and we are always open for contributions that
you can give us.

Case you want do a contribution with an eBPF program, please, be sure that your program
is according with the following patterns:
If you want to contribute an eBPF program, then please be sure that your
program matches the following patterns:

- Your program must run on all kernels since at least kernel `4.11`
- Create an additional code that is responsible to measure the latency of your
program.
- Your program must run on all kernels since at least kernel `4.11`.
- Write some code that's responsible to measure the latency of your program.
- We have the variable NETDATASEL, that selects where the functions will be
attached. Be sure that inside your code `0` is associated `kretprobe`, and `2` is assoacited
with `kprobe`.
24 changes: 0 additions & 24 deletions docs/Compilation-as-normal-user.md

This file was deleted.

31 changes: 0 additions & 31 deletions docs/Kernel-version-ebpf-program.md

This file was deleted.

3 changes: 0 additions & 3 deletions docs/README.md

This file was deleted.

21 changes: 21 additions & 0 deletions docs/centos.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# CentOS

Our eBPF programs are designed to support down to CentOS 7.

Note that CentOS 7 uses Linux 3.10, and supports eBPF via backporting the code
for it to their distribution's kernel fork.

This introduces some complexities in dealing with the eBPF verifier, as it may
behave very differently than on the latest kernels for some code, and reject
it.

For this reason it is strongly advised to create a VM for CentOS 7 and test
whether the verifier will accept your programs on that platform.

## Setting up CentOS 7

Setting up the environment inside the VM is nearly exactly the same as that
used in the `Dockerfile.glibc.centos7`.

When you run any compilation commands with `make`, you must ensure `make` uses
the correct LLVM toolset as well.
28 changes: 28 additions & 0 deletions docs/compiling.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Compiling

## 1. Package Installs

Before compiling this repository, you have to install necessary packages
available on your Linux distribution. The complete list of packages can be
found inside the Docker files in this repository.

## 2. Linux Source Code Directory

Also, if your distribution does not create the symlink `/usr/src/linux`,
pointing to the latest Linux source code of your current live kernel, you
should make one now.

## 3. Disabling Inline Assembly

In case you are trying to compile on a kernel newer than `5.0`, it will be
necessary to disable the `assembly inline` option; this can be done by editing
the file `/usr/src/linux/include/generated/autoconf.h` and commenting the line
`//#define CONFIG_CC_HAS_ASM_INLINE 1`.

## 4. Compile

Now you can simply run `make`:

```bash
$ make -j`nproc`
```
29 changes: 29 additions & 0 deletions docs/kernel-vsn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Kernel version and eBPF program

In the first versions of the `bpf()` syscall, the Linux kernel verified whether
the eBPF programs that had `kprobe` were matching the kernel version, but when
the kernel `5.0` was released they removed this check with the argument that it
was [useless](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/kernel/bpf/syscall.c?h=v5.0&id=6c4fc209fcf9d27efbaa48368773e4d2bfbd59aa):

> bpf: remove useless version check for prog load
> Existing libraries and tracing frameworks work around this kernel
> version check by automatically deriving the kernel version from
> uname(3) or similar such that the user does not need to do it
> manually; these workarounds also make the version check useless
> at the same time.
>
> Moreover, most other BPF tracing types enabling `bpf_probe_read()`-like
> functionality have /not/ adapted this check, and in general these
> days it is well understood anyway that all the tracing programs are
> not stable with regards to future kernels as kernel internal data
> structures are subject to change from release to release.
>
> Back at last netconf we discussed [0] and agreed to remove this
> check from `bpf_prog_load()` and instead document it here in the uapi
> header that there is no such guarantee for stable API for these
> programs.
>
> [0] http://vger.kernel.org/netconf2018_files/DanielBorkmann_netconf2018.pdf
At Netdata we therefore took the decision to always give the current kernel
version of the kernel when any of our `kprobe`-based eBPF programs are loaded.
3 changes: 0 additions & 3 deletions includes/README.md

This file was deleted.

13 changes: 8 additions & 5 deletions kernel-patches/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
# Patches
# Kernel Patches

For some Linux kernels that are not LTS and are used on distributions like Ubuntu, BPF programs cannot be compiled
cleanly. It is necessary to apply some patches on these kernels in order to use them.
For some Linux kernels that are not LTS and are used on distributions like
Ubuntu, eBPF programs cannot be compiled cleanly. It is necessary to apply some
patches on these kernels in order to use them.

The structure of our Docker file forces us to have a directory for every kernel that we are compiling for. In case
the kernel does not need a patch, it is necessary to create the directory and insert an empty `.gitclean` file.
The structure of our Dockerfile forces us to have a directory for every kernel
that we are compiling for, even if a patch is not needed. If you'd like to add
a new kernel version, please make the directory here as well and insert an
empty `.gitclean` file.
Loading

0 comments on commit ea08cdf

Please sign in to comment.