diff --git a/daemon/CMakeLists.txt b/daemon/CMakeLists.txt index 077dae00..f68660d5 100644 --- a/daemon/CMakeLists.txt +++ b/daemon/CMakeLists.txt @@ -43,4 +43,6 @@ set_property(TARGET libbpftime_daemon PROPERTY CXX_STANDARD 20) add_dependencies(bpftime_daemon libbpftime_daemon) target_link_libraries(bpftime_daemon PRIVATE libbpftime_daemon) +install(TARGETS bpftime_daemon CONFIGURATIONS Release Debug DESTINATION ~/.bpftime) + add_subdirectory(test) diff --git a/daemon/README.md b/daemon/README.md index c3661801..8ed9e538 100644 --- a/daemon/README.md +++ b/daemon/README.md @@ -2,3 +2,44 @@ The bpftime daemon is a tool to trace and replay eBPF related events. It's similar to our syscall server but run together with kernel eBPF. + +## Run daemon + +```console +$ sudo SPDLOG_LEVEL=Debug build/daemon/bpftime_daemon +[2023-10-24 11:07:13.143] [info] Global shm constructed. shm_open_type 0 for bpftime_maps_shm +``` + +## Run malloc example + +```console +$ sudo example/malloc/malloc +libbpf: loading object 'malloc_bpf' from buffer +11:08:11 +11:08:12 +11:08:13 +``` + +Unlike the kernel malloc without bpftime_daemon, this malloc will not print any message. This is because we modify the load and attach process of bpf and perf event with eBPF in the kernel. + +## Trace malloc calls in target + +```console +$ sudo SPDLOG_LEVEL=Debug ~/.bpftime/bpftime start example/malloc/victim +malloc called from pid 12314 +continue malloc... +malloc called from pid 12314 +continue malloc... +malloc called from pid 12314 +continue malloc... +malloc called from pid 12314 +continue malloc... +malloc called from pid 12314 +``` + +## Debug: use bpftimetool for dump states + +The dump result example is in [daemon/test/malloc.json](test/malloc.json). + +See [tools/bpftimetool/README.md](../tools/bpftimetool/README.md) for how to load and replay it in the kernel. + diff --git a/daemon/test/malloc.json b/daemon/test/malloc.json new file mode 100644 index 00000000..cd1e5d09 --- /dev/null +++ b/daemon/test/malloc.json @@ -0,0 +1,59 @@ +{ + "0": { + "attr": { + "btf_id": 3, + "btf_key_type_id": 8, + "btf_value_type_id": 12, + "btf_vmlinux_value_type_id": 0, + "flags": 0, + "ifindex": 0, + "key_size": 4, + "map_extra": 0, + "map_type": 1, + "max_entries": 1024, + "value_size": 8 + }, + "name": "libc_malloc_cal", + "type": "bpf_map_handler" + }, + "1": { + "attr": { + "btf_id": 3, + "btf_key_type_id": 0, + "btf_value_type_id": 0, + "btf_vmlinux_value_type_id": 0, + "flags": 128, + "ifindex": 0, + "key_size": 4, + "map_extra": 0, + "map_type": 2, + "max_entries": 1, + "value_size": 27 + }, + "name": ".rodata.str1.1", + "type": "bpf_map_handler" + }, + "2": { + "attr": { + "attach_fds": [ + 3 + ], + "cnt": 55, + "insns": "850000000e0000007700000020000000630af4ff00000000b7010000640a00006b1af0ff00000000180100006f6d207000000000696420257b1ae8ff0000000018010000616c6c6500000000642066727b1ae0ff00000000180100006d616c6c000000006f6320637b1ad8ff00000000b706000000000000736af2ff00000000bfa100000000000007010000d8ffffffb70200001b000000bf0300000000000085000000060000007b6ad8ff00000000bfa200000000000007020000f4ffffff18110000040000000000000000000000850000000100000055000e0000000000bfa600000000000007060000f4ffffffbfa300000000000007030000d8ffffff18110000040000000000000000000000bf62000000000000b704000001000000850000000200000018110000040000000000000000000000bf62000000000000850000000100000015000b0000000000790100000000000007010000010000007b1af8ff00000000bfa200000000000007020000f4ffffffbfa300000000000007030000f8ffffff18110000040000000000000000000000b7040000020000008500000002000000b7000000000000009500000000000000", + "type": 2029950032 + }, + "name": "do_count", + "type": "bpf_prog_handler" + }, + "3": { + "attr": { + "_module_name": "/lib/x86_64-linux-gnu/libc.so.6", + "offset": 653600, + "pid": -1, + "ref_ctr_off": 0, + "tracepoint_id": -1, + "type": 6 + }, + "type": "bpf_perf_event_handler" + } +} \ No newline at end of file diff --git a/daemon/user/handle_bpf_event.cpp b/daemon/user/handle_bpf_event.cpp index 156878f4..07183b5e 100644 --- a/daemon/user/handle_bpf_event.cpp +++ b/daemon/user/handle_bpf_event.cpp @@ -174,10 +174,10 @@ static const char *const bpf_map_type_strings[] = { #define BPF_MAP_TYPE_MAX \ (sizeof(bpf_map_type_strings) / sizeof(bpf_map_type_strings[0])) -static const char *get_bpf_map_type_string(enum bpf_map_type type) +static const char *get_bpf_map_type_string(bpftime::bpf_map_type type) { - if (type >= 0 && type < BPF_MAP_TYPE_MAX) { - return bpf_map_type_strings[type]; + if ((int)type >= 0 && (int)type < BPF_MAP_TYPE_MAX) { + return bpf_map_type_strings[(int)type]; } return "Unknown"; } diff --git a/runtime/include/bpftime_shm.hpp b/runtime/include/bpftime_shm.hpp index 12eeb5af..57d26f43 100644 --- a/runtime/include/bpftime_shm.hpp +++ b/runtime/include/bpftime_shm.hpp @@ -27,6 +27,68 @@ struct bpf_map_attr { uint32_t btf_key_type_id = 0; uint32_t btf_value_type_id = 0; uint64_t map_extra = 0; + + // additional fields for bpftime only + uint32_t kernel_bpf_map_id = 0; +}; + +enum class bpf_event_type { + PERF_TYPE_HARDWARE = 0, + PERF_TYPE_SOFTWARE = 1, + PERF_TYPE_TRACEPOINT = 2, + PERF_TYPE_HW_CACHE = 3, + PERF_TYPE_RAW = 4, + PERF_TYPE_BREAKPOINT = 5, + + // custom types + BPF_TYPE_UPROBE = 6, + BPF_TYPE_URETPROBE = 7, + BPF_TYPE_FILTER = 8, + BPF_TYPE_REPLACE = 9, +}; + +enum class bpf_map_type { + BPF_MAP_TYPE_UNSPEC, + BPF_MAP_TYPE_HASH, + BPF_MAP_TYPE_ARRAY, + BPF_MAP_TYPE_PROG_ARRAY, + BPF_MAP_TYPE_PERF_EVENT_ARRAY, + BPF_MAP_TYPE_PERCPU_HASH, + BPF_MAP_TYPE_PERCPU_ARRAY, + BPF_MAP_TYPE_STACK_TRACE, + BPF_MAP_TYPE_CGROUP_ARRAY, + BPF_MAP_TYPE_LRU_HASH, + BPF_MAP_TYPE_LRU_PERCPU_HASH, + BPF_MAP_TYPE_LPM_TRIE, + BPF_MAP_TYPE_ARRAY_OF_MAPS, + BPF_MAP_TYPE_HASH_OF_MAPS, + BPF_MAP_TYPE_DEVMAP, + BPF_MAP_TYPE_SOCKMAP, + BPF_MAP_TYPE_CPUMAP, + BPF_MAP_TYPE_XSKMAP, + BPF_MAP_TYPE_SOCKHASH, + BPF_MAP_TYPE_CGROUP_STORAGE_DEPRECATED, + /* BPF_MAP_TYPE_CGROUP_STORAGE is available to bpf programs + * attaching to a cgroup. The newer BPF_MAP_TYPE_CGRP_STORAGE is + * available to both cgroup-attached and other progs and + * supports all functionality provided by + * BPF_MAP_TYPE_CGROUP_STORAGE. So mark + * BPF_MAP_TYPE_CGROUP_STORAGE deprecated. + */ + BPF_MAP_TYPE_CGROUP_STORAGE = BPF_MAP_TYPE_CGROUP_STORAGE_DEPRECATED, + BPF_MAP_TYPE_REUSEPORT_SOCKARRAY, + BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE, + BPF_MAP_TYPE_QUEUE, + BPF_MAP_TYPE_STACK, + BPF_MAP_TYPE_SK_STORAGE, + BPF_MAP_TYPE_DEVMAP_HASH, + BPF_MAP_TYPE_STRUCT_OPS, + BPF_MAP_TYPE_RINGBUF, + BPF_MAP_TYPE_INODE_STORAGE, + BPF_MAP_TYPE_TASK_STORAGE, + BPF_MAP_TYPE_BLOOM_FILTER, + BPF_MAP_TYPE_USER_RINGBUF, + BPF_MAP_TYPE_CGRP_STORAGE, }; enum class shm_open_type { @@ -36,6 +98,42 @@ enum class shm_open_type { SHM_CREATE_OR_OPEN, }; +enum class bpf_prog_type { + BPF_PROG_TYPE_UNSPEC, + BPF_PROG_TYPE_SOCKET_FILTER, + BPF_PROG_TYPE_KPROBE, + BPF_PROG_TYPE_SCHED_CLS, + BPF_PROG_TYPE_SCHED_ACT, + BPF_PROG_TYPE_TRACEPOINT, + BPF_PROG_TYPE_XDP, + BPF_PROG_TYPE_PERF_EVENT, + BPF_PROG_TYPE_CGROUP_SKB, + BPF_PROG_TYPE_CGROUP_SOCK, + BPF_PROG_TYPE_LWT_IN, + BPF_PROG_TYPE_LWT_OUT, + BPF_PROG_TYPE_LWT_XMIT, + BPF_PROG_TYPE_SOCK_OPS, + BPF_PROG_TYPE_SK_SKB, + BPF_PROG_TYPE_CGROUP_DEVICE, + BPF_PROG_TYPE_SK_MSG, + BPF_PROG_TYPE_RAW_TRACEPOINT, + BPF_PROG_TYPE_CGROUP_SOCK_ADDR, + BPF_PROG_TYPE_LWT_SEG6LOCAL, + BPF_PROG_TYPE_LIRC_MODE2, + BPF_PROG_TYPE_SK_REUSEPORT, + BPF_PROG_TYPE_FLOW_DISSECTOR, + BPF_PROG_TYPE_CGROUP_SYSCTL, + BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE, + BPF_PROG_TYPE_CGROUP_SOCKOPT, + BPF_PROG_TYPE_TRACING, + BPF_PROG_TYPE_STRUCT_OPS, + BPF_PROG_TYPE_EXT, + BPF_PROG_TYPE_LSM, + BPF_PROG_TYPE_SK_LOOKUP, + BPF_PROG_TYPE_SYSCALL, /* a program that can execute syscalls */ + BPF_PROG_TYPE_NETFILTER, +}; + extern const shm_open_type global_shm_open_type; bpftime::agent_config &bpftime_get_agent_config(); @@ -81,7 +179,7 @@ int bpftime_maps_create(int fd, const char *name, bpftime::bpf_map_attr attr); // get the bpf map info from the global shared memory int bpftime_map_get_info(int fd, bpftime::bpf_map_attr *out_attr, - const char **out_name, int *type); + const char **out_name, bpftime::bpf_map_type *type); // get the map value size from the global shared memory by fd uint32_t bpftime_map_value_size_from_syscall(int fd); diff --git a/runtime/src/attach/bpf_attach_ctx.cpp b/runtime/src/attach/bpf_attach_ctx.cpp index 71a653e9..680d43b1 100644 --- a/runtime/src/attach/bpf_attach_ctx.cpp +++ b/runtime/src/attach/bpf_attach_ctx.cpp @@ -73,7 +73,7 @@ bool bpf_attach_ctx::check_exist_syscall_trace_program( std::get( handler); if (perf_event_handler.type == - bpf_perf_event_handler::bpf_event_type:: + bpf_event_type:: PERF_TYPE_TRACEPOINT) { const auto &tp_table = get_global_syscall_tracepoint_table(); @@ -230,13 +230,13 @@ int bpf_attach_ctx::init_attach_ctx_from_handlers( std::get(handler); void *func_addr = nullptr; switch (event_handler.type) { - case bpf_perf_event_handler::bpf_event_type:: + case bpf_event_type:: BPF_TYPE_FILTER: - case bpf_perf_event_handler::bpf_event_type:: + case bpf_event_type:: BPF_TYPE_REPLACE: - case bpf_perf_event_handler::bpf_event_type:: + case bpf_event_type:: BPF_TYPE_UPROBE: - case bpf_perf_event_handler::bpf_event_type:: + case bpf_event_type:: BPF_TYPE_URETPROBE: func_addr = attach_manager @@ -251,7 +251,7 @@ int bpf_attach_ctx::init_attach_ctx_from_handlers( } // attach base on events switch (event_handler.type) { - case bpf_perf_event_handler::bpf_event_type:: + case bpf_event_type:: BPF_TYPE_FILTER: { auto progs = handler_prog_fds[i]; if (progs.size() > 1) { @@ -277,7 +277,7 @@ int bpf_attach_ctx::init_attach_ctx_from_handlers( i, err); break; } - case bpf_perf_event_handler::bpf_event_type:: + case bpf_event_type:: BPF_TYPE_REPLACE: { auto progs = handler_prog_fds[i]; if (progs.size() > 1) { @@ -303,7 +303,7 @@ int bpf_attach_ctx::init_attach_ctx_from_handlers( i, err); break; } - case bpf_perf_event_handler::bpf_event_type:: + case bpf_event_type:: BPF_TYPE_UPROBE: { spdlog::debug( "Creating uprobe for perf event fd {}", @@ -328,7 +328,7 @@ int bpf_attach_ctx::init_attach_ctx_from_handlers( i, err); break; } - case bpf_perf_event_handler::bpf_event_type:: + case bpf_event_type:: BPF_TYPE_URETPROBE: { spdlog::debug( "Creating uretprobe for perf event fd {}", @@ -353,7 +353,7 @@ int bpf_attach_ctx::init_attach_ctx_from_handlers( i, err); break; } - case bpf_perf_event_handler::bpf_event_type:: + case bpf_event_type:: PERF_TYPE_TRACEPOINT: { err = create_tracepoint( event_handler.tracepoint_id, i, @@ -366,7 +366,7 @@ int bpf_attach_ctx::init_attach_ctx_from_handlers( assert(err >= 0); break; } - case bpf_perf_event_handler::bpf_event_type:: + case bpf_event_type:: PERF_TYPE_SOFTWARE: { spdlog::debug( "Attaching software perf event, nothing need to do"); diff --git a/runtime/src/bpftime_shm.cpp b/runtime/src/bpftime_shm.cpp index a020329b..dc3aae8c 100644 --- a/runtime/src/bpftime_shm.cpp +++ b/runtime/src/bpftime_shm.cpp @@ -122,7 +122,7 @@ void bpftime_close(int fd) shm_holder.global_shared_memory.close_fd(fd); } int bpftime_map_get_info(int fd, bpftime::bpf_map_attr *out_attr, - const char **out_name, int *type) + const char **out_name, bpf_map_type *type) { if (!shm_holder.global_shared_memory.is_map_fd(fd)) { errno = ENOENT; @@ -141,6 +141,7 @@ int bpftime_map_get_info(int fd, bpftime::bpf_map_attr *out_attr, } return 0; } + int bpftime_is_ringbuf_map(int fd) { return shm_holder.global_shared_memory.is_ringbuf_map_fd(fd); @@ -150,6 +151,7 @@ int bpftime_is_array_map(int fd) { return shm_holder.global_shared_memory.is_array_map_fd(fd); } + void *bpftime_get_array_map_raw_data(int fd) { if (auto array_impl = @@ -162,6 +164,7 @@ void *bpftime_get_array_map_raw_data(int fd) return nullptr; } } + void *bpftime_get_ringbuf_consumer_page(int ringbuf_fd) { auto &shm = shm_holder.global_shared_memory; @@ -175,6 +178,7 @@ void *bpftime_get_ringbuf_consumer_page(int ringbuf_fd) return nullptr; } } + void *bpftime_get_ringbuf_producer_page(int ringbuf_fd) { auto &shm = shm_holder.global_shared_memory; @@ -188,6 +192,7 @@ void *bpftime_get_ringbuf_producer_page(int ringbuf_fd) return nullptr; } } + void *bpftime_ringbuf_reserve(int fd, uint64_t size) { auto &shm = shm_holder.global_shared_memory; @@ -200,6 +205,7 @@ void *bpftime_ringbuf_reserve(int fd, uint64_t size) return nullptr; } } + void bpftime_ringbuf_submit(int fd, void *data, int discard) { auto &shm = shm_holder.global_shared_memory; @@ -211,10 +217,12 @@ void bpftime_ringbuf_submit(int fd, void *data, int discard) spdlog::error("Expected fd {} to be ringbuf map fd ", fd); } } + int bpftime_is_epoll_handler(int fd) { return shm_holder.global_shared_memory.is_epoll_fd(fd); } + int bpftime_epoll_wait(int fd, struct epoll_event *out_evts, int max_evt, int timeout) { @@ -276,6 +284,7 @@ int bpftime_epoll_wait(int fd, struct epoll_event *out_evts, int max_evt, } return next_id; } + int bpftime_add_software_perf_event(int cpu, int32_t sample_type, int64_t config) { @@ -289,6 +298,7 @@ int bpftime_add_software_perf_event_fd_to_epoll(int swpe_fd, int epoll_fd, return shm_holder.global_shared_memory.add_software_perf_event_to_epoll( swpe_fd, epoll_fd, extra_data); } + int bpftime_is_software_perf_event(int fd) { return shm_holder.global_shared_memory.is_software_perf_event_handler_fd( @@ -301,6 +311,7 @@ void *bpftime_get_software_perf_event_raw_buffer(int fd, size_t expected_size) .get_software_perf_event_raw_buffer(fd, expected_size) .value_or(nullptr); } + int bpftime_perf_event_output(int fd, const void *buf, size_t sz) { auto &shm = shm_holder.global_shared_memory; @@ -321,11 +332,14 @@ int bpftime_perf_event_output(int fd, const void *buf, size_t sz) return -1; } } + extern "C" uint64_t map_ptr_by_fd(uint32_t fd) { if (!shm_holder.global_shared_memory.get_manager() || !shm_holder.global_shared_memory.is_map_fd(fd)) { errno = ENOENT; + spdlog::error("Expected fd {} to be a map fd", fd); + // Here we just ignore the wrong maps return 0; } // Use a convenient way to represent a pointer @@ -337,6 +351,8 @@ extern "C" uint64_t map_val(uint64_t map_ptr) int fd = (int)(map_ptr >> 32); if (!shm_holder.global_shared_memory.get_manager() || !shm_holder.global_shared_memory.is_map_fd(fd)) { + spdlog::error("Expected fd {} to be a map fd", fd); + // here we just ignore the wrong maps errno = ENOENT; return 0; } diff --git a/runtime/src/bpftime_shm_internal.cpp b/runtime/src/bpftime_shm_internal.cpp index e27853ea..e8c9e696 100644 --- a/runtime/src/bpftime_shm_internal.cpp +++ b/runtime/src/bpftime_shm_internal.cpp @@ -229,7 +229,7 @@ int bpftime_shm::add_software_perf_event_to_epoll(int swpe_fd, int epoll_fd, auto &perf_handler = std::get(manager->get_handler(swpe_fd)); if (perf_handler.type != - bpf_perf_event_handler::bpf_event_type::PERF_TYPE_SOFTWARE) { + bpf_event_type::PERF_TYPE_SOFTWARE) { spdlog::error( "Expected perf fd {} to be a software perf event instance", swpe_fd); @@ -324,14 +324,14 @@ bool bpftime_shm::is_ringbuf_map_fd(int fd) const if (!is_map_fd(fd)) return false; auto &map_impl = std::get(manager->get_handler(fd)); - return map_impl.type == map_impl.BPF_MAP_TYPE_RINGBUF; + return map_impl.type == bpf_map_type::BPF_MAP_TYPE_RINGBUF; } bool bpftime_shm::is_array_map_fd(int fd) const { if (!is_map_fd(fd)) return false; auto &map_impl = std::get(manager->get_handler(fd)); - return map_impl.type == map_impl.BPF_MAP_TYPE_ARRAY; + return map_impl.type == bpf_map_type::BPF_MAP_TYPE_ARRAY; } std::optional bpftime_shm::try_get_ringbuf_map_impl(int fd) const @@ -555,7 +555,7 @@ bool bpftime_shm::is_software_perf_event_handler_fd(int fd) const return false; const auto &hd = std::get(get_handler(fd)); return hd.type == - bpf_perf_event_handler::bpf_event_type::PERF_TYPE_SOFTWARE; + bpf_event_type::PERF_TYPE_SOFTWARE; } bpftime::agent_config &bpftime_get_agent_config() diff --git a/runtime/src/bpftime_shm_json.cpp b/runtime/src/bpftime_shm_json.cpp index fdf9f6d0..7b055fe2 100644 --- a/runtime/src/bpftime_shm_json.cpp +++ b/runtime/src/bpftime_shm_json.cpp @@ -102,16 +102,16 @@ static int import_shm_handler_from_json(bpftime_shm &shm, json value, int fd) int ref_ctr_off = value["attr"]["ref_ctr_off"]; std::string _module_name = value["attr"]["_module_name"]; int tracepoint_id = value["attr"]["tracepoint_id"]; - switch ((bpf_perf_event_handler::bpf_event_type)type) { - case bpf_perf_event_handler::bpf_event_type::BPF_TYPE_UPROBE: + switch ((bpf_event_type)type) { + case bpf_event_type::BPF_TYPE_UPROBE: shm.add_uprobe(fd, pid, _module_name.c_str(), offset, false, ref_ctr_off); break; - case bpf_perf_event_handler::bpf_event_type::BPF_TYPE_URETPROBE: + case bpf_event_type::BPF_TYPE_URETPROBE: shm.add_uprobe(fd, pid, _module_name.c_str(), offset, true, ref_ctr_off); break; - case bpf_perf_event_handler::bpf_event_type::PERF_TYPE_TRACEPOINT: + case bpf_event_type::PERF_TYPE_TRACEPOINT: shm.add_tracepoint(fd, pid, tracepoint_id); break; default: diff --git a/runtime/src/handler/map_handler.cpp b/runtime/src/handler/map_handler.cpp index acb4b2ae..32a5ebc5 100644 --- a/runtime/src/handler/map_handler.cpp +++ b/runtime/src/handler/map_handler.cpp @@ -20,8 +20,8 @@ std::string bpf_map_handler::get_container_name() uint32_t bpf_map_handler::get_value_size() const { auto result = value_size; - if ((type == BPF_MAP_TYPE_PERCPU_ARRAY) || - (type == BPF_MAP_TYPE_PERCPU_HASH)) { + if ((type == bpf_map_type::BPF_MAP_TYPE_PERCPU_ARRAY) || + (type == bpf_map_type::BPF_MAP_TYPE_PERCPU_HASH)) { result *= sysconf(_SC_NPROCESSORS_ONLN); } return result; @@ -29,13 +29,13 @@ uint32_t bpf_map_handler::get_value_size() const std::optional bpf_map_handler::try_get_ringbuf_map_impl() const { - if (type != BPF_MAP_TYPE_RINGBUF) + if (type != bpf_map_type::BPF_MAP_TYPE_RINGBUF) return {}; return static_cast(map_impl_ptr.get()); } std::optional bpf_map_handler::try_get_array_map_impl() const { - if (type != BPF_MAP_TYPE_ARRAY) + if (type != bpf_map_type::BPF_MAP_TYPE_ARRAY) return {}; return static_cast(map_impl_ptr.get()); } @@ -63,30 +63,30 @@ const void *bpf_map_handler::map_lookup_elem(const void *key, }; switch (type) { - case BPF_MAP_TYPE_HASH: { + case bpf_map_type::BPF_MAP_TYPE_HASH: { auto impl = static_cast(map_impl_ptr.get()); return do_lookup(impl); } - case BPF_MAP_TYPE_ARRAY: { + case bpf_map_type::BPF_MAP_TYPE_ARRAY: { auto impl = static_cast(map_impl_ptr.get()); return do_lookup(impl); } - case BPF_MAP_TYPE_RINGBUF: { + case bpf_map_type::BPF_MAP_TYPE_RINGBUF: { auto impl = static_cast(map_impl_ptr.get()); return do_lookup(impl); } - case BPF_MAP_TYPE_PERF_EVENT_ARRAY: { + case bpf_map_type::BPF_MAP_TYPE_PERF_EVENT_ARRAY: { auto impl = static_cast( map_impl_ptr.get()); return do_lookup(impl); } - case BPF_MAP_TYPE_PERCPU_ARRAY: { + case bpf_map_type::BPF_MAP_TYPE_PERCPU_ARRAY: { auto impl = static_cast( map_impl_ptr.get()); return from_userspace ? do_lookup_userspace(impl) : do_lookup(impl); } - case BPF_MAP_TYPE_PERCPU_HASH: { + case bpf_map_type::BPF_MAP_TYPE_PERCPU_HASH: { auto impl = static_cast( map_impl_ptr.get()); return from_userspace ? do_lookup_userspace(impl) : @@ -122,30 +122,30 @@ long bpf_map_handler::map_update_elem(const void *key, const void *value, } }; switch (type) { - case BPF_MAP_TYPE_HASH: { + case bpf_map_type::BPF_MAP_TYPE_HASH: { auto impl = static_cast(map_impl_ptr.get()); return do_update(impl); } - case BPF_MAP_TYPE_ARRAY: { + case bpf_map_type::BPF_MAP_TYPE_ARRAY: { auto impl = static_cast(map_impl_ptr.get()); return do_update(impl); } - case BPF_MAP_TYPE_RINGBUF: { + case bpf_map_type::BPF_MAP_TYPE_RINGBUF: { auto impl = static_cast(map_impl_ptr.get()); return do_update(impl); } - case BPF_MAP_TYPE_PERF_EVENT_ARRAY: { + case bpf_map_type::BPF_MAP_TYPE_PERF_EVENT_ARRAY: { auto impl = static_cast( map_impl_ptr.get()); return do_update(impl); } - case BPF_MAP_TYPE_PERCPU_ARRAY: { + case bpf_map_type::BPF_MAP_TYPE_PERCPU_ARRAY: { auto impl = static_cast( map_impl_ptr.get()); return from_userspace ? do_update_userspace(impl) : do_update(impl); } - case BPF_MAP_TYPE_PERCPU_HASH: { + case bpf_map_type::BPF_MAP_TYPE_PERCPU_HASH: { auto impl = static_cast( map_impl_ptr.get()); return from_userspace ? do_update_userspace(impl) : @@ -170,29 +170,29 @@ int bpf_map_handler::bpf_map_get_next_key(const void *key, void *next_key, } }; switch (type) { - case BPF_MAP_TYPE_HASH: { + case bpf_map_type::BPF_MAP_TYPE_HASH: { auto impl = static_cast(map_impl_ptr.get()); return do_get_next_key(impl); } - case BPF_MAP_TYPE_ARRAY: { + case bpf_map_type::BPF_MAP_TYPE_ARRAY: { auto impl = static_cast(map_impl_ptr.get()); return do_get_next_key(impl); } - case BPF_MAP_TYPE_RINGBUF: { + case bpf_map_type::BPF_MAP_TYPE_RINGBUF: { auto impl = static_cast(map_impl_ptr.get()); return do_get_next_key(impl); } - case BPF_MAP_TYPE_PERF_EVENT_ARRAY: { + case bpf_map_type::BPF_MAP_TYPE_PERF_EVENT_ARRAY: { auto impl = static_cast( map_impl_ptr.get()); return do_get_next_key(impl); } - case BPF_MAP_TYPE_PERCPU_ARRAY: { + case bpf_map_type::BPF_MAP_TYPE_PERCPU_ARRAY: { auto impl = static_cast( map_impl_ptr.get()); return do_get_next_key(impl); } - case BPF_MAP_TYPE_PERCPU_HASH: { + case bpf_map_type::BPF_MAP_TYPE_PERCPU_HASH: { auto impl = static_cast( map_impl_ptr.get()); return do_get_next_key(impl); @@ -226,30 +226,30 @@ long bpf_map_handler::map_delete_elem(const void *key, }; switch (type) { - case BPF_MAP_TYPE_HASH: { + case bpf_map_type::BPF_MAP_TYPE_HASH: { auto impl = static_cast(map_impl_ptr.get()); return do_delete(impl); } - case BPF_MAP_TYPE_ARRAY: { + case bpf_map_type::BPF_MAP_TYPE_ARRAY: { auto impl = static_cast(map_impl_ptr.get()); return do_delete(impl); } - case BPF_MAP_TYPE_RINGBUF: { + case bpf_map_type::BPF_MAP_TYPE_RINGBUF: { auto impl = static_cast(map_impl_ptr.get()); return do_delete(impl); } - case BPF_MAP_TYPE_PERF_EVENT_ARRAY: { + case bpf_map_type::BPF_MAP_TYPE_PERF_EVENT_ARRAY: { auto impl = static_cast( map_impl_ptr.get()); return do_delete(impl); } - case BPF_MAP_TYPE_PERCPU_ARRAY: { + case bpf_map_type::BPF_MAP_TYPE_PERCPU_ARRAY: { auto impl = static_cast( map_impl_ptr.get()); return from_userspace ? do_delete_userspace(impl) : do_delete(impl); } - case BPF_MAP_TYPE_PERCPU_HASH: { + case bpf_map_type::BPF_MAP_TYPE_PERCPU_HASH: { auto impl = static_cast( map_impl_ptr.get()); return from_userspace ? do_delete_userspace(impl) : @@ -265,18 +265,18 @@ int bpf_map_handler::map_init(managed_shared_memory &memory) { auto container_name = get_container_name(); switch (type) { - case BPF_MAP_TYPE_HASH: { + case bpf_map_type::BPF_MAP_TYPE_HASH: { map_impl_ptr = memory.construct( container_name.c_str())(memory, key_size, value_size); return 0; } - case BPF_MAP_TYPE_ARRAY: { + case bpf_map_type::BPF_MAP_TYPE_ARRAY: { map_impl_ptr = memory.construct( container_name.c_str())(memory, value_size, max_entries); return 0; } - case BPF_MAP_TYPE_RINGBUF: { + case bpf_map_type::BPF_MAP_TYPE_RINGBUF: { auto max_ent = max_entries; int pop_cnt = 0; while (max_ent) { @@ -293,19 +293,19 @@ int bpf_map_handler::map_init(managed_shared_memory &memory) container_name.c_str())(max_entries, memory); return 0; } - case BPF_MAP_TYPE_PERF_EVENT_ARRAY: { + case bpf_map_type::BPF_MAP_TYPE_PERF_EVENT_ARRAY: { map_impl_ptr = memory.construct( container_name.c_str())(memory, key_size, value_size, max_entries); return 0; } - case BPF_MAP_TYPE_PERCPU_ARRAY: { + case bpf_map_type::BPF_MAP_TYPE_PERCPU_ARRAY: { map_impl_ptr = memory.construct( container_name.c_str())(memory, value_size, max_entries); return 0; } - case BPF_MAP_TYPE_PERCPU_HASH: { + case bpf_map_type::BPF_MAP_TYPE_PERCPU_HASH: { map_impl_ptr = memory.construct( container_name.c_str())(memory, key_size, value_size); return 0; @@ -321,23 +321,23 @@ void bpf_map_handler::map_free(managed_shared_memory &memory) { auto container_name = get_container_name(); switch (type) { - case BPF_MAP_TYPE_HASH: + case bpf_map_type::BPF_MAP_TYPE_HASH: memory.destroy(container_name.c_str()); break; - case BPF_MAP_TYPE_ARRAY: + case bpf_map_type::BPF_MAP_TYPE_ARRAY: memory.destroy(container_name.c_str()); break; - case BPF_MAP_TYPE_RINGBUF: + case bpf_map_type::BPF_MAP_TYPE_RINGBUF: memory.destroy(container_name.c_str()); break; - case BPF_MAP_TYPE_PERF_EVENT_ARRAY: + case bpf_map_type::BPF_MAP_TYPE_PERF_EVENT_ARRAY: memory.destroy( container_name.c_str()); break; - case BPF_MAP_TYPE_PERCPU_ARRAY: + case bpf_map_type::BPF_MAP_TYPE_PERCPU_ARRAY: memory.destroy(container_name.c_str()); break; - case BPF_MAP_TYPE_PERCPU_HASH: + case bpf_map_type::BPF_MAP_TYPE_PERCPU_HASH: memory.destroy(container_name.c_str()); break; diff --git a/runtime/src/handler/map_handler.hpp b/runtime/src/handler/map_handler.hpp index d08da6ac..ccd6b036 100644 --- a/runtime/src/handler/map_handler.hpp +++ b/runtime/src/handler/map_handler.hpp @@ -31,51 +31,7 @@ class bpf_map_handler { public: bpf_map_attr attr; using general_map_impl_ptr = boost::interprocess::offset_ptr; - enum bpf_map_type { - BPF_MAP_TYPE_UNSPEC, - BPF_MAP_TYPE_HASH, - BPF_MAP_TYPE_ARRAY, - BPF_MAP_TYPE_PROG_ARRAY, - BPF_MAP_TYPE_PERF_EVENT_ARRAY, - BPF_MAP_TYPE_PERCPU_HASH, - BPF_MAP_TYPE_PERCPU_ARRAY, - BPF_MAP_TYPE_STACK_TRACE, - BPF_MAP_TYPE_CGROUP_ARRAY, - BPF_MAP_TYPE_LRU_HASH, - BPF_MAP_TYPE_LRU_PERCPU_HASH, - BPF_MAP_TYPE_LPM_TRIE, - BPF_MAP_TYPE_ARRAY_OF_MAPS, - BPF_MAP_TYPE_HASH_OF_MAPS, - BPF_MAP_TYPE_DEVMAP, - BPF_MAP_TYPE_SOCKMAP, - BPF_MAP_TYPE_CPUMAP, - BPF_MAP_TYPE_XSKMAP, - BPF_MAP_TYPE_SOCKHASH, - BPF_MAP_TYPE_CGROUP_STORAGE_DEPRECATED, - /* BPF_MAP_TYPE_CGROUP_STORAGE is available to bpf programs - * attaching to a cgroup. The newer BPF_MAP_TYPE_CGRP_STORAGE is - * available to both cgroup-attached and other progs and - * supports all functionality provided by - * BPF_MAP_TYPE_CGROUP_STORAGE. So mark - * BPF_MAP_TYPE_CGROUP_STORAGE deprecated. - */ - BPF_MAP_TYPE_CGROUP_STORAGE = - BPF_MAP_TYPE_CGROUP_STORAGE_DEPRECATED, - BPF_MAP_TYPE_REUSEPORT_SOCKARRAY, - BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE, - BPF_MAP_TYPE_QUEUE, - BPF_MAP_TYPE_STACK, - BPF_MAP_TYPE_SK_STORAGE, - BPF_MAP_TYPE_DEVMAP_HASH, - BPF_MAP_TYPE_STRUCT_OPS, - BPF_MAP_TYPE_RINGBUF, - BPF_MAP_TYPE_INODE_STORAGE, - BPF_MAP_TYPE_TASK_STORAGE, - BPF_MAP_TYPE_BLOOM_FILTER, - BPF_MAP_TYPE_USER_RINGBUF, - BPF_MAP_TYPE_CGRP_STORAGE, - }; - enum bpf_map_type type; + bpf_map_type type; boost_shm_string name; bpf_map_handler(const char *name, boost::interprocess::managed_shared_memory &mem, diff --git a/runtime/src/handler/perf_event_handler.hpp b/runtime/src/handler/perf_event_handler.hpp index 85f93555..3fcf30b0 100644 --- a/runtime/src/handler/perf_event_handler.hpp +++ b/runtime/src/handler/perf_event_handler.hpp @@ -10,6 +10,8 @@ #include #include #include "linux/perf_event.h" +#include "bpftime_shm.hpp" + namespace bpftime { @@ -89,20 +91,7 @@ using software_perf_event_weak_ptr = boost::interprocess::managed_weak_ptr< // perf event handler struct bpf_perf_event_handler { - enum class bpf_event_type { - PERF_TYPE_HARDWARE = 0, - PERF_TYPE_SOFTWARE = 1, - PERF_TYPE_TRACEPOINT = 2, - PERF_TYPE_HW_CACHE = 3, - PERF_TYPE_RAW = 4, - PERF_TYPE_BREAKPOINT = 5, - - // custom types - BPF_TYPE_UPROBE = 6, - BPF_TYPE_URETPROBE = 7, - BPF_TYPE_FILTER = 8, - BPF_TYPE_REPLACE = 9, - } type; + bpf_event_type type; int enable() const { // TODO: implement enable logic. diff --git a/runtime/src/handler/prog_handler.hpp b/runtime/src/handler/prog_handler.hpp index 63f4fe3b..d369f2a7 100644 --- a/runtime/src/handler/prog_handler.hpp +++ b/runtime/src/handler/prog_handler.hpp @@ -4,6 +4,8 @@ #include #include #include +#include "bpftime_shm.hpp" + namespace bpftime { @@ -27,42 +29,7 @@ class bpf_prog_handler { * programs correspond to /a/ specific kernel which is to be * analyzed, and not /a/ specific kernel /and/ all future ones. */ - enum class bpf_prog_type { - BPF_PROG_TYPE_UNSPEC, - BPF_PROG_TYPE_SOCKET_FILTER, - BPF_PROG_TYPE_KPROBE, - BPF_PROG_TYPE_SCHED_CLS, - BPF_PROG_TYPE_SCHED_ACT, - BPF_PROG_TYPE_TRACEPOINT, - BPF_PROG_TYPE_XDP, - BPF_PROG_TYPE_PERF_EVENT, - BPF_PROG_TYPE_CGROUP_SKB, - BPF_PROG_TYPE_CGROUP_SOCK, - BPF_PROG_TYPE_LWT_IN, - BPF_PROG_TYPE_LWT_OUT, - BPF_PROG_TYPE_LWT_XMIT, - BPF_PROG_TYPE_SOCK_OPS, - BPF_PROG_TYPE_SK_SKB, - BPF_PROG_TYPE_CGROUP_DEVICE, - BPF_PROG_TYPE_SK_MSG, - BPF_PROG_TYPE_RAW_TRACEPOINT, - BPF_PROG_TYPE_CGROUP_SOCK_ADDR, - BPF_PROG_TYPE_LWT_SEG6LOCAL, - BPF_PROG_TYPE_LIRC_MODE2, - BPF_PROG_TYPE_SK_REUSEPORT, - BPF_PROG_TYPE_FLOW_DISSECTOR, - BPF_PROG_TYPE_CGROUP_SYSCTL, - BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE, - BPF_PROG_TYPE_CGROUP_SOCKOPT, - BPF_PROG_TYPE_TRACING, - BPF_PROG_TYPE_STRUCT_OPS, - BPF_PROG_TYPE_EXT, - BPF_PROG_TYPE_LSM, - BPF_PROG_TYPE_SK_LOOKUP, - BPF_PROG_TYPE_SYSCALL, /* a program that can execute syscalls */ - BPF_PROG_TYPE_NETFILTER, - }; - enum bpf_prog_type type; + bpf_prog_type type; bpf_prog_handler(managed_shared_memory &mem, const struct ebpf_inst *insn, size_t insn_cnt, diff --git a/runtime/syscall-server/syscall_context.cpp b/runtime/syscall-server/syscall_context.cpp index 62332fee..75efcb77 100644 --- a/runtime/syscall-server/syscall_context.cpp +++ b/runtime/syscall-server/syscall_context.cpp @@ -179,7 +179,7 @@ long syscall_context::handle_sysbpf(int cmd, union bpf_attr *attr, size_t size) spdlog::debug("Getting info by fd"); bpftime::bpf_map_attr map_attr; const char *map_name; - int map_type; + bpftime::bpf_map_type map_type; int res = bpftime_map_get_info(attr->info.bpf_fd, &map_attr, &map_name, &map_type); if (res < 0) { @@ -190,7 +190,7 @@ long syscall_context::handle_sysbpf(int cmd, union bpf_attr *attr, size_t size) ptr->btf_id = map_attr.btf_id; ptr->btf_key_type_id = map_attr.btf_key_type_id; ptr->btf_value_type_id = map_attr.btf_value_type_id; - ptr->type = map_type; + ptr->type = (int)map_type; ptr->value_size = map_attr.value_size; ptr->btf_vmlinux_value_type_id = map_attr.btf_vmlinux_value_type_id; @@ -238,14 +238,14 @@ int syscall_context::handle_perfevent(perf_event_attr *attr, pid_t pid, int cpu, spdlog::debug("Created uprobe {}", id); return id; } else if ((int)attr->type == - (int)bpf_perf_event_handler::bpf_event_type:: + (int)bpf_event_type:: PERF_TYPE_TRACEPOINT) { spdlog::debug("Detected tracepoint perf event creation"); int fd = bpftime_tracepoint_create(-1/* let the shm alloc fd for us */, pid, (int32_t)attr->config); spdlog::debug("Created tracepoint perf event with fd {}", fd); return fd; } else if ((int)attr->type == - (int)bpf_perf_event_handler::bpf_event_type:: + (int)bpf_event_type:: PERF_TYPE_SOFTWARE) { spdlog::debug("Detected software perf event creation"); int fd = bpftime_add_software_perf_event(cpu, attr->sample_type, diff --git a/runtime/test/src/test_shm_progs_attach.cpp b/runtime/test/src/test_shm_progs_attach.cpp index 74122534..6383fab3 100644 --- a/runtime/test/src/test_shm_progs_attach.cpp +++ b/runtime/test/src/test_shm_progs_attach.cpp @@ -91,7 +91,7 @@ void attach_replace(bpftime::handler_manager &manager_ref, 0, bpf_prog_handler(segment, prog->get_insns().data(), prog->get_insns().size(), prog->prog_name(), - bpftime::bpf_map_handler::BPF_MAP_TYPE_UNSPEC), + (int)bpftime::bpf_prog_type::BPF_PROG_TYPE_UNSPEC), segment); auto &prog_handler = std::get(manager_ref[0]); // the attach fd is 3 @@ -100,7 +100,7 @@ void attach_replace(bpftime::handler_manager &manager_ref, manager_ref.set_handler( 3, bpf_perf_event_handler( - bpf_perf_event_handler::bpf_event_type::BPF_TYPE_REPLACE, + bpf_event_type::BPF_TYPE_REPLACE, offset, -1, "", segment), segment); } diff --git a/runtime/test/src/test_shm_server.cpp b/runtime/test/src/test_shm_server.cpp index e566dc92..b80ba589 100644 --- a/runtime/test/src/test_shm_server.cpp +++ b/runtime/test/src/test_shm_server.cpp @@ -20,7 +20,7 @@ int main(int argc, const char **argv) { bpftime_initialize_global_shm(shm_open_type::SHM_REMOVE_AND_CREATE); bpftime::bpf_map_attr attr; - attr.type = bpf_map_handler::BPF_MAP_TYPE_HASH; + attr.type = bpf_map_type::BPF_MAP_TYPE_HASH; bpftime_maps_create(-1, "test", attr); return system( (std::string("./test_shm_client_Tests") + " sub").c_str());