Skip to content
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

Add PCP netatop BPF PMDA to extract per process network statistic. #1884

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
44 changes: 44 additions & 0 deletions .github/docker/Dockerfile.ubuntu
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
ARG VERSION="22.04"
FROM ubuntu:${VERSION}

ARG LLVM_VERSION="14"
ENV LLVM_VERSION=$LLVM_VERSION

ARG SHORTNAME="jammy"

RUN apt-get update && apt-get install -y curl gnupg
RUN if [ "${LLVM_VERSION}" = "16" ]; \
then \
echo "\n\
deb http://apt.llvm.org/${SHORTNAME}/ llvm-toolchain-${SHORTNAME} main\n\
deb-src http://apt.llvm.org/${SHORTNAME}/ llvm-toolchain-${SHORTNAME} main\n\
" >> /etc/apt/sources.list;\
else \
echo "\n\
deb http://apt.llvm.org/${SHORTNAME}/ llvm-toolchain-${SHORTNAME}-${LLVM_VERSION} main\n\
deb-src http://apt.llvm.org/${SHORTNAME}/ llvm-toolchain-${SHORTNAME}-${LLVM_VERSION} main\n\
" >> /etc/apt/sources.list; \
fi
RUN curl -L https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -

ARG DEBIAN_FRONTEND="noninteractive"
ENV TZ="Etc/UTC"

RUN apt-get update && apt-get install -y \
libelf-dev \
zlib1g-dev \
libbfd-dev \
clang-${LLVM_VERSION} \
libclang-${LLVM_VERSION}-dev \
libclang-common-${LLVM_VERSION}-dev \
libclang1-${LLVM_VERSION} \
llvm-${LLVM_VERSION} \
llvm-${LLVM_VERSION}-dev \
llvm-${LLVM_VERSION}-runtime \
libllvm${LLVM_VERSION} \
make pkg-config \
rustc cargo rustfmt \
sudo \
&& apt-get -y clean

RUN ln -s /usr/bin/clang-${LLVM_VERSION} /usr/bin/clang && ln -s /usr/bin/llvm-strip-${LLVM_VERSION} /usr/bin/llvm-strip
40 changes: 40 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: libbpf-bootstrap build

on:
push:
branches:
- master
pull_request:

jobs:
build_libbpf_bootstrap:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
llvm: [14, 15, 16]
steps:
- uses: actions/checkout@v2
with:
submodules: recursive
- name: Build container
uses: docker/build-push-action@v3
with:
push: false
build-args: LLVM_VERSION=${{ matrix.llvm }}
file: ./.github/docker/Dockerfile.ubuntu
tags: build_container
- name: Build examples/c
run: |
docker run \
-v $(pwd):/libbpf-bootstrap \
build_container \
/bin/bash -c \
'cd /libbpf-bootstrap/examples/c && make'
- name: Build examples/rust
run: |
docker run \
-v $(pwd):/libbpf-bootstrap \
build_container \
/bin/bash -c \
'cd /libbpf-bootstrap/examples/rust && cargo build'
5 changes: 3 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ jobs:
CC: clang
steps:
- uses: actions/checkout@v4
- name: Install dependencies
run: brew install gnu-tar pkg-config python-setuptools
- name: Build packages
# python disabled for now until brew build without distutils
run: ./Makepkgs --verbose --with-python=no --with-python3=no
run: ./Makepkgs --verbose
6 changes: 6 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[submodule "libbpf"]
path = libbpf
url = https://github.com/libbpf/libbpf.git
[submodule "bpftool"]
path = bpftool
url = https://github.com/libbpf/bpftool.git
29 changes: 29 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
BSD 3-Clause License

Copyright (c) 2020, Andrii Nakryiko
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
171 changes: 171 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
# SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
OUTPUT := .output
CLANG ?= clang
LLVM_STRIP ?= llvm-strip
LIBBPF_SRC := $(abspath libbpf/src)
BPFTOOL_SRC := $(abspath bpftool/src)
LIBBPF_OBJ := $(abspath $(OUTPUT)/libbpf.a)
BPFTOOL_OUTPUT ?= $(abspath $(OUTPUT)/bpftool)
BPFTOOL ?= $(BPFTOOL_OUTPUT)/bootstrap/bpftool
# LIBBLAZESYM_SRC := $(abspath blazesym/)
# LIBBLAZESYM_OBJ := $(abspath $(OUTPUT)/libblazesym.a)
# LIBBLAZESYM_HEADER := $(abspath $(OUTPUT)/blazesym.h)
ARCH := $(shell uname -m | sed 's/x86_64/x86/' | sed 's/aarch64/arm64/' | sed 's/ppc64le/powerpc/' | sed 's/mips.*/mips/')
VMLINUX := vmlinux/$(ARCH)/vmlinux.h
# Use our own libbpf API headers and Linux UAPI headers distributed with
# libbpf to avoid dependency on system-wide headers, which could be missing or
# outdated
INCLUDES := -I$(OUTPUT) -I../../libbpf/include/uapi -I$(dir $(VMLINUX))
CFLAGS := -g -Wall
ALL_LDFLAGS := $(LDFLAGS) $(EXTRA_LDFLAGS)

DESTDIR =
SBINPATH = /usr/sbin
SYSDPATH = /lib/systemd/system

# APPS = minimal minimal_legacy bootstrap uprobe netatop fentry usdt sockfilter tc
APPS = netatop

# CARGO ?= $(shell which cargo)
# ifeq ($(strip $(CARGO)),)
# BZS_APPS :=
# else
# BZS_APPS := profile
# APPS += $(BZS_APPS)
# # Required by libblazesym
# ALL_LDFLAGS += -lrt -ldl -lpthread -lm
# endif

# Get Clang's default includes on this system. We'll explicitly add these dirs
# to the includes list when compiling with `-target bpf` because otherwise some
# architecture-specific dirs will be "missing" on some architectures/distros -
# headers such as asm/types.h, asm/byteorder.h, asm/socket.h, asm/sockios.h,
# sys/cdefs.h etc. might be missing.
#
# Use '-idirafter': Don't interfere with include mechanics except where the
# build would have failed anyways.
CLANG_BPF_SYS_INCLUDES = $(shell $(CLANG) -v -E - </dev/null 2>&1 \
| sed -n '/<...> search starts here:/,/End of search list./{ s| \(/.*\)|-idirafter \1|p }')

ifeq ($(V),1)
Q =
msg =
else
Q = @
msg = @printf ' %-8s %s%s\n' \
"$(1)" \
"$(patsubst $(abspath $(OUTPUT))/%,%,$(2))" \
"$(if $(3), $(3))";
MAKEFLAGS += --no-print-directory
endif

define allow-override
$(if $(or $(findstring environment,$(origin $(1))),\
$(findstring command line,$(origin $(1)))),,\
$(eval $(1) = $(2)))
endef

$(call allow-override,CC,$(CROSS_COMPILE)cc)
$(call allow-override,LD,$(CROSS_COMPILE)ld)

.PHONY: all
all: $(APPS)

.PHONY: clean
clean:
$(call msg,CLEAN)
$(Q)rm -rf $(OUTPUT) netatop

$(OUTPUT) $(OUTPUT)/libbpf $(BPFTOOL_OUTPUT):
$(call msg,MKDIR,$@)
$(Q)mkdir -p $@

# Build libbpf
$(LIBBPF_OBJ): $(wildcard $(LIBBPF_SRC)/*.[ch] $(LIBBPF_SRC)/Makefile) | $(OUTPUT)/libbpf
$(call msg,LIB,$@)
$(Q)$(MAKE) -C $(LIBBPF_SRC) BUILD_STATIC_ONLY=1 \
OBJDIR=$(dir $@)/libbpf DESTDIR=$(dir $@) \
INCLUDEDIR= LIBDIR= UAPIDIR= \
install

# Build bpftool
$(BPFTOOL): | $(BPFTOOL_OUTPUT)
$(call msg,BPFTOOL,$@)
$(Q)$(MAKE) ARCH= CROSS_COMPILE= OUTPUT=$(BPFTOOL_OUTPUT)/ -C $(BPFTOOL_SRC) bootstrap


# $(LIBBLAZESYM_SRC)/target/release/libblazesym.a::
# $(Q)cd $(LIBBLAZESYM_SRC) && $(CARGO) build --features=cheader --release

# $(LIBBLAZESYM_OBJ): $(LIBBLAZESYM_SRC)/target/release/libblazesym.a | $(OUTPUT)
# $(call msg,LIB, $@)
# $(Q)cp $(LIBBLAZESYM_SRC)/target/release/libblazesym.a $@

# $(LIBBLAZESYM_HEADER): $(LIBBLAZESYM_SRC)/target/release/libblazesym.a | $(OUTPUT)
# $(call msg,LIB,$@)
# $(Q)cp $(LIBBLAZESYM_SRC)/target/release/blazesym.h $@

# Build BPF code
$(OUTPUT)/%.bpf.o: %.bpf.c $(LIBBPF_OBJ) $(wildcard %.h) $(VMLINUX) | $(OUTPUT)
$(call msg,BPF,$@)
$(Q)$(CLANG) -g -O2 -target bpf -D__TARGET_ARCH_$(ARCH) $(INCLUDES) $(CLANG_BPF_SYS_INCLUDES) -c $(filter %.c,$^) -o $@
$(Q)$(LLVM_STRIP) -g $@ # strip useless DWARF info

# Generate BPF skeletons
$(OUTPUT)/%.skel.h: $(OUTPUT)/%.bpf.o | $(OUTPUT) $(BPFTOOL)
$(call msg,GEN-SKEL,$@)
$(Q)$(BPFTOOL) gen skeleton $< > $@

# Build user-space code
$(patsubst %,$(OUTPUT)/%.o,$(APPS)): %.o: %.skel.h

$(OUTPUT)/%.o: %.c $(wildcard %.h) | $(OUTPUT)
$(call msg,CC,$@)
$(Q)$(CC) $(CFLAGS) $(INCLUDES) -c $(filter %.c,$^) -o $@

$(patsubst %,$(OUTPUT)/%.o,$(APPS)): $(LIBBLAZESYM_HEADER)

# $(BZS_APPS): $(LIBBLAZESYM_OBJ)

OBJ1 := $(OUTPUT)/server.o
OBJ2 := $(OUTPUT)/deal.o

${OBJ1}: server.c server.h
$(CC) -c server.c -o ${OBJ1}

${OBJ2}: deal.c deal.h
$(CC) -c deal.c -o ${OBJ2}

# Build application binary
$(APPS): %: $(OUTPUT)/%.o ${OBJ1} ${OBJ2} $(LIBBPF_OBJ) | $(OUTPUT)
$(call msg,BINARY,$@)
$(Q)$(CC) $(CFLAGS) $^ $(ALL_LDFLAGS) -lelf -lz -o $@

# # Build application binary
# $(APPS): %: $(OUTPUT)/%.o $(LIBBPF_OBJ) | $(OUTPUT)
# $(call msg,BINARY,$@)
# $(Q)$(CC) deal.c server.c $(CFLAGS) $^ $(ALL_LDFLAGS) -lelf -lz -o $@

# delete failed targets
.DELETE_ON_ERROR:

# keep intermediate (.skel.h, .bpf.o, etc) targets
.SECONDARY:

install:
if [ ! -d $(DESTDIR)$(SBINPATH) ]; \
then mkdir -p $(DESTDIR)$(SBINPATH); fi
if [ ! -d $(DESTDIR)$(SYSDPATH) ]; \
then mkdir -p $(DESTDIR)$(SYSDPATH); fi

cp netatop-bpf.service $(DESTDIR)$(SYSDPATH)/netatop-bpf.service
chmod 0644 $(DESTDIR)$(SYSDPATH)/netatop-bpf.service

cp netatop $(DESTDIR)$(SBINPATH)/netatop
chmod 0711 $(DESTDIR)$(SBINPATH)/netatop

if [ -z "$(DESTDIR)" -a -f /bin/systemctl ]; \
then /bin/systemctl disable --now netatop-bpf 2> /dev/null; \
/bin/systemctl daemon-reload; \
/bin/systemctl enable --now netatop-bpf; \
fi
1 change: 1 addition & 0 deletions bpftool
Submodule bpftool added at eb56fb
2 changes: 2 additions & 0 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -9182,6 +9182,8 @@ printf "%s\n" "no (libbpf version required: 1.0.0, installed: $libbpf_version)"
printf "%s\n" "yes" >&6; }
fi
pmdabpf_modules="${pmdabpf_modules} bashreadline.so biolatency.so execsnoop.so exitsnoop.so fsslower.so opensnoop.so runqlat.so statsnoop.so tcpconnect.so tcpconnlat.so vfsstat.so biosnoop.so"
# TODO need kernel tracepoint version check here
pmdabpf_modules="${pmdabpf_modules} netatop.so"

{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking which bpf PMDA modules should be included" >&5
printf %s "checking which bpf PMDA modules should be included... " >&6; }
Expand Down
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -2115,7 +2115,7 @@ dnl Checks for library functions.
AC_FUNC_VPRINTF
AC_CHECK_FUNCS(mktime nanosleep usleep unsetenv getrusage)
AC_CHECK_FUNCS(select socket syslog sendmsg recvmsg setns)
AC_CHECK_FUNCS(getuid getgid getpeerucred getpeereid getresuid)
AC_CHECK_FUNCS(getuid getgid getpeerucred getpeereid)
AC_CHECK_FUNCS(uname gethostname getdomainname getmachineid)
AC_CHECK_FUNCS(__clone pipe2 fcntl ioctl)
AC_CHECK_FUNCS(prctl setlinebuf waitpid atexit kill)
Expand Down
Loading
Loading