Rebase to the latest version

Rebase bcc to v0.25 and fix some doc and manpages issue.

Resolves: rhbz#2033155
Resolves: rhbz#2074061
Resolves: rhbz#2074580
Resolves: rhbz#2074584
Resolves: rhbz#2074982
Resolves: rhbz#2074995
Resolves: rhbz#2075000
Resolves: rhbz#2075008
Resolves: rhbz#2075014
Resolves: rhbz#2075028
Resolves: rhbz#2075185
Resolves: rhbz#2075196
Resolves: rhbz#2075500
Resolves: rhbz#2075754
Resolves: rhbz#2075798
Resolves: rhbz#2075828
Resolves: rhbz#2075832
Resolves: rhbz#2075877
Resolves: rhbz#2077863
Resolves: rhbz#2078065
Resolves: rhbz#2078067
Resolves: rhbz#2078432
Resolves: rhbz#2118993
Resolves: rhbz#2121919

Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
This commit is contained in:
Jerome Marchand 2022-11-28 11:42:31 +01:00
parent 54d6fada7d
commit 20eb383fc1
18 changed files with 574 additions and 5127 deletions

1
.gitignore vendored
View File

@ -15,3 +15,4 @@
/bcc-src-with-submodule.tar.gz
/bcc-0.20.0.tar.gz
/bcc-0.24.0.tar.gz
/bcc-0.25.0.tar.gz

View File

@ -1,44 +0,0 @@
From 5e7543d35596fabd9e5b02b58f8910bf572ca2fa Mon Sep 17 00:00:00 2001
From: Jerome Marchand <jmarchan@redhat.com>
Date: Thu, 7 Oct 2021 17:31:53 +0200
Subject: [PATCH] C9S: Fix mdflush
Since kernel commit 309dca309fc ("block: store a block_device pointer
in struct bio") struct bio points again to a block_device and not to a
gendisk directly. However mdflush is looking at the presence or not of
the bio_dev macro to check whether to get the gendisk directly from
the bio or not, which doesn't work anymore since the bio_dev macro
still exists. Since we don't have to deal other ekrnel kernel version
but our own, just use the definition that we use in our kernels.
Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
---
tools/mdflush.py | 11 -----------
1 file changed, 11 deletions(-)
diff --git a/tools/mdflush.py b/tools/mdflush.py
index 8a23520b..3581d1bf 100755
--- a/tools/mdflush.py
+++ b/tools/mdflush.py
@@ -35,18 +35,7 @@ int kprobe__md_flush_request(struct pt_regs *ctx, void *mddev, struct bio *bio)
u32 pid = bpf_get_current_pid_tgid() >> 32;
data.pid = pid;
bpf_get_current_comm(&data.comm, sizeof(data.comm));
-/*
- * The following deals with a kernel version change (in mainline 4.14, although
- * it may be backported to earlier kernels) with how the disk name is accessed.
- * We handle both pre- and post-change versions here. Please avoid kernel
- * version tests like this as much as possible: they inflate the code, test,
- * and maintenance burden.
- */
-#ifdef bio_dev
- struct gendisk *bi_disk = bio->bi_disk;
-#else
struct gendisk *bi_disk = bio->bi_bdev->bd_disk;
-#endif
bpf_probe_read_kernel(&data.disk, sizeof(data.disk), bi_disk->disk_name);
events.perf_submit(ctx, &data, sizeof(data));
return 0;
--
2.35.1

View File

@ -1,297 +0,0 @@
From a81f219d7f2bfc70dba1eb12208e3e6ab7c81b50 Mon Sep 17 00:00:00 2001
From: Jerome Marchand <jmarchan@redhat.com>
Date: Thu, 24 Mar 2022 16:08:17 +0100
Subject: [PATCH] C9S: libpbf version fixes
Revert "bcc: Replace deprecated libbpf APIs" since the libbpf version
provided in C9S doesn't provide the new APIs.
Remove BPF_MAP_TYPE_BLOOM_FILTER from bps since the libbpf version in
C9S, doesn't provide bloom filter map.
Add definition of struct bpf_core_relo.
---
introspection/bps.c | 1 -
src/cc/bcc_btf.cc | 73 +++++++++++++++++++++++++++++++++++++++-
src/cc/libbpf.c | 82 ++++++---------------------------------------
3 files changed, 83 insertions(+), 73 deletions(-)
diff --git a/introspection/bps.c b/introspection/bps.c
index 232b23d4..6ec02e6c 100644
--- a/introspection/bps.c
+++ b/introspection/bps.c
@@ -80,7 +80,6 @@ static const char * const map_type_strings[] = {
[BPF_MAP_TYPE_RINGBUF] = "ringbuf",
[BPF_MAP_TYPE_INODE_STORAGE] = "inode_storage",
[BPF_MAP_TYPE_TASK_STORAGE] = "task_storage",
- [BPF_MAP_TYPE_BLOOM_FILTER] = "bloom_filter",
};
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
diff --git a/src/cc/bcc_btf.cc b/src/cc/bcc_btf.cc
index 7f551ae8..c78ba823 100644
--- a/src/cc/bcc_btf.cc
+++ b/src/cc/bcc_btf.cc
@@ -170,6 +170,77 @@ static int btf_ext_setup_line_info(struct btf_ext *btf_ext)
return btf_ext_setup_info(btf_ext, &param);
}
+/* bpf_core_relo_kind encodes which aspect of captured field/type/enum value
+ * has to be adjusted by relocations.
+ */
+enum bpf_core_relo_kind {
+ BPF_FIELD_BYTE_OFFSET = 0, /* field byte offset */
+ BPF_FIELD_BYTE_SIZE = 1, /* field size in bytes */
+ BPF_FIELD_EXISTS = 2, /* field existence in target kernel */
+ BPF_FIELD_SIGNED = 3, /* field signedness (0 - unsigned, 1 - signed) */
+ BPF_FIELD_LSHIFT_U64 = 4, /* bitfield-specific left bitshift */
+ BPF_FIELD_RSHIFT_U64 = 5, /* bitfield-specific right bitshift */
+ BPF_TYPE_ID_LOCAL = 6, /* type ID in local BPF object */
+ BPF_TYPE_ID_TARGET = 7, /* type ID in target kernel */
+ BPF_TYPE_EXISTS = 8, /* type existence in target kernel */
+ BPF_TYPE_SIZE = 9, /* type size in bytes */
+ BPF_ENUMVAL_EXISTS = 10, /* enum value existence in target kernel */
+ BPF_ENUMVAL_VALUE = 11, /* enum value integer value */
+};
+
+/* The minimum bpf_core_relo checked by the loader
+ *
+ * CO-RE relocation captures the following data:
+ * - insn_off - instruction offset (in bytes) within a BPF program that needs
+ * its insn->imm field to be relocated with actual field info;
+ * - type_id - BTF type ID of the "root" (containing) entity of a relocatable
+ * type or field;
+ * - access_str_off - offset into corresponding .BTF string section. String
+ * interpretation depends on specific relocation kind:
+ * - for field-based relocations, string encodes an accessed field using
+ * a sequence of field and array indices, separated by colon (:). It's
+ * conceptually very close to LLVM's getelementptr ([0]) instruction's
+ * arguments for identifying offset to a field.
+ * - for type-based relocations, strings is expected to be just "0";
+ * - for enum value-based relocations, string contains an index of enum
+ * value within its enum type;
+ *
+ * Example to provide a better feel.
+ *
+ * struct sample {
+ * int a;
+ * struct {
+ * int b[10];
+ * };
+ * };
+ *
+ * struct sample *s = ...;
+ * int x = &s->a; // encoded as "0:0" (a is field #0)
+ * int y = &s->b[5]; // encoded as "0:1:0:5" (anon struct is field #1,
+ * // b is field #0 inside anon struct, accessing elem #5)
+ * int z = &s[10]->b; // encoded as "10:1" (ptr is used as an array)
+ *
+ * type_id for all relocs in this example will capture BTF type id of
+ * `struct sample`.
+ *
+ * Such relocation is emitted when using __builtin_preserve_access_index()
+ * Clang built-in, passing expression that captures field address, e.g.:
+ *
+ * bpf_probe_read(&dst, sizeof(dst),
+ * __builtin_preserve_access_index(&src->a.b.c));
+ *
+ * In this case Clang will emit field relocation recording necessary data to
+ * be able to find offset of embedded `a.b.c` field within `src` struct.
+ *
+ * [0] https://llvm.org/docs/LangRef.html#getelementptr-instruction
+ */
+struct bpf_core_relo {
+ __u32 insn_off;
+ __u32 type_id;
+ __u32 access_str_off;
+ enum bpf_core_relo_kind kind;
+};
+
static int btf_ext_setup_core_relos(struct btf_ext *btf_ext)
{
struct btf_ext_sec_setup_param param = {
@@ -597,7 +668,7 @@ int BTF::load(uint8_t *btf_sec, uintptr_t btf_sec_size,
return -1;
}
- if (btf__load_into_kernel(btf)) {
+ if (btf__load(btf)) {
btf__free(btf);
warning("Loading .BTF section failed\n");
return -1;
diff --git a/src/cc/libbpf.c b/src/cc/libbpf.c
index e6403299..68af4b35 100644
--- a/src/cc/libbpf.c
+++ b/src/cc/libbpf.c
@@ -297,25 +297,6 @@ static uint64_t ptr_to_u64(void *ptr)
return (uint64_t) (unsigned long) ptr;
}
-static int libbpf_bpf_map_create(struct bpf_create_map_attr *create_attr)
-{
- LIBBPF_OPTS(bpf_map_create_opts, p);
-
- p.map_flags = create_attr->map_flags;
- p.numa_node = create_attr->numa_node;
- p.btf_fd = create_attr->btf_fd;
- p.btf_key_type_id = create_attr->btf_key_type_id;
- p.btf_value_type_id = create_attr->btf_value_type_id;
- p.map_ifindex = create_attr->map_ifindex;
- if (create_attr->map_type == BPF_MAP_TYPE_STRUCT_OPS)
- p.btf_vmlinux_value_type_id = create_attr->btf_vmlinux_value_type_id;
- else
- p.inner_map_fd = create_attr->inner_map_fd;
-
- return bpf_map_create(create_attr->map_type, create_attr->name, create_attr->key_size,
- create_attr->value_size, create_attr->max_entries, &p);
-}
-
int bcc_create_map_xattr(struct bpf_create_map_attr *attr, bool allow_rlimit)
{
unsigned name_len = attr->name ? strlen(attr->name) : 0;
@@ -323,7 +304,7 @@ int bcc_create_map_xattr(struct bpf_create_map_attr *attr, bool allow_rlimit)
memcpy(map_name, attr->name, min(name_len, BPF_OBJ_NAME_LEN - 1));
attr->name = map_name;
- int ret = libbpf_bpf_map_create(attr);
+ int ret = bpf_create_map_xattr(attr);
if (ret < 0 && errno == EPERM) {
if (!allow_rlimit)
@@ -335,7 +316,7 @@ int bcc_create_map_xattr(struct bpf_create_map_attr *attr, bool allow_rlimit)
rl.rlim_max = RLIM_INFINITY;
rl.rlim_cur = rl.rlim_max;
if (setrlimit(RLIMIT_MEMLOCK, &rl) == 0)
- ret = libbpf_bpf_map_create(attr);
+ ret = bpf_create_map_xattr(attr);
}
}
@@ -345,12 +326,12 @@ int bcc_create_map_xattr(struct bpf_create_map_attr *attr, bool allow_rlimit)
attr->btf_fd = 0;
attr->btf_key_type_id = 0;
attr->btf_value_type_id = 0;
- ret = libbpf_bpf_map_create(attr);
+ ret = bpf_create_map_xattr(attr);
}
if (ret < 0 && name_len && (errno == E2BIG || errno == EINVAL)) {
map_name[0] = '\0';
- ret = libbpf_bpf_map_create(attr);
+ ret = bpf_create_map_xattr(attr);
}
if (ret < 0 && errno == EPERM) {
@@ -363,7 +344,7 @@ int bcc_create_map_xattr(struct bpf_create_map_attr *attr, bool allow_rlimit)
rl.rlim_max = RLIM_INFINITY;
rl.rlim_cur = rl.rlim_max;
if (setrlimit(RLIMIT_MEMLOCK, &rl) == 0)
- ret = libbpf_bpf_map_create(attr);
+ ret = bpf_create_map_xattr(attr);
}
}
return ret;
@@ -627,47 +608,6 @@ int bpf_prog_get_tag(int fd, unsigned long long *ptag)
return 0;
}
-static int libbpf_bpf_prog_load(const struct bpf_load_program_attr *load_attr,
- char *log_buf, size_t log_buf_sz)
-{
- LIBBPF_OPTS(bpf_prog_load_opts, p);
-
- if (!load_attr || !log_buf != !log_buf_sz) {
- errno = EINVAL;
- return -EINVAL;
- }
-
- p.expected_attach_type = load_attr->expected_attach_type;
- switch (load_attr->prog_type) {
- case BPF_PROG_TYPE_STRUCT_OPS:
- case BPF_PROG_TYPE_LSM:
- p.attach_btf_id = load_attr->attach_btf_id;
- break;
- case BPF_PROG_TYPE_TRACING:
- case BPF_PROG_TYPE_EXT:
- p.attach_btf_id = load_attr->attach_btf_id;
- p.attach_prog_fd = load_attr->attach_prog_fd;
- break;
- default:
- p.prog_ifindex = load_attr->prog_ifindex;
- p.kern_version = load_attr->kern_version;
- }
- p.log_level = load_attr->log_level;
- p.log_buf = log_buf;
- p.log_size = log_buf_sz;
- p.prog_btf_fd = load_attr->prog_btf_fd;
- p.func_info_rec_size = load_attr->func_info_rec_size;
- p.func_info_cnt = load_attr->func_info_cnt;
- p.func_info = load_attr->func_info;
- p.line_info_rec_size = load_attr->line_info_rec_size;
- p.line_info_cnt = load_attr->line_info_cnt;
- p.line_info = load_attr->line_info;
- p.prog_flags = load_attr->prog_flags;
-
- return bpf_prog_load(load_attr->prog_type, load_attr->name, load_attr->license,
- load_attr->insns, load_attr->insns_cnt, &p);
-}
-
int bcc_prog_load_xattr(struct bpf_load_program_attr *attr, int prog_len,
char *log_buf, unsigned log_buf_size, bool allow_rlimit)
{
@@ -750,7 +690,7 @@ int bcc_prog_load_xattr(struct bpf_load_program_attr *attr, int prog_len,
attr->name = prog_name;
}
- ret = libbpf_bpf_prog_load(attr, attr_log_buf, attr_log_buf_size);
+ ret = bpf_load_program_xattr(attr, attr_log_buf, attr_log_buf_size);
// func_info/line_info may not be supported in old kernels.
if (ret < 0 && attr->func_info && errno == EINVAL) {
@@ -761,14 +701,14 @@ int bcc_prog_load_xattr(struct bpf_load_program_attr *attr, int prog_len,
attr->line_info = NULL;
attr->line_info_cnt = 0;
attr->line_info_rec_size = 0;
- ret = libbpf_bpf_prog_load(attr, attr_log_buf, attr_log_buf_size);
+ ret = bpf_load_program_xattr(attr, attr_log_buf, attr_log_buf_size);
}
// BPF object name is not supported on older Kernels.
// If we failed due to this, clear the name and try again.
if (ret < 0 && name_len && (errno == E2BIG || errno == EINVAL)) {
prog_name[0] = '\0';
- ret = libbpf_bpf_prog_load(attr, attr_log_buf, attr_log_buf_size);
+ ret = bpf_load_program_xattr(attr, attr_log_buf, attr_log_buf_size);
}
if (ret < 0 && errno == EPERM) {
@@ -787,7 +727,7 @@ int bcc_prog_load_xattr(struct bpf_load_program_attr *attr, int prog_len,
rl.rlim_max = RLIM_INFINITY;
rl.rlim_cur = rl.rlim_max;
if (setrlimit(RLIMIT_MEMLOCK, &rl) == 0)
- ret = libbpf_bpf_prog_load(attr, attr_log_buf, attr_log_buf_size);
+ ret = bpf_load_program_xattr(attr, attr_log_buf, attr_log_buf_size);
}
}
@@ -805,7 +745,7 @@ int bcc_prog_load_xattr(struct bpf_load_program_attr *attr, int prog_len,
// If logging is not already enabled, enable it and do the syscall again.
if (attr->log_level == 0) {
attr->log_level = 1;
- ret = libbpf_bpf_prog_load(attr, log_buf, log_buf_size);
+ ret = bpf_load_program_xattr(attr, log_buf, log_buf_size);
}
// Print the log message and return.
bpf_print_hints(ret, log_buf);
@@ -829,7 +769,7 @@ int bcc_prog_load_xattr(struct bpf_load_program_attr *attr, int prog_len,
goto return_result;
}
tmp_log_buf[0] = 0;
- ret = libbpf_bpf_prog_load(attr, tmp_log_buf, tmp_log_buf_size);
+ ret = bpf_load_program_xattr(attr, tmp_log_buf, tmp_log_buf_size);
if (ret < 0 && errno == ENOSPC) {
// Temporary buffer size is not enough. Double it and try again.
free(tmp_log_buf);
--
2.36.1

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,125 +0,0 @@
From 879792d2d47c1308e884fb59d92fe535f7bb8d71 Mon Sep 17 00:00:00 2001
From: Tejun Heo <tj@kernel.org>
Date: Thu, 10 Mar 2022 08:37:21 -1000
Subject: [PATCH 1/2] biolatency, biolatpcts, biosnoop, biotop: Build fix for
v5.17+
During 5.17 dev cycle, the kernel dropped request->rq_disk. It can now be
accessed through request->q->disk. Fix the python ones in tools/. There are
more usages in other places which need to be fixed too.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
---
tools/biolatency.py | 8 ++++++--
tools/biolatpcts.py | 11 ++++++++---
tools/biosnoop.py | 6 +++++-
tools/biotop.py | 9 +++++++--
4 files changed, 26 insertions(+), 8 deletions(-)
diff --git a/tools/biolatency.py b/tools/biolatency.py
index 427cee47..10c852ac 100755
--- a/tools/biolatency.py
+++ b/tools/biolatency.py
@@ -128,12 +128,16 @@ storage_str = ""
store_str = ""
if args.disks:
storage_str += "BPF_HISTOGRAM(dist, disk_key_t);"
- store_str += """
+ disks_str = """
disk_key_t key = {.slot = bpf_log2l(delta)};
- void *__tmp = (void *)req->rq_disk->disk_name;
+ void *__tmp = (void *)req->__RQ_DISK__->disk_name;
bpf_probe_read(&key.disk, sizeof(key.disk), __tmp);
dist.atomic_increment(key);
"""
+ if BPF.kernel_struct_has_field(b'request', b'rq_disk'):
+ store_str += disks_str.replace('__RQ_DISK__', 'rq_disk')
+ else:
+ store_str += disks_str.replace('__RQ_DISK__', 'q->disk')
elif args.flags:
storage_str += "BPF_HISTOGRAM(dist, flag_key_t);"
store_str += """
diff --git a/tools/biolatpcts.py b/tools/biolatpcts.py
index 0f334419..ea8b1ce6 100755
--- a/tools/biolatpcts.py
+++ b/tools/biolatpcts.py
@@ -72,9 +72,9 @@ void kprobe_blk_account_io_done(struct pt_regs *ctx, struct request *rq, u64 now
if (!rq->__START_TIME_FIELD__)
return;
- if (!rq->rq_disk ||
- rq->rq_disk->major != __MAJOR__ ||
- rq->rq_disk->first_minor != __MINOR__)
+ if (!rq->__RQ_DISK__ ||
+ rq->__RQ_DISK__->major != __MAJOR__ ||
+ rq->__RQ_DISK__->first_minor != __MINOR__)
return;
cmd_flags = rq->cmd_flags;
@@ -142,6 +142,11 @@ bpf_source = bpf_source.replace('__START_TIME_FIELD__', start_time_field)
bpf_source = bpf_source.replace('__MAJOR__', str(major))
bpf_source = bpf_source.replace('__MINOR__', str(minor))
+if BPF.kernel_struct_has_field(b'request', b'rq_disk'):
+ bpf_source = bpf_source.replace('__RQ_DISK__', 'rq_disk')
+else:
+ bpf_source = bpf_source.replace('__RQ_DISK__', 'q->disk')
+
bpf = BPF(text=bpf_source)
if BPF.get_kprobe_functions(b'__blk_account_io_done'):
bpf.attach_kprobe(event="__blk_account_io_done", fn_name="kprobe_blk_account_io_done")
diff --git a/tools/biosnoop.py b/tools/biosnoop.py
index ae38e384..a2b636aa 100755
--- a/tools/biosnoop.py
+++ b/tools/biosnoop.py
@@ -125,7 +125,7 @@ int trace_req_completion(struct pt_regs *ctx, struct request *req)
data.pid = valp->pid;
data.sector = req->__sector;
bpf_probe_read_kernel(&data.name, sizeof(data.name), valp->name);
- struct gendisk *rq_disk = req->rq_disk;
+ struct gendisk *rq_disk = req->__RQ_DISK__;
bpf_probe_read_kernel(&data.disk_name, sizeof(data.disk_name),
rq_disk->disk_name);
}
@@ -156,6 +156,10 @@ int trace_req_completion(struct pt_regs *ctx, struct request *req)
bpf_text = bpf_text.replace('##QUEUE##', '1')
else:
bpf_text = bpf_text.replace('##QUEUE##', '0')
+if BPF.kernel_struct_has_field(b'request', b'rq_disk'):
+ bpf_text = bpf_text.replace('__RQ_DISK__', 'rq_disk')
+else:
+ bpf_text = bpf_text.replace('__RQ_DISK__', 'q->disk')
if debug or args.ebpf:
print(bpf_text)
if args.ebpf:
diff --git a/tools/biotop.py b/tools/biotop.py
index b3e3ea00..882835f6 100755
--- a/tools/biotop.py
+++ b/tools/biotop.py
@@ -129,8 +129,8 @@ int trace_req_completion(struct pt_regs *ctx, struct request *req)
// setup info_t key
struct info_t info = {};
- info.major = req->rq_disk->major;
- info.minor = req->rq_disk->first_minor;
+ info.major = req->__RQ_DISK__->major;
+ info.minor = req->__RQ_DISK__->first_minor;
/*
* The following deals with a kernel version change (in mainline 4.7, although
* it may be backported to earlier kernels) with how block request write flags
@@ -174,6 +174,11 @@ int trace_req_completion(struct pt_regs *ctx, struct request *req)
print(bpf_text)
exit()
+if BPF.kernel_struct_has_field(b'request', b'rq_disk'):
+ bpf_text = bpf_text.replace('__RQ_DISK__', 'rq_disk')
+else:
+ bpf_text = bpf_text.replace('__RQ_DISK__', 'q->disk')
+
b = BPF(text=bpf_text)
if BPF.get_kprobe_functions(b'__blk_account_io_start'):
b.attach_kprobe(event="__blk_account_io_start", fn_name="trace_pid_start")
--
2.35.1

View File

@ -1,60 +0,0 @@
From 2ada4cee035c4d07391faa870a5df1874d657b65 Mon Sep 17 00:00:00 2001
From: Tejun Heo <tj@kernel.org>
Date: Thu, 27 Jan 2022 06:25:31 -1000
Subject: [PATCH 2/3] biolatpcts: Build fixes on recent kernels
* `struct request` definition recently moved from blkdev.h to blk-mq.h
breaking both tools/biolatpcts and examples/tracing/biolatpcts. Fix them
by also including blk-mq.h.
* blk_account_io_done() got split into two parts - inline condition checks
and the actual accounting with the latter now done in
__blk_account_io_done(). The kprobe attachment needs to be conditionalized
to work across the change. tools/biolatpcts was already updated but
examples/tracing/biolatpcts wasn't. Fix it.
Signed-off-by: Tejun Heo <tj@kernel.org>
---
examples/tracing/biolatpcts.py | 6 +++++-
tools/biolatpcts.py | 1 +
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/examples/tracing/biolatpcts.py b/examples/tracing/biolatpcts.py
index c9bb834e..68a59516 100755
--- a/examples/tracing/biolatpcts.py
+++ b/examples/tracing/biolatpcts.py
@@ -11,6 +11,7 @@ from time import sleep
bpf_source = """
#include <linux/blk_types.h>
+#include <linux/blk-mq.h>
#include <linux/blkdev.h>
#include <linux/time64.h>
@@ -45,7 +46,10 @@ void kprobe_blk_account_io_done(struct pt_regs *ctx, struct request *rq, u64 now
"""
bpf = BPF(text=bpf_source)
-bpf.attach_kprobe(event='blk_account_io_done', fn_name='kprobe_blk_account_io_done')
+if BPF.get_kprobe_functions(b'__blk_account_io_done'):
+ bpf.attach_kprobe(event="__blk_account_io_done", fn_name="kprobe_blk_account_io_done")
+else:
+ bpf.attach_kprobe(event="blk_account_io_done", fn_name="kprobe_blk_account_io_done")
cur_lat_100ms = bpf['lat_100ms']
cur_lat_1ms = bpf['lat_1ms']
diff --git a/tools/biolatpcts.py b/tools/biolatpcts.py
index a2f59592..0f334419 100755
--- a/tools/biolatpcts.py
+++ b/tools/biolatpcts.py
@@ -56,6 +56,7 @@ parser.add_argument('--verbose', '-v', action='count', default = 0)
bpf_source = """
#include <linux/blk_types.h>
#include <linux/blkdev.h>
+#include <linux/blk-mq.h>
#include <linux/time64.h>
BPF_PERCPU_ARRAY(rwdf_100ms, u64, 400);
--
2.35.1

View File

@ -1,49 +0,0 @@
From a6a5dba23d19f6a900b0359a7390df4a6b9a42f4 Mon Sep 17 00:00:00 2001
From: Jerome Marchand <jmarchan@redhat.com>
Date: Tue, 15 Mar 2022 17:59:24 +0100
Subject: [PATCH 1/3] libbpf-tools: Allow to use different cflags for bpf
targets
commit 531b698cdc20 ("libbpf-tools: Enable compilation warnings for
BPF programs") applies CFLAGS to all targets. However, some of the c
flags typically used by distribution are not available to the bpf
target. Add a new BPFCFLAGS macro to take care of that.
Fixes the following compilation error on fedora:
BPF bashreadline.bpf.o
clang-13: warning: optimization flag '-ffat-lto-objects' is not supported [-Wignored-optimization-argument]
clang-13: warning: argument unused during compilation: '-specs=/usr/lib/rpm/redhat/redhat-hardened-cc1' [-Wunused-command-line-argument]
clang-13: warning: argument unused during compilation: '-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1' [-Wunused-command-line-argument]
clang-13: warning: argument unused during compilation: '-fstack-clash-protection' [-Wunused-command-line-argument]
error: option 'cf-protection=return' cannot be specified on this target
error: option 'cf-protection=branch' cannot be specified on this target
2 errors generated.
---
libbpf-tools/Makefile | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libbpf-tools/Makefile b/libbpf-tools/Makefile
index 6bf1ed08..39af95ec 100644
--- a/libbpf-tools/Makefile
+++ b/libbpf-tools/Makefile
@@ -7,6 +7,7 @@ LIBBPF_SRC := $(abspath ../src/cc/libbpf/src)
LIBBPF_OBJ := $(abspath $(OUTPUT)/libbpf.a)
INCLUDES := -I$(OUTPUT) -I../src/cc/libbpf/include/uapi
CFLAGS := -g -O2 -Wall
+BPFCFLAGS := -g -O2 -Wall
INSTALL ?= install
prefix ?= /usr/local
ARCH := $(shell uname -m | sed 's/x86_64/x86/' | sed 's/aarch64/arm64/' | sed 's/ppc64le/powerpc/' | sed 's/mips.*/mips/')
@@ -106,7 +107,7 @@ $(OUTPUT)/%.skel.h: $(OUTPUT)/%.bpf.o | $(OUTPUT)
$(OUTPUT)/%.bpf.o: %.bpf.c $(LIBBPF_OBJ) $(wildcard %.h) $(ARCH)/vmlinux.h | $(OUTPUT)
$(call msg,BPF,$@)
- $(Q)$(CLANG) $(CFLAGS) -target bpf -D__TARGET_ARCH_$(ARCH) \
+ $(Q)$(CLANG) $(BPFCFLAGS) -target bpf -D__TARGET_ARCH_$(ARCH) \
-I$(ARCH)/ $(INCLUDES) -c $(filter %.c,$^) -o $@ && \
$(LLVM_STRIP) -g $@
--
2.35.1

View File

@ -1,158 +0,0 @@
From 50480835adf15a389267393674504551b68987a2 Mon Sep 17 00:00:00 2001
From: xingfeng2510 <xingfeng25100@163.com>
Date: Wed, 30 Mar 2022 16:10:51 +0800
Subject: [PATCH 2/2] libbpf-tools: Fix dropped request->rq_disk for kernel
5.17+
Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
---
libbpf-tools/biolatency.bpf.c | 20 ++++++++++++++++++--
libbpf-tools/biosnoop.bpf.c | 12 +++++++++++-
libbpf-tools/biostacks.bpf.c | 12 +++++++++++-
libbpf-tools/bitesize.bpf.c | 12 +++++++++++-
4 files changed, 51 insertions(+), 5 deletions(-)
diff --git a/libbpf-tools/biolatency.bpf.c b/libbpf-tools/biolatency.bpf.c
index 648dda78..8f325046 100644
--- a/libbpf-tools/biolatency.bpf.c
+++ b/libbpf-tools/biolatency.bpf.c
@@ -19,6 +19,10 @@ const volatile bool targ_ms = false;
const volatile bool filter_dev = false;
const volatile __u32 targ_dev = 0;
+struct request_queue___x {
+ struct gendisk *disk;
+} __attribute__((preserve_access_index));
+
struct {
__uint(type, BPF_MAP_TYPE_CGROUP_ARRAY);
__type(key, u32);
@@ -53,9 +57,15 @@ int trace_rq_start(struct request *rq, int issue)
u64 ts = bpf_ktime_get_ns();
if (filter_dev) {
- struct gendisk *disk = BPF_CORE_READ(rq, rq_disk);
+ struct request_queue___x *q = (void *)BPF_CORE_READ(rq, q);
+ struct gendisk *disk;
u32 dev;
+ if (bpf_core_field_exists(q->disk))
+ disk = BPF_CORE_READ(q, disk);
+ else
+ disk = BPF_CORE_READ(rq, rq_disk);
+
dev = disk ? MKDEV(BPF_CORE_READ(disk, major),
BPF_CORE_READ(disk, first_minor)) : 0;
if (targ_dev != dev)
@@ -119,7 +129,13 @@ int BPF_PROG(block_rq_complete, struct request *rq, int error,
goto cleanup;
if (targ_per_disk) {
- struct gendisk *disk = BPF_CORE_READ(rq, rq_disk);
+ struct request_queue___x *q = (void *)BPF_CORE_READ(rq, q);
+ struct gendisk *disk;
+
+ if (bpf_core_field_exists(q->disk))
+ disk = BPF_CORE_READ(q, disk);
+ else
+ disk = BPF_CORE_READ(rq, rq_disk);
hkey.dev = disk ? MKDEV(BPF_CORE_READ(disk, major),
BPF_CORE_READ(disk, first_minor)) : 0;
diff --git a/libbpf-tools/biosnoop.bpf.c b/libbpf-tools/biosnoop.bpf.c
index 54226e43..05903473 100644
--- a/libbpf-tools/biosnoop.bpf.c
+++ b/libbpf-tools/biosnoop.bpf.c
@@ -15,6 +15,10 @@ const volatile __u32 targ_dev = 0;
extern __u32 LINUX_KERNEL_VERSION __kconfig;
+struct request_queue___x {
+ struct gendisk *disk;
+} __attribute__((preserve_access_index));
+
struct {
__uint(type, BPF_MAP_TYPE_CGROUP_ARRAY);
__type(key, u32);
@@ -92,7 +96,13 @@ int trace_rq_start(struct request *rq, bool insert)
stagep = bpf_map_lookup_elem(&start, &rq);
if (!stagep) {
- struct gendisk *disk = BPF_CORE_READ(rq, rq_disk);
+ struct request_queue___x *q = (void *)BPF_CORE_READ(rq, q);
+ struct gendisk *disk;
+
+ if (bpf_core_field_exists(q->disk))
+ disk = BPF_CORE_READ(q, disk);
+ else
+ disk = BPF_CORE_READ(rq, rq_disk);
stage.dev = disk ? MKDEV(BPF_CORE_READ(disk, major),
BPF_CORE_READ(disk, first_minor)) : 0;
diff --git a/libbpf-tools/biostacks.bpf.c b/libbpf-tools/biostacks.bpf.c
index 01993737..c13975fa 100644
--- a/libbpf-tools/biostacks.bpf.c
+++ b/libbpf-tools/biostacks.bpf.c
@@ -14,6 +14,10 @@ const volatile bool targ_ms = false;
const volatile bool filter_dev = false;
const volatile __u32 targ_dev = -1;
+struct request_queue___x {
+ struct gendisk *disk;
+} __attribute__((preserve_access_index));
+
struct internal_rqinfo {
u64 start_ts;
struct rqinfo rqinfo;
@@ -41,9 +45,15 @@ static __always_inline
int trace_start(void *ctx, struct request *rq, bool merge_bio)
{
struct internal_rqinfo *i_rqinfop = NULL, i_rqinfo = {};
- struct gendisk *disk = BPF_CORE_READ(rq, rq_disk);
+ struct request_queue___x *q = (void *)BPF_CORE_READ(rq, q);
+ struct gendisk *disk;
u32 dev;
+ if (bpf_core_field_exists(q->disk))
+ disk = BPF_CORE_READ(q, disk);
+ else
+ disk = BPF_CORE_READ(rq, rq_disk);
+
dev = disk ? MKDEV(BPF_CORE_READ(disk, major),
BPF_CORE_READ(disk, first_minor)) : 0;
if (filter_dev && targ_dev != dev)
diff --git a/libbpf-tools/bitesize.bpf.c b/libbpf-tools/bitesize.bpf.c
index 80672c9b..5066ca33 100644
--- a/libbpf-tools/bitesize.bpf.c
+++ b/libbpf-tools/bitesize.bpf.c
@@ -13,6 +13,10 @@ const volatile __u32 targ_dev = 0;
extern __u32 LINUX_KERNEL_VERSION __kconfig;
+struct request_queue___x {
+ struct gendisk *disk;
+} __attribute__((preserve_access_index));
+
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 10240);
@@ -41,9 +45,15 @@ static int trace_rq_issue(struct request *rq)
u64 slot;
if (filter_dev) {
- struct gendisk *disk = BPF_CORE_READ(rq, rq_disk);
+ struct request_queue___x *q = (void *)BPF_CORE_READ(rq, q);
+ struct gendisk *disk;
u32 dev;
+ if (bpf_core_field_exists(q->disk))
+ disk = BPF_CORE_READ(q, disk);
+ else
+ disk = BPF_CORE_READ(rq, rq_disk);
+
dev = disk ? MKDEV(BPF_CORE_READ(disk, major),
BPF_CORE_READ(disk, first_minor)) : 0;
if (targ_dev != dev)
--
2.35.1

View File

@ -1,66 +0,0 @@
From 1eafb1f5aa0d3a9f60f89aad0ea55ae93899baff Mon Sep 17 00:00:00 2001
From: Jerome Marchand <jmarchan@redhat.com>
Date: Wed, 23 Feb 2022 16:04:30 +0100
Subject: [PATCH 3/3] tools: include blk-mq.h in bio tools
Kernel commit 24b83deb29b ("block: move struct request to blk-mq.h")
has moved struct request from blkdev.h to blk-mq.h. It results in
several bio tools to fail with errors of the following type:
error: incomplete definition of type 'struct request'
Since blk-mq.h had always included blkdev.h. it is safe to simply
replace the inclusion of blkdev.h by blk-mq-h. It works on both older
and newer kernel.
Fixes: #3869
Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
---
tools/biolatency.py | 2 +-
tools/biosnoop.py | 2 +-
tools/biotop.py | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/tools/biolatency.py b/tools/biolatency.py
index f4e2c9ea..427cee47 100755
--- a/tools/biolatency.py
+++ b/tools/biolatency.py
@@ -64,7 +64,7 @@ debug = 0
# define BPF program
bpf_text = """
#include <uapi/linux/ptrace.h>
-#include <linux/blkdev.h>
+#include <linux/blk-mq.h>
typedef struct disk_key {
char disk[DISK_NAME_LEN];
diff --git a/tools/biosnoop.py b/tools/biosnoop.py
index 2b954ac9..ae38e384 100755
--- a/tools/biosnoop.py
+++ b/tools/biosnoop.py
@@ -37,7 +37,7 @@ debug = 0
# define BPF program
bpf_text="""
#include <uapi/linux/ptrace.h>
-#include <linux/blkdev.h>
+#include <linux/blk-mq.h>
// for saving the timestamp and __data_len of each request
struct start_req_t {
diff --git a/tools/biotop.py b/tools/biotop.py
index eac4dab9..b3e3ea00 100755
--- a/tools/biotop.py
+++ b/tools/biotop.py
@@ -54,7 +54,7 @@ diskstats = "/proc/diskstats"
# load BPF program
bpf_text = """
#include <uapi/linux/ptrace.h>
-#include <linux/blkdev.h>
+#include <linux/blk-mq.h>
// for saving the timestamp and __data_len of each request
struct start_req_t {
--
2.35.1

View File

@ -1,30 +0,0 @@
From 93a464e2ef05b7ef78b5679e366b89fcddf6a575 Mon Sep 17 00:00:00 2001
From: Jerome Marchand <jmarchan@redhat.com>
Date: Mon, 1 Aug 2022 11:45:41 +0200
Subject: [PATCH] tools/mdflush: include blkdev.h instead of genhd.h
In recent kernels, i.e. since commit 322cbb50de71 ("block: remove
genhd.h"), genhd.h header has been removed and its content moved to
blkdev.h. Since genhd.h has been included in blkdev.h since forever,
including blkdev instead of genhd in the mdflush tool works for both
older and newer kernel.
---
tools/mdflush.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/mdflush.py b/tools/mdflush.py
index 3581d1bf..6741d563 100755
--- a/tools/mdflush.py
+++ b/tools/mdflush.py
@@ -19,7 +19,7 @@ from time import strftime
b = BPF(text="""
#include <uapi/linux/ptrace.h>
#include <linux/sched.h>
-#include <linux/genhd.h>
+#include <linux/blkdev.h>
#include <linux/bio.h>
struct data_t {
--
2.37.1

View File

@ -0,0 +1,77 @@
From c17a12ac030c5d9c812e611f8132570af0e795af Mon Sep 17 00:00:00 2001
From: Yonghong Song <yhs@fb.com>
Date: Sat, 13 Aug 2022 17:50:07 -0700
Subject: [PATCH 1/2] Fix bpf_pseudo_fd() type conversion error
With llvm15 and llvm16, the following command line
sudo ./trace.py 'smp_call_function_single "%K", arg1'
will cause error:
/virtual/main.c:60:36: error: incompatible integer to pointer conversion passing 'u64'
(aka 'unsigned long long') to parameter of type 'void *' [-Wint-conversion]
bpf_perf_event_output(ctx, bpf_pseudo_fd(1, -1), CUR_CPU_IDENTIFIER, &__data, sizeof(__data));
^~~~~~~~~~~~~~~~~~~~
1 error generated.
Failed to compile BPF module <text>
In helpers.h, we have
u64 bpf_pseudo_fd(u64, u64) asm("llvm.bpf.pseudo");
Apparently, <= llvm14 can tolerate u64 -> 'void *' conversion, but
llvm15 by default will cause an error.
Let us explicitly convert bpf_pseudo_fd to 'void *' to avoid
such errors.
Signed-off-by: Yonghong Song <yhs@fb.com>
---
src/cc/frontends/clang/b_frontend_action.cc | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/cc/frontends/clang/b_frontend_action.cc b/src/cc/frontends/clang/b_frontend_action.cc
index a4e05b16..dbeba3e4 100644
--- a/src/cc/frontends/clang/b_frontend_action.cc
+++ b/src/cc/frontends/clang/b_frontend_action.cc
@@ -957,7 +957,7 @@ bool BTypeVisitor::VisitCallExpr(CallExpr *Call) {
string arg0 = rewriter_.getRewrittenText(expansionRange(Call->getArg(0)->getSourceRange()));
string args_other = rewriter_.getRewrittenText(expansionRange(SourceRange(GET_BEGINLOC(Call->getArg(1)),
GET_ENDLOC(Call->getArg(2)))));
- txt = "bpf_perf_event_output(" + arg0 + ", bpf_pseudo_fd(1, " + fd + ")";
+ txt = "bpf_perf_event_output(" + arg0 + ", (void *)bpf_pseudo_fd(1, " + fd + ")";
txt += ", CUR_CPU_IDENTIFIER, " + args_other + ")";
// e.g.
@@ -986,7 +986,7 @@ bool BTypeVisitor::VisitCallExpr(CallExpr *Call) {
string meta_len = rewriter_.getRewrittenText(expansionRange(Call->getArg(3)->getSourceRange()));
txt = "bpf_perf_event_output(" +
skb + ", " +
- "bpf_pseudo_fd(1, " + fd + "), " +
+ "(void *)bpf_pseudo_fd(1, " + fd + "), " +
"((__u64)" + skb_len + " << 32) | BPF_F_CURRENT_CPU, " +
meta + ", " +
meta_len + ");";
@@ -1006,12 +1006,12 @@ bool BTypeVisitor::VisitCallExpr(CallExpr *Call) {
string keyp = rewriter_.getRewrittenText(expansionRange(Call->getArg(1)->getSourceRange()));
string flag = rewriter_.getRewrittenText(expansionRange(Call->getArg(2)->getSourceRange()));
txt = "bpf_" + string(memb_name) + "(" + ctx + ", " +
- "bpf_pseudo_fd(1, " + fd + "), " + keyp + ", " + flag + ");";
+ "(void *)bpf_pseudo_fd(1, " + fd + "), " + keyp + ", " + flag + ");";
} else if (memb_name == "ringbuf_output") {
string name = string(Ref->getDecl()->getName());
string args = rewriter_.getRewrittenText(expansionRange(SourceRange(GET_BEGINLOC(Call->getArg(0)),
GET_ENDLOC(Call->getArg(2)))));
- txt = "bpf_ringbuf_output(bpf_pseudo_fd(1, " + fd + ")";
+ txt = "bpf_ringbuf_output((void *)bpf_pseudo_fd(1, " + fd + ")";
txt += ", " + args + ")";
// e.g.
@@ -1033,7 +1033,7 @@ bool BTypeVisitor::VisitCallExpr(CallExpr *Call) {
} else if (memb_name == "ringbuf_reserve") {
string name = string(Ref->getDecl()->getName());
string arg0 = rewriter_.getRewrittenText(expansionRange(Call->getArg(0)->getSourceRange()));
- txt = "bpf_ringbuf_reserve(bpf_pseudo_fd(1, " + fd + ")";
+ txt = "bpf_ringbuf_reserve((void *)bpf_pseudo_fd(1, " + fd + ")";
txt += ", " + arg0 + ", 0)"; // Flags in reserve are meaningless
} else if (memb_name == "ringbuf_discard") {
string name = string(Ref->getDecl()->getName());
--
2.38.1

View File

@ -0,0 +1,96 @@
From 9ae3908ae38b3e8d8e36a52c0e5664c453d4c015 Mon Sep 17 00:00:00 2001
From: Jerome Marchand <jmarchan@redhat.com>
Date: Wed, 26 Oct 2022 14:41:54 +0200
Subject: [PATCH 2/2] Fix clang 15 int to pointer conversion errors
Since version 15, clang issues error for implicit conversion of
integer to pointer. Several tools are broken. This patch add explicit
pointer cast where needed.
Fixes the following errors:
/virtual/main.c:37:18: error: incompatible integer to pointer conversion initializing 'struct request *' with an expression of type 'unsigned long' [-Wint-conversion]
struct request *req = ctx->di;
^ ~~~~~~~
/virtual/main.c:49:18: error: incompatible integer to pointer conversion initializing 'struct request *' with an expression of type 'unsigned long' [-Wint-conversion]
struct request *req = ctx->di;
^ ~~~~~~~
2 errors generated.
/virtual/main.c:73:19: error: incompatible integer to pointer conversion initializing 'struct pt_regs *' with an expression of type 'unsigned long' [-Wint-conversion]
struct pt_regs * __ctx = ctx->di;
^ ~~~~~~~
/virtual/main.c:100:240: error: incompatible integer to pointer conversion passing 'u64' (aka 'unsigned long long') to parameter of type 'const void *' [-Wint-conversion]
data.ppid = ({ typeof(pid_t) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (u64)&({ typeof(struct task_struct *) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (u64)&task->real_parent); _val; })->tgid); _val; });
^~~~~~~~~~~~~~~~~~~~~~~
/virtual/main.c:100:118: error: incompatible integer to pointer conversion passing 'u64' (aka 'unsigned long long') to parameter of type 'const void *' [-Wint-conversion]
data.ppid = ({ typeof(pid_t) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (u64)&({ typeof(struct task_struct *) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (u64)&task->real_parent); _val; })->tgid); _val; });
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
---
src/cc/frontends/clang/b_frontend_action.cc | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/src/cc/frontends/clang/b_frontend_action.cc b/src/cc/frontends/clang/b_frontend_action.cc
index dbeba3e4..c0582464 100644
--- a/src/cc/frontends/clang/b_frontend_action.cc
+++ b/src/cc/frontends/clang/b_frontend_action.cc
@@ -517,9 +517,9 @@ bool ProbeVisitor::VisitUnaryOperator(UnaryOperator *E) {
string pre, post;
pre = "({ typeof(" + E->getType().getAsString() + ") _val; __builtin_memset(&_val, 0, sizeof(_val));";
if (cannot_fall_back_safely)
- pre += " bpf_probe_read_kernel(&_val, sizeof(_val), (u64)";
+ pre += " bpf_probe_read_kernel(&_val, sizeof(_val), (void *)";
else
- pre += " bpf_probe_read(&_val, sizeof(_val), (u64)";
+ pre += " bpf_probe_read(&_val, sizeof(_val), (void *)";
post = "); _val; })";
rewriter_.ReplaceText(expansionLoc(E->getOperatorLoc()), 1, pre);
rewriter_.InsertTextAfterToken(expansionLoc(GET_ENDLOC(sub)), post);
@@ -581,9 +581,9 @@ bool ProbeVisitor::VisitMemberExpr(MemberExpr *E) {
string pre, post;
pre = "({ typeof(" + E->getType().getAsString() + ") _val; __builtin_memset(&_val, 0, sizeof(_val));";
if (cannot_fall_back_safely)
- pre += " bpf_probe_read_kernel(&_val, sizeof(_val), (u64)&";
+ pre += " bpf_probe_read_kernel(&_val, sizeof(_val), (void *)&";
else
- pre += " bpf_probe_read(&_val, sizeof(_val), (u64)&";
+ pre += " bpf_probe_read(&_val, sizeof(_val), (void *)&";
post = rhs + "); _val; })";
rewriter_.InsertText(expansionLoc(GET_BEGINLOC(E)), pre);
rewriter_.ReplaceText(expansionRange(SourceRange(member, GET_ENDLOC(E))), post);
@@ -635,9 +635,9 @@ bool ProbeVisitor::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
pre = "({ typeof(" + E->getType().getAsString() + ") _val; __builtin_memset(&_val, 0, sizeof(_val));";
if (cannot_fall_back_safely)
- pre += " bpf_probe_read_kernel(&_val, sizeof(_val), (u64)((";
+ pre += " bpf_probe_read_kernel(&_val, sizeof(_val), (void *)((";
else
- pre += " bpf_probe_read(&_val, sizeof(_val), (u64)((";
+ pre += " bpf_probe_read(&_val, sizeof(_val), (void *)((";
if (isMemberDereference(base)) {
pre += "&";
// If the base of the array subscript is a member dereference, we'll rewrite
@@ -747,8 +747,8 @@ void BTypeVisitor::genParamDirectAssign(FunctionDecl *D, string& preamble,
arg->addAttr(UnavailableAttr::CreateImplicit(C, "ptregs"));
size_t d = idx - 1;
const char *reg = calling_conv_regs[d];
- preamble += " " + text + " = " + fn_args_[0]->getName().str() + "->" +
- string(reg) + ";";
+ preamble += " " + text + " = (" + arg->getType().getAsString() + ")" +
+ fn_args_[0]->getName().str() + "->" + string(reg) + ";";
}
}
}
@@ -762,7 +762,7 @@ void BTypeVisitor::genParamIndirectAssign(FunctionDecl *D, string& preamble,
if (idx == 0) {
new_ctx = "__" + arg->getName().str();
- preamble += " struct pt_regs * " + new_ctx + " = " +
+ preamble += " struct pt_regs * " + new_ctx + " = (void *)" +
arg->getName().str() + "->" +
string(calling_conv_regs[0]) + ";";
} else {
--
2.38.1

View File

@ -0,0 +1,222 @@
From 2f6565681e627d11dde0177503100669df020684 Mon Sep 17 00:00:00 2001
From: Jerome Marchand <jmarchan@redhat.com>
Date: Sun, 28 Aug 2022 07:44:01 +0200
Subject: [PATCH] Fix some documentation issues (#4197)
* compactsnoop-manpage: fix the name of the tool in the NAME section
In its manpage, compactsnoop tools is called compacstall in the NAME
section. I don't know where that name comes from, but it should be
compactsnoop.
* dirtop-manpage: use '-d' option in the EXAMPLES section
The mandatory '-d' option of dirtop is missing in the EXAMPLES
section. Copy it from the usage message. Also remove '.py' suffixes.
* funclatency-manpage: fix typo in one of the examples
There is a spurious colon in one of the manpage examples. Remove it.
* tools/killsnoop: add '-s' option in the synopsis of the example file
Commit 33c8b1ac ("Update man page and example file") added '-s' option
to the manpage and an example in the example file, but missed the
sysnopsis in that later case.
* trace-manpage: add missing options (-c,-n,-f and -B) to the synopsis
Copy the full sysopsis from the usage message.
* tcptracer-manpage: add missing '-t' option in the manpage
Add '-t' option to the synopsis and description.
* tcpsubnet-manpage: remove '--ebpf' option from the manpage
This option is explicitly suppressed in argparse and no manpage of
other tools mentions it.
* manpages: remove '.py' suffix from the synopsis of some *snoop tools
Other manpages don't show the suffix, nor do the usage messages.
---
man/man8/bindsnoop.8 | 2 +-
man/man8/compactsnoop.8 | 4 ++--
man/man8/dirtop.8 | 8 ++++----
man/man8/drsnoop.8 | 2 +-
man/man8/funclatency.8 | 2 +-
man/man8/opensnoop.8 | 2 +-
man/man8/tcpsubnet.8 | 5 +----
man/man8/tcptracer.8 | 5 ++++-
man/man8/trace.8 | 6 ++++--
tools/killsnoop_example.txt | 2 ++
10 files changed, 21 insertions(+), 17 deletions(-)
diff --git a/man/man8/bindsnoop.8 b/man/man8/bindsnoop.8
index f8fa1850..0eb42ccb 100644
--- a/man/man8/bindsnoop.8
+++ b/man/man8/bindsnoop.8
@@ -2,7 +2,7 @@
.SH NAME
bindsnoop \- Trace bind() system calls.
.SH SYNOPSIS
-.B bindsnoop.py [\fB-h\fP] [\fB-w\fP] [\fB-t\fP] [\fB-p\fP PID] [\fB-P\fP PORT] [\fB-E\fP] [\fB-U\fP] [\fB-u\fP UID] [\fB--count\fP] [\fB--cgroupmap MAP\fP] [\fB--mntnsmap MNTNSMAP\fP]
+.B bindsnoop [\fB-h\fP] [\fB-w\fP] [\fB-t\fP] [\fB-p\fP PID] [\fB-P\fP PORT] [\fB-E\fP] [\fB-U\fP] [\fB-u\fP UID] [\fB--count\fP] [\fB--cgroupmap MAP\fP] [\fB--mntnsmap MNTNSMAP\fP]
.SH DESCRIPTION
bindsnoop reports socket options set before the bind call that would impact this system call behavior.
.PP
diff --git a/man/man8/compactsnoop.8 b/man/man8/compactsnoop.8
index a2933d7a..e9cde0ce 100644
--- a/man/man8/compactsnoop.8
+++ b/man/man8/compactsnoop.8
@@ -1,8 +1,8 @@
.TH compactsnoop 8 "2019-11-1" "USER COMMANDS"
.SH NAME
-compactstall \- Trace compact zone events. Uses Linux eBPF/bcc.
+compactsnoop \- Trace compact zone events. Uses Linux eBPF/bcc.
.SH SYNOPSIS
-.B compactsnoop.py [\-h] [\-T] [\-p PID] [\-d DURATION] [\-K] [\-e]
+.B compactsnoop [\-h] [\-T] [\-p PID] [\-d DURATION] [\-K] [\-e]
.SH DESCRIPTION
compactsnoop traces the compact zone events, showing which processes are
allocing pages with memory compaction. This can be useful for discovering
diff --git a/man/man8/dirtop.8 b/man/man8/dirtop.8
index cc61a676..eaa0c0c4 100644
--- a/man/man8/dirtop.8
+++ b/man/man8/dirtop.8
@@ -55,19 +55,19 @@ Number of interval summaries.
.TP
Summarize block device I/O by directory, 1 second screen refresh:
#
-.B dirtop.py
+.B dirtop -d '/hdfs/uuid/*/yarn'
.TP
Don't clear the screen, and top 8 rows only:
#
-.B dirtop.py -Cr 8
+.B dirtop -d '/hdfs/uuid/*/yarn' -Cr 8
.TP
5 second summaries, 10 times only:
#
-.B dirtop.py 5 10
+.B dirtop -d '/hdfs/uuid/*/yarn' 5 10
.TP
Report read & write IOs generated in mutliple yarn and data directories:
#
-.B dirtop.py -d '/hdfs/uuid/*/yarn,/hdfs/uuid/*/data'
+.B dirtop -d '/hdfs/uuid/*/yarn,/hdfs/uuid/*/data'
.SH FIELDS
.TP
loadavg:
diff --git a/man/man8/drsnoop.8 b/man/man8/drsnoop.8
index 90ca901f..8fb3789a 100644
--- a/man/man8/drsnoop.8
+++ b/man/man8/drsnoop.8
@@ -2,7 +2,7 @@
.SH NAME
drsnoop \- Trace direct reclaim events. Uses Linux eBPF/bcc.
.SH SYNOPSIS
-.B drsnoop.py [\-h] [\-T] [\-U] [\-p PID] [\-t TID] [\-u UID] [\-d DURATION] [-n name] [-v]
+.B drsnoop [\-h] [\-T] [\-U] [\-p PID] [\-t TID] [\-u UID] [\-d DURATION] [-n name] [-v]
.SH DESCRIPTION
drsnoop trace direct reclaim events, showing which processes are allocing pages
with direct reclaiming. This can be useful for discovering when allocstall (/p-
diff --git a/man/man8/funclatency.8 b/man/man8/funclatency.8
index 9012b832..f96f6098 100644
--- a/man/man8/funclatency.8
+++ b/man/man8/funclatency.8
@@ -89,7 +89,7 @@ Print the BPF program (for debugging purposes).
.TP
Time vfs_read() for process ID 181 only:
#
-.B funclatency \-p 181 vfs_read:
+.B funclatency \-p 181 vfs_read
.TP
Time both vfs_fstat() and vfs_fstatat() calls, by use of a wildcard:
#
diff --git a/man/man8/opensnoop.8 b/man/man8/opensnoop.8
index fee83263..d1888772 100644
--- a/man/man8/opensnoop.8
+++ b/man/man8/opensnoop.8
@@ -2,7 +2,7 @@
.SH NAME
opensnoop \- Trace open() syscalls. Uses Linux eBPF/bcc.
.SH SYNOPSIS
-.B opensnoop.py [\-h] [\-T] [\-U] [\-x] [\-p PID] [\-t TID] [\-u UID]
+.B opensnoop [\-h] [\-T] [\-U] [\-x] [\-p PID] [\-t TID] [\-u UID]
[\-d DURATION] [\-n NAME] [\-e] [\-f FLAG_FILTER]
[--cgroupmap MAPPATH] [--mntnsmap MAPPATH]
.SH DESCRIPTION
diff --git a/man/man8/tcpsubnet.8 b/man/man8/tcpsubnet.8
index 525b8082..ad5f1be1 100644
--- a/man/man8/tcpsubnet.8
+++ b/man/man8/tcpsubnet.8
@@ -2,7 +2,7 @@
.SH NAME
tcpsubnet \- Summarize and aggregate IPv4 TCP traffic by subnet.
.SH SYNOPSIS
-.B tcpsubnet [\-h] [\-v] [\--ebpf] [\-J] [\-f FORMAT] [\-i INTERVAL] [subnets]
+.B tcpsubnet [\-h] [\-v] [\-J] [\-f FORMAT] [\-i INTERVAL] [subnets]
.SH DESCRIPTION
This tool summarizes and aggregates IPv4 TCP sent to the subnets
passed in argument and prints to stdout on a fixed interval.
@@ -35,9 +35,6 @@ Interval between updates, seconds (default 1).
Format output units. Supported values are bkmBKM. When using
kmKM the output will be rounded to floor.
.TP
-\--ebpf
-Prints the BPF program.
-.TP
subnets
Comma separated list of subnets. Traffic will be categorized
in theses subnets. Order matters.
diff --git a/man/man8/tcptracer.8 b/man/man8/tcptracer.8
index 59240f4b..19a6164d 100644
--- a/man/man8/tcptracer.8
+++ b/man/man8/tcptracer.8
@@ -2,7 +2,7 @@
.SH NAME
tcptracer \- Trace TCP established connections. Uses Linux eBPF/bcc.
.SH SYNOPSIS
-.B tcptracer [\-h] [\-v] [\-p PID] [\-N NETNS] [\-\-cgroupmap MAPPATH] [--mntnsmap MAPPATH] [\-4 | \-6]
+.B tcptracer [\-h] [\-v] [-t] [\-p PID] [\-N NETNS] [\-\-cgroupmap MAPPATH] [--mntnsmap MAPPATH] [\-4 | \-6]
.SH DESCRIPTION
This tool traces established TCP connections that open and close while tracing,
and prints a line of output per connect, accept and close events. This includes
@@ -23,6 +23,9 @@ Print usage message.
\-v
Print full lines, with long event type names and network namespace numbers.
.TP
+\-t
+Include timestamp on output
+.TP
\-p PID
Trace this process ID only (filtered in-kernel).
.TP
diff --git a/man/man8/trace.8 b/man/man8/trace.8
index c4417e5f..64a5e799 100644
--- a/man/man8/trace.8
+++ b/man/man8/trace.8
@@ -2,9 +2,11 @@
.SH NAME
trace \- Trace a function and print its arguments or return value, optionally evaluating a filter. Uses Linux eBPF/bcc.
.SH SYNOPSIS
-.B trace [-h] [-b BUFFER_PAGES] [-p PID] [-L TID] [--uid UID] [-v] [-Z STRING_SIZE] [-S] [-s SYM_FILE_LIST]
- [-M MAX_EVENTS] [-t] [-u] [-T] [-C] [-K] [-U] [-a] [-I header] [-A]
+.B trace [-h] [-b BUFFER_PAGES] [-p PID] [-L TID] [--uid UID] [-v] [-Z STRING_SIZE] [-S] [-M MAX_EVENTS] [-t]
+ [-u] [-T] [-C] [-c CGROUP_PATH] [-n NAME] [-f MSG_FILTER] [-B] [-s SYM_FILE_LIST] [-K] [-U] [-a]
+ [-I header] [-A]
probe [probe ...]
+
.SH DESCRIPTION
trace probes functions you specify and displays trace messages if a particular
condition is met. You can control the message format to display function
diff --git a/tools/killsnoop_example.txt b/tools/killsnoop_example.txt
index 7746f2a0..038d09c6 100644
--- a/tools/killsnoop_example.txt
+++ b/tools/killsnoop_example.txt
@@ -27,6 +27,8 @@ Trace signals issued by the kill() syscall
-h, --help show this help message and exit
-x, --failed only show failed kill syscalls
-p PID, --pid PID trace this PID only
+ -s SIGNAL, --signal SIGNAL
+ trace this signal only
examples:
./killsnoop # trace all kill() signals
--
2.38.1

View File

@ -0,0 +1,100 @@
From 2e14fbaf9105e0b504f243ffc6d7d5a16e13a2a7 Mon Sep 17 00:00:00 2001
From: Alan Maguire <alan.maguire@oracle.com>
Date: Fri, 14 Oct 2022 13:01:58 +0000
Subject: [PATCH] bcc: support building with external libbpf package and older
uapi linux/bpf.h
When building bcc with a relatively new packaged libbpf (0.8.1)
and -DCMAKE_USE_LIBBPF_PACKAGE:BOOL=TRUE, multiple compilation
failures are encountered due the fact the system uapi header
in /usr/include/linux/bpf.h is not very recent (this is often
the case for distros, which sync it via a kernel headers
package quite conservatively due to use by glibc).
With libbpf built via git submodule, the uapi header included in
the libbpf package is used, so here a similar approach is proposed
for the external package build. Instead of having to sync
another file the already present compat/linux/virtual_bpf.h
is used; we copy it to compat/linux/bpf.h (eliminating the
string prefix/suffix on first/last lines).
From there, we ensure that places that assume the presence of
the libbpf git submodule point at compat/ as a location to
find the uapi header.
Signed-off-by: Alan Maguire <alan.maguire@oracle.com>
---
examples/cpp/CMakeLists.txt | 4 ++++
introspection/CMakeLists.txt | 4 ++++
src/cc/CMakeLists.txt | 6 ++++++
tests/cc/CMakeLists.txt | 4 ++++
4 files changed, 18 insertions(+)
diff --git a/examples/cpp/CMakeLists.txt b/examples/cpp/CMakeLists.txt
index 801e6bad..8d09ae11 100644
--- a/examples/cpp/CMakeLists.txt
+++ b/examples/cpp/CMakeLists.txt
@@ -4,7 +4,11 @@
include_directories(${PROJECT_BINARY_DIR}/src/cc)
include_directories(${PROJECT_SOURCE_DIR}/src/cc)
include_directories(${PROJECT_SOURCE_DIR}/src/cc/api)
+if (CMAKE_USE_LIBBPF_PACKAGE AND LIBBPF_FOUND)
+include_directories(${PROJECT_SOURCE_DIR}/src/cc/compat)
+else()
include_directories(${PROJECT_SOURCE_DIR}/src/cc/libbpf/include/uapi)
+endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
diff --git a/introspection/CMakeLists.txt b/introspection/CMakeLists.txt
index dcbe69a3..ce2d03dc 100644
--- a/introspection/CMakeLists.txt
+++ b/introspection/CMakeLists.txt
@@ -3,7 +3,11 @@
include_directories(${PROJECT_SOURCE_DIR}/src/cc)
include_directories(${PROJECT_SOURCE_DIR}/src/cc/api)
+if (CMAKE_USE_LIBBPF_PACKAGE AND LIBBPF_FOUND)
+include_directories(${PROJECT_SOURCE_DIR}/src/cc/compat)
+else()
include_directories(${PROJECT_SOURCE_DIR}/src/cc/libbpf/include/uapi)
+endif()
option(INSTALL_INTROSPECTION "Install BPF introspection tools" ON)
option(BPS_LINK_RT "Pass -lrt to linker when linking bps tool" ON)
diff --git a/src/cc/CMakeLists.txt b/src/cc/CMakeLists.txt
index ffe8feec..c7f53530 100644
--- a/src/cc/CMakeLists.txt
+++ b/src/cc/CMakeLists.txt
@@ -15,6 +15,12 @@ endif (LIBDEBUGINFOD_FOUND)
# todo: if check for kernel version
if (CMAKE_USE_LIBBPF_PACKAGE AND LIBBPF_FOUND)
include_directories(${LIBBPF_INCLUDE_DIRS})
+ # create up-to-date linux/bpf.h from virtual_bpf.h (remove string wrapper);
+ # when libbpf is built as a submodule we use its version of linux/bpf.h
+ # so this does similar for the libbpf package, removing reliance on the
+ # system uapi header which can be out of date.
+ execute_process(COMMAND sh -c "cd ${CMAKE_CURRENT_SOURCE_DIR}/compat/linux && grep -ve '\\*\\*\\*\\*' virtual_bpf.h > bpf.h")
+ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/compat)
else()
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/libbpf/include)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/libbpf/include/uapi)
diff --git a/tests/cc/CMakeLists.txt b/tests/cc/CMakeLists.txt
index 677867d7..47056455 100644
--- a/tests/cc/CMakeLists.txt
+++ b/tests/cc/CMakeLists.txt
@@ -3,7 +3,11 @@
include_directories(${PROJECT_SOURCE_DIR}/src/cc)
include_directories(${PROJECT_SOURCE_DIR}/src/cc/api)
+if (CMAKE_USE_LIBBPF_PACKAGE AND LIBBPF_FOUND)
+include_directories(${PROJECT_SOURCE_DIR}/src/cc/compat)
+else()
include_directories(${PROJECT_SOURCE_DIR}/src/cc/libbpf/include/uapi)
+endif()
include_directories(${PROJECT_SOURCE_DIR}/tests/python/include)
add_executable(test_static test_static.c)
--
2.37.3

View File

@ -0,0 +1,64 @@
From acc8800b6f4380b6f4c7f04ee9a1263cf11deb35 Mon Sep 17 00:00:00 2001
From: Jerome Marchand <jmarchan@redhat.com>
Date: Tue, 20 Dec 2022 11:33:51 +0100
Subject: [PATCH] tools: nfsslower: fix an uninitialized struct error
Fixes the following error:
bpf: Failed to load program: Permission denied
reg type unsupported for arg#0 function trace_read_return#22
0: R1=ctx(off=0,imm=0) R10=fp0
; int trace_read_return(struct pt_regs *ctx)
0: (bf) r6 = r1 ; R1=ctx(off=0,imm=0) R6_w=ctx(off=0,imm=0)
[...]
; bpf_probe_read_kernel(&data.file, sizeof(data.file), (void *)qs.name);
75: (b7) r2 = 32 ; R2_w=32
76: (85) call bpf_probe_read_kernel#113 ; R0_w=scalar() fp-16=????mmmm fp-24=mmmmmmmm fp-32=mmmmmmmm fp-40=mmmmmmmm fp-48=mmmmmmmm
; bpf_perf_event_output(ctx, (void *)bpf_pseudo_fd(1, -2), CUR_CPU_IDENTIFIER, &data, sizeof(data));
77: (18) r2 = 0xffff9a0a42177200 ; R2_w=map_ptr(off=0,ks=4,vs=4,imm=0)
79: (bf) r4 = r10 ; R4_w=fp0 R10=fp0
; bpf_probe_read_kernel(&data.file, sizeof(data.file), (void *)qs.name);
80: (07) r4 += -104 ; R4_w=fp-104
; bpf_perf_event_output(ctx, (void *)bpf_pseudo_fd(1, -2), CUR_CPU_IDENTIFIER, &data, sizeof(data));
81: (bf) r1 = r6 ; R1_w=ctx(off=0,imm=0) R6=ctx(off=0,imm=0)
82: (18) r3 = 0xffffffff ; R3_w=4294967295
84: (b7) r5 = 96 ; R5_w=96
85: (85) call bpf_perf_event_output#25
invalid indirect read from stack R4 off -104+92 size 96
processed 82 insns (limit 1000000) max_states_per_insn 0 total_states 4 peak_states 4 mark_read 3
Traceback (most recent call last):
File "/usr/share/bcc/tools/nfsslower", line 283, in <module>
b.attach_kretprobe(event="nfs_file_read", fn_name="trace_read_return")
File "/usr/lib/python3.9/site-packages/bcc/__init__.py", line 872, in attach_kretprobe
fn = self.load_func(fn_name, BPF.KPROBE)
File "/usr/lib/python3.9/site-packages/bcc/__init__.py", line 523, in load_func
raise Exception("Failed to load BPF program %s: %s" %
Exception: Failed to load BPF program b'trace_read_return': Permission denied
---
tools/nfsslower.py | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/tools/nfsslower.py b/tools/nfsslower.py
index b5df8f19..682a3fb7 100755
--- a/tools/nfsslower.py
+++ b/tools/nfsslower.py
@@ -179,8 +179,12 @@ static int trace_exit(struct pt_regs *ctx, int type)
// populate output struct
u32 size = PT_REGS_RC(ctx);
- struct data_t data = {.type = type, .size = size, .delta_us = delta_us,
- .pid = pid};
+ struct data_t data;
+ __builtin_memset(&data, 0, sizeof(data));
+ data.type = type;
+ data.size = size;
+ data.delta_us = delta_us;
+ data.pid = pid;
data.ts_us = ts / 1000;
data.offset = valp->offset;
bpf_get_current_comm(&data.task, sizeof(data.task));
--
2.38.1

View File

@ -24,21 +24,17 @@
Name: bcc
Version: 0.24.0
Release: 4%{?dist}
Version: 0.25.0
Release: 1%{?dist}
Summary: BPF Compiler Collection (BCC)
License: ASL 2.0
URL: https://github.com/iovisor/bcc
Source0: %{url}/archive/v%{version}/%{name}-%{version}.tar.gz
Patch0: %{name}-%{version}-libbpf-tools-Allow-to-use-different-cflags-for-bpf-t.patch
Patch1: %{name}-%{version}-biolatpcts-Build-fixes-on-recent-kernels.patch
Patch2: %{name}-%{version}-tools-include-blk-mq.h-in-bio-tools.patch
Patch3: %{name}-%{version}-C9S-libpbf-version-fixes.patch
Patch4: %{name}-%{version}-Revert-libbpf-1.0-changes.patch
Patch5: %{name}-%{version}-C9S-Fix-mdflush.patch
Patch6: %{name}-%{version}-biolatency-biolatpcts-biosnoop-biotop-Build-fix-for-.patch
Patch7: %{name}-%{version}-libbpf-tools-Fix-dropped-request-rq_disk-for-kernel-.patch
Patch8: %{name}-%{version}-tools-mdflush-include-blkdev.h-instead-of-genhd.h.patch
Patch0: %%{name}-%%{version}-bcc-support-building-with-external-libbpf-package-an.patch
Patch2: %%{name}-%%{version}-Fix-bpf_pseudo_fd-type-conversion-error.patch
Patch3: %%{name}-%%{version}-Fix-clang-15-int-to-pointer-conversion-errors.patch
Patch4: %%{name}-%%{version}-Fix-some-documentation-issues-4197.patch
Patch5: %%{name}-%%{version}-tools-nfsslower-fix-an-uninitialized-struct-error.patch
# Arches will be included as upstream support is added and dependencies are
# satisfied in the respective arches
@ -60,9 +56,9 @@ BuildRequires: ncurses-devel
%if %{with lua}
BuildRequires: pkgconfig(luajit)
%endif
BuildRequires: libbpf-devel >= 0.6.0, libbpf-static >= 0.6.0
BuildRequires: libbpf-devel >= 2:0.8.0, libbpf-static >= 2:0.8.0
Requires: libbpf >= 0.6.0
Requires: libbpf >= 2:0.8.0
Requires: tar
Recommends: kernel-devel
@ -262,6 +258,10 @@ cp -a libbpf-tools/tmp-install/bin/* %{buildroot}/%{_sbindir}/
%endif
%changelog
* Tue Dec 20 2022 Jerome Marchand <jmarchan@redhat.com> - 0.25.0-1
- Rebase to v0.25.0
- Misc documentation and man pages fixes
* Tue Aug 23 2022 Jerome Marchand <jmarchan@redhat.com> - 0.24.1-4
- Fix mdflush tool (rhbz#2108001)

View File

@ -1 +1 @@
SHA512 (bcc-0.24.0.tar.gz) = 951672e3a8e5ad56eedf513477317ec3d3b4cf2d594bbfce20f3d19ddf7ce255e9dcfc69d9b05bb765a16e769c8e42d7c57071ddb86fb32437f527d3d25d19b6
SHA512 (bcc-0.25.0.tar.gz) = 9f71f6c21d1f66054985562168d5848352f5029383e9c65c907a6f044258bc23df842cc65db20bfaaf33789e69c9b8e7b606a32dc882cbdf093b71768c8b521d