Skip to content

Commit

Permalink
almost working
Browse files Browse the repository at this point in the history
  • Loading branch information
Officeyutong committed Aug 27, 2024
1 parent 761b118 commit a9598f8
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 5 deletions.
2 changes: 1 addition & 1 deletion runtime/syscall-server/syscall-server.version
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
global: epoll_wait; epoll_ctl; epoll_create1; ioctl; mmap64; mmap; close; syscall; munmap;
global: epoll_wait; epoll_ctl; epoll_create1; ioctl; mmap64; mmap; close; syscall; munmap; open; openat; read; fopen; fopen64; _IO_new_fopen;
local: *;
};
31 changes: 31 additions & 0 deletions runtime/syscall-server/syscall_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/
#include "bpftime_logger.hpp"
#include "bpftime_shm.hpp"
#include <cstdio>
#include <ebpf-vm.h>
#include "syscall_context.hpp"
#include "handler/map_handler.hpp"
Expand Down Expand Up @@ -810,3 +811,33 @@ int syscall_context::handle_munmap(void *addr, size_t size)
return orig_munmap_fn(addr, size);
}
}

FILE *syscall_context::handle_fopen(const char *pathname, const char *flags)
{
if (!enable_mock)
return orig_fopen_fn(pathname, flags);
try_startup();
if (auto mocker = create_mocked_file_based_on_full_path(pathname);
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_fopen_fn(pathname, flags);
}
auto itr =
this->mocked_files.emplace(fake_fd, std::move(*mocker))
.first;
FILE *replacement_fp = fopen(filename_buf, "r");

itr->second->replacement_file = replacement_fp;
auto size_written = write(fake_fd, itr->second->buf.c_str(),
itr->second->buf.size());
SPDLOG_DEBUG(
"Created fake fd {}, replacement fp {:x}, written {} bytes",
fake_fd, (uintptr_t)replacement_fp, size_written);
return replacement_fp;
}
return orig_fopen_fn(pathname, flags);
}
11 changes: 10 additions & 1 deletion runtime/syscall-server/syscall_context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ struct mocked_file_provider {
int cursor = 0;
std::string buf;
pthread_spinlock_t access_lock;
FILE *replacement_file = nullptr;
mocked_file_provider(std::string buf) : buf(buf)
{
pthread_spin_init(&access_lock, 0);
Expand Down Expand Up @@ -60,6 +61,8 @@ class syscall_context {
using openat_fn = int (*)(int, const char *, int, ...);
using open_fn = int (*)(const char *, int, ...);
using read_fn = ssize_t (*)(int fd, void *buf, size_t count);
using fopen_fn = FILE *(*)(const char *, const char *);

close_fn orig_close_fn = nullptr;
mmap64_fn orig_mmap64_fn = nullptr;
ioctl_fn orig_ioctl_fn = nullptr;
Expand All @@ -71,6 +74,8 @@ class syscall_context {
open_fn orig_open_fn = nullptr;
mmap_fn orig_mmap_fn = nullptr;
read_fn orig_read_fn = nullptr;
fopen_fn orig_fopen_fn = nullptr;

std::unordered_set<uintptr_t> mocked_mmap_values;
pthread_spinlock_t mocked_file_lock;
std::unordered_map<int, std::unique_ptr<mocked_file_provider> >
Expand All @@ -91,6 +96,8 @@ class syscall_context {
(mmap_fn)dlsym(RTLD_NEXT, "mmap");
orig_openat_fn = (openat_fn)dlsym(RTLD_NEXT, "openat");
orig_open_fn = (open_fn)dlsym(RTLD_NEXT, "open");
orig_fopen_fn = (fopen_fn)dlsym(RTLD_NEXT, "fopen");

// To avoid polluting other child processes,
// unset the LD_PRELOAD env var after syscall context being
// initialized
Expand All @@ -103,7 +110,8 @@ class syscall_context {
(uintptr_t)orig_ioctl_fn, (uintptr_t)orig_syscall_fn,
(uintptr_t)orig_mmap64_fn, (uintptr_t)orig_close_fn,
(uintptr_t)orig_munmap_fn, (uintptr_t)orig_mmap_fn,
(uintptr_t)orig_openat_fn, (uintptr_t)orig_open_fn);
(uintptr_t)orig_openat_fn, (uintptr_t)orig_open_fn,
(uintptr_t)orig_fopen_fn);
}

int create_kernel_bpf_map(int fd);
Expand Down Expand Up @@ -153,6 +161,7 @@ class syscall_context {
unsigned short mode);
int handle_open(const char *file, int oflag, unsigned short mode);
ssize_t handle_read(int fd, void *buf, size_t count);
FILE *handle_fopen(const char *pathname, const char *flags);
};

#endif
45 changes: 42 additions & 3 deletions runtime/syscall-server/syscall_server_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
* All rights reserved.
*/
#include "syscall_context.hpp"
#include "bpftime_shm.hpp"
#include <boost/interprocess/exceptions.hpp>
#include <cstdio>
#if __linux__
#include "linux/bpf.h"
#include <asm-generic/errno-base.h>
Expand All @@ -16,8 +17,6 @@
#include <unistd.h>
#include <spdlog/cfg/env.h>
#include <cstdarg>
using namespace bpftime;

// global context for bpf syscall server
static syscall_context context;

Expand Down Expand Up @@ -123,6 +122,46 @@ extern "C" ssize_t read(int fd, void *buf, size_t count)
{
return context.handle_read(fd, buf, count);
}

extern "C" FILE *fopen(const char *pathname, const char *flags)
{
SPDLOG_DEBUG("fopen {} {}", pathname, flags);
return context.handle_fopen(pathname, flags);
}
extern "C" FILE *fopen64(const char *pathname, const char *flags)
{
SPDLOG_DEBUG("fopen64 {} {}", pathname, flags);
return context.handle_fopen(pathname, flags);
}
extern "C" FILE *_IO_new_fopen(const char *pathname, const char *flags)
{
SPDLOG_DEBUG("_IO_new_fopen {} {}", pathname, flags);
return context.handle_fopen(pathname, flags);
}
// extern "C" int fclose(FILE *f)
// {
// SPDLOG_DEBUG("fclose {:x}", (uintptr_t)f);
// return context.handle_fclose(f);
// }
// extern "C" int fscanf(FILE *fp, const char *fmt, ...)
// {
// SPDLOG_DEBUG("fscanf {:x} {}", (uintptr_t)fp, fmt);
// va_list args;
// va_start(args, fmt);
// int result = context.handle_fscanf(fp, fmt, args);
// va_end(args);
// return result;
// }

// extern "C" int __isoc99_fscanf(FILE *fp, const char *fmt, ...)
// {
// SPDLOG_DEBUG("__isoc99_fscanf {:x} {}", (uintptr_t)fp, fmt);
// va_list args;
// va_start(args, fmt);
// int result = context.handle_fscanf(fp, fmt, args);
// va_end(args);
// return result;
// }
#if __linux__
extern "C" long syscall(long sysno, ...)
{
Expand Down

0 comments on commit a9598f8

Please sign in to comment.