bpf.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Nikolay Borisov <nborisov@suse.com>
To: bpf@vger.kernel.org
Cc: daniel@iogearbox.net, andrii@kernel.org, ast@kernel.org,
	Nikolay Borisov <nborisov@suse.com>
Subject: [RFC PATCH 2/2] libbpf: Add btf__field_exists
Date: Mon,  4 Apr 2022 11:38:16 +0300	[thread overview]
Message-ID: <20220404083816.1560501-3-nborisov@suse.com> (raw)
In-Reply-To: <20220404083816.1560501-1-nborisov@suse.com>

There isn't currently a convenience function to check if a particular
kernel version is running similar to bpf_core_field_exists. There can be
cases where based on the actual kernel being run different kprobes has
to be used when tracing the kernel. One example is the change introduced
in 4c5b47997521 ("vfs: add fileattr ops"). Before this commit if one
wants to trace fileattr changes this has to be done by a distinct kprobe
on every filesystem as there was no common code where fileattr changes
when through. Post this commit this can be performed by a single kprobe
on the common vfs_fileattr_set function.

To accommodate such use cases simply add a libbpf api btf__field_exists
which can be used to check for the running kernel version and act
appropriately.

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
---
 tools/lib/bpf/btf.c      | 28 ++++++++++++++++++++++++++++
 tools/lib/bpf/btf.h      |  2 ++
 tools/lib/bpf/libbpf.map |  1 +
 3 files changed, 31 insertions(+)

diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c
index 9aa19c89f758..890a2071bd00 100644
--- a/tools/lib/bpf/btf.c
+++ b/tools/lib/bpf/btf.c
@@ -697,6 +697,34 @@ int btf__resolve_type(const struct btf *btf, __u32 type_id)
 	return type_id;
 }
 
+bool btf__field_exists(const struct btf *btf, const char *struct_name,
+		       const char *field_name)
+{
+	const struct btf_type *t;
+	struct btf_member *m;
+	int i;
+	__s32 type_id = btf__find_by_name(btf, struct_name);
+
+	if (type_id < 0)
+		return false;
+
+	t = btf__type_by_id(btf, type_id);
+	if (!t)
+		return false;
+
+	if (!btf_is_composite(t))
+		return false;
+
+	for_each_member(i, t, m) {
+		const char *n = btf__name_by_offset(btf, m->name_off);
+
+		if (strcmp(n, field_name) == 0)
+			return true;
+	}
+
+	return false;
+}
+
 __s32 btf__find_by_name(const struct btf *btf, const char *type_name)
 {
 	__u32 i, nr_types = btf__type_cnt(btf);
diff --git a/tools/lib/bpf/btf.h b/tools/lib/bpf/btf.h
index 74039f8afc63..1eb8d840b46b 100644
--- a/tools/lib/bpf/btf.h
+++ b/tools/lib/bpf/btf.h
@@ -144,6 +144,8 @@ LIBBPF_API enum btf_endianness btf__endianness(const struct btf *btf);
 LIBBPF_API int btf__set_endianness(struct btf *btf, enum btf_endianness endian);
 LIBBPF_API __s64 btf__resolve_size(const struct btf *btf, __u32 type_id);
 LIBBPF_API int btf__resolve_type(const struct btf *btf, __u32 type_id);
+LIBBPF_API bool btf__field_exists(const struct btf *btf, const char *struct_name,
+				 const char *field_name);
 LIBBPF_API int btf__align_of(const struct btf *btf, __u32 id);
 LIBBPF_API int btf__fd(const struct btf *btf);
 LIBBPF_API void btf__set_fd(struct btf *btf, int fd);
diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map
index 529783967793..9a0d50604cca 100644
--- a/tools/lib/bpf/libbpf.map
+++ b/tools/lib/bpf/libbpf.map
@@ -427,6 +427,7 @@ LIBBPF_0.7.0 {
 		bpf_program__log_level;
 		bpf_program__set_log_buf;
 		bpf_program__set_log_level;
+		btf__field_exists;
 		libbpf_probe_bpf_helper;
 		libbpf_probe_bpf_map_type;
 		libbpf_probe_bpf_prog_type;
-- 
2.25.1


  parent reply	other threads:[~2022-04-04  8:38 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-04  8:38 [RFC PATCH 0/2] Add btf__field_exists Nikolay Borisov
2022-04-04  8:38 ` [RFC PATCH 1/2] libbpf: Add userspace version of for_each_member macro Nikolay Borisov
2022-04-05 23:31   ` Andrii Nakryiko
2022-04-04  8:38 ` Nikolay Borisov [this message]
2022-04-05 23:37 ` [RFC PATCH 0/2] Add btf__field_exists Andrii Nakryiko
2022-04-06  6:41   ` Nikolay Borisov
2022-04-06 17:14     ` Andrii Nakryiko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220404083816.1560501-3-nborisov@suse.com \
    --to=nborisov@suse.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).