diff --git a/ebpf-fix-collect-iodump.patch b/ebpf-fix-collect-iodump.patch new file mode 100644 index 0000000000000000000000000000000000000000..3eadc847e20685a0969cd6cae31f28d81953995b --- /dev/null +++ b/ebpf-fix-collect-iodump.patch @@ -0,0 +1,822 @@ +From 3e89cc2ae3f4c62b3b7141bfae2e432f54775b63 Mon Sep 17 00:00:00 2001 +From: zhangnan +Date: Fri, 11 Oct 2024 22:50:07 +0800 +Subject: [PATCH] fix xxx bug + +--- + src/c/ebpf_collector/ebpf_collector.bpf.c | 292 +++++++++++----------- + src/c/ebpf_collector/ebpf_collector.c | 104 +++++++- + src/c/ebpf_collector/ebpf_collector.h | 18 +- + 3 files changed, 259 insertions(+), 155 deletions(-) + +diff --git a/src/c/ebpf_collector/ebpf_collector.bpf.c b/src/c/ebpf_collector/ebpf_collector.bpf.c +index 28cdde2..870a677 100644 +--- a/src/c/ebpf_collector/ebpf_collector.bpf.c ++++ b/src/c/ebpf_collector/ebpf_collector.bpf.c +@@ -92,6 +92,35 @@ struct bpf_map_def SEC("maps") tag_args = { + .max_entries = 1000, + }; + ++struct bpf_map_def SEC("maps") blk_res_2 = { ++ .type = BPF_MAP_TYPE_HASH, ++ .key_size = sizeof(u64), ++ .value_size = sizeof(struct time_range_io_count), ++ .max_entries = MAX_IO_TIME, ++}; ++ ++struct bpf_map_def SEC("maps") bio_res_2 = { ++ .type = BPF_MAP_TYPE_HASH, ++ .key_size = sizeof(u64), ++ .value_size = sizeof(struct time_range_io_count), ++ .max_entries = MAX_IO_TIME, ++}; ++ ++struct bpf_map_def SEC("maps") wbt_res_2 = { ++ .type = BPF_MAP_TYPE_HASH, ++ .key_size = sizeof(u64), ++ .value_size = sizeof(struct time_range_io_count), ++ .max_entries = MAX_IO_TIME, ++}; ++ ++struct bpf_map_def SEC("maps") tag_res_2 = { ++ .type = BPF_MAP_TYPE_HASH, ++ .key_size = sizeof(u64), ++ .value_size = sizeof(struct time_range_io_count), ++ .max_entries = MAX_IO_TIME, ++}; ++ ++ + struct blk_mq_alloc_data { + /* input parameter */ + struct request_queue *q; +@@ -148,39 +177,12 @@ static __always_inline void blk_fill_rwbs(char *rwbs, unsigned int op) + } + } + +-void update_new_data_in_start(struct stage_data *new_data, struct update_params *params) { +- blk_fill_rwbs(new_data->io_type, params->cmd_flags); +- if (new_data->bucket[params->update_bucket].start_range == params->curr_start_range){ +- new_data->bucket[params->update_bucket].io_count += 1; +- } else { +- new_data->bucket[MAX_BUCKETS].io_count += new_data->bucket[params->update_bucket].io_count; +- new_data->bucket[params->update_bucket].io_count = 1; +- new_data->bucket[params->update_bucket].start_range = params->curr_start_range; +- } +-} +- + void update_curr_data_in_start(struct stage_data *curr_data, struct update_params *params) { + if (curr_data && params) { + curr_data->start_count += 1; + curr_data->major = params->major; + curr_data->first_minor = params->first_minor; + blk_fill_rwbs(curr_data->io_type, params->cmd_flags); +- if (curr_data->bucket[params->update_bucket].start_range == params->curr_start_range) { +- curr_data->bucket[params->update_bucket].io_count += 1; +- } else { +- curr_data->bucket[MAX_BUCKETS].io_count += curr_data->bucket[params->update_bucket].io_count; +- curr_data->bucket[params->update_bucket].io_count = 1; +- } +- curr_data->bucket[params->update_bucket].start_range = params->curr_start_range; +- } +-} +- +-void update_new_data_in_finish(struct stage_data *new_data, struct update_params *params) { +- blk_fill_rwbs(new_data->io_type, params->cmd_flags); +- if (new_data->bucket[params->update_bucket].start_range == params->curr_start_range){ +- new_data->bucket[params->update_bucket].io_count = (new_data->bucket[params->update_bucket].io_count > 1) ? new_data->bucket[params->update_bucket].io_count - 1 : 0; +- } else { +- new_data->bucket[MAX_BUCKETS].io_count = (new_data->bucket[MAX_BUCKETS].io_count > 1) ? new_data->bucket[MAX_BUCKETS].io_count - 1 : 0; + } + } + +@@ -204,7 +206,6 @@ static void init_io_counter(struct io_counter *counterp, int major, int first_mi + } + } + +- + u32 find_matching_tag_1_keys(int major, int minor) { + u32 key = 0; + struct stage_data *curr_data = bpf_map_lookup_elem(&tag_res, &key); +@@ -705,6 +706,7 @@ u32 find_matching_wbt_5_keys(int major, int minor) { + return MAP_SIZE + 1; + } + ++// start rq_driver + SEC("kprobe/blk_mq_start_request") + int kprobe_blk_mq_start_request(struct pt_regs *regs) + { +@@ -742,14 +744,12 @@ int kprobe_blk_mq_start_request(struct pt_regs *regs) + if (err) + return 0; + +- u64 curr_start_range = zero.start_time / THRESHOLD / MAX_BUCKETS; +- u64 update_bucket = curr_start_range % MAX_BUCKETS; ++ u64 curr_start_range = zero.start_time / THRESHOLD; + + struct update_params params = { + .major = major, + .first_minor = first_minor, + .cmd_flags = cmd_flags, +- .update_bucket = update_bucket, + .curr_start_range = curr_start_range, + }; + +@@ -764,20 +764,28 @@ int kprobe_blk_mq_start_request(struct pt_regs *regs) + .major = major, + .first_minor = first_minor, + .io_type = "", +- .bucket = { +- [0] = {.start_range = 0, .io_count = 0}, +- [1] = {.start_range = 0, .io_count = 0}, +- }, + }; +- update_new_data_in_start(&new_data, ¶ms); ++ blk_fill_rwbs(new_data.io_type, cmd_flags); + bpf_map_update_elem(&blk_res, &key, &new_data, 0); + } else { + update_curr_data_in_start(curr_data, ¶ms); + } + ++ struct time_range_io_count *curr_data_time_range; ++ curr_data_time_range = bpf_map_lookup_elem(&blk_res_2, &curr_start_range); ++ if (curr_data_time_range == NULL) { ++ struct time_range_io_count new_data = { .count = {0} }; ++ bpf_map_update_elem(&blk_res_2, &curr_start_range, &new_data, 0); ++ } else { ++ if (key < MAP_SIZE) { ++ __sync_fetch_and_add(&curr_data_time_range->count[key], 1); ++ } ++ } ++ + return 0; + } + ++// finish rq_driver + SEC("kprobe/blk_mq_free_request") + int kprobe_blk_mq_free_request(struct pt_regs *regs) + { +@@ -811,15 +819,13 @@ int kprobe_blk_mq_free_request(struct pt_regs *regs) + return 0; + } + +- u64 duration = bpf_ktime_get_ns() - counterp->start_time; +- u64 curr_start_range = counterp->start_time / THRESHOLD / MAX_BUCKETS; +- u64 update_bucket = curr_start_range % MAX_BUCKETS; ++ u64 duration = bpf_ktime_get_ns() - counterp->start_time; ++ u64 curr_start_range = counterp->start_time / THRESHOLD; + + struct update_params params = { + .major = major, + .first_minor = first_minor, + .cmd_flags = cmd_flags, +- .update_bucket = update_bucket, + .curr_start_range = curr_start_range, + }; + +@@ -834,12 +840,8 @@ int kprobe_blk_mq_free_request(struct pt_regs *regs) + .major = major, + .first_minor = first_minor, + .io_type = "", +- .bucket = { +- [0] = {.start_range = 0, .io_count = 0}, +- [1] = {.start_range = 0, .io_count = 0}, +- }, + }; +- update_new_data_in_finish(&new_data, ¶ms); ++ blk_fill_rwbs(new_data.io_type, cmd_flags); + bpf_map_update_elem(&blk_res, &key, &new_data, 0); + } else if (curr_data == NULL) { + struct stage_data new_data = { +@@ -850,28 +852,30 @@ int kprobe_blk_mq_free_request(struct pt_regs *regs) + .major = major, + .first_minor = first_minor, + .io_type = "", +- .bucket = { +- [0] = {.start_range = 0, .io_count = 0}, +- [1] = {.start_range = 0, .io_count = 0}, +- }, + }; +- update_new_data_in_finish(&new_data, ¶ms); ++ blk_fill_rwbs(new_data.io_type, cmd_flags); + bpf_map_update_elem(&blk_res, &key, &new_data, 0); + } else { +- if (curr_data->bucket[update_bucket].start_range == curr_start_range) { +- curr_data->bucket[update_bucket].io_count = (curr_data->bucket[update_bucket].io_count > 1) ? curr_data->bucket[update_bucket].io_count - 1 : 0; +- } else { +- curr_data->bucket[MAX_BUCKETS].io_count = (curr_data->bucket[MAX_BUCKETS].io_count > 1) ? curr_data->bucket[MAX_BUCKETS].io_count - 1 : 0; +- +- } + curr_data->duration += duration; + update_curr_data_in_finish(curr_data, ¶ms, &duration); + } + ++ struct time_range_io_count *curr_data_time_range; ++ curr_data_time_range = bpf_map_lookup_elem(&blk_res_2, &curr_start_range); ++ if (curr_data_time_range == NULL) { ++ struct time_range_io_count new_data = { .count = {0} }; ++ bpf_map_update_elem(&blk_res_2, &curr_start_range, &new_data, 0); ++ } else { ++ if (key < MAP_SIZE && curr_data_time_range->count[key] > 0) { ++ __sync_fetch_and_add(&curr_data_time_range->count[key], -1); ++ } ++ } ++ + bpf_map_delete_elem(&blk_map, &rq); + return 0; + } + ++// start bio + SEC("kprobe/blk_mq_make_request") + int kprobe_blk_mq_make_request(struct pt_regs *regs) + { +@@ -909,20 +913,18 @@ int kprobe_blk_mq_make_request(struct pt_regs *regs) + if (err && err != -EEXIST) + return 0; + +- u64 curr_start_range = zero.start_time / THRESHOLD / MAX_BUCKETS; +- u64 update_bucket = curr_start_range % MAX_BUCKETS; ++ u64 curr_start_range = zero.start_time / THRESHOLD; + + struct update_params params = { + .major = major, + .first_minor = first_minor, + .cmd_flags = cmd_flags, +- .update_bucket = update_bucket, + .curr_start_range = curr_start_range, + }; + + struct stage_data *curr_data; + curr_data = bpf_map_lookup_elem(&bio_res, &key); +- if (curr_data == NULL) { ++ if (curr_data == NULL) { + struct stage_data new_data = { + .start_count = 1, + .finish_count = 0, +@@ -931,20 +933,28 @@ int kprobe_blk_mq_make_request(struct pt_regs *regs) + .major = major, + .first_minor = first_minor, + .io_type = "", +- .bucket = { +- [0] = {.start_range = 0, .io_count = 0}, +- [1] = {.start_range = 0, .io_count = 0}, +- }, + }; +- update_new_data_in_start(&new_data, ¶ms); ++ blk_fill_rwbs(new_data.io_type, cmd_flags); + bpf_map_update_elem(&bio_res, &key, &new_data, 0); +- } else { ++ } else { + update_curr_data_in_start(curr_data, ¶ms); + } + ++ struct time_range_io_count *curr_data_time_range; ++ curr_data_time_range = bpf_map_lookup_elem(&bio_res_2, &curr_start_range); ++ if (curr_data_time_range == NULL) { ++ struct time_range_io_count new_data = { .count = {0} }; ++ bpf_map_update_elem(&bio_res_2, &curr_start_range, &new_data, 0); ++ } else { ++ if (key < MAP_SIZE) { ++ __sync_fetch_and_add(&curr_data_time_range->count[key], 1); ++ } ++ } ++ + return 0; + } + ++// finish bio + SEC("kprobe/bio_endio") + int kprobe_bio_endio(struct pt_regs *regs) + { +@@ -982,20 +992,18 @@ int kprobe_bio_endio(struct pt_regs *regs) + delete_map = &bio_map; + + u64 duration = bpf_ktime_get_ns() - counterp->start_time; +- u64 curr_start_range = counterp->start_time / THRESHOLD / MAX_BUCKETS; +- u64 update_bucket = curr_start_range % MAX_BUCKETS; ++ u64 curr_start_range = counterp->start_time / THRESHOLD; + + struct update_params params = { + .major = major, + .first_minor = first_minor, + .cmd_flags = cmd_flags, +- .update_bucket = update_bucket, + .curr_start_range = curr_start_range, + }; + + struct stage_data *curr_data; + curr_data = bpf_map_lookup_elem(&bio_res, &key); +- if (curr_data == NULL && duration > DURATION_THRESHOLD) { ++ if (curr_data == NULL && duration > DURATION_THRESHOLD) { + struct stage_data new_data = { + .start_count = 1, + .finish_count = 1, +@@ -1004,14 +1012,10 @@ int kprobe_bio_endio(struct pt_regs *regs) + .major = major, + .first_minor = first_minor, + .io_type = "", +- .bucket = { +- [0] = {.start_range = 0, .io_count = 0}, +- [1] = {.start_range = 0, .io_count = 0}, +- }, + }; +- update_new_data_in_finish(&new_data, ¶ms); ++ blk_fill_rwbs(new_data.io_type, cmd_flags); + bpf_map_update_elem(&bio_res, &key, &new_data, 0); +- } else if (curr_data == NULL) { ++ } else if (curr_data == NULL) { + struct stage_data new_data = { + .start_count = 1, + .finish_count = 1, +@@ -1020,28 +1024,30 @@ int kprobe_bio_endio(struct pt_regs *regs) + .major = major, + .first_minor = first_minor, + .io_type = "", +- .bucket = { +- [0] = {.start_range = 0, .io_count = 0}, +- [1] = {.start_range = 0, .io_count = 0}, +- }, + }; +- update_new_data_in_finish(&new_data, ¶ms); ++ blk_fill_rwbs(new_data.io_type, cmd_flags); + bpf_map_update_elem(&bio_res, &key, &new_data, 0); + } else { +- if (curr_data->bucket[update_bucket].start_range == curr_start_range) { +- curr_data->bucket[update_bucket].io_count = (curr_data->bucket[update_bucket].io_count > 1) ? curr_data->bucket[update_bucket].io_count - 1 : 0; +- } else { +- curr_data->bucket[MAX_BUCKETS].io_count = (curr_data->bucket[MAX_BUCKETS].io_count > 1) ? curr_data->bucket[MAX_BUCKETS].io_count - 1 : 0; +- +- } + curr_data->duration += duration; + update_curr_data_in_finish(curr_data, ¶ms, &duration); + } + ++ struct time_range_io_count *curr_data_time_range; ++ curr_data_time_range = bpf_map_lookup_elem(&bio_res_2, &curr_start_range); ++ if (curr_data_time_range == NULL) { ++ struct time_range_io_count new_data = { .count = {0} }; ++ bpf_map_update_elem(&bio_res_2, &curr_start_range, &new_data, 0); ++ } else { ++ if (key < MAP_SIZE && curr_data_time_range->count[key] > 0) { ++ __sync_fetch_and_add(&curr_data_time_range->count[key], -1); ++ } ++ } ++ + bpf_map_delete_elem(delete_map, &bio); + return 0; + } + ++// start wbt + SEC("kprobe/wbt_wait") + int kprobe_wbt_wait(struct pt_regs *regs) + { +@@ -1082,14 +1088,12 @@ int kprobe_wbt_wait(struct pt_regs *regs) + if (err) + return 0; + +- u64 curr_start_range = zero.start_time / THRESHOLD / MAX_BUCKETS; +- u64 update_bucket = curr_start_range % MAX_BUCKETS; ++ u64 curr_start_range = zero.start_time / THRESHOLD; + + struct update_params params = { + .major = major, + .first_minor = first_minor, + .cmd_flags = cmd_flags, +- .update_bucket = update_bucket, + .curr_start_range = curr_start_range, + }; + +@@ -1104,20 +1108,28 @@ int kprobe_wbt_wait(struct pt_regs *regs) + .major = major, + .first_minor = first_minor, + .io_type = "", +- .bucket = { +- [0] = {.start_range = 0, .io_count = 0}, +- [1] = {.start_range = 0, .io_count = 0}, +- }, + }; +- update_new_data_in_start(&new_data, ¶ms); ++ blk_fill_rwbs(new_data.io_type, cmd_flags); + bpf_map_update_elem(&wbt_res, &key, &new_data, 0); + } else { + update_curr_data_in_start(curr_data, ¶ms); + } + ++ struct time_range_io_count *curr_data_time_range; ++ curr_data_time_range = bpf_map_lookup_elem(&wbt_res_2, &curr_start_range); ++ if (curr_data_time_range == NULL) { ++ struct time_range_io_count new_data = { .count = {0} }; ++ bpf_map_update_elem(&wbt_res_2, &curr_start_range, &new_data, 0); ++ } else { ++ if (key < MAP_SIZE) { ++ __sync_fetch_and_add(&curr_data_time_range->count[key], 1); ++ } ++ } ++ + return 0; + } + ++// finish wbt + SEC("kretprobe/wbt_wait") + int kretprobe_wbt_wait(struct pt_regs *regs) + { +@@ -1159,14 +1171,12 @@ int kretprobe_wbt_wait(struct pt_regs *regs) + return 0; + + u64 duration = bpf_ktime_get_ns() - counterp->start_time; +- u64 curr_start_range = counterp->start_time / THRESHOLD / MAX_BUCKETS; +- u64 update_bucket = curr_start_range % MAX_BUCKETS; ++ u64 curr_start_range = counterp->start_time / THRESHOLD; + + struct update_params params = { + .major = major, + .first_minor = first_minor, + .cmd_flags = cmd_flags, +- .update_bucket = update_bucket, + .curr_start_range = curr_start_range, + }; + +@@ -1181,12 +1191,8 @@ int kretprobe_wbt_wait(struct pt_regs *regs) + .major = major, + .first_minor = first_minor, + .io_type = "", +- .bucket = { +- [0] = {.start_range = 0, .io_count = 0}, +- [1] = {.start_range = 0, .io_count = 0}, +- }, + }; +- update_new_data_in_finish(&new_data, ¶ms); ++ blk_fill_rwbs(new_data.io_type, cmd_flags); + bpf_map_update_elem(&wbt_res, &key, &new_data, 0); + } else if (curr_data == NULL) { + struct stage_data new_data = { +@@ -1197,29 +1203,31 @@ int kretprobe_wbt_wait(struct pt_regs *regs) + .io_type = "", + .major = major, + .first_minor = first_minor, +- .bucket = { +- [0] = {.start_range = 0, .io_count = 0}, +- [1] = {.start_range = 0, .io_count = 0}, +- }, + }; +- update_new_data_in_finish(&new_data, ¶ms); ++ blk_fill_rwbs(new_data.io_type, cmd_flags); + bpf_map_update_elem(&wbt_res, &key, &new_data, 0); + } else { +- if (curr_data->bucket[update_bucket].start_range == curr_start_range) { +- curr_data->bucket[update_bucket].io_count = (curr_data->bucket[update_bucket].io_count > 1) ? curr_data->bucket[update_bucket].io_count - 1 : 0; +- } else { +- curr_data->bucket[MAX_BUCKETS].io_count = (curr_data->bucket[MAX_BUCKETS].io_count > 1) ? curr_data->bucket[MAX_BUCKETS].io_count - 1 : 0; +- +- } + curr_data->duration += duration; + update_curr_data_in_finish(curr_data, ¶ms, &duration); + } + ++ struct time_range_io_count *curr_data_time_range; ++ curr_data_time_range = bpf_map_lookup_elem(&wbt_res_2, &curr_start_range); ++ if (curr_data_time_range == NULL) { ++ struct time_range_io_count new_data = { .count = {0} }; ++ bpf_map_update_elem(&wbt_res_2, &curr_start_range, &new_data, 0); ++ } else { ++ if (key < MAP_SIZE && curr_data_time_range->count[key] > 0) { ++ __sync_fetch_and_add(&curr_data_time_range->count[key], -1); ++ } ++ } ++ + bpf_map_delete_elem(&wbt_map, &wbtkey); + bpf_map_delete_elem(&wbt_args, &wbtkey); + return 0; + } + ++// start get_tag + SEC("kprobe/blk_mq_get_tag") + int kprobe_blk_mq_get_tag(struct pt_regs *regs) + { +@@ -1262,14 +1270,12 @@ int kprobe_blk_mq_get_tag(struct pt_regs *regs) + if (err) + return 0; + +- u64 curr_start_range = zero.start_time / THRESHOLD / MAX_BUCKETS; +- u64 update_bucket = curr_start_range % MAX_BUCKETS; ++ u64 curr_start_range = zero.start_time / THRESHOLD; + + struct update_params params = { + .major = major, + .first_minor = first_minor, + .cmd_flags = cmd_flags, +- .update_bucket = update_bucket, + .curr_start_range = curr_start_range, + }; + +@@ -1284,20 +1290,28 @@ int kprobe_blk_mq_get_tag(struct pt_regs *regs) + .major = major, + .first_minor = first_minor, + .io_type = "", +- .bucket = { +- [0] = {.start_range = 0, .io_count = 0}, +- [1] = {.start_range = 0, .io_count = 0}, +- }, + }; +- update_new_data_in_start(&new_data, ¶ms); ++ blk_fill_rwbs(new_data.io_type, cmd_flags); + bpf_map_update_elem(&tag_res, &key, &new_data, 0); + } else { + update_curr_data_in_start(curr_data, ¶ms); + } + ++ struct time_range_io_count *curr_data_time_range; ++ curr_data_time_range = bpf_map_lookup_elem(&tag_res_2, &curr_start_range); ++ if (curr_data_time_range == NULL) { ++ struct time_range_io_count new_data = { .count = {0} }; ++ bpf_map_update_elem(&tag_res_2, &curr_start_range, &new_data, 0); ++ } else { ++ if (key < MAP_SIZE) { ++ __sync_fetch_and_add(&curr_data_time_range->count[key], 1); ++ } ++ } ++ + return 0; + } + ++// finish get_tag + SEC("kretprobe/blk_mq_get_tag") + int kretprobe_blk_mq_get_tag(struct pt_regs *regs) + { +@@ -1343,14 +1357,12 @@ int kretprobe_blk_mq_get_tag(struct pt_regs *regs) + return 0; + + u64 duration = bpf_ktime_get_ns() - counterp->start_time; +- u64 curr_start_range = counterp->start_time / THRESHOLD / MAX_BUCKETS; +- u64 update_bucket = curr_start_range % MAX_BUCKETS; ++ u64 curr_start_range = counterp->start_time / THRESHOLD; + + struct update_params params = { + .major = major, + .first_minor = first_minor, + .cmd_flags = cmd_flags, +- .update_bucket = update_bucket, + .curr_start_range = curr_start_range, + }; + +@@ -1365,12 +1377,8 @@ int kretprobe_blk_mq_get_tag(struct pt_regs *regs) + .major = major, + .first_minor = first_minor, + .io_type = "", +- .bucket = { +- [0] = {.start_range = 0, .io_count = 0}, +- [1] = {.start_range = 0, .io_count = 0}, +- }, + }; +- update_new_data_in_finish(&new_data, ¶ms); ++ blk_fill_rwbs(new_data.io_type, cmd_flags); + bpf_map_update_elem(&tag_res, &key, &new_data, 0); + } else if (curr_data == NULL) { + struct stage_data new_data = { +@@ -1381,23 +1389,25 @@ int kretprobe_blk_mq_get_tag(struct pt_regs *regs) + .major = major, + .first_minor = first_minor, + .io_type = "", +- .bucket = { +- [0] = {.start_range = 0, .io_count = 0}, +- [1] = {.start_range = 0, .io_count = 0}, +- }, + }; +- update_new_data_in_finish(&new_data, ¶ms); ++ blk_fill_rwbs(new_data.io_type, cmd_flags); + bpf_map_update_elem(&tag_res, &key, &new_data, 0); + } else { +- if (curr_data->bucket[update_bucket].start_range == curr_start_range) { +- curr_data->bucket[update_bucket].io_count = (curr_data->bucket[update_bucket].io_count > 1) ? curr_data->bucket[update_bucket].io_count - 1 : 0; +- } else { +- curr_data->bucket[MAX_BUCKETS].io_count = (curr_data->bucket[MAX_BUCKETS].io_count > 1) ? curr_data->bucket[MAX_BUCKETS].io_count - 1 : 0; +- +- } + curr_data->duration += duration; + update_curr_data_in_finish(curr_data, ¶ms, &duration); + } ++ ++ struct time_range_io_count *curr_data_time_range; ++ curr_data_time_range = bpf_map_lookup_elem(&tag_res_2, &curr_start_range); ++ if (curr_data_time_range == NULL) { ++ struct time_range_io_count new_data = { .count = {0} }; ++ bpf_map_update_elem(&tag_res_2, &curr_start_range, &new_data, 0); ++ } else { ++ if (key < MAP_SIZE && curr_data_time_range->count[key] > 0) { ++ __sync_fetch_and_add(&curr_data_time_range->count[key], -1); ++ } ++ } ++ + bpf_map_delete_elem(&tag_map, &tagkey); + bpf_map_delete_elem(&tag_args, &tagkey); + return 0; +diff --git a/src/c/ebpf_collector/ebpf_collector.c b/src/c/ebpf_collector/ebpf_collector.c +index a949ae8..bd98bb7 100644 +--- a/src/c/ebpf_collector/ebpf_collector.c ++++ b/src/c/ebpf_collector/ebpf_collector.c +@@ -30,6 +30,10 @@ + #define WBT_RES (map_fd[5]) + #define TAG_MAP (map_fd[7]) + #define TAG_RES (map_fd[8]) ++#define BLK_RES_2 (map_fd[10]) ++#define BIO_RES_2 (map_fd[11]) ++#define WBT_RES_2 (map_fd[12]) ++#define TAG_RES_2 (map_fd[13]) + #define BPF_FILE "/usr/lib/ebpf_collector.bpf.o" + + typedef struct { +@@ -115,14 +119,103 @@ char* find_device_name(dev_t dev) { + + static int print_map_res(struct bpf_map *map_res, char *stage, int *map_size) + { ++ int err; + struct stage_data counter; +- int key = 0; ++ struct time_range_io_count time_count; ++ int key = 0; ++ int io_dump[MAP_SIZE] = {0}; ++ u32 io_dump_key = 0, io_dump_next_key = 0; + + struct sysinfo info; + sysinfo(&info); + ++ if (strcmp(stage, "bio") == 0) { ++ while (bpf_map_get_next_key(BIO_RES_2, &io_dump_key, &io_dump_next_key) == 0) { ++ err = bpf_map_lookup_elem(BIO_RES_2, &io_dump_next_key, &time_count); ++ if (err < 0) { ++ fprintf(stderr, "failed to lookup %s io dump: %d\n", stage, err); ++ continue;; ++ } ++ io_dump_key = io_dump_next_key; ++ if ((info.uptime - io_dump_key) > 2) { ++ int isempty = 1; ++ for (key = 0; key < map_size; key++){ ++ if (time_count.count[key] > 0) { ++ io_dump[key] += time_count.count[key]; ++ isempty = 0; ++ } ++ } ++ if (isempty || (info.uptime - io_dump_key) > IO_DUMP_THRESHOLD) { ++ bpf_map_delete_elem(BIO_RES_2, &io_dump_next_key); ++ } ++ } ++ } ++ } else if (strcmp(stage, "rq_driver") == 0) { ++ while (bpf_map_get_next_key(BLK_RES_2, &io_dump_key, &io_dump_next_key) == 0) { ++ err = bpf_map_lookup_elem(BLK_RES_2, &io_dump_next_key, &time_count); ++ if (err < 0) { ++ fprintf(stderr, "failed to lookup %s io dump: %d\n", stage, err); ++ continue;; ++ } ++ io_dump_key = io_dump_next_key; ++ if ((info.uptime - io_dump_key) > 2) { ++ int isempty = 1; ++ for (key = 0; key < map_size; key++){ ++ if (time_count.count[key] > 0) { ++ io_dump[key] += time_count.count[key]; ++ isempty = 0; ++ } ++ } ++ if (isempty || (info.uptime - io_dump_key) > IO_DUMP_THRESHOLD) { ++ bpf_map_delete_elem(BLK_RES_2, &io_dump_next_key); ++ } ++ } ++ } ++ } else if (strcmp(stage, "wbt") == 0) { ++ while (bpf_map_get_next_key(WBT_RES_2, &io_dump_key, &io_dump_next_key) == 0) { ++ err = bpf_map_lookup_elem(WBT_RES_2, &io_dump_next_key, &time_count); ++ if (err < 0) { ++ fprintf(stderr, "failed to lookup %s io dump: %d\n", stage, err); ++ continue;; ++ } ++ io_dump_key = io_dump_next_key; ++ if ((info.uptime - io_dump_key) > 2) { ++ int isempty = 1; ++ for (key = 0; key < map_size; key++){ ++ if (time_count.count[key] > 0) { ++ io_dump[key] += time_count.count[key]; ++ isempty = 0; ++ } ++ } ++ if (isempty || (info.uptime - io_dump_key) > IO_DUMP_THRESHOLD) { ++ bpf_map_delete_elem(WBT_RES_2, &io_dump_next_key); ++ } ++ } ++ } ++ } else { ++ while (bpf_map_get_next_key(TAG_RES_2, &io_dump_key, &io_dump_next_key) == 0) { ++ err = bpf_map_lookup_elem(TAG_RES_2, &io_dump_next_key, &time_count); ++ if (err < 0) { ++ fprintf(stderr, "failed to lookup %s io dump: %d\n", stage, err); ++ continue;; ++ } ++ io_dump_key = io_dump_next_key; ++ if ((info.uptime - io_dump_key) > 2) { ++ int isempty = 1; ++ for (key = 0; key < map_size; key++){ ++ if (time_count.count[key] > 0) { ++ io_dump[key] += time_count.count[key]; ++ isempty = 0; ++ } ++ } ++ if (isempty || (info.uptime - io_dump_key) > IO_DUMP_THRESHOLD) { ++ bpf_map_delete_elem(TAG_RES_2, &io_dump_next_key); ++ } ++ } ++ } ++ } ++ + for (key = 0; key < map_size; key++) { +- int err; + err = bpf_map_lookup_elem(map_res, &key, &counter); + if (err < 0) { + fprintf(stderr, "failed to lookup %s map_res: %d\n", stage, err); +@@ -141,11 +234,11 @@ static int print_map_res(struct bpf_map *map_res, char *stage, int *map_size) + dev_t dev = makedev(major, first_minor); + char *device_name = find_device_name(dev); + if (device_name && io_type) { +- printf("%-7s %10llu %10llu %u %c %s\n", ++ printf("%-7s %10llu %10llu %d %c %s\n", + stage, + counter.finish_count, + counter.duration, +- counter.bucket[MAX_BUCKETS].io_count, ++ io_dump[key], + io_type, + device_name + ); +@@ -158,8 +251,8 @@ static int print_map_res(struct bpf_map *map_res, char *stage, int *map_size) + + int init_map(int *map_fd, const char *map_name, int *map_size, DeviceInfo *devices) { + struct stage_data init_data = {0}; ++ + memset(init_data.io_type, 0, sizeof(init_data.io_type)); +- memset(init_data.bucket, 0, sizeof(init_data.bucket)); + + for (int i = 0; i < map_size; i++) { + init_data.major = devices[i].major; +@@ -268,3 +361,4 @@ int main(int argc, char **argv) { + + return -err; + } ++ +diff --git a/src/c/ebpf_collector/ebpf_collector.h b/src/c/ebpf_collector/ebpf_collector.h +index dca04d8..fcebc93 100644 +--- a/src/c/ebpf_collector/ebpf_collector.h ++++ b/src/c/ebpf_collector/ebpf_collector.h +@@ -10,7 +10,8 @@ + typedef long long unsigned int u64; + typedef unsigned int u32; + +-#define MAX_BUCKETS 1 ++#define MAX_IO_TIME 130 ++#define IO_DUMP_THRESHOLD 120 + #define THRESHOLD 1000000000 + #define DURATION_THRESHOLD 500000000 + +@@ -29,7 +30,7 @@ typedef unsigned int u32; + #define REQ_OP_DISCARD 3 + #define REQ_OP_SECURE_ERASE 5 + #define REQ_OP_WRITE_SAME 7 +-#define MAP_SIZE 128 ++#define MAP_SIZE 15 + + enum stage_type { + BIO=0, +@@ -42,11 +43,6 @@ enum stage_type { + MAX_STAGE_TYPE, + }; + +-struct time_bucket { +- u64 start_range; +- u32 io_count; +-}; +- + struct stage_data { + u64 start_count; + u64 finish_count; +@@ -55,7 +51,6 @@ struct stage_data { + int major; + int first_minor; + char io_type[RWBS_LEN]; +- struct time_bucket bucket[MAX_BUCKETS+1]; + }; + + struct io_counter { +@@ -70,8 +65,13 @@ struct update_params { + int major; + int first_minor; + unsigned int cmd_flags; +- u64 update_bucket; + u64 curr_start_range; + }; + ++struct time_range_io_count ++{ ++ u32 count[MAP_SIZE]; ++}; ++ + #endif /* __EBPFCOLLECTOR_H */ ++ +-- +2.33.0 + diff --git a/sysSentry.spec b/sysSentry.spec index 7776e90586c0110a32bd928a369777b68f8bae01..c5a5068eb61303e77713057ecafeb086b1e70aa9 100644 --- a/sysSentry.spec +++ b/sysSentry.spec @@ -4,7 +4,7 @@ Summary: System Inspection Framework Name: sysSentry Version: 1.0.2 -Release: 35 +Release: 36 License: Mulan PSL v2 Group: System Environment/Daemons Source0: https://gitee.com/openeuler/sysSentry/releases/download/v%{version}/%{name}-%{version}.tar.gz @@ -50,6 +50,7 @@ Patch37: fix-xalarm_Report-function-not-refuse-alarm-msg-exce.patch Patch38: fix-xalarm_upgrade-not-return-val-and-fail-when-thre.patch Patch39: add-log-for-xalarm-when-sending-msg-and-clean-invali.patch Patch40: add-xalarm-cleanup-invalid-server-socket-peroidly.patch +Patch41: ebpf-fix-collect-iodump.patch BuildRequires: cmake gcc-c++ BuildRequires: python3 python3-setuptools @@ -304,6 +305,12 @@ rm -rf %{buildroot} %attr(0550,root,root) %{python3_sitelib}/sentryPlugins/ai_block_io %changelog +* Fri Oct 11 2024 zhangnan - 1.0.2-36 +- Type:bugfix +- CVE:NA +- SUG:NA +- DESC:fix ebpf collect iodump + * Fri Oct 11 2024 caixiaomeng - 1.0.2-35 - Type:bugfix - CVE:NA