This commit is contained in:
2026-03-09 07:53:06 +00:00
parent 975afaf3f0
commit 470412a1c2
82 changed files with 7094 additions and 5234 deletions

298
src/hook/zvfs_hook_init.c Normal file
View File

@@ -0,0 +1,298 @@
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include "zvfs_hook_init.h"
#include "zvfs_hook_reentrant.h"
#include "fs/zvfs.h"
#include "fs/zvfs_open_file.h"
#include <dlfcn.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
#include <pthread.h>
/* ------------------------------------------------------------------ */
/* 线程局部重入计数定义 */
/* ------------------------------------------------------------------ */
__thread int _zvfs_hook_depth = 0;
/* ------------------------------------------------------------------ */
/* zvfs 挂载点 */
/* ------------------------------------------------------------------ */
#define ZVFS_MOUNT_PREFIX "/zvfs"
#define ZVFS_MOUNT_PREFIX_LEN 5 /* strlen("/zvfs") */
/* ------------------------------------------------------------------ */
/* real_* 函数指针定义 */
/* ------------------------------------------------------------------ */
/* open / close / dup */
int (*real_open)(const char *, int, ...) = NULL;
int (*real_open64)(const char *, int, ...) = NULL;
int (*real_openat)(int, const char *, int, ...) = NULL;
int (*real_openat64)(int, const char *, int, ...) = NULL;
int (*real_creat)(const char *, mode_t) = NULL;
int (*real_creat64)(const char *, mode_t) = NULL;
int (*real_close)(int) = NULL;
int (*real_close_range)(unsigned, unsigned, unsigned) = NULL;
int (*real_dup)(int) = NULL;
int (*real_dup2)(int, int) = NULL;
int (*real_dup3)(int, int, int) = NULL;
/* read */
ssize_t (*real_read)(int, void *, size_t) = NULL;
ssize_t (*real_pread)(int, void *, size_t, off_t) = NULL;
ssize_t (*real_pread64)(int, void *, size_t, off_t) = NULL;
ssize_t (*real_readv)(int, const struct iovec *, int) = NULL;
ssize_t (*real_preadv)(int, const struct iovec *, int, off_t) = NULL;
ssize_t (*real_preadv64)(int, const struct iovec *, int, off_t) = NULL;
ssize_t (*real_preadv2)(int, const struct iovec *, int, off_t, int) = NULL;
/* write */
ssize_t (*real_write)(int, const void *, size_t) = NULL;
ssize_t (*real_pwrite)(int, const void *, size_t, off_t) = NULL;
ssize_t (*real_pwrite64)(int, const void *, size_t, off_t) = NULL;
ssize_t (*real_writev)(int, const struct iovec *, int) = NULL;
ssize_t (*real_pwritev)(int, const struct iovec *, int, off_t) = NULL;
ssize_t (*real_pwritev64)(int, const struct iovec *, int, off_t) = NULL;
ssize_t (*real_pwritev2)(int, const struct iovec *, int, off_t, int) = NULL;
/* lseek / truncate / fallocate */
off_t (*real_lseek)(int, off_t, int) = NULL;
off_t (*real_lseek64)(int, off_t, int) = NULL;
int (*real_truncate)(const char *, off_t) = NULL;
int (*real_truncate64)(const char *, off_t) = NULL;
int (*real_ftruncate)(int, off_t) = NULL;
int (*real_ftruncate64)(int, off_t) = NULL;
int (*real_fallocate)(int, int, off_t, off_t) = NULL;
int (*real_posix_fallocate)(int, off_t, off_t) = NULL;
/* stat */
int (*real_stat)(const char *, struct stat *) = NULL;
int (*real_stat64)(const char *, struct stat64 *) = NULL;
int (*real_fstat)(int, struct stat *) = NULL;
int (*real_fstat64)(int, struct stat64 *) = NULL;
int (*real_lstat)(const char *, struct stat *) = NULL;
int (*real_lstat64)(const char *, struct stat64 *) = NULL;
int (*real_fstatat)(int, const char *, struct stat *, int) = NULL;
int (*real_fstatat64)(int, const char *, struct stat64 *, int) = NULL;
int (*real_statx)(int, const char *, int, unsigned int,
struct statx *) = NULL;
/* sync */
int (*real_fsync)(int) = NULL;
int (*real_fdatasync)(int) = NULL;
int (*real_sync_file_range)(int, off_t, off_t, unsigned int) = NULL;
/* fcntl / ioctl */
int (*real_fcntl)(int, int, ...) = NULL;
int (*real_fcntl64)(int, int, ...) = NULL;
int (*real_ioctl)(int, unsigned long, ...) = NULL;
/* 目录 */
int (*real_unlink)(const char *) = NULL;
int (*real_unlinkat)(int, const char *, int) = NULL;
int (*real_rename)(const char *, const char *) = NULL;
int (*real_renameat)(int, const char *, int, const char *) = NULL;
int (*real_renameat2)(int, const char *, int, const char *,
unsigned int) = NULL;
/* mmap */
void *(*real_mmap)(void *, size_t, int, int, int, off_t) = NULL;
void *(*real_mmap64)(void *, size_t, int, int, int, off_t) = NULL;
int (*real_munmap)(void *, size_t) = NULL;
int (*real_msync)(void *, size_t, int) = NULL;
/* fork */
pid_t (*real_fork)(void) = NULL;
pid_t (*real_vfork)(void) = NULL;
/* glibc 别名 */
int (*real___open)(const char *, int, ...) = NULL;
int (*real___open64)(const char *, int, ...) = NULL;
int (*real___libc_open)(const char *, int, ...) = NULL;
ssize_t (*real___read)(int, void *, size_t) = NULL;
ssize_t (*real___libc_read)(int, void *, size_t) = NULL;
ssize_t (*real___write)(int, const void *, size_t) = NULL;
ssize_t (*real___libc_write)(int, const void *, size_t) = NULL;
int (*real___close)(int) = NULL;
int (*real___libc_close)(int) = NULL;
/* ------------------------------------------------------------------ */
/* dlsym 辅助宏 */
/* ------------------------------------------------------------------ */
/*
* 找不到符号时不 fatal部分 glibc 内部别名在某些发行版上可能不存在,
* 置 NULL 后 hook 函数里做 NULL 检查再回退即可。
*/
#define LOAD_SYM(var, name) \
do { \
(var) = dlsym(RTLD_NEXT, (name)); \
if (!(var)) \
fprintf(stderr, "[zvfs] WARNING: dlsym(%s) = NULL\n", (name)); \
} while (0)
#define LOAD_SYM_OPTIONAL(var, name) \
do { (var) = dlsym(RTLD_NEXT, (name)); } while (0)
/* ------------------------------------------------------------------ */
/* 初始化 */
/* ------------------------------------------------------------------ */
__attribute__((constructor))
void zvfs_hook_init(void)
{
/* 必须存在的符号 */
LOAD_SYM(real_open, "open");
LOAD_SYM(real_open64, "open64");
LOAD_SYM(real_openat, "openat");
LOAD_SYM(real_openat64, "openat64");
LOAD_SYM(real_creat, "creat");
LOAD_SYM(real_creat64, "creat64");
LOAD_SYM(real_close, "close");
LOAD_SYM(real_dup, "dup");
LOAD_SYM(real_dup2, "dup2");
LOAD_SYM(real_dup3, "dup3");
LOAD_SYM(real_read, "read");
LOAD_SYM(real_pread, "pread");
LOAD_SYM(real_pread64, "pread64");
LOAD_SYM(real_readv, "readv");
LOAD_SYM(real_preadv, "preadv");
LOAD_SYM(real_preadv64, "preadv64");
LOAD_SYM(real_write, "write");
LOAD_SYM(real_pwrite, "pwrite");
LOAD_SYM(real_pwrite64, "pwrite64");
LOAD_SYM(real_writev, "writev");
LOAD_SYM(real_pwritev, "pwritev");
LOAD_SYM(real_pwritev64, "pwritev64");
LOAD_SYM(real_lseek, "lseek");
LOAD_SYM(real_lseek64, "lseek64");
LOAD_SYM(real_truncate, "truncate");
LOAD_SYM(real_truncate64, "truncate64");
LOAD_SYM(real_ftruncate, "ftruncate");
LOAD_SYM(real_ftruncate64, "ftruncate64");
LOAD_SYM(real_fallocate, "fallocate");
LOAD_SYM(real_posix_fallocate,"posix_fallocate");
LOAD_SYM(real_stat, "stat");
LOAD_SYM(real_stat64, "stat64");
LOAD_SYM(real_fstat, "fstat");
LOAD_SYM(real_fstat64, "fstat64");
LOAD_SYM(real_lstat, "lstat");
LOAD_SYM(real_lstat64, "lstat64");
LOAD_SYM(real_fstatat, "fstatat");
LOAD_SYM(real_fstatat64, "fstatat64");
LOAD_SYM(real_fsync, "fsync");
LOAD_SYM(real_fdatasync, "fdatasync");
LOAD_SYM(real_fcntl, "fcntl");
LOAD_SYM(real_fcntl64, "fcntl64");
LOAD_SYM(real_ioctl, "ioctl");
LOAD_SYM(real_unlink, "unlink");
LOAD_SYM(real_unlinkat, "unlinkat");
LOAD_SYM(real_rename, "rename");
LOAD_SYM(real_renameat, "renameat");
LOAD_SYM(real_mmap, "mmap");
LOAD_SYM(real_mmap64, "mmap64");
LOAD_SYM(real_munmap, "munmap");
LOAD_SYM(real_msync, "msync");
LOAD_SYM(real_fork, "fork");
LOAD_SYM(real_vfork, "vfork");
/* 可选符号glibc 内部别名,不一定存在 */
LOAD_SYM_OPTIONAL(real_close_range, "close_range");
LOAD_SYM_OPTIONAL(real_preadv2, "preadv2");
LOAD_SYM_OPTIONAL(real_pwritev2, "pwritev2");
LOAD_SYM_OPTIONAL(real_statx, "statx");
LOAD_SYM_OPTIONAL(real_sync_file_range,"sync_file_range");
LOAD_SYM_OPTIONAL(real_renameat2, "renameat2");
LOAD_SYM_OPTIONAL(real___open, "__open");
LOAD_SYM_OPTIONAL(real___open64, "__open64");
LOAD_SYM_OPTIONAL(real___libc_open, "__libc_open");
LOAD_SYM_OPTIONAL(real___read, "__read");
LOAD_SYM_OPTIONAL(real___libc_read, "__libc_read");
LOAD_SYM_OPTIONAL(real___write, "__write");
LOAD_SYM_OPTIONAL(real___libc_write, "__libc_write");
LOAD_SYM_OPTIONAL(real___close, "__close");
LOAD_SYM_OPTIONAL(real___libc_close, "__libc_close");
/* 初始化全局 fs 结构 */
zvfs_fs_init();
}
/* ------------------------------------------------------------------ */
/* 路径 / fd 判断 */
/* ------------------------------------------------------------------ */
int
zvfs_is_zvfs_path(const char *path)
{
if (!path)
return 0;
/* 路径必须以 /zvfs 开头,且后一个字符是 '/' 或 '\0' */
if (strncmp(path, ZVFS_MOUNT_PREFIX, ZVFS_MOUNT_PREFIX_LEN) != 0)
return 0;
char next = path[ZVFS_MOUNT_PREFIX_LEN];
return (next == '/' || next == '\0');
}
int
zvfs_is_zvfs_fd(int fd)
{
if (fd < 0)
return 0;
pthread_mutex_lock(&g_fs.fd_mu);
struct zvfs_open_file *of = openfile_lookup(fd);
pthread_mutex_unlock(&g_fs.fd_mu);
return (of != NULL);
}
/* ------------------------------------------------------------------ */
/* dirfd + 相对路径 → 绝对路径 */
/* ------------------------------------------------------------------ */
int
zvfs_resolve_atpath(int dirfd, const char *path, char *buf, size_t bufsz)
{
/* 绝对路径:直接拷贝 */
if (path && path[0] == '/') {
if (strlen(path) >= bufsz) {
errno = ENAMETOOLONG;
return -1;
}
strncpy(buf, path, bufsz);
buf[bufsz - 1] = '\0';
return 0;
}
/* AT_FDCWD以当前工作目录为基准 */
if (dirfd == AT_FDCWD) {
if (!getcwd(buf, bufsz)) return -1;
} else {
/* 通过 /proc/self/fd/<dirfd> 读出目录的绝对路径 */
char proc_path[64];
snprintf(proc_path, sizeof(proc_path), "/proc/self/fd/%d", dirfd);
ssize_t len = readlink(proc_path, buf, bufsz - 1);
if (len < 0) return -1;
buf[len] = '\0';
}
/* 拼接 path */
size_t dir_len = strlen(buf);
size_t path_len = path ? strlen(path) : 0;
if (dir_len + 1 + path_len >= bufsz) {
errno = ENAMETOOLONG;
return -1;
}
if (path_len > 0) {
buf[dir_len] = '/';
memcpy(buf + dir_len + 1, path, path_len + 1);
}
return 0;
}