From: Hengqi Chen Date: Sun, 31 Oct 2021 13:29:45 +0000 (+0800) Subject: bcc: Add kernel_struct_has_field function to BPF object X-Git-Tag: v0.23.0~9 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8270cf28bcd41107b71160fa609ec6a50b405f0a;p=platform%2Fupstream%2Fbcc.git bcc: Add kernel_struct_has_field function to BPF object Add a new function kernel_struct_has_field, which allows user to check that whether a kernel struct has a specific field. This enable us to deal with some kernel changes like in 2f064a59a1 ([0]) of the linux kernel. [0]: https://github.com/torvalds/linux/commit/2f064a59a1 Signed-off-by: Hengqi Chen --- diff --git a/src/cc/libbpf.c b/src/cc/libbpf.c index b1787e16..6c2faed6 100644 --- a/src/cc/libbpf.c +++ b/src/cc/libbpf.c @@ -558,8 +558,8 @@ int bpf_prog_compute_tag(const struct bpf_insn *insns, int prog_len, } union { - unsigned char sha[20]; - unsigned long long tag; + unsigned char sha[20]; + unsigned long long tag; } u = {}; ret = read(shafd2, u.sha, 20); if (ret != 20) { @@ -1109,8 +1109,8 @@ static int bpf_attach_probe(int progfd, enum bpf_probe_attach_type attach_type, // delete that event and start again without maxactive. if (is_kprobe && maxactive > 0 && attach_type == BPF_PROBE_RETURN) { if (snprintf(fname, sizeof(fname), "%s/id", buf) >= sizeof(fname)) { - fprintf(stderr, "filename (%s) is too long for buffer\n", buf); - goto error; + fprintf(stderr, "filename (%s) is too long for buffer\n", buf); + goto error; } if (access(fname, F_OK) == -1) { // Deleting kprobe event with incorrect name. @@ -1286,6 +1286,39 @@ bool bpf_has_kernel_btf(void) return libbpf_find_vmlinux_btf_id("bpf_prog_put", 0) > 0; } +int kernel_struct_has_field(const char *struct_name, const char *field_name) +{ + const struct btf_type *btf_type; + const struct btf_member *btf_member; + struct btf *btf; + int i, ret, btf_id; + + btf = btf__load_vmlinux_btf(); + ret = libbpf_get_error(btf); + if (ret) + return -1; + + btf_id = btf__find_by_name_kind(btf, struct_name, BTF_KIND_STRUCT); + if (btf_id < 0) { + ret = -1; + goto cleanup; + } + + btf_type = btf__type_by_id(btf, btf_id); + btf_member = btf_members(btf_type); + for (i = 0; i < btf_vlen(btf_type); i++, btf_member++) { + if (!strcmp(btf__name_by_offset(btf, btf_member->name_off), field_name)) { + ret = 1; + goto cleanup; + } + } + ret = 0; + +cleanup: + btf__free(btf); + return ret; +} + int bpf_attach_kfunc(int prog_fd) { int ret; diff --git a/src/cc/libbpf.h b/src/cc/libbpf.h index 657ed7c9..b3608e22 100644 --- a/src/cc/libbpf.h +++ b/src/cc/libbpf.h @@ -101,6 +101,8 @@ int bpf_attach_lsm(int prog_fd); bool bpf_has_kernel_btf(void); +int kernel_struct_has_field(const char *struct_name, const char *field_name); + void * bpf_open_perf_buffer(perf_reader_raw_cb raw_cb, perf_reader_lost_cb lost_cb, void *cb_cookie, int pid, int cpu, int page_cnt); diff --git a/src/python/bcc/__init__.py b/src/python/bcc/__init__.py index b4a05219..2c014c78 100644 --- a/src/python/bcc/__init__.py +++ b/src/python/bcc/__init__.py @@ -104,7 +104,6 @@ class SymbolCache(object): return -1 return addr.value - class PerfType: # From perf_type_id in uapi/linux/perf_event.h HARDWARE = 0 @@ -896,7 +895,6 @@ class BPF(object): else: self.detach_kprobe_event(ev_name) - def detach_kretprobe(self, event, fn_name=None): event = _assert_is_bytes(event) ev_name = b"r_" + event.replace(b"+", b"_").replace(b".", b"_") @@ -939,8 +937,6 @@ class BPF(object): raise Exception("Failed to detach BPF from device %s: %s" % (dev, errstr)) - - @classmethod def _check_path_symbol(cls, module, symname, addr, pid, sym_off=0): module = _assert_is_bytes(module) @@ -1183,6 +1179,12 @@ class BPF(object): return True return False + @staticmethod + def kernel_struct_has_field(struct_name, field_name): + struct_name = _assert_is_bytes(struct_name) + field_name = _assert_is_bytes(field_name) + return lib.kernel_struct_has_field(struct_name, field_name) + def detach_tracepoint(self, tp=b""): """detach_tracepoint(tp="") diff --git a/src/python/bcc/libbcc.py b/src/python/bcc/libbcc.py index 049968bb..3a39d044 100644 --- a/src/python/bcc/libbcc.py +++ b/src/python/bcc/libbcc.py @@ -132,6 +132,8 @@ lib.bpf_prog_detach2.restype = ct.c_int lib.bpf_prog_detach2.argtype = [ct.c_int, ct.c_int, ct.c_int] lib.bpf_has_kernel_btf.restype = ct.c_bool lib.bpf_has_kernel_btf.argtypes = None +lib.kernel_struct_has_field.restype = ct.c_int +lib.kernel_struct_has_field.argtypes = [ct.c_char_p, ct.c_char_p] lib.bpf_open_perf_buffer.restype = ct.c_void_p lib.bpf_open_perf_buffer.argtypes = [_RAW_CB_TYPE, _LOST_CB_TYPE, ct.py_object, ct.c_int, ct.c_int, ct.c_int] lib.bpf_open_perf_event.restype = ct.c_int