[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20251031075908.1472249-5-jianyungao89@gmail.com>
Date: Fri, 31 Oct 2025 15:59:06 +0800
From: Jianyun Gao <jianyungao89@...il.com>
To: linux-kernel@...r.kernel.org
Cc: Jianyun Gao <jianyungao89@...il.com>,
Andrii Nakryiko <andrii@...nel.org>,
Eduard Zingerman <eddyz87@...il.com>,
Alexei Starovoitov <ast@...nel.org>,
Daniel Borkmann <daniel@...earbox.net>,
Martin KaFai Lau <martin.lau@...ux.dev>,
Song Liu <song@...nel.org>,
Yonghong Song <yonghong.song@...ux.dev>,
John Fastabend <john.fastabend@...il.com>,
KP Singh <kpsingh@...nel.org>,
Stanislav Fomichev <sdf@...ichev.me>,
Hao Luo <haoluo@...gle.com>,
Jiri Olsa <jolsa@...nel.org>,
bpf@...r.kernel.org (open list:BPF [LIBRARY] (libbpf))
Subject: [PATCH v2 4/5] libbpf: Add doxygen documentation for bpf_obj_* APIs in bpf.h
Add doxygen comment blocks for all public bpf_obj_* APIs in
tools/lib/bpf/bpf.h. These doc comments are for:
-bpf_obj_pin()
-bpf_obj_pin_opts()
-bpf_obj_get()
-bpf_obj_get_opts()
-bpf_obj_get_info_by_fd()
Signed-off-by: Jianyun Gao <jianyungao89@...il.com>
---
v1->v2:
- Fixed the non-ASCII characters in this patch.
The v1 is here:
https://lore.kernel.org/lkml/20251031032627.1414462-5-jianyungao89@gmail.com/
tools/lib/bpf/bpf.h | 430 +++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 427 insertions(+), 3 deletions(-)
diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
index 9040fc891b81..a0cebda09e16 100644
--- a/tools/lib/bpf/bpf.h
+++ b/tools/lib/bpf/bpf.h
@@ -900,8 +900,175 @@ struct bpf_obj_pin_opts {
size_t :0;
};
#define bpf_obj_pin_opts__last_field path_fd
-
+/**
+ * @brief Pin a BPF object (map, program, BTF, link, etc.) to a persistent
+ * location in the BPF filesystem (bpffs).
+ *
+ * bpf_obj_pin() wraps the BPF_OBJ_PIN command and creates a bpffs file
+ * at @p pathname that permanently references the in-kernel BPF object
+ * associated with @p fd. Once pinned, the object survives process exit
+ * and can later be reopened (referenced) by other processes via
+ * bpf_obj_get()/bpf_obj_get_opts().
+ *
+ * Typical use cases:
+ * - Share maps or programs across processes (e.g., loader + consumer).
+ * - Preserve objects across service restarts.
+ * - Provide stable, discoverable paths for orchestration tooling.
+ *
+ * Requirements:
+ * - The BPF filesystem (usually mounted at /sys/fs/bpf) must be mounted.
+ * - All parent directories in @p pathname must already exist; this helper
+ * does NOT create intermediate directories.
+ * - @p fd must reference a pin-able BPF object (map, program, link, BTF, etc.).
+ *
+ * Idempotency & overwriting:
+ * - If a file already exists at @p pathname, the call fails (typically
+ * with -EEXIST). Remove or rename the existing entry before pinning
+ * a new object to that path.
+ *
+ * Lifetime semantics:
+ * - Pinning increments the in-kernel object's refcount. The object will
+ * remain alive until the pinned bpffs entry is removed and all other
+ * references (FDs, links, attachments) are closed.
+ * - Closing @p fd after pinning does NOT unpin the object.
+ *
+ * Security & permissions:
+ * - Usually requires write permission to the bpffs mount and appropriate
+ * capabilities (CAP_BPF and/or CAP_SYS_ADMIN depending on kernel/LSM).
+ * - Path components must not traverse outside bpffs (no ".." escapes).
+ *
+ * Example:
+ * int map_fd = bpf_map_create(...);
+ * if (map_fd < 0)
+ * return -1;
+ * if (bpf_obj_pin(map_fd, "/sys/fs/bpf/myapp/session_map") < 0) {
+ * perror("bpf_obj_pin");
+ * // handle error (e.g., create parent dir, adjust permissions)
+ * }
+ *
+ * Re-opening later:
+ * int pinned_fd = bpf_obj_get("/sys/fs/bpf/myapp/session_map");
+ * if (pinned_fd >= 0) {
+ * // use map
+ * close(pinned_fd);
+ * }
+ *
+ * @param fd File descriptor of the loaded BPF object to pin.
+ * @param pathname Absolute or relative path inside bpffs where the object
+ * should be pinned (e.g. "/sys/fs/bpf/my_map"). Must not be NULL.
+ *
+ * @return 0 on success; < 0 negative error code (libbpf style == -errno) on failure.
+ *
+ * Common errors (negative libbpf-style return codes == -errno):
+ * - -EBADF: @p fd is not a valid BPF object FD.
+ * - -EINVAL: @p fd refers to an object type that cannot be pinned, or
+ * pathname is invalid.
+ * - -EEXIST: A file already exists at @p pathname.
+ * - -ENOENT: One or more parent directories in the path do not exist.
+ * - -ENOTDIR: A path component expected to be a directory is not.
+ * - -EPERM / -EACCES: Insufficient privileges or denied by security policy.
+ * - -ENOMEM: Kernel failed to allocate internal metadata.
+ * - Other -errno codes may be propagated from the underlying syscall.
+ *
+ */
LIBBPF_API int bpf_obj_pin(int fd, const char *pathname);
+
+/**
+ * @brief Pin a BPF object (map, program, BTF, link, etc.) to bpffs with
+ * extended options controlling filesystem open semantics.
+ *
+ * This is an extended variant of bpf_obj_pin() that allows specifying
+ * additional pinning attributes through @p opts. On success a new file
+ * (bpffs inode) at @p pathname references the in-kernel BPF object
+ * associated with @p fd, incrementing its refcount and making it
+ * persist beyond the lifetime of the creating process.
+ *
+ * Differences vs bpf_obj_pin():
+ * - Supports optional struct bpf_obj_pin_opts for forward/backward
+ * compatibility without breaking older kernels.
+ * - Allows passing file creation flags (opts->file_flags) and a
+ * directory file descriptor (opts->path_fd) for path resolution
+ * using the underlying kernel support (e.g. enabling O_EXCL-style
+ * semantics if/when supported).
+ *
+ * Typical usage:
+ * struct bpf_obj_pin_opts popts = {
+ * .sz = sizeof(popts),
+ * .file_flags = 0, // reserved / must be 0 unless documented
+ * .path_fd = -1, // optional dir FD; -1 means unused
+ * };
+ * if (bpf_obj_pin_opts(obj_fd, "/sys/fs/bpf/myapp/session_map", &popts) < 0) {
+ * perror("bpf_obj_pin_opts");
+ * // handle error (inspect errno or negative return value)
+ * }
+ *
+ * Notes on @p pathname:
+ * - Must reside within a mounted BPF filesystem (bpffs), typically
+ * /sys/fs/bpf.
+ * - All parent directories must already exist; intermediate directories
+ * are not created automatically.
+ * - Existing path results in -EEXIST (no overwrite).
+ * - Avoid relative paths that could escape bpffs (no ".." traversal).
+ *
+ * opts initialization:
+ * - If @p opts is non-NULL, opts->sz MUST be set to sizeof(*opts).
+ * - Unused/unknown fields should be zeroed for forward compatibility.
+ * - opts->file_flags: Currently reserved; pass 0 unless a kernel
+ * extension explicitly documents valid bits (non-zero may yield
+ * -EINVAL on older kernels).
+ * - opts->path_fd: Optional directory file descriptor that serves as
+ * the base for relative @p pathname resolution (similar to *at()
+ * syscalls). Set to -1 or 0 to ignore and use normal absolute path
+ * semantics. If used, ensure it refers to bpffs.
+ *
+ * Concurrency:
+ * - Pinning is atomic with respect to path name; two simultaneous
+ * attempts to pin to the same pathname will result in one success
+ * and one -EEXIST failure.
+ * - After success, closing @p fd does NOT unpin; removal of the pinned
+ * bpffs file (unlink) plus closing all other references is required
+ * to allow object destruction.
+ *
+ * Security / Privileges:
+ * - May require CAP_BPF and/or CAP_SYS_ADMIN depending on kernel
+ * configuration, LSM policy, and lockdown mode.
+ * - Filesystem permissions on bpffs apply; lack of write/execute on
+ * parent directories yields -EACCES / -EPERM.
+ *
+ * After pinning:
+ * - Object can be reopened via bpf_obj_get()/bpf_obj_get_opts() using
+ * the same pathname.
+ * - Can be safely shared across processes and persists across
+ * restarts until explicitly unpinned (unlink).
+ *
+ * Best practices:
+ * - Zero-initialize opts: struct bpf_obj_pin_opts popts = {};
+ * - Always set popts.sz = sizeof(popts) when passing opts.
+ * - Validate that bpffs is mounted (e.g., stat("/sys/fs/bpf")) before
+ * attempting to pin.
+ * - Use distinct subdirectories (e.g., /sys/fs/bpf/<app>/...) to avoid
+ * naming collisions and facilitate cleanup.
+ *
+ * @param fd File descriptor of the loaded BPF object to pin.
+ * @param pathname Absolute (recommended) or relative path inside bpffs
+ * identifying where to create the pin entry. Must not be NULL.
+ * @param opts Optional pointer to a struct bpf_obj_pin_opts providing
+ * extended pin options; may be NULL for defaults.
+ *
+ * @return 0 on success; < 0 negative error code (libbpf style == -errno) on failure.
+ *
+ * Error handling (negative libbpf-style return codes == -errno):
+ * - -EBADF: Invalid @p fd, or @p path_fd (if used) not a valid directory FD.
+ * - -EINVAL: opts->sz mismatch, unsupported file_flags, invalid pathname,
+ * or object type cannot be pinned.
+ * - -EEXIST: A file already exists at @p pathname.
+ * - -ENOENT: Parent directory component missing (or @p path_fd base invalid).
+ * - -ENOTDIR: A path component expected to be a directory is not.
+ * - -EPERM / -EACCES: Insufficient privileges or blocked by security policy.
+ * - -ENOMEM: Kernel failed to allocate internal metadata.
+ * - Other -errno codes may be propagated from the underlying bpf() syscall.
+ *
+ */
LIBBPF_API int bpf_obj_pin_opts(int fd, const char *pathname,
const struct bpf_obj_pin_opts *opts);
@@ -914,8 +1081,190 @@ struct bpf_obj_get_opts {
size_t :0;
};
#define bpf_obj_get_opts__last_field path_fd
-
+/**
+ * @brief Open (re-reference) a pinned BPF object by its bpffs pathname.
+ *
+ * bpf_obj_get() wraps the BPF_OBJ_GET command of the bpf(2) syscall. It
+ * converts a persistent BPF filesystem (bpffs) entry (previously created
+ * with bpf_obj_pin()/bpf_obj_pin_opts()) back into a live file descriptor
+ * that the caller owns and can use for further operations (e.g. map
+ * lookups/updates, program introspection, link detachment, BTF queries).
+ *
+ * Supported object kinds (depending on kernel version):
+ * - Maps
+ * - Programs
+ * - BTF objects
+ * - Links
+ * - (Future kinds may also become accessible through the same API)
+ *
+ * Typical usage:
+ * int fd = bpf_obj_get("/sys/fs/bpf/myapp/session_map");
+ * if (fd < 0) {
+ * perror("bpf_obj_get");
+ * // handle error
+ * } else {
+ * // use fd
+ * close(fd);
+ * }
+ *
+ * Path requirements:
+ * - @p pathname must reside inside a mounted BPF filesystem (usually
+ * /sys/fs/bpf).
+ * - Intermediate directories must already exist.
+ * - The path must reference a previously pinned object; regular files
+ * or non-BPF entries yield errors.
+ *
+ * Lifetime semantics:
+ * - Success returns a new file descriptor referencing the existing
+ * in-kernel object; the object's lifetime is extended while this FD
+ * (and any others) remain open or while the bpffs entry stays pinned.
+ * - Closing the returned FD does not remove or unpin the object.
+ * - To permanently remove the object, unlink the bpffs path and close
+ * all remaining descriptors.
+ *
+ * Concurrency & races:
+ * - If the pinned entry is removed (unlink) between name resolution and
+ * the syscall, the call may fail with -ENOENT.
+ * - Multiple opens of the same pinned path are safe and return distinct
+ * FDs.
+ *
+ * Privileges & security:
+ * - May require CAP_BPF and/or CAP_SYS_ADMIN depending on kernel config,
+ * LSM policies, and lockdown mode.
+ * - Filesystem permission checks apply (read/search on parent dirs).
+ *
+ * Thread safety:
+ * - The function itself is thread-safe; distinct threads can open the
+ * same pinned path concurrently.
+ *
+ * Performance considerations:
+ * - Operation cost is dominated by path lookup and a single bpf()
+ * syscall; typically negligible compared to subsequent map/program
+ * usage.
+ *
+ * @param pathname Absolute (recommended) or relative bpffs path of the
+ * pinned BPF object; must not be NULL.
+ *
+ * @return >= 0 : File descriptor referencing the object (caller must close()).
+ * < 0 : Negative error code (libbpf style, see list above).
+ *
+ *
+ * Error handling (negative libbpf-style return codes == -errno):
+ * - -ENOENT: Path does not exist or was unpinned.
+ * - -ENOTDIR: A path component expected to be a directory is not.
+ * - -EACCES / -EPERM: Insufficient privileges or denied by security policy.
+ * - -EINVAL: Path does not refer to a valid pinned BPF object (type mismatch,
+ * corrupted entry, or unsupported kernel feature).
+ * - -ENOMEM: Kernel could not allocate internal resources.
+ * - -EBADF: Rare: internal descriptor handling failed.
+ * - Other negative codes propagated from the underlying syscall.
+ *
+ */
LIBBPF_API int bpf_obj_get(const char *pathname);
+
+/**
+ * @brief Open (re-reference) a pinned BPF object with extended options.
+ *
+ * bpf_obj_get_opts() is an extended variant of bpf_obj_get() that wraps the
+ * BPF_OBJ_GET command of the bpf(2) syscall. It converts a bpffs pathname
+ * (previously created via bpf_obj_pin()/bpf_obj_pin_opts()) into a process-local
+ * file descriptor referencing the underlying in-kernel BPF object (map, program,
+ * BTF object, link, etc.), honoring additional lookup/open semantics supplied
+ * through @p opts.
+ *
+ * Extended capabilities vs bpf_obj_get():
+ * - Structured forward/backward compatibility via @p opts->sz.
+ * - Optional directory FD-relative path resolution (opts->path_fd),
+ * similar to *at() family syscalls (openat, fstatat, etc.).
+ * - Future room for file/open semantic modifiers (opts->file_flags).
+ *
+ * Requirements:
+ * - The target pathname must reside inside a mounted BPF filesystem
+ * (usually /sys/fs/bpf). Relative paths are resolved either against
+ * the current working directory (if opts->path_fd is -1 or 0) or
+ * against the directory represented by opts->path_fd.
+ * - All parent directories must already exist; intermediate components
+ * are not created automatically.
+ * - The bpffs entry at @p pathname must refer to a pinned BPF object.
+ *
+ * Lifetime semantics:
+ * - Success returns a new file descriptor owning a user space reference
+ * to the object. Closing this FD does NOT unpin or destroy the object
+ * if other references (FDs or pinned entries) remain.
+ * - To remove the persistent reference, unlink(2) the bpffs path and
+ * close all remaining FDs.
+ *
+ * Concurrency & races:
+ * - If the pinned entry is unlinked concurrently, the call may fail
+ * with -ENOENT.
+ * - Multiple successful opens of the same path yield distinct FDs.
+ *
+ * Security / privileges:
+ * - May require CAP_BPF and/or CAP_SYS_ADMIN depending on kernel config,
+ * LSM policies, or lockdown mode.
+ * - Filesystem permission checks apply to path traversal and directory
+ * components (execute/search permissions).
+ *
+ * @param pathname
+ * Absolute or relative bpffs path of the pinned BPF object. Must
+ * not be NULL. If relative and opts->path_fd is a valid directory
+ * FD, resolution is performed relative to that directory; otherwise
+ * relative to the process's current working directory.
+ * @param opts
+ * Optional pointer to a zero-initialized bpf_obj_get_opts structure.
+ * May be NULL for default behavior. Fields:
+ * - sz: MUST be set to sizeof(struct bpf_obj_get_opts) when @p opts
+ * is non-NULL; mismatch causes -EINVAL.
+ * - file_flags: Reserved for future extensions; MUST be 0 on
+ * current kernels or the call may fail with -EINVAL.
+ * - path_fd: Directory file descriptor for *at()-style relative
+ * path resolution. Set to -1 (or 0) to ignore and use normal
+ * pathname semantics. Must reference a directory within bpffs
+ * if used with relative @p pathname.
+ *
+ * @return
+ * >= 0 : File descriptor referencing the pinned BPF object (caller must close()).
+ * < 0 : Negative libbpf-style error code (== -errno):
+ * - -ENOENT: Path does not exist or was unpinned.
+ * - -ENOTDIR: A path component is not a directory; or opts->path_fd
+ * is not a directory when required.
+ * - -EACCES / -EPERM: Insufficient privileges or denied by security policy.
+ * - -EBADF: Invalid opts->path_fd (not an open FD) or internal FD misuse.
+ * - -EINVAL: opts->sz mismatch, unsupported file_flags, invalid pathname,
+ * or path does not refer to a valid pinned BPF object.
+ * - -ENOMEM: Kernel failed to allocate internal metadata/resources.
+ * - Other -errno codes may be propagated from the underlying syscall.
+ *
+ * Usage example:
+ * struct bpf_obj_get_opts gopts = {
+ * .sz = sizeof(gopts),
+ * .file_flags = 0,
+ * .path_fd = -1,
+ * };
+ * int fd = bpf_obj_get_opts("/sys/fs/bpf/myapp/session_map", &gopts);
+ * if (fd < 0) {
+ * // handle error (inspect -fd or errno)
+ * } else {
+ * // use fd
+ * close(fd);
+ * }
+ *
+ * Best practices:
+ * - Always zero-initialize the opts struct before setting recognized fields.
+ * - Verify bpffs is mounted (e.g., stat("/sys/fs/bpf")) before calling.
+ * - Avoid passing non-zero file_flags until documented by newer kernels.
+ * - Treat -ENOENT as a normal condition if the object might have been
+ * cleaned up asynchronously.
+ *
+ * Thread safety:
+ * - Safe to call concurrently from multiple threads; each successful call
+ * yields its own FD.
+ *
+ * Forward compatibility:
+ * - Unrecognized future fields must remain zeroed to avoid -EINVAL.
+ * - Ensure opts->sz matches the libbpf version's struct size to enable
+ * kernel-side bounds checking and extension handling.
+ */
LIBBPF_API int bpf_obj_get_opts(const char *pathname,
const struct bpf_obj_get_opts *opts);
/**
@@ -1603,6 +1952,7 @@ LIBBPF_API int bpf_prog_get_next_id(__u32 start_id, __u32 *next_id);
* Other negative libbpf-style errors for transient or system failures.
*/
LIBBPF_API int bpf_map_get_next_id(__u32 start_id, __u32 *next_id);
+
LIBBPF_API int bpf_btf_get_next_id(__u32 start_id, __u32 *next_id);
/**
* @brief Retrieve the next existing BPF link ID after a given starting ID.
@@ -1877,7 +2227,9 @@ LIBBPF_API int bpf_map_get_fd_by_id(__u32 id);
*/
LIBBPF_API int bpf_map_get_fd_by_id_opts(__u32 id,
const struct bpf_get_fd_by_id_opts *opts);
+
LIBBPF_API int bpf_btf_get_fd_by_id(__u32 id);
+
LIBBPF_API int bpf_btf_get_fd_by_id_opts(__u32 id,
const struct bpf_get_fd_by_id_opts *opts);
/**
@@ -2026,7 +2378,77 @@ LIBBPF_API int bpf_link_get_fd_by_id(__u32 id);
*/
LIBBPF_API int bpf_link_get_fd_by_id_opts(__u32 id,
const struct bpf_get_fd_by_id_opts *opts);
-
+/**
+ * @brief Retrieve information about a BPF object (program, map, BTF, or link) given
+ * its file descriptor.
+ *
+ * This is a generic libbpf wrapper around the kernel's BPF_OBJ_GET_INFO_BY_FD
+ * command. Depending on what type of BPF object @p bpf_fd refers to, the kernel
+ * expects @p info to point to an appropriately typed info structure:
+ *
+ * - struct bpf_prog_info (for program FDs)
+ * - struct bpf_map_info (for map FDs)
+ * - struct bpf_btf_info (for BTF object FDs)
+ * - struct bpf_link_info (for link FDs)
+ *
+ * You must:
+ * 1. Zero-initialize the chosen info structure (to avoid undefined padding contents).
+ * 2. Set *@p info_len to sizeof(struct <relevant_info_type>) before the call.
+ * 3. Pass a pointer to the structure as @p info.
+ *
+ * On success, the kernel fills as much of the structure as it supports/recognizes
+ * for the running kernel version and may update *@p info_len with the actual number
+ * of bytes written (libbpf preserves kernel behavior). Unrecognized future fields
+ * remain zeroed. If *@p info_len is smaller than the minimum required size for that
+ * object type, the call fails with -EINVAL.
+ *
+ * Typical usage (program example):
+ * struct bpf_prog_info pinfo = {};
+ * __u32 len = sizeof(pinfo);
+ * if (bpf_obj_get_info_by_fd(prog_fd, &pinfo, &len) == 0) {
+ * // pinfo now populated (len bytes). Inspect fields like pinfo.id, pinfo.type, ...
+ * } else {
+ * // handle error (errno set; negative return value also provided)
+ * }
+ *
+ * Concurrency & races:
+ * - The object referenced by @p bpf_fd remains valid while its FD is open, so
+ * races are limited. However, fields referring to related kernel entities
+ * (e.g., map IDs a program references) may change if other management operations
+ * occur concurrently.
+ *
+ * Forward/backward compatibility:
+ * - Always zero the entire info struct before calling; newer kernels may fill
+ * additional fields.
+ * - Do not assume all fields are populated; check size/version or specific
+ * feature flags if present.
+ *
+ * Security / privileges:
+ * - Access may require CAP_BPF and/or CAP_SYS_ADMIN depending on kernel configuration,
+ * LSM policy, and lockdown mode. Insufficient privilege yields -EPERM / -EACCES.
+ *
+ * @param bpf_fd File descriptor of a loaded BPF object (program, map, BTF, or link).
+ * @param info Pointer to a zero-initialized, type-appropriate info structure
+ * (see list above).
+ * @param info_len Pointer to a __u32 containing the size of *info* on input; on
+ * success updated to the number of bytes actually written. Must
+ * not be NULL.
+ *
+ * @return 0 on success;
+ * < 0 negative error code (libbpf style == -errno) on failure:
+ * - -EBADF: @p bpf_fd is not a valid BPF object descriptor.
+ * - -EINVAL: Wrong object type, info_len too small, malformed arguments.
+ * - -EFAULT: @p info or @p info_len points to inaccessible user memory.
+ * - -EPERM / -EACCES: Insufficient privileges / blocked by security policy.
+ * - -ENOMEM: Kernel failed to allocate internal resources.
+ * - Other -errno values may be propagated from the underlying syscall.
+ *
+ * Error handling notes:
+ * - Treat -EINVAL as often indicating a size mismatch; verify that sizeof(your struct)
+ * matches what the kernel expects for your libbpf/kernel version.
+ * - Always inspect errno (or the negative return value) for precise failure reasons.
+ *
+ */
LIBBPF_API int bpf_obj_get_info_by_fd(int bpf_fd, void *info, __u32 *info_len);
/**
@@ -2230,7 +2652,9 @@ struct bpf_raw_tp_opts {
#define bpf_raw_tp_opts__last_field cookie
LIBBPF_API int bpf_raw_tracepoint_open_opts(int prog_fd, struct bpf_raw_tp_opts *opts);
+
LIBBPF_API int bpf_raw_tracepoint_open(const char *name, int prog_fd);
+
LIBBPF_API int bpf_task_fd_query(int pid, int fd, __u32 flags, char *buf,
__u32 *buf_len, __u32 *prog_id, __u32 *fd_type,
__u64 *probe_offset, __u64 *probe_addr);
--
2.34.1
Powered by blists - more mailing lists