diff --git a/runtime/syscall-server/syscall_context.cpp b/runtime/syscall-server/syscall_context.cpp index f5168a17..343a7c4d 100644 --- a/runtime/syscall-server/syscall_context.cpp +++ b/runtime/syscall-server/syscall_context.cpp @@ -8,8 +8,8 @@ #include #include "syscall_context.hpp" #include "handler/map_handler.hpp" -#include "handler/perf_event_handler.hpp" #include +#include #if __linux__ #include "linux/perf_event.h" #include @@ -115,7 +115,24 @@ int syscall_context::handle_openat(int fd, const char *file, int oflag, if (!enable_mock) return orig_openat_fn(fd, file, oflag, mode); try_startup(); - // const char * new_file = bpftime_checkfile(file); + auto path = resolve_filename_and_fd_to_full_path(fd, file); + if (!path) { + SPDLOG_WARN("Failed to resolve fd={}/file=`{}`", fd, file); + return orig_openat_fn(fd, file, oflag, mode); + } + if (auto mocker = create_mocked_file_based_on_full_path(*path); + mocker) { + bpftime_lock_guard _guard(this->mocked_file_lock); + char filename_buf[] = "/tmp/bpftime-mock.XXXXXX"; + int fake_fd = mkstemp(filename_buf); + if (fake_fd < 0) { + SPDLOG_WARN("Unable to create mock fd: {}", errno); + return orig_open_fn(file, oflag, mode); + } + this->mocked_files.emplace(fake_fd, std::move(*mocker)); + SPDLOG_DEBUG("Created mocked file with fd {}", fake_fd); + return fake_fd; + } return orig_openat_fn(fd, file, oflag, mode); } @@ -125,7 +142,18 @@ int syscall_context::handle_open(const char *file, int oflag, if (!enable_mock) return orig_open_fn(file, oflag, mode); try_startup(); - // const char * new_file = bpftime_checkfile(file); + if (auto mocker = create_mocked_file_based_on_full_path(file); mocker) { + bpftime_lock_guard _guard(this->mocked_file_lock); + char filename_buf[] = "/tmp/bpftime-mock.XXXXXX"; + int fake_fd = mkstemp(filename_buf); + if (fake_fd < 0) { + SPDLOG_WARN("Unable to create mock fd: {}", errno); + return orig_open_fn(file, oflag, mode); + } + this->mocked_files.emplace(fake_fd, std::move(*mocker)); + SPDLOG_DEBUG("Created mocked file with fd {}", fake_fd); + return fake_fd; + } return orig_open_fn(file, oflag, mode); } @@ -141,15 +169,17 @@ ssize_t syscall_context::handle_read(int fd, void *buf, size_t count) SPDLOG_DEBUG("Mock read fd={}, buf={:x}, count={}", fd, (uintptr_t)buf, count); auto &mock_file = itr->second; - bpftime_lock_guard _access_guard(mock_file.access_lock); - auto can_read_bytes = std::min( - count, mock_file.buf.size() - mock_file.cursor); + bpftime_lock_guard _access_guard( + mock_file->access_lock); + auto can_read_bytes = + std::min(count, mock_file->buf.size() - + mock_file->cursor); SPDLOG_DEBUG("Reading {} bytes", can_read_bytes); if (can_read_bytes == 0) return can_read_bytes; - memcpy(buf, &mock_file.buf[mock_file.cursor], + memcpy(buf, &mock_file->buf[mock_file->cursor], can_read_bytes); - mock_file.cursor += can_read_bytes; + mock_file->cursor += can_read_bytes; SPDLOG_DEBUG("Copied {} bytes", can_read_bytes); return can_read_bytes; diff --git a/runtime/syscall-server/syscall_context.hpp b/runtime/syscall-server/syscall_context.hpp index 30bb2ce1..a6614b2b 100644 --- a/runtime/syscall-server/syscall_context.hpp +++ b/runtime/syscall-server/syscall_context.hpp @@ -40,6 +40,11 @@ struct mocked_file_provider { { pthread_spin_destroy(&access_lock); } + mocked_file_provider(const mocked_file_provider &) = delete; + mocked_file_provider &operator=(const mocked_file_provider &) = delete; + + mocked_file_provider(mocked_file_provider &&) = default; + mocked_file_provider &operator=(mocked_file_provider &&) = default; }; class syscall_context { @@ -68,7 +73,8 @@ class syscall_context { read_fn orig_read_fn = nullptr; std::unordered_set mocked_mmap_values; pthread_spinlock_t mocked_file_lock; - std::unordered_map mocked_files; + std::unordered_map > + mocked_files; void init_original_functions() { orig_epoll_wait_fn = diff --git a/runtime/syscall-server/syscall_server_utils.cpp b/runtime/syscall-server/syscall_server_utils.cpp index 7442d9ca..5bcb9c07 100644 --- a/runtime/syscall-server/syscall_server_utils.cpp +++ b/runtime/syscall-server/syscall_server_utils.cpp @@ -6,6 +6,7 @@ #include "bpftime_shm_internal.hpp" #include "syscall_context.hpp" #include +#include #include #include #include "bpftime_logger.hpp" @@ -126,16 +127,16 @@ int determine_uprobe_retprobe_bit() "config:%d\n"); } -std::optional +std::optional > create_mocked_file_based_on_full_path(const std::filesystem::path &path) { if (path == UPROBE_TYPE_FILE_NAME) { SPDLOG_DEBUG("{} is uprobe type file", path.c_str()); - return mocked_file_provider( + return std::make_unique( std::to_string(MOCKED_UPROBE_TYPE_VALUE)); } else if (path == URETPROBE_BIT_FILE_NAME) { SPDLOG_DEBUG("{} is uretprobe bit file", path.c_str()); - return mocked_file_provider( + return std::make_unique( "config:" + std::to_string(MOCKED_URETPROBE_BIT)); } else { SPDLOG_DEBUG("Unmocked file path: {}", path.c_str()); @@ -144,7 +145,7 @@ create_mocked_file_based_on_full_path(const std::filesystem::path &path) } std::optional -filename_and_fd_to_full_path(int fd, const char *file) +resolve_filename_and_fd_to_full_path(int fd, const char *file) { std::error_code ec; auto dir_path = std::filesystem::read_symlink( diff --git a/runtime/syscall-server/syscall_server_utils.hpp b/runtime/syscall-server/syscall_server_utils.hpp index 0939468c..dc245ec3 100644 --- a/runtime/syscall-server/syscall_server_utils.hpp +++ b/runtime/syscall-server/syscall_server_utils.hpp @@ -13,10 +13,10 @@ int determine_uprobe_perf_type(); int determine_uprobe_retprobe_bit(); void start_up(); -std::optional +std::optional > create_mocked_file_based_on_full_path(const std::filesystem::path &path); std::optional -filename_and_fd_to_full_path(int fd, const char *file); +resolve_filename_and_fd_to_full_path(int fd, const char *file); #define PERF_UPROBE_REF_CTR_OFFSET_BITS 32 #define PERF_UPROBE_REF_CTR_OFFSET_SHIFT 32 diff --git a/vm/llvm-jit b/vm/llvm-jit index 850dde3a..374c2fd5 160000 --- a/vm/llvm-jit +++ b/vm/llvm-jit @@ -1 +1 @@ -Subproject commit 850dde3a29af4d480e97ff4f853046d6a687aeb1 +Subproject commit 374c2fd5d2083c0ffdc6987ad45d6750e7eba20c