mirror of
https://github.com/netdata/libbpf.git
synced 2026-03-23 17:59:06 +08:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
17
.readthedocs.yaml
Normal file
17
.readthedocs.yaml
Normal file
@@ -0,0 +1,17 @@
|
||||
# .readthedocs.yaml
|
||||
# Read the Docs configuration file
|
||||
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
||||
|
||||
# Required
|
||||
version: 2
|
||||
|
||||
# Build documentation in the docs/ directory with Sphinx
|
||||
sphinx:
|
||||
builder: html
|
||||
configuration: docs/conf.py
|
||||
|
||||
# Optionally set the version of Python and requirements required to build your docs
|
||||
python:
|
||||
version: 3.7
|
||||
install:
|
||||
- requirements: docs/sphinx/requirements.txt
|
||||
@@ -1 +1 @@
|
||||
a02215ce72a37a19a690803b23b091186ee4f7b2
|
||||
3776f3517ed94d40ff0e3851d7ce2ce17b63099f
|
||||
|
||||
@@ -1 +1 @@
|
||||
372642ea83ff1c71a5d567a704c912359eb59776
|
||||
d20b41115ad53293201cc07ee429a38740cb056b
|
||||
|
||||
2
docs/.gitignore
vendored
Normal file
2
docs/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
sphinx/build
|
||||
sphinx/doxygen/build
|
||||
51
docs/api.rst
Normal file
51
docs/api.rst
Normal file
@@ -0,0 +1,51 @@
|
||||
.. SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
|
||||
|
||||
.. _api:
|
||||
|
||||
.. toctree:: Table of Contents
|
||||
|
||||
|
||||
LIBBPF API
|
||||
==================
|
||||
|
||||
libbpf.h
|
||||
--------
|
||||
.. doxygenfile:: libbpf.h
|
||||
:project: libbpf
|
||||
:sections: func define public-type
|
||||
|
||||
bpf.h
|
||||
-----
|
||||
.. doxygenfile:: bpf.h
|
||||
:project: libbpf
|
||||
:sections: func define public-type
|
||||
|
||||
btf.h
|
||||
-----
|
||||
.. doxygenfile:: btf.h
|
||||
:project: libbpf
|
||||
:sections: func define public-type
|
||||
|
||||
xsk.h
|
||||
-----
|
||||
.. doxygenfile:: xsk.h
|
||||
:project: libbpf
|
||||
:sections: func define public-type
|
||||
|
||||
bpf_tracing.h
|
||||
-------------
|
||||
.. doxygenfile:: bpf_tracing.h
|
||||
:project: libbpf
|
||||
:sections: func define public-type
|
||||
|
||||
bpf_core_read.h
|
||||
---------------
|
||||
.. doxygenfile:: bpf_core_read.h
|
||||
:project: libbpf
|
||||
:sections: func define public-type
|
||||
|
||||
bpf_endian.h
|
||||
------------
|
||||
.. doxygenfile:: bpf_endian.h
|
||||
:project: libbpf
|
||||
:sections: func define public-type
|
||||
40
docs/conf.py
Normal file
40
docs/conf.py
Normal file
@@ -0,0 +1,40 @@
|
||||
#!/usr/bin/env python3
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# Configuration file for the Sphinx documentation builder.
|
||||
#
|
||||
# This file only contains a selection of the most common options. For a full
|
||||
# list see the documentation:
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
project = "libbpf"
|
||||
|
||||
extensions = [
|
||||
'sphinx.ext.autodoc',
|
||||
'sphinx.ext.doctest',
|
||||
'sphinx.ext.mathjax',
|
||||
'sphinx.ext.viewcode',
|
||||
'sphinx.ext.imgmath',
|
||||
'sphinx.ext.todo',
|
||||
'breathe',
|
||||
]
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
# This pattern also affects html_static_path and html_extra_path.
|
||||
exclude_patterns = []
|
||||
|
||||
read_the_docs_build = os.environ.get('READTHEDOCS', None) == 'True'
|
||||
|
||||
if read_the_docs_build:
|
||||
subprocess.call('cd sphinx ; make clean', shell=True)
|
||||
subprocess.call('cd sphinx/doxygen ; doxygen', shell=True)
|
||||
|
||||
html_theme = 'sphinx_rtd_theme'
|
||||
|
||||
breathe_projects = { "libbpf": "./sphinx/doxygen/build/xml/" }
|
||||
breathe_default_project = "libbpf"
|
||||
breathe_show_define_initializer = True
|
||||
breathe_show_enumvalue_initializer = True
|
||||
22
docs/index.rst
Normal file
22
docs/index.rst
Normal file
@@ -0,0 +1,22 @@
|
||||
.. SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
|
||||
|
||||
libbpf
|
||||
======
|
||||
|
||||
For API documentation see the `versioned API documentation site <https://libbpf.readthedocs.io/en/latest/api.html>`_.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
libbpf_naming_convention
|
||||
libbpf_build
|
||||
|
||||
This is documentation for libbpf, a userspace library for loading and
|
||||
interacting with bpf programs.
|
||||
|
||||
All general BPF questions, including kernel functionality, libbpf APIs and
|
||||
their application, should be sent to bpf@vger.kernel.org mailing list.
|
||||
You can `subscribe <http://vger.kernel.org/vger-lists.html#bpf>`_ to the
|
||||
mailing list search its `archive <https://lore.kernel.org/bpf/>`_.
|
||||
Please search the archive before asking new questions. It very well might
|
||||
be that this was already addressed or answered before.
|
||||
37
docs/libbpf_build.rst
Normal file
37
docs/libbpf_build.rst
Normal file
@@ -0,0 +1,37 @@
|
||||
.. SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
|
||||
|
||||
Building libbpf
|
||||
===============
|
||||
|
||||
libelf and zlib are internal dependencies of libbpf and thus are required to link
|
||||
against and must be installed on the system for applications to work.
|
||||
pkg-config is used by default to find libelf, and the program called
|
||||
can be overridden with PKG_CONFIG.
|
||||
|
||||
If using pkg-config at build time is not desired, it can be disabled by
|
||||
setting NO_PKG_CONFIG=1 when calling make.
|
||||
|
||||
To build both static libbpf.a and shared libbpf.so:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ cd src
|
||||
$ make
|
||||
|
||||
To build only static libbpf.a library in directory build/ and install them
|
||||
together with libbpf headers in a staging directory root/:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ cd src
|
||||
$ mkdir build root
|
||||
$ BUILD_STATIC_ONLY=y OBJDIR=build DESTDIR=root make install
|
||||
|
||||
To build both static libbpf.a and shared libbpf.so against a custom libelf
|
||||
dependency installed in /build/root/ and install them together with libbpf
|
||||
headers in a build directory /build/root/:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ cd src
|
||||
$ PKG_CONFIG_PATH=/build/root/lib64/pkgconfig DESTDIR=/build/root make
|
||||
162
docs/libbpf_naming_convention.rst
Normal file
162
docs/libbpf_naming_convention.rst
Normal file
@@ -0,0 +1,162 @@
|
||||
.. SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
|
||||
|
||||
API naming convention
|
||||
=====================
|
||||
|
||||
libbpf API provides access to a few logically separated groups of
|
||||
functions and types. Every group has its own naming convention
|
||||
described here. It's recommended to follow these conventions whenever a
|
||||
new function or type is added to keep libbpf API clean and consistent.
|
||||
|
||||
All types and functions provided by libbpf API should have one of the
|
||||
following prefixes: ``bpf_``, ``btf_``, ``libbpf_``, ``xsk_``,
|
||||
``btf_dump_``, ``ring_buffer_``, ``perf_buffer_``.
|
||||
|
||||
System call wrappers
|
||||
--------------------
|
||||
|
||||
System call wrappers are simple wrappers for commands supported by
|
||||
sys_bpf system call. These wrappers should go to ``bpf.h`` header file
|
||||
and map one to one to corresponding commands.
|
||||
|
||||
For example ``bpf_map_lookup_elem`` wraps ``BPF_MAP_LOOKUP_ELEM``
|
||||
command of sys_bpf, ``bpf_prog_attach`` wraps ``BPF_PROG_ATTACH``, etc.
|
||||
|
||||
Objects
|
||||
-------
|
||||
|
||||
Another class of types and functions provided by libbpf API is "objects"
|
||||
and functions to work with them. Objects are high-level abstractions
|
||||
such as BPF program or BPF map. They're represented by corresponding
|
||||
structures such as ``struct bpf_object``, ``struct bpf_program``,
|
||||
``struct bpf_map``, etc.
|
||||
|
||||
Structures are forward declared and access to their fields should be
|
||||
provided via corresponding getters and setters rather than directly.
|
||||
|
||||
These objects are associated with corresponding parts of ELF object that
|
||||
contains compiled BPF programs.
|
||||
|
||||
For example ``struct bpf_object`` represents ELF object itself created
|
||||
from an ELF file or from a buffer, ``struct bpf_program`` represents a
|
||||
program in ELF object and ``struct bpf_map`` is a map.
|
||||
|
||||
Functions that work with an object have names built from object name,
|
||||
double underscore and part that describes function purpose.
|
||||
|
||||
For example ``bpf_object__open`` consists of the name of corresponding
|
||||
object, ``bpf_object``, double underscore and ``open`` that defines the
|
||||
purpose of the function to open ELF file and create ``bpf_object`` from
|
||||
it.
|
||||
|
||||
All objects and corresponding functions other than BTF related should go
|
||||
to ``libbpf.h``. BTF types and functions should go to ``btf.h``.
|
||||
|
||||
Auxiliary functions
|
||||
-------------------
|
||||
|
||||
Auxiliary functions and types that don't fit well in any of categories
|
||||
described above should have ``libbpf_`` prefix, e.g.
|
||||
``libbpf_get_error`` or ``libbpf_prog_type_by_name``.
|
||||
|
||||
AF_XDP functions
|
||||
-------------------
|
||||
|
||||
AF_XDP functions should have an ``xsk_`` prefix, e.g.
|
||||
``xsk_umem__get_data`` or ``xsk_umem__create``. The interface consists
|
||||
of both low-level ring access functions and high-level configuration
|
||||
functions. These can be mixed and matched. Note that these functions
|
||||
are not reentrant for performance reasons.
|
||||
|
||||
ABI
|
||||
---
|
||||
|
||||
libbpf can be both linked statically or used as DSO. To avoid possible
|
||||
conflicts with other libraries an application is linked with, all
|
||||
non-static libbpf symbols should have one of the prefixes mentioned in
|
||||
API documentation above. See API naming convention to choose the right
|
||||
name for a new symbol.
|
||||
|
||||
Symbol visibility
|
||||
-----------------
|
||||
|
||||
libbpf follow the model when all global symbols have visibility "hidden"
|
||||
by default and to make a symbol visible it has to be explicitly
|
||||
attributed with ``LIBBPF_API`` macro. For example:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
LIBBPF_API int bpf_prog_get_fd_by_id(__u32 id);
|
||||
|
||||
This prevents from accidentally exporting a symbol, that is not supposed
|
||||
to be a part of ABI what, in turn, improves both libbpf developer- and
|
||||
user-experiences.
|
||||
|
||||
ABI versionning
|
||||
---------------
|
||||
|
||||
To make future ABI extensions possible libbpf ABI is versioned.
|
||||
Versioning is implemented by ``libbpf.map`` version script that is
|
||||
passed to linker.
|
||||
|
||||
Version name is ``LIBBPF_`` prefix + three-component numeric version,
|
||||
starting from ``0.0.1``.
|
||||
|
||||
Every time ABI is being changed, e.g. because a new symbol is added or
|
||||
semantic of existing symbol is changed, ABI version should be bumped.
|
||||
This bump in ABI version is at most once per kernel development cycle.
|
||||
|
||||
For example, if current state of ``libbpf.map`` is:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
LIBBPF_0.0.1 {
|
||||
global:
|
||||
bpf_func_a;
|
||||
bpf_func_b;
|
||||
local:
|
||||
\*;
|
||||
};
|
||||
|
||||
, and a new symbol ``bpf_func_c`` is being introduced, then
|
||||
``libbpf.map`` should be changed like this:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
LIBBPF_0.0.1 {
|
||||
global:
|
||||
bpf_func_a;
|
||||
bpf_func_b;
|
||||
local:
|
||||
\*;
|
||||
};
|
||||
LIBBPF_0.0.2 {
|
||||
global:
|
||||
bpf_func_c;
|
||||
} LIBBPF_0.0.1;
|
||||
|
||||
, where new version ``LIBBPF_0.0.2`` depends on the previous
|
||||
``LIBBPF_0.0.1``.
|
||||
|
||||
Format of version script and ways to handle ABI changes, including
|
||||
incompatible ones, described in details in [1].
|
||||
|
||||
Stand-alone build
|
||||
-------------------
|
||||
|
||||
Under https://github.com/libbpf/libbpf there is a (semi-)automated
|
||||
mirror of the mainline's version of libbpf for a stand-alone build.
|
||||
|
||||
However, all changes to libbpf's code base must be upstreamed through
|
||||
the mainline kernel tree.
|
||||
|
||||
License
|
||||
-------------------
|
||||
|
||||
libbpf is dual-licensed under LGPL 2.1 and BSD 2-Clause.
|
||||
|
||||
Links
|
||||
-------------------
|
||||
|
||||
[1] https://www.akkadia.org/drepper/dsohowto.pdf
|
||||
(Chapter 3. Maintaining APIs and ABIs).
|
||||
9
docs/sphinx/Makefile
Normal file
9
docs/sphinx/Makefile
Normal file
@@ -0,0 +1,9 @@
|
||||
SPHINXBUILD ?= sphinx-build
|
||||
SOURCEDIR = ../src
|
||||
BUILDDIR = build
|
||||
|
||||
help:
|
||||
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)"
|
||||
|
||||
%:
|
||||
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)"
|
||||
277
docs/sphinx/doxygen/Doxyfile
Normal file
277
docs/sphinx/doxygen/Doxyfile
Normal file
@@ -0,0 +1,277 @@
|
||||
DOXYFILE_ENCODING = UTF-8
|
||||
PROJECT_NAME = "libbpf"
|
||||
PROJECT_NUMBER =
|
||||
PROJECT_BRIEF =
|
||||
PROJECT_LOGO =
|
||||
OUTPUT_DIRECTORY = ./build
|
||||
CREATE_SUBDIRS = NO
|
||||
ALLOW_UNICODE_NAMES = NO
|
||||
OUTPUT_LANGUAGE = English
|
||||
OUTPUT_TEXT_DIRECTION = None
|
||||
BRIEF_MEMBER_DESC = YES
|
||||
REPEAT_BRIEF = YES
|
||||
ALWAYS_DETAILED_SEC = NO
|
||||
INLINE_INHERITED_MEMB = NO
|
||||
FULL_PATH_NAMES = YES
|
||||
STRIP_FROM_PATH =
|
||||
STRIP_FROM_INC_PATH =
|
||||
SHORT_NAMES = NO
|
||||
JAVADOC_AUTOBRIEF = NO
|
||||
JAVADOC_BANNER = NO
|
||||
QT_AUTOBRIEF = NO
|
||||
MULTILINE_CPP_IS_BRIEF = NO
|
||||
PYTHON_DOCSTRING = NO
|
||||
INHERIT_DOCS = YES
|
||||
SEPARATE_MEMBER_PAGES = NO
|
||||
TAB_SIZE = 4
|
||||
ALIASES =
|
||||
OPTIMIZE_OUTPUT_FOR_C = YES
|
||||
OPTIMIZE_OUTPUT_JAVA = NO
|
||||
OPTIMIZE_FOR_FORTRAN = NO
|
||||
OPTIMIZE_OUTPUT_VHDL = NO
|
||||
OPTIMIZE_OUTPUT_SLICE = NO
|
||||
EXTENSION_MAPPING =
|
||||
MARKDOWN_SUPPORT = YES
|
||||
TOC_INCLUDE_HEADINGS = 5
|
||||
AUTOLINK_SUPPORT = YES
|
||||
BUILTIN_STL_SUPPORT = NO
|
||||
CPP_CLI_SUPPORT = NO
|
||||
SIP_SUPPORT = NO
|
||||
IDL_PROPERTY_SUPPORT = YES
|
||||
DISTRIBUTE_GROUP_DOC = NO
|
||||
GROUP_NESTED_COMPOUNDS = NO
|
||||
SUBGROUPING = YES
|
||||
INLINE_GROUPED_CLASSES = NO
|
||||
INLINE_SIMPLE_STRUCTS = NO
|
||||
TYPEDEF_HIDES_STRUCT = NO
|
||||
LOOKUP_CACHE_SIZE = 0
|
||||
NUM_PROC_THREADS = 1
|
||||
EXTRACT_ALL = NO
|
||||
EXTRACT_PRIVATE = NO
|
||||
EXTRACT_PRIV_VIRTUAL = NO
|
||||
EXTRACT_PACKAGE = NO
|
||||
EXTRACT_STATIC = NO
|
||||
EXTRACT_LOCAL_CLASSES = YES
|
||||
EXTRACT_LOCAL_METHODS = NO
|
||||
EXTRACT_ANON_NSPACES = NO
|
||||
RESOLVE_UNNAMED_PARAMS = YES
|
||||
HIDE_UNDOC_MEMBERS = NO
|
||||
HIDE_UNDOC_CLASSES = NO
|
||||
HIDE_FRIEND_COMPOUNDS = NO
|
||||
HIDE_IN_BODY_DOCS = NO
|
||||
INTERNAL_DOCS = NO
|
||||
CASE_SENSE_NAMES = YES
|
||||
HIDE_SCOPE_NAMES = NO
|
||||
HIDE_COMPOUND_REFERENCE= NO
|
||||
SHOW_INCLUDE_FILES = YES
|
||||
SHOW_GROUPED_MEMB_INC = NO
|
||||
FORCE_LOCAL_INCLUDES = NO
|
||||
INLINE_INFO = YES
|
||||
SORT_MEMBER_DOCS = YES
|
||||
SORT_BRIEF_DOCS = NO
|
||||
SORT_MEMBERS_CTORS_1ST = NO
|
||||
SORT_GROUP_NAMES = NO
|
||||
SORT_BY_SCOPE_NAME = NO
|
||||
STRICT_PROTO_MATCHING = NO
|
||||
GENERATE_TODOLIST = YES
|
||||
GENERATE_TESTLIST = YES
|
||||
GENERATE_BUGLIST = YES
|
||||
GENERATE_DEPRECATEDLIST= YES
|
||||
ENABLED_SECTIONS =
|
||||
MAX_INITIALIZER_LINES = 30
|
||||
SHOW_USED_FILES = YES
|
||||
SHOW_FILES = YES
|
||||
SHOW_NAMESPACES = YES
|
||||
FILE_VERSION_FILTER =
|
||||
LAYOUT_FILE =
|
||||
CITE_BIB_FILES =
|
||||
QUIET = NO
|
||||
WARNINGS = YES
|
||||
WARN_IF_UNDOCUMENTED = YES
|
||||
WARN_IF_DOC_ERROR = YES
|
||||
WARN_NO_PARAMDOC = NO
|
||||
WARN_AS_ERROR = NO
|
||||
WARN_FORMAT = "$file:$line: $text"
|
||||
WARN_LOGFILE =
|
||||
INPUT = ../../../src
|
||||
INPUT_ENCODING = UTF-8
|
||||
FILE_PATTERNS = *.c \
|
||||
*.h
|
||||
RECURSIVE = NO
|
||||
EXCLUDE =
|
||||
EXCLUDE_SYMLINKS = NO
|
||||
EXCLUDE_PATTERNS =
|
||||
EXCLUDE_SYMBOLS = ___*
|
||||
EXAMPLE_PATH =
|
||||
EXAMPLE_PATTERNS = *
|
||||
EXAMPLE_RECURSIVE = NO
|
||||
IMAGE_PATH =
|
||||
INPUT_FILTER =
|
||||
FILTER_PATTERNS =
|
||||
FILTER_SOURCE_FILES = NO
|
||||
FILTER_SOURCE_PATTERNS =
|
||||
USE_MDFILE_AS_MAINPAGE = YES
|
||||
SOURCE_BROWSER = NO
|
||||
INLINE_SOURCES = NO
|
||||
STRIP_CODE_COMMENTS = YES
|
||||
REFERENCED_BY_RELATION = NO
|
||||
REFERENCES_RELATION = NO
|
||||
REFERENCES_LINK_SOURCE = YES
|
||||
SOURCE_TOOLTIPS = YES
|
||||
USE_HTAGS = NO
|
||||
VERBATIM_HEADERS = YES
|
||||
ALPHABETICAL_INDEX = YES
|
||||
IGNORE_PREFIX =
|
||||
GENERATE_HTML = NO
|
||||
HTML_OUTPUT = html
|
||||
HTML_FILE_EXTENSION = .html
|
||||
HTML_HEADER =
|
||||
HTML_FOOTER =
|
||||
HTML_STYLESHEET =
|
||||
HTML_EXTRA_STYLESHEET =
|
||||
HTML_EXTRA_FILES =
|
||||
HTML_COLORSTYLE_HUE = 220
|
||||
HTML_COLORSTYLE_SAT = 100
|
||||
HTML_COLORSTYLE_GAMMA = 80
|
||||
HTML_TIMESTAMP = NO
|
||||
HTML_DYNAMIC_MENUS = YES
|
||||
HTML_DYNAMIC_SECTIONS = NO
|
||||
HTML_INDEX_NUM_ENTRIES = 100
|
||||
GENERATE_DOCSET = NO
|
||||
DOCSET_FEEDNAME = "Doxygen generated docs"
|
||||
DOCSET_BUNDLE_ID = org.doxygen.Project
|
||||
DOCSET_PUBLISHER_ID = org.doxygen.Publisher
|
||||
DOCSET_PUBLISHER_NAME = Publisher
|
||||
GENERATE_HTMLHELP = NO
|
||||
CHM_FILE =
|
||||
HHC_LOCATION =
|
||||
GENERATE_CHI = NO
|
||||
CHM_INDEX_ENCODING =
|
||||
BINARY_TOC = NO
|
||||
TOC_EXPAND = NO
|
||||
GENERATE_QHP = NO
|
||||
QCH_FILE =
|
||||
QHP_NAMESPACE = org.doxygen.Project
|
||||
QHP_VIRTUAL_FOLDER = doc
|
||||
QHP_CUST_FILTER_NAME =
|
||||
QHP_CUST_FILTER_ATTRS =
|
||||
QHP_SECT_FILTER_ATTRS =
|
||||
QHG_LOCATION =
|
||||
GENERATE_ECLIPSEHELP = NO
|
||||
ECLIPSE_DOC_ID = org.doxygen.Project
|
||||
DISABLE_INDEX = NO
|
||||
GENERATE_TREEVIEW = NO
|
||||
ENUM_VALUES_PER_LINE = 4
|
||||
TREEVIEW_WIDTH = 250
|
||||
EXT_LINKS_IN_WINDOW = NO
|
||||
HTML_FORMULA_FORMAT = png
|
||||
FORMULA_FONTSIZE = 10
|
||||
FORMULA_TRANSPARENT = YES
|
||||
FORMULA_MACROFILE =
|
||||
USE_MATHJAX = NO
|
||||
MATHJAX_FORMAT = HTML-CSS
|
||||
MATHJAX_RELPATH = https://cdn.jsdelivr.net/npm/mathjax@2
|
||||
MATHJAX_EXTENSIONS =
|
||||
MATHJAX_CODEFILE =
|
||||
SEARCHENGINE = YES
|
||||
SERVER_BASED_SEARCH = NO
|
||||
EXTERNAL_SEARCH = NO
|
||||
SEARCHENGINE_URL =
|
||||
SEARCHDATA_FILE = searchdata.xml
|
||||
EXTERNAL_SEARCH_ID =
|
||||
EXTRA_SEARCH_MAPPINGS =
|
||||
GENERATE_LATEX = NO
|
||||
LATEX_OUTPUT = latex
|
||||
LATEX_CMD_NAME =
|
||||
MAKEINDEX_CMD_NAME = makeindex
|
||||
LATEX_MAKEINDEX_CMD = makeindex
|
||||
COMPACT_LATEX = NO
|
||||
PAPER_TYPE = a4
|
||||
EXTRA_PACKAGES =
|
||||
LATEX_HEADER =
|
||||
LATEX_FOOTER =
|
||||
LATEX_EXTRA_STYLESHEET =
|
||||
LATEX_EXTRA_FILES =
|
||||
PDF_HYPERLINKS = YES
|
||||
USE_PDFLATEX = YES
|
||||
LATEX_BATCHMODE = NO
|
||||
LATEX_HIDE_INDICES = NO
|
||||
LATEX_SOURCE_CODE = NO
|
||||
LATEX_BIB_STYLE = plain
|
||||
LATEX_TIMESTAMP = NO
|
||||
LATEX_EMOJI_DIRECTORY =
|
||||
GENERATE_RTF = NO
|
||||
RTF_OUTPUT = rtf
|
||||
COMPACT_RTF = NO
|
||||
RTF_HYPERLINKS = NO
|
||||
RTF_STYLESHEET_FILE =
|
||||
RTF_EXTENSIONS_FILE =
|
||||
RTF_SOURCE_CODE = NO
|
||||
GENERATE_MAN = NO
|
||||
MAN_OUTPUT = man
|
||||
MAN_EXTENSION = .3
|
||||
MAN_SUBDIR =
|
||||
MAN_LINKS = NO
|
||||
GENERATE_XML = YES
|
||||
XML_OUTPUT = xml
|
||||
XML_PROGRAMLISTING = YES
|
||||
XML_NS_MEMB_FILE_SCOPE = NO
|
||||
GENERATE_DOCBOOK = NO
|
||||
DOCBOOK_OUTPUT = docbook
|
||||
DOCBOOK_PROGRAMLISTING = NO
|
||||
GENERATE_AUTOGEN_DEF = NO
|
||||
GENERATE_PERLMOD = NO
|
||||
PERLMOD_LATEX = NO
|
||||
PERLMOD_PRETTY = YES
|
||||
PERLMOD_MAKEVAR_PREFIX =
|
||||
ENABLE_PREPROCESSING = YES
|
||||
MACRO_EXPANSION = NO
|
||||
EXPAND_ONLY_PREDEF = YES
|
||||
SEARCH_INCLUDES = YES
|
||||
INCLUDE_PATH =
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
PREDEFINED =
|
||||
EXPAND_AS_DEFINED =
|
||||
SKIP_FUNCTION_MACROS = NO
|
||||
TAGFILES =
|
||||
GENERATE_TAGFILE =
|
||||
ALLEXTERNALS = NO
|
||||
EXTERNAL_GROUPS = YES
|
||||
EXTERNAL_PAGES = YES
|
||||
CLASS_DIAGRAMS = YES
|
||||
DIA_PATH =
|
||||
HIDE_UNDOC_RELATIONS = YES
|
||||
HAVE_DOT = NO
|
||||
DOT_NUM_THREADS = 0
|
||||
DOT_FONTNAME = Helvetica
|
||||
DOT_FONTSIZE = 10
|
||||
DOT_FONTPATH =
|
||||
CLASS_GRAPH = YES
|
||||
COLLABORATION_GRAPH = YES
|
||||
GROUP_GRAPHS = YES
|
||||
UML_LOOK = NO
|
||||
UML_LIMIT_NUM_FIELDS = 10
|
||||
DOT_UML_DETAILS = NO
|
||||
DOT_WRAP_THRESHOLD = 17
|
||||
TEMPLATE_RELATIONS = NO
|
||||
INCLUDE_GRAPH = YES
|
||||
INCLUDED_BY_GRAPH = YES
|
||||
CALL_GRAPH = NO
|
||||
CALLER_GRAPH = NO
|
||||
GRAPHICAL_HIERARCHY = YES
|
||||
DIRECTORY_GRAPH = YES
|
||||
DOT_IMAGE_FORMAT = png
|
||||
INTERACTIVE_SVG = NO
|
||||
DOT_PATH =
|
||||
DOTFILE_DIRS =
|
||||
MSCFILE_DIRS =
|
||||
DIAFILE_DIRS =
|
||||
PLANTUML_JAR_PATH =
|
||||
PLANTUML_CFG_FILE =
|
||||
PLANTUML_INCLUDE_PATH =
|
||||
DOT_GRAPH_MAX_NODES = 50
|
||||
MAX_DOT_GRAPH_DEPTH = 0
|
||||
DOT_TRANSPARENT = NO
|
||||
DOT_MULTI_TARGETS = NO
|
||||
GENERATE_LEGEND = YES
|
||||
DOT_CLEANUP = YES
|
||||
1
docs/sphinx/requirements.txt
Normal file
1
docs/sphinx/requirements.txt
Normal file
@@ -0,0 +1 @@
|
||||
breathe
|
||||
@@ -993,6 +993,7 @@ enum bpf_attach_type {
|
||||
BPF_SK_SKB_VERDICT,
|
||||
BPF_SK_REUSEPORT_SELECT,
|
||||
BPF_SK_REUSEPORT_SELECT_OR_MIGRATE,
|
||||
BPF_PERF_EVENT,
|
||||
__MAX_BPF_ATTACH_TYPE
|
||||
};
|
||||
|
||||
@@ -1006,6 +1007,7 @@ enum bpf_link_type {
|
||||
BPF_LINK_TYPE_ITER = 4,
|
||||
BPF_LINK_TYPE_NETNS = 5,
|
||||
BPF_LINK_TYPE_XDP = 6,
|
||||
BPF_LINK_TYPE_PERF_EVENT = 7,
|
||||
|
||||
MAX_BPF_LINK_TYPE,
|
||||
};
|
||||
@@ -1446,6 +1448,13 @@ union bpf_attr {
|
||||
__aligned_u64 iter_info; /* extra bpf_iter_link_info */
|
||||
__u32 iter_info_len; /* iter_info length */
|
||||
};
|
||||
struct {
|
||||
/* black box user-provided value passed through
|
||||
* to BPF program at the execution time and
|
||||
* accessible through bpf_get_attach_cookie() BPF helper
|
||||
*/
|
||||
__u64 bpf_cookie;
|
||||
} perf_event;
|
||||
};
|
||||
} link_create;
|
||||
|
||||
@@ -4847,6 +4856,21 @@ union bpf_attr {
|
||||
* Get address of the traced function (for tracing and kprobe programs).
|
||||
* Return
|
||||
* Address of the traced function.
|
||||
*
|
||||
* u64 bpf_get_attach_cookie(void *ctx)
|
||||
* Description
|
||||
* Get bpf_cookie value provided (optionally) during the program
|
||||
* attachment. It might be different for each individual
|
||||
* attachment, even if BPF program itself is the same.
|
||||
* Expects BPF program context *ctx* as a first argument.
|
||||
*
|
||||
* Supported for the following program types:
|
||||
* - kprobe/uprobe;
|
||||
* - tracepoint;
|
||||
* - perf_event.
|
||||
* Return
|
||||
* Value specified by user at BPF link creation/attachment time
|
||||
* or 0, if it was not specified.
|
||||
*/
|
||||
#define __BPF_FUNC_MAPPER(FN) \
|
||||
FN(unspec), \
|
||||
@@ -5023,6 +5047,7 @@ union bpf_attr {
|
||||
FN(timer_start), \
|
||||
FN(timer_cancel), \
|
||||
FN(get_func_ip), \
|
||||
FN(get_attach_cookie), \
|
||||
/* */
|
||||
|
||||
/* integer value in 'imm' field of BPF_CALL instruction selects which helper
|
||||
|
||||
@@ -653,6 +653,7 @@ enum {
|
||||
IFLA_BOND_AD_ACTOR_SYSTEM,
|
||||
IFLA_BOND_TLB_DYNAMIC_LB,
|
||||
IFLA_BOND_PEER_NOTIF_DELAY,
|
||||
IFLA_BOND_AD_LACP_ACTIVE,
|
||||
__IFLA_BOND_MAX,
|
||||
};
|
||||
|
||||
|
||||
@@ -47,11 +47,12 @@ PATH_MAP=( \
|
||||
[tools/include/uapi/linux/netlink.h]=include/uapi/linux/netlink.h \
|
||||
[tools/include/uapi/linux/pkt_cls.h]=include/uapi/linux/pkt_cls.h \
|
||||
[tools/include/uapi/linux/pkt_sched.h]=include/uapi/linux/pkt_sched.h \
|
||||
[Documentation/bpf/libbpf]=docs \
|
||||
)
|
||||
|
||||
LIBBPF_PATHS="${!PATH_MAP[@]} :^tools/lib/bpf/Makefile :^tools/lib/bpf/Build :^tools/lib/bpf/.gitignore :^tools/include/tools/libc_compat.h"
|
||||
LIBBPF_VIEW_PATHS="${PATH_MAP[@]}"
|
||||
LIBBPF_VIEW_EXCLUDE_REGEX='^src/(Makefile|Build|test_libbpf\.c|bpf_helper_defs\.h|\.gitignore)$'
|
||||
LIBBPF_VIEW_EXCLUDE_REGEX='^src/(Makefile|Build|test_libbpf\.c|bpf_helper_defs\.h|\.gitignore)$|^docs/(\.gitignore|api\.rst|conf\.py)$|^docs/sphinx/.*'
|
||||
LINUX_VIEW_EXCLUDE_REGEX='^include/tools/libc_compat.h$'
|
||||
|
||||
LIBBPF_TREE_FILTER="mkdir -p __libbpf/include/uapi/linux __libbpf/include/tools && "$'\\\n'
|
||||
|
||||
32
src/bpf.c
32
src/bpf.c
@@ -684,8 +684,13 @@ int bpf_link_create(int prog_fd, int target_fd,
|
||||
iter_info_len = OPTS_GET(opts, iter_info_len, 0);
|
||||
target_btf_id = OPTS_GET(opts, target_btf_id, 0);
|
||||
|
||||
if (iter_info_len && target_btf_id)
|
||||
return libbpf_err(-EINVAL);
|
||||
/* validate we don't have unexpected combinations of non-zero fields */
|
||||
if (iter_info_len || target_btf_id) {
|
||||
if (iter_info_len && target_btf_id)
|
||||
return libbpf_err(-EINVAL);
|
||||
if (!OPTS_ZEROED(opts, target_btf_id))
|
||||
return libbpf_err(-EINVAL);
|
||||
}
|
||||
|
||||
memset(&attr, 0, sizeof(attr));
|
||||
attr.link_create.prog_fd = prog_fd;
|
||||
@@ -693,14 +698,27 @@ int bpf_link_create(int prog_fd, int target_fd,
|
||||
attr.link_create.attach_type = attach_type;
|
||||
attr.link_create.flags = OPTS_GET(opts, flags, 0);
|
||||
|
||||
if (iter_info_len) {
|
||||
attr.link_create.iter_info =
|
||||
ptr_to_u64(OPTS_GET(opts, iter_info, (void *)0));
|
||||
attr.link_create.iter_info_len = iter_info_len;
|
||||
} else if (target_btf_id) {
|
||||
if (target_btf_id) {
|
||||
attr.link_create.target_btf_id = target_btf_id;
|
||||
goto proceed;
|
||||
}
|
||||
|
||||
switch (attach_type) {
|
||||
case BPF_TRACE_ITER:
|
||||
attr.link_create.iter_info = ptr_to_u64(OPTS_GET(opts, iter_info, (void *)0));
|
||||
attr.link_create.iter_info_len = iter_info_len;
|
||||
break;
|
||||
case BPF_PERF_EVENT:
|
||||
attr.link_create.perf_event.bpf_cookie = OPTS_GET(opts, perf_event.bpf_cookie, 0);
|
||||
if (!OPTS_ZEROED(opts, perf_event))
|
||||
return libbpf_err(-EINVAL);
|
||||
break;
|
||||
default:
|
||||
if (!OPTS_ZEROED(opts, flags))
|
||||
return libbpf_err(-EINVAL);
|
||||
break;
|
||||
}
|
||||
proceed:
|
||||
fd = sys_bpf(BPF_LINK_CREATE, &attr, sizeof(attr));
|
||||
return libbpf_err_errno(fd);
|
||||
}
|
||||
|
||||
@@ -177,8 +177,14 @@ struct bpf_link_create_opts {
|
||||
union bpf_iter_link_info *iter_info;
|
||||
__u32 iter_info_len;
|
||||
__u32 target_btf_id;
|
||||
union {
|
||||
struct {
|
||||
__u64 bpf_cookie;
|
||||
} perf_event;
|
||||
};
|
||||
size_t :0;
|
||||
};
|
||||
#define bpf_link_create_opts__last_field target_btf_id
|
||||
#define bpf_link_create_opts__last_field perf_event
|
||||
|
||||
LIBBPF_API int bpf_link_create(int prog_fd, int target_fd,
|
||||
enum bpf_attach_type attach_type,
|
||||
|
||||
@@ -4014,4 +4014,23 @@ static long (*bpf_timer_cancel)(struct bpf_timer *timer) = (void *) 172;
|
||||
*/
|
||||
static __u64 (*bpf_get_func_ip)(void *ctx) = (void *) 173;
|
||||
|
||||
/*
|
||||
* bpf_get_attach_cookie
|
||||
*
|
||||
* Get bpf_cookie value provided (optionally) during the program
|
||||
* attachment. It might be different for each individual
|
||||
* attachment, even if BPF program itself is the same.
|
||||
* Expects BPF program context *ctx* as a first argument.
|
||||
*
|
||||
* Supported for the following program types:
|
||||
* - kprobe/uprobe;
|
||||
* - tracepoint;
|
||||
* - perf_event.
|
||||
*
|
||||
* Returns
|
||||
* Value specified by user at BPF link creation/attachment time
|
||||
* or 0, if it was not specified.
|
||||
*/
|
||||
static __u64 (*bpf_get_attach_cookie)(void *ctx) = (void *) 174;
|
||||
|
||||
|
||||
|
||||
231
src/libbpf.c
231
src/libbpf.c
@@ -193,6 +193,8 @@ enum kern_feature_id {
|
||||
FEAT_MODULE_BTF,
|
||||
/* BTF_KIND_FLOAT support */
|
||||
FEAT_BTF_FLOAT,
|
||||
/* BPF perf link support */
|
||||
FEAT_PERF_LINK,
|
||||
__FEAT_CNT,
|
||||
};
|
||||
|
||||
@@ -4337,6 +4339,37 @@ static int probe_module_btf(void)
|
||||
return !err;
|
||||
}
|
||||
|
||||
static int probe_perf_link(void)
|
||||
{
|
||||
struct bpf_load_program_attr attr;
|
||||
struct bpf_insn insns[] = {
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
};
|
||||
int prog_fd, link_fd, err;
|
||||
|
||||
memset(&attr, 0, sizeof(attr));
|
||||
attr.prog_type = BPF_PROG_TYPE_TRACEPOINT;
|
||||
attr.insns = insns;
|
||||
attr.insns_cnt = ARRAY_SIZE(insns);
|
||||
attr.license = "GPL";
|
||||
prog_fd = bpf_load_program_xattr(&attr, NULL, 0);
|
||||
if (prog_fd < 0)
|
||||
return -errno;
|
||||
|
||||
/* use invalid perf_event FD to get EBADF, if link is supported;
|
||||
* otherwise EINVAL should be returned
|
||||
*/
|
||||
link_fd = bpf_link_create(prog_fd, -1, BPF_PERF_EVENT, NULL);
|
||||
err = -errno; /* close() can clobber errno */
|
||||
|
||||
if (link_fd >= 0)
|
||||
close(link_fd);
|
||||
close(prog_fd);
|
||||
|
||||
return link_fd < 0 && err == -EBADF;
|
||||
}
|
||||
|
||||
enum kern_feature_result {
|
||||
FEAT_UNKNOWN = 0,
|
||||
FEAT_SUPPORTED = 1,
|
||||
@@ -4387,6 +4420,9 @@ static struct kern_feature_desc {
|
||||
[FEAT_BTF_FLOAT] = {
|
||||
"BTF_KIND_FLOAT support", probe_kern_btf_float,
|
||||
},
|
||||
[FEAT_PERF_LINK] = {
|
||||
"BPF perf link support", probe_perf_link,
|
||||
},
|
||||
};
|
||||
|
||||
static bool kernel_supports(const struct bpf_object *obj, enum kern_feature_id feat_id)
|
||||
@@ -5277,11 +5313,11 @@ bpf_object__relocate_data(struct bpf_object *obj, struct bpf_program *prog)
|
||||
}
|
||||
insn[1].imm = ext->kcfg.data_off;
|
||||
} else /* EXT_KSYM */ {
|
||||
if (ext->ksym.type_id) { /* typed ksyms */
|
||||
if (ext->ksym.type_id && ext->is_set) { /* typed ksyms */
|
||||
insn[0].src_reg = BPF_PSEUDO_BTF_ID;
|
||||
insn[0].imm = ext->ksym.kernel_btf_id;
|
||||
insn[1].imm = ext->ksym.kernel_btf_obj_fd;
|
||||
} else { /* typeless ksyms */
|
||||
} else { /* typeless ksyms or unresolved typed ksyms */
|
||||
insn[0].imm = (__u32)ext->ksym.addr;
|
||||
insn[1].imm = ext->ksym.addr >> 32;
|
||||
}
|
||||
@@ -6608,11 +6644,8 @@ static int find_ksym_btf_id(struct bpf_object *obj, const char *ksym_name,
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (id <= 0) {
|
||||
pr_warn("extern (%s ksym) '%s': failed to find BTF ID in kernel BTF(s).\n",
|
||||
__btf_kind_str(kind), ksym_name);
|
||||
if (id <= 0)
|
||||
return -ESRCH;
|
||||
}
|
||||
|
||||
*res_btf = btf;
|
||||
*res_btf_fd = btf_fd;
|
||||
@@ -6629,8 +6662,13 @@ static int bpf_object__resolve_ksym_var_btf_id(struct bpf_object *obj,
|
||||
struct btf *btf = NULL;
|
||||
|
||||
id = find_ksym_btf_id(obj, ext->name, BTF_KIND_VAR, &btf, &btf_fd);
|
||||
if (id < 0)
|
||||
if (id == -ESRCH && ext->is_weak) {
|
||||
return 0;
|
||||
} else if (id < 0) {
|
||||
pr_warn("extern (var ksym) '%s': not found in kernel BTF\n",
|
||||
ext->name);
|
||||
return id;
|
||||
}
|
||||
|
||||
/* find local type_id */
|
||||
local_type_id = ext->ksym.type_id;
|
||||
@@ -8808,7 +8846,7 @@ int bpf_prog_load_xattr(const struct bpf_prog_load_attr *attr,
|
||||
|
||||
struct bpf_link {
|
||||
int (*detach)(struct bpf_link *link);
|
||||
int (*destroy)(struct bpf_link *link);
|
||||
void (*dealloc)(struct bpf_link *link);
|
||||
char *pin_path; /* NULL, if not pinned */
|
||||
int fd; /* hook FD, -1 if not applicable */
|
||||
bool disconnected;
|
||||
@@ -8847,11 +8885,12 @@ int bpf_link__destroy(struct bpf_link *link)
|
||||
|
||||
if (!link->disconnected && link->detach)
|
||||
err = link->detach(link);
|
||||
if (link->destroy)
|
||||
link->destroy(link);
|
||||
if (link->pin_path)
|
||||
free(link->pin_path);
|
||||
free(link);
|
||||
if (link->dealloc)
|
||||
link->dealloc(link);
|
||||
else
|
||||
free(link);
|
||||
|
||||
return libbpf_err(err);
|
||||
}
|
||||
@@ -8948,23 +8987,42 @@ int bpf_link__unpin(struct bpf_link *link)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bpf_link__detach_perf_event(struct bpf_link *link)
|
||||
{
|
||||
int err;
|
||||
struct bpf_link_perf {
|
||||
struct bpf_link link;
|
||||
int perf_event_fd;
|
||||
};
|
||||
|
||||
err = ioctl(link->fd, PERF_EVENT_IOC_DISABLE, 0);
|
||||
if (err)
|
||||
static int bpf_link_perf_detach(struct bpf_link *link)
|
||||
{
|
||||
struct bpf_link_perf *perf_link = container_of(link, struct bpf_link_perf, link);
|
||||
int err = 0;
|
||||
|
||||
if (ioctl(perf_link->perf_event_fd, PERF_EVENT_IOC_DISABLE, 0) < 0)
|
||||
err = -errno;
|
||||
|
||||
if (perf_link->perf_event_fd != link->fd)
|
||||
close(perf_link->perf_event_fd);
|
||||
close(link->fd);
|
||||
|
||||
return libbpf_err(err);
|
||||
}
|
||||
|
||||
struct bpf_link *bpf_program__attach_perf_event(struct bpf_program *prog, int pfd)
|
||||
static void bpf_link_perf_dealloc(struct bpf_link *link)
|
||||
{
|
||||
struct bpf_link_perf *perf_link = container_of(link, struct bpf_link_perf, link);
|
||||
|
||||
free(perf_link);
|
||||
}
|
||||
|
||||
struct bpf_link *bpf_program__attach_perf_event_opts(struct bpf_program *prog, int pfd,
|
||||
const struct bpf_perf_event_opts *opts)
|
||||
{
|
||||
char errmsg[STRERR_BUFSIZE];
|
||||
struct bpf_link *link;
|
||||
int prog_fd, err;
|
||||
struct bpf_link_perf *link;
|
||||
int prog_fd, link_fd = -1, err;
|
||||
|
||||
if (!OPTS_VALID(opts, bpf_perf_event_opts))
|
||||
return libbpf_err_ptr(-EINVAL);
|
||||
|
||||
if (pfd < 0) {
|
||||
pr_warn("prog '%s': invalid perf event FD %d\n",
|
||||
@@ -8981,27 +9039,59 @@ struct bpf_link *bpf_program__attach_perf_event(struct bpf_program *prog, int pf
|
||||
link = calloc(1, sizeof(*link));
|
||||
if (!link)
|
||||
return libbpf_err_ptr(-ENOMEM);
|
||||
link->detach = &bpf_link__detach_perf_event;
|
||||
link->fd = pfd;
|
||||
link->link.detach = &bpf_link_perf_detach;
|
||||
link->link.dealloc = &bpf_link_perf_dealloc;
|
||||
link->perf_event_fd = pfd;
|
||||
|
||||
if (ioctl(pfd, PERF_EVENT_IOC_SET_BPF, prog_fd) < 0) {
|
||||
err = -errno;
|
||||
free(link);
|
||||
pr_warn("prog '%s': failed to attach to pfd %d: %s\n",
|
||||
prog->name, pfd, libbpf_strerror_r(err, errmsg, sizeof(errmsg)));
|
||||
if (err == -EPROTO)
|
||||
pr_warn("prog '%s': try add PERF_SAMPLE_CALLCHAIN to or remove exclude_callchain_[kernel|user] from pfd %d\n",
|
||||
prog->name, pfd);
|
||||
return libbpf_err_ptr(err);
|
||||
if (kernel_supports(prog->obj, FEAT_PERF_LINK)) {
|
||||
DECLARE_LIBBPF_OPTS(bpf_link_create_opts, link_opts,
|
||||
.perf_event.bpf_cookie = OPTS_GET(opts, bpf_cookie, 0));
|
||||
|
||||
link_fd = bpf_link_create(prog_fd, pfd, BPF_PERF_EVENT, &link_opts);
|
||||
if (link_fd < 0) {
|
||||
err = -errno;
|
||||
pr_warn("prog '%s': failed to create BPF link for perf_event FD %d: %d (%s)\n",
|
||||
prog->name, pfd,
|
||||
err, libbpf_strerror_r(err, errmsg, sizeof(errmsg)));
|
||||
goto err_out;
|
||||
}
|
||||
link->link.fd = link_fd;
|
||||
} else {
|
||||
if (OPTS_GET(opts, bpf_cookie, 0)) {
|
||||
pr_warn("prog '%s': user context value is not supported\n", prog->name);
|
||||
err = -EOPNOTSUPP;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
if (ioctl(pfd, PERF_EVENT_IOC_SET_BPF, prog_fd) < 0) {
|
||||
err = -errno;
|
||||
pr_warn("prog '%s': failed to attach to perf_event FD %d: %s\n",
|
||||
prog->name, pfd, libbpf_strerror_r(err, errmsg, sizeof(errmsg)));
|
||||
if (err == -EPROTO)
|
||||
pr_warn("prog '%s': try add PERF_SAMPLE_CALLCHAIN to or remove exclude_callchain_[kernel|user] from pfd %d\n",
|
||||
prog->name, pfd);
|
||||
goto err_out;
|
||||
}
|
||||
link->link.fd = pfd;
|
||||
}
|
||||
if (ioctl(pfd, PERF_EVENT_IOC_ENABLE, 0) < 0) {
|
||||
err = -errno;
|
||||
free(link);
|
||||
pr_warn("prog '%s': failed to enable pfd %d: %s\n",
|
||||
pr_warn("prog '%s': failed to enable perf_event FD %d: %s\n",
|
||||
prog->name, pfd, libbpf_strerror_r(err, errmsg, sizeof(errmsg)));
|
||||
return libbpf_err_ptr(err);
|
||||
goto err_out;
|
||||
}
|
||||
return link;
|
||||
|
||||
return &link->link;
|
||||
err_out:
|
||||
if (link_fd >= 0)
|
||||
close(link_fd);
|
||||
free(link);
|
||||
return libbpf_err_ptr(err);
|
||||
}
|
||||
|
||||
struct bpf_link *bpf_program__attach_perf_event(struct bpf_program *prog, int pfd)
|
||||
{
|
||||
return bpf_program__attach_perf_event_opts(prog, pfd, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -9062,13 +9152,19 @@ static int determine_uprobe_retprobe_bit(void)
|
||||
return parse_uint_from_file(file, "config:%d\n");
|
||||
}
|
||||
|
||||
#define PERF_UPROBE_REF_CTR_OFFSET_BITS 32
|
||||
#define PERF_UPROBE_REF_CTR_OFFSET_SHIFT 32
|
||||
|
||||
static int perf_event_open_probe(bool uprobe, bool retprobe, const char *name,
|
||||
uint64_t offset, int pid)
|
||||
uint64_t offset, int pid, size_t ref_ctr_off)
|
||||
{
|
||||
struct perf_event_attr attr = {};
|
||||
char errmsg[STRERR_BUFSIZE];
|
||||
int type, pfd, err;
|
||||
|
||||
if (ref_ctr_off >= (1ULL << PERF_UPROBE_REF_CTR_OFFSET_BITS))
|
||||
return -EINVAL;
|
||||
|
||||
type = uprobe ? determine_uprobe_perf_type()
|
||||
: determine_kprobe_perf_type();
|
||||
if (type < 0) {
|
||||
@@ -9091,6 +9187,7 @@ static int perf_event_open_probe(bool uprobe, bool retprobe, const char *name,
|
||||
}
|
||||
attr.size = sizeof(attr);
|
||||
attr.type = type;
|
||||
attr.config |= (__u64)ref_ctr_off << PERF_UPROBE_REF_CTR_OFFSET_SHIFT;
|
||||
attr.config1 = ptr_to_u64(name); /* kprobe_func or uprobe_path */
|
||||
attr.config2 = offset; /* kprobe_addr or probe_offset */
|
||||
|
||||
@@ -9112,8 +9209,9 @@ static int perf_event_open_probe(bool uprobe, bool retprobe, const char *name,
|
||||
struct bpf_link *
|
||||
bpf_program__attach_kprobe_opts(struct bpf_program *prog,
|
||||
const char *func_name,
|
||||
struct bpf_kprobe_opts *opts)
|
||||
const struct bpf_kprobe_opts *opts)
|
||||
{
|
||||
DECLARE_LIBBPF_OPTS(bpf_perf_event_opts, pe_opts);
|
||||
char errmsg[STRERR_BUFSIZE];
|
||||
struct bpf_link *link;
|
||||
unsigned long offset;
|
||||
@@ -9125,16 +9223,17 @@ bpf_program__attach_kprobe_opts(struct bpf_program *prog,
|
||||
|
||||
retprobe = OPTS_GET(opts, retprobe, false);
|
||||
offset = OPTS_GET(opts, offset, 0);
|
||||
pe_opts.bpf_cookie = OPTS_GET(opts, bpf_cookie, 0);
|
||||
|
||||
pfd = perf_event_open_probe(false /* uprobe */, retprobe, func_name,
|
||||
offset, -1 /* pid */);
|
||||
offset, -1 /* pid */, 0 /* ref_ctr_off */);
|
||||
if (pfd < 0) {
|
||||
pr_warn("prog '%s': failed to create %s '%s' perf event: %s\n",
|
||||
prog->name, retprobe ? "kretprobe" : "kprobe", func_name,
|
||||
libbpf_strerror_r(pfd, errmsg, sizeof(errmsg)));
|
||||
return libbpf_err_ptr(pfd);
|
||||
}
|
||||
link = bpf_program__attach_perf_event(prog, pfd);
|
||||
link = bpf_program__attach_perf_event_opts(prog, pfd, &pe_opts);
|
||||
err = libbpf_get_error(link);
|
||||
if (err) {
|
||||
close(pfd);
|
||||
@@ -9189,17 +9288,27 @@ static struct bpf_link *attach_kprobe(const struct bpf_sec_def *sec,
|
||||
return link;
|
||||
}
|
||||
|
||||
struct bpf_link *bpf_program__attach_uprobe(struct bpf_program *prog,
|
||||
bool retprobe, pid_t pid,
|
||||
const char *binary_path,
|
||||
size_t func_offset)
|
||||
LIBBPF_API struct bpf_link *
|
||||
bpf_program__attach_uprobe_opts(struct bpf_program *prog, pid_t pid,
|
||||
const char *binary_path, size_t func_offset,
|
||||
const struct bpf_uprobe_opts *opts)
|
||||
{
|
||||
DECLARE_LIBBPF_OPTS(bpf_perf_event_opts, pe_opts);
|
||||
char errmsg[STRERR_BUFSIZE];
|
||||
struct bpf_link *link;
|
||||
size_t ref_ctr_off;
|
||||
int pfd, err;
|
||||
bool retprobe;
|
||||
|
||||
pfd = perf_event_open_probe(true /* uprobe */, retprobe,
|
||||
binary_path, func_offset, pid);
|
||||
if (!OPTS_VALID(opts, bpf_uprobe_opts))
|
||||
return libbpf_err_ptr(-EINVAL);
|
||||
|
||||
retprobe = OPTS_GET(opts, retprobe, false);
|
||||
ref_ctr_off = OPTS_GET(opts, ref_ctr_offset, 0);
|
||||
pe_opts.bpf_cookie = OPTS_GET(opts, bpf_cookie, 0);
|
||||
|
||||
pfd = perf_event_open_probe(true /* uprobe */, retprobe, binary_path,
|
||||
func_offset, pid, ref_ctr_off);
|
||||
if (pfd < 0) {
|
||||
pr_warn("prog '%s': failed to create %s '%s:0x%zx' perf event: %s\n",
|
||||
prog->name, retprobe ? "uretprobe" : "uprobe",
|
||||
@@ -9207,7 +9316,7 @@ struct bpf_link *bpf_program__attach_uprobe(struct bpf_program *prog,
|
||||
libbpf_strerror_r(pfd, errmsg, sizeof(errmsg)));
|
||||
return libbpf_err_ptr(pfd);
|
||||
}
|
||||
link = bpf_program__attach_perf_event(prog, pfd);
|
||||
link = bpf_program__attach_perf_event_opts(prog, pfd, &pe_opts);
|
||||
err = libbpf_get_error(link);
|
||||
if (err) {
|
||||
close(pfd);
|
||||
@@ -9220,6 +9329,16 @@ struct bpf_link *bpf_program__attach_uprobe(struct bpf_program *prog,
|
||||
return link;
|
||||
}
|
||||
|
||||
struct bpf_link *bpf_program__attach_uprobe(struct bpf_program *prog,
|
||||
bool retprobe, pid_t pid,
|
||||
const char *binary_path,
|
||||
size_t func_offset)
|
||||
{
|
||||
DECLARE_LIBBPF_OPTS(bpf_uprobe_opts, opts, .retprobe = retprobe);
|
||||
|
||||
return bpf_program__attach_uprobe_opts(prog, pid, binary_path, func_offset, &opts);
|
||||
}
|
||||
|
||||
static int determine_tracepoint_id(const char *tp_category,
|
||||
const char *tp_name)
|
||||
{
|
||||
@@ -9270,14 +9389,21 @@ static int perf_event_open_tracepoint(const char *tp_category,
|
||||
return pfd;
|
||||
}
|
||||
|
||||
struct bpf_link *bpf_program__attach_tracepoint(struct bpf_program *prog,
|
||||
const char *tp_category,
|
||||
const char *tp_name)
|
||||
struct bpf_link *bpf_program__attach_tracepoint_opts(struct bpf_program *prog,
|
||||
const char *tp_category,
|
||||
const char *tp_name,
|
||||
const struct bpf_tracepoint_opts *opts)
|
||||
{
|
||||
DECLARE_LIBBPF_OPTS(bpf_perf_event_opts, pe_opts);
|
||||
char errmsg[STRERR_BUFSIZE];
|
||||
struct bpf_link *link;
|
||||
int pfd, err;
|
||||
|
||||
if (!OPTS_VALID(opts, bpf_tracepoint_opts))
|
||||
return libbpf_err_ptr(-EINVAL);
|
||||
|
||||
pe_opts.bpf_cookie = OPTS_GET(opts, bpf_cookie, 0);
|
||||
|
||||
pfd = perf_event_open_tracepoint(tp_category, tp_name);
|
||||
if (pfd < 0) {
|
||||
pr_warn("prog '%s': failed to create tracepoint '%s/%s' perf event: %s\n",
|
||||
@@ -9285,7 +9411,7 @@ struct bpf_link *bpf_program__attach_tracepoint(struct bpf_program *prog,
|
||||
libbpf_strerror_r(pfd, errmsg, sizeof(errmsg)));
|
||||
return libbpf_err_ptr(pfd);
|
||||
}
|
||||
link = bpf_program__attach_perf_event(prog, pfd);
|
||||
link = bpf_program__attach_perf_event_opts(prog, pfd, &pe_opts);
|
||||
err = libbpf_get_error(link);
|
||||
if (err) {
|
||||
close(pfd);
|
||||
@@ -9297,6 +9423,13 @@ struct bpf_link *bpf_program__attach_tracepoint(struct bpf_program *prog,
|
||||
return link;
|
||||
}
|
||||
|
||||
struct bpf_link *bpf_program__attach_tracepoint(struct bpf_program *prog,
|
||||
const char *tp_category,
|
||||
const char *tp_name)
|
||||
{
|
||||
return bpf_program__attach_tracepoint_opts(prog, tp_category, tp_name, NULL);
|
||||
}
|
||||
|
||||
static struct bpf_link *attach_tp(const struct bpf_sec_def *sec,
|
||||
struct bpf_program *prog)
|
||||
{
|
||||
|
||||
75
src/libbpf.h
75
src/libbpf.h
@@ -104,17 +104,6 @@ struct bpf_object_open_opts {
|
||||
};
|
||||
#define bpf_object_open_opts__last_field btf_custom_path
|
||||
|
||||
struct bpf_kprobe_opts {
|
||||
/* size of this struct, for forward/backward compatiblity */
|
||||
size_t sz;
|
||||
/* function's offset to install kprobe to */
|
||||
unsigned long offset;
|
||||
/* kprobe is return probe */
|
||||
bool retprobe;
|
||||
size_t :0;
|
||||
};
|
||||
#define bpf_kprobe_opts__last_field retprobe
|
||||
|
||||
LIBBPF_API struct bpf_object *bpf_object__open(const char *path);
|
||||
LIBBPF_API struct bpf_object *
|
||||
bpf_object__open_file(const char *path, const struct bpf_object_open_opts *opts);
|
||||
@@ -255,24 +244,86 @@ LIBBPF_API int bpf_link__destroy(struct bpf_link *link);
|
||||
|
||||
LIBBPF_API struct bpf_link *
|
||||
bpf_program__attach(struct bpf_program *prog);
|
||||
|
||||
struct bpf_perf_event_opts {
|
||||
/* size of this struct, for forward/backward compatiblity */
|
||||
size_t sz;
|
||||
/* custom user-provided value fetchable through bpf_get_attach_cookie() */
|
||||
__u64 bpf_cookie;
|
||||
};
|
||||
#define bpf_perf_event_opts__last_field bpf_cookie
|
||||
|
||||
LIBBPF_API struct bpf_link *
|
||||
bpf_program__attach_perf_event(struct bpf_program *prog, int pfd);
|
||||
|
||||
LIBBPF_API struct bpf_link *
|
||||
bpf_program__attach_perf_event_opts(struct bpf_program *prog, int pfd,
|
||||
const struct bpf_perf_event_opts *opts);
|
||||
|
||||
struct bpf_kprobe_opts {
|
||||
/* size of this struct, for forward/backward compatiblity */
|
||||
size_t sz;
|
||||
/* custom user-provided value fetchable through bpf_get_attach_cookie() */
|
||||
__u64 bpf_cookie;
|
||||
/* function's offset to install kprobe to */
|
||||
unsigned long offset;
|
||||
/* kprobe is return probe */
|
||||
bool retprobe;
|
||||
size_t :0;
|
||||
};
|
||||
#define bpf_kprobe_opts__last_field retprobe
|
||||
|
||||
LIBBPF_API struct bpf_link *
|
||||
bpf_program__attach_kprobe(struct bpf_program *prog, bool retprobe,
|
||||
const char *func_name);
|
||||
LIBBPF_API struct bpf_link *
|
||||
bpf_program__attach_kprobe_opts(struct bpf_program *prog,
|
||||
const char *func_name,
|
||||
struct bpf_kprobe_opts *opts);
|
||||
const struct bpf_kprobe_opts *opts);
|
||||
|
||||
struct bpf_uprobe_opts {
|
||||
/* size of this struct, for forward/backward compatiblity */
|
||||
size_t sz;
|
||||
/* offset of kernel reference counted USDT semaphore, added in
|
||||
* a6ca88b241d5 ("trace_uprobe: support reference counter in fd-based uprobe")
|
||||
*/
|
||||
size_t ref_ctr_offset;
|
||||
/* custom user-provided value fetchable through bpf_get_attach_cookie() */
|
||||
__u64 bpf_cookie;
|
||||
/* uprobe is return probe, invoked at function return time */
|
||||
bool retprobe;
|
||||
size_t :0;
|
||||
};
|
||||
#define bpf_uprobe_opts__last_field retprobe
|
||||
|
||||
LIBBPF_API struct bpf_link *
|
||||
bpf_program__attach_uprobe(struct bpf_program *prog, bool retprobe,
|
||||
pid_t pid, const char *binary_path,
|
||||
size_t func_offset);
|
||||
LIBBPF_API struct bpf_link *
|
||||
bpf_program__attach_uprobe_opts(struct bpf_program *prog, pid_t pid,
|
||||
const char *binary_path, size_t func_offset,
|
||||
const struct bpf_uprobe_opts *opts);
|
||||
|
||||
struct bpf_tracepoint_opts {
|
||||
/* size of this struct, for forward/backward compatiblity */
|
||||
size_t sz;
|
||||
/* custom user-provided value fetchable through bpf_get_attach_cookie() */
|
||||
__u64 bpf_cookie;
|
||||
};
|
||||
#define bpf_tracepoint_opts__last_field bpf_cookie
|
||||
|
||||
LIBBPF_API struct bpf_link *
|
||||
bpf_program__attach_tracepoint(struct bpf_program *prog,
|
||||
const char *tp_category,
|
||||
const char *tp_name);
|
||||
LIBBPF_API struct bpf_link *
|
||||
bpf_program__attach_tracepoint_opts(struct bpf_program *prog,
|
||||
const char *tp_category,
|
||||
const char *tp_name,
|
||||
const struct bpf_tracepoint_opts *opts);
|
||||
|
||||
LIBBPF_API struct bpf_link *
|
||||
bpf_program__attach_raw_tracepoint(struct bpf_program *prog,
|
||||
const char *tp_name);
|
||||
LIBBPF_API struct bpf_link *
|
||||
|
||||
@@ -374,6 +374,9 @@ LIBBPF_0.5.0 {
|
||||
bpf_map__pin_path;
|
||||
bpf_map_lookup_and_delete_elem_flags;
|
||||
bpf_program__attach_kprobe_opts;
|
||||
bpf_program__attach_perf_event_opts;
|
||||
bpf_program__attach_tracepoint_opts;
|
||||
bpf_program__attach_uprobe_opts;
|
||||
bpf_object__gen_loader;
|
||||
btf__load_from_kernel_by_id;
|
||||
btf__load_from_kernel_by_id_split;
|
||||
|
||||
@@ -196,6 +196,17 @@ void *libbpf_add_mem(void **data, size_t *cap_cnt, size_t elem_sz,
|
||||
size_t cur_cnt, size_t max_cnt, size_t add_cnt);
|
||||
int libbpf_ensure_mem(void **data, size_t *cap_cnt, size_t elem_sz, size_t need_cnt);
|
||||
|
||||
static inline bool libbpf_is_mem_zeroed(const char *p, ssize_t len)
|
||||
{
|
||||
while (len > 0) {
|
||||
if (*p)
|
||||
return false;
|
||||
p++;
|
||||
len--;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool libbpf_validate_opts(const char *opts,
|
||||
size_t opts_sz, size_t user_sz,
|
||||
const char *type_name)
|
||||
@@ -204,16 +215,9 @@ static inline bool libbpf_validate_opts(const char *opts,
|
||||
pr_warn("%s size (%zu) is too small\n", type_name, user_sz);
|
||||
return false;
|
||||
}
|
||||
if (user_sz > opts_sz) {
|
||||
size_t i;
|
||||
|
||||
for (i = opts_sz; i < user_sz; i++) {
|
||||
if (opts[i]) {
|
||||
pr_warn("%s has non-zero extra bytes\n",
|
||||
type_name);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!libbpf_is_mem_zeroed(opts + opts_sz, (ssize_t)user_sz - opts_sz)) {
|
||||
pr_warn("%s has non-zero extra bytes\n", type_name);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -233,6 +237,14 @@ static inline bool libbpf_validate_opts(const char *opts,
|
||||
(opts)->field = value; \
|
||||
} while (0)
|
||||
|
||||
#define OPTS_ZEROED(opts, last_nonzero_field) \
|
||||
({ \
|
||||
ssize_t __off = offsetofend(typeof(*(opts)), last_nonzero_field); \
|
||||
!(opts) || libbpf_is_mem_zeroed((const void *)opts + __off, \
|
||||
(opts)->sz - __off); \
|
||||
})
|
||||
|
||||
|
||||
int parse_cpu_mask_str(const char *s, bool **mask, int *mask_sz);
|
||||
int parse_cpu_mask_file(const char *fcpu, bool **mask, int *mask_sz);
|
||||
int libbpf__load_raw_btf(const char *raw_types, size_t types_len,
|
||||
|
||||
@@ -10,7 +10,6 @@ sudo apt-get -y install python-docutils # for rst2man
|
||||
|
||||
LLVM_VER=14
|
||||
LIBBPF_PATH="${REPO_ROOT}"
|
||||
REPO_PATH="travis-ci/vmtest/bpf-next"
|
||||
|
||||
PREPARE_SELFTESTS_SCRIPT=${VMTEST_ROOT}/prepare_selftests-${KERNEL}.sh
|
||||
if [ -f "${PREPARE_SELFTESTS_SCRIPT}" ]; then
|
||||
|
||||
@@ -3,6 +3,7 @@ align # verifier output format changed
|
||||
atomics # new atomic operations (v5.12+)
|
||||
atomic_bounds # new atomic operations (v5.12+)
|
||||
bind_perm # changed semantics of return values (v5.12+)
|
||||
bpf_cookie # 5.15+
|
||||
bpf_iter # bpf_iter support is missing
|
||||
bpf_obj_id # bpf_link support missing for GET_OBJ_INFO, GET_FD_BY_ID, etc
|
||||
bpf_tcp_ca # STRUCT_OPS is missing
|
||||
@@ -47,6 +48,7 @@ netcnt
|
||||
ns_current_pid_tgid # bpf_get_ns_current_pid_tgid() helper is missing
|
||||
pe_preserve_elems # v5.10+
|
||||
perf_branches # bpf_read_branch_records() helper is missing
|
||||
perf_link # v5.15+
|
||||
pkt_access # 32-bit pointer arith in test_pkt_access
|
||||
probe_read_user_str # kernel bug with garbage bytes at the end
|
||||
prog_run_xattr # 32-bit pointer arith in test_pkt_access
|
||||
@@ -97,6 +99,7 @@ varlen # verifier bug fixed in later kernels
|
||||
vmlinux # hrtimer_nanosleep() signature changed incompatibly
|
||||
xdp_adjust_tail # new XDP functionality added in 5.8
|
||||
xdp_attach # IFLA_XDP_EXPECTED_FD support is missing
|
||||
xdp_bonding # v5.15+
|
||||
xdp_bpf2bpf # freplace is missing
|
||||
xdp_context_test_run # v5.15+
|
||||
xdp_cpumap_attach # v5.9+
|
||||
|
||||
@@ -4,17 +4,18 @@ set -eu
|
||||
|
||||
source $(cd $(dirname $0) && pwd)/helpers.sh
|
||||
|
||||
REPO_PATH=$1
|
||||
REPO_PATH=${1:-}
|
||||
|
||||
${VMTEST_ROOT}/checkout_latest_kernel.sh ${REPO_PATH}
|
||||
cd ${REPO_PATH}
|
||||
if [[ ! -z "$REPO_PATH" ]]; then
|
||||
${VMTEST_ROOT}/checkout_latest_kernel.sh ${REPO_PATH}
|
||||
cd ${REPO_PATH}
|
||||
fi
|
||||
|
||||
if [[ "${KERNEL}" = 'LATEST' ]]; then
|
||||
travis_fold start build_kernel "Kernel build"
|
||||
|
||||
cp ${VMTEST_ROOT}/configs/latest.config .config
|
||||
make -j $((4*$(nproc))) olddefconfig all >/dev/null
|
||||
|
||||
travis_fold end build_kernel
|
||||
fi
|
||||
|
||||
|
||||
@@ -92,6 +92,12 @@ SKIPSOURCE=0
|
||||
APPEND=""
|
||||
DIR="$PWD"
|
||||
LIST=0
|
||||
|
||||
# by default will copy all files that aren't listed in git exclusions
|
||||
# but it doesn't work for entire kernel tree very well
|
||||
# so for full kernel tree you may need to SOURCE_FULLCOPY=0
|
||||
SOURCE_FULLCOPY=${SOURCE_FULLCOPY:-1}
|
||||
|
||||
while true; do
|
||||
case "$1" in
|
||||
-k|--kernel)
|
||||
@@ -374,27 +380,38 @@ fi
|
||||
|
||||
travis_fold end vmlinux_setup
|
||||
|
||||
REPO_PATH="${SELFTEST_REPO_PATH:-travis-ci/vmtest/bpf-next}"
|
||||
LIBBPF_PATH="${REPO_ROOT}" \
|
||||
REPO_PATH="travis-ci/vmtest/bpf-next" \
|
||||
VMTEST_ROOT="${VMTEST_ROOT}" \
|
||||
REPO_PATH="${REPO_PATH}" \
|
||||
VMLINUX_BTF=${vmlinux} ${VMTEST_ROOT}/build_selftests.sh
|
||||
|
||||
travis_fold start bpftool_checks "Running bpftool checks..."
|
||||
if [[ "${KERNEL}" = 'LATEST' ]]; then
|
||||
"${REPO_ROOT}/${REPO_PATH}/tools/testing/selftests/bpf/test_bpftool_synctypes.py" && \
|
||||
echo "Consistency checks passed successfully."
|
||||
else
|
||||
echo "Consistency checks skipped."
|
||||
fi
|
||||
travis_fold end bpftool_checks
|
||||
|
||||
travis_fold start vm_init "Starting virtual machine..."
|
||||
|
||||
if (( SKIPSOURCE )); then
|
||||
echo "Not copying source files..." >&2
|
||||
else
|
||||
echo "Copying source files..." >&2
|
||||
|
||||
# Copy the source files in.
|
||||
sudo mkdir -p -m 0755 "$mnt/${PROJECT_NAME}"
|
||||
{
|
||||
if [[ -e .git ]]; then
|
||||
git ls-files -z
|
||||
if [[ "${SOURCE_FULLCOPY}" == "1" ]]; then
|
||||
git ls-files -z | sudo rsync --files-from=- -0cpt . "$mnt/${PROJECT_NAME}"
|
||||
else
|
||||
tr '\n' '\0' < "${PROJECT_NAME}.egg-info/SOURCES.txt"
|
||||
fi
|
||||
} | sudo rsync --files-from=- -0cpt . "$mnt/${PROJECT_NAME}"
|
||||
sudo mkdir -p -m 0755 ${mnt}/${PROJECT_NAME}/{selftests,travis-ci}
|
||||
tree --du -shaC "${REPO_ROOT}/selftests/bpf"
|
||||
sudo rsync -avm "${REPO_ROOT}/selftests/bpf" "$mnt/${PROJECT_NAME}/selftests/"
|
||||
sudo rsync -avm "${REPO_ROOT}/travis-ci/vmtest" "$mnt/${PROJECT_NAME}/travis-ci/"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
setup_script="#!/bin/sh
|
||||
|
||||
@@ -6,6 +6,10 @@ source $(cd $(dirname $0) && pwd)/helpers.sh
|
||||
|
||||
VMTEST_SETUPCMD="GITHUB_WORKFLOW=${GITHUB_WORKFLOW:-} PROJECT_NAME=${PROJECT_NAME} ./${PROJECT_NAME}/travis-ci/vmtest/run_selftests.sh"
|
||||
|
||||
# if CHECKOUT_KERNEL is 1 code will consider that kernel code lives elsewhere
|
||||
# if 0 it will consider that REPO_ROOT is a kernel tree
|
||||
CHECKOUT_KERNEL=${CHECKOUT_KERNEL:-1}
|
||||
|
||||
echo "KERNEL: $KERNEL"
|
||||
echo
|
||||
|
||||
@@ -24,7 +28,12 @@ sudo aptitude install -y clang-14 lld-14 llvm-14
|
||||
travis_fold end install_clang
|
||||
|
||||
# Build selftests (and latest kernel, if necessary)
|
||||
${VMTEST_ROOT}/prepare_selftests.sh travis-ci/vmtest/bpf-next
|
||||
|
||||
if [[ "$CHECKOUT_KERNEL" == "1" ]]; then
|
||||
${VMTEST_ROOT}/prepare_selftests.sh travis-ci/vmtest/bpf-next
|
||||
else
|
||||
${VMTEST_ROOT}/prepare_selftests.sh
|
||||
fi
|
||||
|
||||
# Escape whitespace characters.
|
||||
setup_cmd=$(sed 's/\([[:space:]]\)/\\\1/g' <<< "${VMTEST_SETUPCMD}")
|
||||
@@ -32,7 +41,11 @@ setup_cmd=$(sed 's/\([[:space:]]\)/\\\1/g' <<< "${VMTEST_SETUPCMD}")
|
||||
sudo adduser "${USER}" kvm
|
||||
|
||||
if [[ "${KERNEL}" = 'LATEST' ]]; then
|
||||
sudo -E sudo -E -u "${USER}" "${VMTEST_ROOT}/run.sh" -b travis-ci/vmtest/bpf-next -o -d ~ -s "${setup_cmd}" ~/root.img;
|
||||
if [[ "$CHECKOUT_KERNEL" == "1" ]]; then
|
||||
sudo -E sudo -E -u "${USER}" "${VMTEST_ROOT}/run.sh" -b travis-ci/vmtest/bpf-next -o -d ~ -s "${setup_cmd}" ~/root.img
|
||||
else
|
||||
sudo -E sudo -E -u "${USER}" "${VMTEST_ROOT}/run.sh" -b "${REPO_ROOT}" -o -d ~ -s "${setup_cmd}" ~/root.img
|
||||
fi
|
||||
else
|
||||
sudo -E sudo -E -u "${USER}" "${VMTEST_ROOT}/run.sh" -k "${KERNEL}*" -o -d ~ -s "${setup_cmd}" ~/root.img;
|
||||
sudo -E sudo -E -u "${USER}" "${VMTEST_ROOT}/run.sh" -k "${KERNEL}*" -o -d ~ -s "${setup_cmd}" ~/root.img
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user