Skip to content

bpf: Generate helpers for pinning through bpf object skeleton #358

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

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions .github/actions/vmtest/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: 'vmtest'
description: 'Build + run vmtest'
inputs:
arch:
description: 'what arch to test'
required: true
default: 'x86_64'
runs:
using: "composite"
steps:
# 1. Setup environment
- name: Setup build environment
uses: libbpf/ci/setup-build-env@master
# 2. Build
- name: Build kernel image
shell: bash
run: ${GITHUB_ACTION_PATH}/build.sh ${{ inputs.arch }}
- name: Build selftests
shell: bash
run: ${GITHUB_ACTION_PATH}/build_selftests.sh
env:
VMLINUX_BTF: ${{ github.workspace }}/vmlinux
# 3. Test
- name: Prepare rootfs
uses: libbpf/ci/prepare-rootfs@master
with:
project-name: 'libbpf'
arch: ${{ inputs.arch }}
kernel-root: '.'
- name: Run selftests
uses: libbpf/ci/run-qemu@master
with:
arch: ${{ inputs.arch}}
img: '/tmp/root.img'
vmlinuz: '${{ github.workspace }}/vmlinuz'
17 changes: 17 additions & 0 deletions .github/actions/vmtest/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash

set -euo pipefail

ARCH="$1"

THISDIR="$(cd $(dirname $0) && pwd)"

source "${THISDIR}"/helpers.sh

travis_fold start build_kernel "Building kernel"

cp ${GITHUB_WORKSPACE}/travis-ci/vmtest/configs/config-latest.${ARCH} .config

make -j $((4*$(nproc))) olddefconfig all > /dev/null

travis_fold end build_kernel
42 changes: 42 additions & 0 deletions .github/actions/vmtest/build_selftests.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/bin/bash

set -euo pipefail

THISDIR="$(cd $(dirname $0) && pwd)"

source "${THISDIR}"/helpers.sh

travis_fold start prepare_selftests "Building selftests"

LLVM_VER=15
LIBBPF_PATH="${REPO_ROOT}"

PREPARE_SELFTESTS_SCRIPT=${THISDIR}/prepare_selftests-${KERNEL}.sh
if [ -f "${PREPARE_SELFTESTS_SCRIPT}" ]; then
(cd "${REPO_ROOT}/${REPO_PATH}/tools/testing/selftests/bpf" && ${PREPARE_SELFTESTS_SCRIPT})
fi

if [[ "${KERNEL}" = 'LATEST' ]]; then
VMLINUX_H=
else
VMLINUX_H=${THISDIR}/vmlinux.h
fi

cd ${REPO_ROOT}/${REPO_PATH}
make \
CLANG=clang-${LLVM_VER} \
LLC=llc-${LLVM_VER} \
LLVM_STRIP=llvm-strip-${LLVM_VER} \
VMLINUX_BTF="${VMLINUX_BTF}" \
VMLINUX_H="${VMLINUX_H}" \
-C "${REPO_ROOT}/${REPO_PATH}/tools/testing/selftests/bpf" \
-j $((4*$(nproc))) > /dev/null
cd -
mkdir "${LIBBPF_PATH}"/selftests
cp -R "${REPO_ROOT}/${REPO_PATH}/tools/testing/selftests/bpf" \
"${LIBBPF_PATH}"/selftests
cd "${LIBBPF_PATH}"
rm selftests/bpf/.gitignore
git add selftests

travis_fold end prepare_selftests
44 changes: 44 additions & 0 deletions .github/actions/vmtest/helpers.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# $1 - start or end
# $2 - fold identifier, no spaces
# $3 - fold section description
travis_fold() {
local YELLOW='\033[1;33m'
local NOCOLOR='\033[0m'
if [ -z ${GITHUB_WORKFLOW+x} ]; then
echo travis_fold:$1:$2
if [ ! -z "${3:-}" ]; then
echo -e "${YELLOW}$3${NOCOLOR}"
fi
echo
else
if [ $1 = "start" ]; then
line="::group::$2"
if [ ! -z "${3:-}" ]; then
line="$line - ${YELLOW}$3${NOCOLOR}"
fi
else
line="::endgroup::"
fi
echo -e "$line"
fi
}

__print() {
local TITLE=""
if [[ -n $2 ]]; then
TITLE=" title=$2"
fi
echo "::$1${TITLE}::$3"
}

# $1 - title
# $2 - message
print_error() {
__print error $1 $2
}

# $1 - title
# $2 - message
print_notice() {
__print notice $1 $2
}
50 changes: 50 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: bpf-ci

on:
pull_request:

concurrency:
group: ci-test-${{ github.head_ref }}
cancel-in-progress: true

jobs:
VM_Test:
runs-on: ${{ matrix.runs_on }}
name: Kernel ${{ matrix.kernel }} on ${{ matrix.runs_on }} + selftests
timeout-minutes: 100
strategy:
fail-fast: false
matrix:
include:
- kernel: 'LATEST'
runs_on: ubuntu-latest
arch: 'x86_64'
- kernel: 'LATEST'
runs_on: z15
arch: 's390x'
env:
AUTHOR_EMAIL: "$(git log -1 --pretty=\"%aE\")"
KERNEL: LATEST
REPO_ROOT: ${{ github.workspace }}
REPO_PATH: ""
steps:
- uses: actions/checkout@v2
- if: ${{ github.repository != 'kernel-patches/bpf' && github.repository != 'kernel-patches/bpf-rc' }}
name: Download bpf-next tree
uses: libbpf/ci/get-linux-source@master
with:
dest: '.kernel'
- if: ${{ github.repository != 'kernel-patches/bpf' && github.repository != 'kernel-patches/bpf-rc' }}
name: Move linux source in place
shell: bash
run: |
rm -rf .kernel/.git
cp -rf .kernel/. .
rm -rf .kernel
- uses: libbpf/ci/patch-kernel@master
with:
patches-root: '${{ github.workspace }}/travis-ci/diffs'
repo-root: '${{ github.workspace }}'
- uses: ./.github/actions/vmtest
with:
arch: ${{ matrix.arch }}
18 changes: 0 additions & 18 deletions README
Original file line number Diff line number Diff line change
@@ -1,18 +0,0 @@
Linux kernel
============

There are several guides for kernel developers and users. These guides can
be rendered in a number of formats, like HTML and PDF. Please read
Documentation/admin-guide/README.rst first.

In order to build the documentation, use ``make htmldocs`` or
``make pdfdocs``. The formatted documentation can also be read online at:

https://www.kernel.org/doc/html/latest/

There are various text files in the Documentation/ subdirectory,
several of them using the Restructured Text markup notation.

Please read the Documentation/process/changes.rst file, as it contains the
requirements for building and running the kernel, and information about
the problems which may result by upgrading your kernel.
18 changes: 17 additions & 1 deletion tools/bpf/bpftool/gen.c
Original file line number Diff line number Diff line change
Expand Up @@ -1087,6 +1087,8 @@ static int do_skeleton(int argc, char **argv)
static inline int load(struct %1$s *skel); \n\
static inline int attach(struct %1$s *skel); \n\
static inline void detach(struct %1$s *skel); \n\
static inline int pin_prog(struct %1$s *skel, const char *path);\n\
static inline void unpin_prog(struct %1$s *skel); \n\
static inline void destroy(struct %1$s *skel); \n\
static inline const void *elf_bytes(size_t *sz); \n\
#endif /* __cplusplus */ \n\
Expand Down Expand Up @@ -1171,7 +1173,19 @@ static int do_skeleton(int argc, char **argv)
static inline void \n\
%1$s__detach(struct %1$s *obj) \n\
{ \n\
return bpf_object__detach_skeleton(obj->skeleton); \n\
bpf_object__detach_skeleton(obj->skeleton); \n\
} \n\
\n\
static inline int \n\
%1$s__pin_prog(struct %1$s *obj, const char *path) \n\
{ \n\
return bpf_object__pin_skeleton_prog(obj->skeleton, path);\n\
} \n\
\n\
static inline void \n\
%1$s__unpin_prog(struct %1$s *obj) \n\
{ \n\
bpf_object__unpin_skeleton_prog(obj->skeleton); \n\
} \n\
",
obj_name
Expand Down Expand Up @@ -1237,6 +1251,8 @@ static int do_skeleton(int argc, char **argv)
int %1$s::load(struct %1$s *skel) { return %1$s__load(skel); } \n\
int %1$s::attach(struct %1$s *skel) { return %1$s__attach(skel); } \n\
void %1$s::detach(struct %1$s *skel) { %1$s__detach(skel); } \n\
int %1$s::pin_prog(struct %1$s *skel, const char *path) { return %1$s__pin_prog(skel, path); }\n\
void %1$s::unpin_prog(struct %1$s *skel) { %1$s__unpin_prog(skel); } \n\
void %1$s::destroy(struct %1$s *skel) { %1$s__destroy(skel); } \n\
const void *%1$s::elf_bytes(size_t *sz) { return %1$s__elf_bytes(sz); } \n\
#endif /* __cplusplus */ \n\
Expand Down
2 changes: 1 addition & 1 deletion tools/lib/bpf/bpf_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ struct bpf_map_def {

enum libbpf_pin_type {
LIBBPF_PIN_NONE,
/* PIN_BY_NAME: pin maps by name (in /sys/fs/bpf by default) */
/* PIN_BY_NAME: pin maps by name (in DEFAULT_BPFFS by default) */
LIBBPF_PIN_BY_NAME,
};

Expand Down
61 changes: 60 additions & 1 deletion tools/lib/bpf/libbpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -2180,7 +2180,7 @@ static int build_map_pin_path(struct bpf_map *map, const char *path)
int len;

if (!path)
path = "/sys/fs/bpf";
path = DEFAULT_BPFFS;

len = snprintf(buf, PATH_MAX, "%s/%s", path, bpf_map__name(map));
if (len < 0)
Expand Down Expand Up @@ -12726,6 +12726,65 @@ void bpf_object__detach_skeleton(struct bpf_object_skeleton *s)
}
}

int bpf_object__pin_skeleton_prog(struct bpf_object_skeleton *s,
const char *path)
{
struct bpf_link *link;
int err;
int i;

if (!s->prog_cnt)
return libbpf_err(-EINVAL);

if (!path)
path = DEFAULT_BPFFS;

for (i = 0; i < s->prog_cnt; i++) {
char buf[PATH_MAX];
int len;

len = snprintf(buf, PATH_MAX, "%s/%s", path, s->progs[i].name);
if (len < 0) {
err = -EINVAL;
goto err_unpin_prog;
} else if (len >= PATH_MAX) {
err = -ENAMETOOLONG;
goto err_unpin_prog;
}

link = *s->progs[i].link;
if (!link) {
err = -EINVAL;
goto err_unpin_prog;
}

err = bpf_link__pin(link, buf);
if (err)
goto err_unpin_prog;
}

return 0;

err_unpin_prog:
bpf_object__unpin_skeleton_prog(s);

return libbpf_err(err);
}

void bpf_object__unpin_skeleton_prog(struct bpf_object_skeleton *s)
{
struct bpf_link *link;
int i;

for (i = 0; i < s->prog_cnt; i++) {
link = *s->progs[i].link;
if (!link || !link->pin_path)
continue;

bpf_link__unpin(link);
}
}

void bpf_object__destroy_skeleton(struct bpf_object_skeleton *s)
{
if (!s)
Expand Down
10 changes: 8 additions & 2 deletions tools/lib/bpf/libbpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ LIBBPF_API __u32 libbpf_major_version(void);
LIBBPF_API __u32 libbpf_minor_version(void);
LIBBPF_API const char *libbpf_version_string(void);

#define DEFAULT_BPFFS "/sys/fs/bpf"

enum libbpf_errno {
__LIBBPF_ERRNO__START = 4000,

Expand Down Expand Up @@ -91,7 +93,7 @@ struct bpf_object_open_opts {
bool relaxed_core_relocs;
/* maps that set the 'pinning' attribute in their definition will have
* their pin_path attribute set to a file in this directory, and be
* auto-pinned to that path on load; defaults to "/sys/fs/bpf".
* auto-pinned to that path on load; defaults to DEFAULT_BPFFS.
*/
const char *pin_root_path;

Expand Down Expand Up @@ -190,7 +192,7 @@ bpf_object__open_xattr(struct bpf_object_open_attr *attr);

enum libbpf_pin_type {
LIBBPF_PIN_NONE,
/* PIN_BY_NAME: pin maps by name (in /sys/fs/bpf by default) */
/* PIN_BY_NAME: pin maps by name (in DEFAULT_BPFFS by default) */
LIBBPF_PIN_BY_NAME,
};

Expand Down Expand Up @@ -1425,6 +1427,10 @@ bpf_object__open_skeleton(struct bpf_object_skeleton *s,
LIBBPF_API int bpf_object__load_skeleton(struct bpf_object_skeleton *s);
LIBBPF_API int bpf_object__attach_skeleton(struct bpf_object_skeleton *s);
LIBBPF_API void bpf_object__detach_skeleton(struct bpf_object_skeleton *s);
LIBBPF_API int
bpf_object__pin_skeleton_prog(struct bpf_object_skeleton *s, const char *path);
LIBBPF_API void
bpf_object__unpin_skeleton_prog(struct bpf_object_skeleton *s);
LIBBPF_API void bpf_object__destroy_skeleton(struct bpf_object_skeleton *s);

struct bpf_var_skeleton {
Expand Down
2 changes: 2 additions & 0 deletions tools/lib/bpf/libbpf.map
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ LIBBPF_0.0.1 {
bpf_object__unload;
bpf_object__unpin_maps;
bpf_object__unpin_programs;
bpf_object__pin_skeleton_prog;
bpf_object__unpin_skeleton_prog;
bpf_perf_event_read_simple;
bpf_prog_attach;
bpf_prog_detach;
Expand Down
Loading