diff --git a/include/client/gkfs_libc.hpp b/include/client/gkfs_libc.hpp new file mode 100644 index 0000000000000000000000000000000000000000..f2a15c062623f7f1c0bf85265334498c1970091e --- /dev/null +++ b/include/client/gkfs_libc.hpp @@ -0,0 +1,346 @@ +/* + * Copyright 2000-2024 Felix Garcia Carballeira, Diego Camarmas Alonso, + * Alejandro Calderon Mateos, Luis Miguel Sanchez Garcia, Borja Bergua Guerra + * + * This file is part of Expand. + * + * Expand is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Expand is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Expand. If not, see . + * + * Modifications to support GekkoFS done by : + * Copyright 2018-2024, Barcelona Supercomputing Center (BSC), Spain + * Copyright 2015-2024, Johannes Gutenberg Universitaet Mainz, Germany + * + * This software was partially supported by the + * EC H2020 funded project NEXTGenIO (Project ID: 671951, www.nextgenio.eu). + * + * This software was partially supported by the + * ADA-FS project under the SPPEXA project funded by the DFG. + * + * SPDX-License-Identifier: LGPL-3.0-or-later + */ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include +#include + +#include +#include + + +#ifndef _STAT_VER +#define _STAT_VER 0 +#endif + +struct __dirstream { + int fd; // File descriptor. + //__libc_lock_define (, lock) // Mutex lock for this structure. //TODO + size_t allocation; // Space allocated for the block. + size_t size; // Total valid data in the block. + size_t offset; // Current offset into the block. + off_t filepos; // Position of next entry to read. + // Directory block. + char data[0] __attribute__((aligned(__alignof__(void*)))); + + char* path; +}; + + +// File API +int +dlsym_open(char* path, int flags); +int +dlsym_open2(char* path, int flags, mode_t mode); +int +dlsym_open64(char* path, int flags, mode_t mode); +int +dlsym_openat(int fd, const char* pathname, int flags, mode_t mode); +int +dlsym___open_2(char* path, int flags); +int +dlsym_close(int fd); +int +dlsym_close_range(unsigned int low, unsigned int high, int flags); +int +dlsym_creat(const char* path, mode_t mode); +int +dlsym_ftruncate(int fd, off_t length); +int +dlsym_mkstemp(char* templates); + +ssize_t +dlsym_read(int fd, void* buf, size_t nbyte); +ssize_t +dlsym_write(int fd, void* buf, size_t nbyte); + +ssize_t +dlsym_pread(int fd, void* buf, size_t count, off_t offset); +ssize_t +dlsym_pwrite(int fd, const void* buf, size_t count, off_t offset); +ssize_t +dlsym_pread64(int fd, void* buf, size_t count, off_t offset); +ssize_t +dlsym_pwrite64(int fd, const void* buf, size_t count, off_t offset); + +off_t +dlsym_lseek(int fd, off_t offset, int whence); +off64_t +dlsym_lseek64(int fd, off64_t offset, int whence); + +int +dlsym_fstat(int ver, int fd, struct stat* buf); +int +dlsym_fxstat64(int ver, int fd, struct stat64* buf); +int +dlsym_stat(int ver, const char* path, struct stat* buf); +int +dlsym_lstat(int ver, const char* path, struct stat* buf); +int +dlsym_lxstat64(int ver, const char* path, struct stat64* buf); +int +dlsym_xstat64(int ver, const char* path, struct stat64* buf); +int +dlsym_fstatat(int dfd, const char* path, struct stat* buf, int flags); +int +dlsym_fstatat64(int dfd, const char* path, struct stat64* buf, int flags); + +int +dlsym_statx(int dirfd, const char* path, int flags, unsigned int mask, + struct statx* buf); +int +dlsym_rename(const char* old_path, const char* new_path); +int +dlsym_unlink(char* path); +int +dlsym_remove(char* path); + + +// File API (stdio) +FILE* +dlsym_fopen(const char* filename, const char* mode); +FILE* +dlsym_fdopen(int fd, const char* mode); +int +dlsym_fclose(FILE* stream); + +size_t +dlsym_fread(void* ptr, size_t size, size_t nmemb, FILE* stream); +size_t +dlsym_fwrite(const void* ptr, size_t size, size_t nmemb, FILE* stream); + +int +dlsym_fseek(FILE* stream, long int offset, int whence); +long +dlsym_ftell(FILE* stream); +void +dlsym_rewind(FILE* stream); +int +dlsym_feof(FILE* stream); + + +// Directory API +DIR* +dlsym_opendir(char* dirname); +DIR* +dlsym_opendir64(char* dirname); +int +dlsym_closedir(DIR* dirp); + +long +dlsym_telldir(DIR* dirp); +void +dlsym_seekdir(DIR* dirp, long loc); + +struct dirent* +dlsym_readdir(DIR* dirp); +struct dirent64* +dlsym_readdir64(DIR* dirp); + +int +dlsym_mkdir(char* path, mode_t mode); +int +dlsym_rmdir(char* path); + + +// Proccess API +int +dlsym_fork(void); + +int +dlsym_pipe(int pipefd[2]); + +int +dlsym_dup(int fd); +int +dlsym_dup2(int fd, int fd2); + +void +dlsym_exit(int status); + + +// Manager API +int +dlsym_chdir(char* path); +int +dlsym_chmod(char* path, mode_t mode); +int +dlsym_fchmod(int fd, mode_t mode); +int +dlsym_chown(char* path, uid_t owner, gid_t group); +int +dlsym_fcntl(int fd, int cmd, long arg); +int +dlsym_access(const char* path, int mode); +int +dlsym_fsync(int fd); +int +dlsym_flock(int fd, int operation); + +// Manager API + +char* +dlsym_realpath(const char* path, char* resolved_path); + + +// Memory API +void* +dlsym_mmap(void* addr, size_t length, int prot, int flags, int fd, + off_t offset); + +int +open64(const char* path, int flags, ...); +int +open(const char* path, int flags, ...); +// openat +int +openat(int __fd, const char* __file, int __oflag, ...); + + +int +openat64(int dirfd, const char* path, int flags, ...); + + +int +close(int fd); +int +creat(const char* path, mode_t mode); +int +ftruncate(int fd, off_t length) noexcept; +int +mkstemp(char* templates); + +ssize_t +read(int fd, void* buf, size_t nbyte); +ssize_t +write(int fd, const void* buf, size_t nbyte); + +int +mkdir(const char* path, mode_t mode); + +int +rmdir(const char* path) noexcept; +int +dup(int oldfd) __THROW __wur; +int +dup2(int oldfd, int newfd) __THROW; +int +dup3(int oldfd, int newfd, int flags) __THROW; +ssize_t +pread(int fd, void* buf, size_t count, off_t offset); +ssize_t +pwrite(int fd, const void* buf, size_t count, off_t offset); +ssize_t +pread64(int fd, void* buf, size_t count, off_t offset); +ssize_t +pwrite64(int fd, const void* buf, size_t count, off_t offset); + +off_t +lseek(int fd, off_t offset, int whence) __THROW; +off64_t +lseek64(int fd, off64_t offset, int whence) __THROW; +// statvfs + +int +statvfs(const char* path, struct statvfs* buf); +int +fstatvfs(int fd, struct statvfs* buf); + +int +fstat(int fd, struct stat* buf); +int +fstat64(int fd, struct stat64* buf); +int +stat(const char* path, struct stat* buf); + + +int +__xstat(int ver, const char* path, struct stat* buf); +int +__xstat64(int ver, const char* path, struct stat64* buf); +int +__fxstat64(int ver, int fd, struct stat64* buf); +int +__lxstat(int ver, const char* path, struct stat* buf); +int +__lxstat64(int ver, const char* path, struct stat64* buf); +int +__fxstat(int ver, int fd, struct stat* buf); +int +__fxstatat(int ver, int dfd, const char* path, struct stat* buf, int flags); +int +__fxstatat64(int ver, int dfd, const char* path, struct stat64* buf, int flags); + +int +statx(int dirfd, const char* pathname, int flags, unsigned int mask, + struct statx* statxbuf); +int +rename(const char* old_path, const char* new_path); +int +unlink(const char* path) __THROW __nonnull((1)); +int +remove(const char* path); + +DIR* +opendir(const char* dirname); +DIR* +opendir64(const char* dirname); +int +closedir(DIR* dirp); + +long +telldir(DIR* dirp); +void +seekdir(DIR* dirp, long loc); + +struct dirent* +readdir(DIR* dirp); +struct dirent64* +readdir64(DIR* dirp); + +int +clone(int (*fn)(void*), void* stack, int flags, void* arg, ...); +/* pid_t *parent_tid, void *tls, pid_t *child_tid */ + +/* ................................................................... */ + +#ifdef __cplusplus +} +#endif diff --git a/include/client/preload.hpp b/include/client/preload.hpp index afad97c684bbb5736bceef4079e67adc7b120b3c..88d708251c4e246f61ccf81adfa92eb60351293c 100644 --- a/include/client/preload.hpp +++ b/include/client/preload.hpp @@ -38,6 +38,8 @@ #define CTX gkfs::preload::PreloadContext::getInstance() namespace gkfs::preload { void +init_environment(); +void init_ld_env_if_needed(); } // namespace gkfs::preload @@ -47,6 +49,12 @@ init_preload() __attribute__((constructor)); void destroy_preload() __attribute__((destructor)); +#elif ENABLE_INIT +void +init_libc() __attribute__((constructor)); + +void +destroy_libc() __attribute__((destructor)); #endif #endif // IOINTERCEPT_PRELOAD_HPP diff --git a/include/client/preload_context.hpp b/include/client/preload_context.hpp index d818ca21eb287ea89f54be42910937465b48c5d2..ef3c4da2b7cc3050982cd071d26916c014d07106 100644 --- a/include/client/preload_context.hpp +++ b/include/client/preload_context.hpp @@ -128,6 +128,11 @@ private: std::bitset protected_fds_; std::string hostname; int replicas_; +#ifdef BYPASS_SYSCALL + bool protect_fds_{false}; +#else + bool protect_fds_{true}; +#endif std::shared_ptr write_metrics_; std::shared_ptr read_metrics_; @@ -301,6 +306,12 @@ public: int get_replicas(); + bool + protect_fds() const; + + void + protect_fds(bool protect); + const std::shared_ptr write_metrics(); diff --git a/include/client/syscalls/decoder.hpp b/include/client/syscalls/decoder.hpp index 3172cc2df291c118dcf3de9c13cfa19f7177b10c..04d4ecb1be7d308c08540455ba599e3f3bc5bf3a 100644 --- a/include/client/syscalls/decoder.hpp +++ b/include/client/syscalls/decoder.hpp @@ -60,7 +60,8 @@ decode(FmtBuffer& buffer, const long syscall_number, const auto sc = lookup_by_number(syscall_number, argv); - fmt::format_to(std::back_inserter(buffer), "{}(", sc.name()); + fmt::format_to(std::back_inserter(buffer), "{} {}(", sc.name(), + syscall_number); for(int i = 0; i < sc.num_args(); ++i) { const auto arg = sc.args().at(i); diff --git a/include/client/user_functions.hpp b/include/client/user_functions.hpp index 5f96ab3c1927dfb5ffcd3233ccccf64ec3994e05..0d79409fce1f810115106414399399924ad6120c 100644 --- a/include/client/user_functions.hpp +++ b/include/client/user_functions.hpp @@ -38,6 +38,7 @@ extern "C" { #include } +struct linux_dirent; struct linux_dirent64; namespace gkfs { @@ -73,11 +74,37 @@ gkfs_pread(int fd, void* buf, size_t count, off64_t offset); int gkfs_stat(const std::string& path, struct stat* buf, bool follow_links = true); +int +gkfs_statx(int dirfs, const std::string& path, int flags, unsigned int mask, + struct statx* buf, bool follow_links = true); + int gkfs_remove(const std::string& path); +int +gkfs_dup(const int oldfd); + +int +gkfs_dup2(const int oldfd, const int newfd); + +int +gkfs_access(const std::string& path, const int mask, bool follow_links); + std::vector gkfs_get_file_list(const std::string& path); + + +int +gkfs_opendir(const std::string& path); + +int +gkfs_getdents(unsigned int fd, struct linux_dirent* dirp, unsigned int count); + +int +gkfs_getdents64(unsigned int fd, struct linux_dirent64* dirp, + unsigned int count); + + } // namespace syscall namespace malleable { diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt index c31abeedcfe4b304288e5eeafb3b0359bfa79d44..62d6fb17a82fe4bcea019dd771baf8325b63a077 100644 --- a/src/client/CMakeLists.txt +++ b/src/client/CMakeLists.txt @@ -34,6 +34,7 @@ add_library(gkfs_intercept SHARED) add_library(gkfs_user_lib SHARED) +add_library(gkfs_libc_intercept SHARED) target_sources(gkfs_intercept @@ -80,9 +81,38 @@ target_sources( syscalls/detail/syscall_info.c syscalls/util.S ) +target_sources( + gkfs_libc_intercept + PRIVATE gkfs_functions.cpp + gkfs_libc.cpp + intercept.cpp + hooks.cpp + logging.cpp + open_file_map.cpp + open_dir.cpp + path.cpp + preload.cpp + preload_context.cpp + preload_util.cpp + malleability.cpp + cache.cpp + rpc/rpc_types.cpp + rpc/forward_data.cpp + rpc/forward_data_proxy.cpp + rpc/forward_management.cpp + rpc/forward_metadata.cpp + rpc/forward_metadata_proxy.cpp + rpc/forward_malleability.cpp + syscalls/detail/syscall_info.c syscalls/util.S + +) + target_compile_definitions(gkfs_user_lib PUBLIC BYPASS_SYSCALL) target_link_options(gkfs_user_lib PRIVATE -z noexecstack) +target_compile_definitions(gkfs_libc_intercept PUBLIC BYPASS_SYSCALL ENABLE_INIT) +target_link_options(gkfs_libc_intercept PRIVATE -z noexecstack) + if (GKFS_ENABLE_AGIOS) target_compile_definitions(gkfs_intercept PUBLIC GKFS_ENABLE_AGIOS) endif () @@ -120,6 +150,18 @@ target_link_libraries( Microsoft.GSL::GSL ) +target_link_libraries( + gkfs_libc_intercept + PRIVATE metadata distributor env_util arithmetic path_util rpc_utils + PUBLIC dl + Mercury::Mercury + hermes + fmt::fmt + Threads::Threads + Microsoft.GSL::GSL +) + + install( TARGETS gkfs_intercept LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} @@ -141,3 +183,16 @@ install( ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/gkfs ) + +set_target_properties(gkfs_libc_intercept + PROPERTIES + PUBLIC_HEADER "../../include/client/void_syscall_intercept.hpp" + PUBLIC_HEADER "../../include/client/user_functions.hpp" +) + +install( + TARGETS gkfs_libc_intercept + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/gkfs +) \ No newline at end of file diff --git a/src/client/gkfs_functions.cpp b/src/client/gkfs_functions.cpp index 17dd464808a330bf15449ccbfad9ab899f99645d..0e50c83ee15f3a61d27100e4768802df94ae3b77 100644 --- a/src/client/gkfs_functions.cpp +++ b/src/client/gkfs_functions.cpp @@ -65,9 +65,15 @@ using namespace std; * kernel: fs/readdir.c. */ struct linux_dirent { +#ifndef __USE_FILE_OFFSET64 unsigned long d_ino; unsigned long d_off; +#else + uint64_t d_ino; + int64_t d_off; +#endif unsigned short d_reclen; + unsigned char d_type; // Does it break dirents? char d_name[1]; }; /* @@ -140,12 +146,6 @@ namespace gkfs::syscall { int gkfs_open(const std::string& path, mode_t mode, int flags) { - if(flags & O_PATH) { - LOG(ERROR, "`O_PATH` flag is not supported"); - errno = ENOTSUP; - return -1; - } - // metadata object filled during create or stat gkfs::metadata::Metadata md{}; if(flags & O_CREAT) { @@ -1495,7 +1495,7 @@ gkfs_getdents(unsigned int fd, struct linux_dirent* dirp, unsigned int count) { current_dirp->d_reclen = total_size; - *(reinterpret_cast(current_dirp) + total_size - 1) = + current_dirp->d_type = ((de.type() == gkfs::filemap::FileType::regular) ? DT_REG : DT_DIR); @@ -1643,7 +1643,8 @@ gkfs_close(unsigned int fd) { if(CTX->is_internal_fd(fd)) { // the client application (for some reason) is trying to close an // internal fd: ignore it - return 0; + return -1; + // Maybe we should return -1? } return -1; diff --git a/src/client/gkfs_libc.cpp b/src/client/gkfs_libc.cpp new file mode 100644 index 0000000000000000000000000000000000000000..172b93607377166e9b24691d5b4810896c92f0af --- /dev/null +++ b/src/client/gkfs_libc.cpp @@ -0,0 +1,2378 @@ +/* + * Copyright 2000-2024 Felix Garcia Carballeira, Diego Camarmas Alonso, + * Alejandro Calderon Mateos, Luis Miguel Sanchez Garcia, Borja Bergua Guerra + * + * This file is part of Expand. + * + * Expand is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Expand is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Expand. If not, see . + * + * Modifications to support GekkoFS done by : + * Copyright 2018-2024, Barcelona Supercomputing Center (BSC), Spain + * Copyright 2015-2024, Johannes Gutenberg Universitaet Mainz, Germany + * + * This software was partially supported by the + * EC H2020 funded project NEXTGenIO (Project ID: 671951, www.nextgenio.eu). + * + * This software was partially supported by the + * ADA-FS project under the SPPEXA project funded by the DFG. + * + * SPDX-License-Identifier: LGPL-3.0-or-later + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +std::atomic activated{false}; +std::atomic initializing{false}; +#define debug_info printf +// #define debug_info(...) + +thread_local std::atomic reentrant = false; +int (*real_open)(char*, int, mode_t) = NULL; +int (*real_open64)(char*, int, mode_t) = NULL; +int (*real___open_2)(char*, int) = NULL; +int (*real_openat)(int, char*, int, mode_t) = NULL; +int (*real_close)(int) = NULL; +int (*real_close_range)(unsigned int, unsigned int, int) = NULL; +int (*real_creat)(const char*, mode_t) = NULL; +int (*real_ftruncate)(int, off_t) = NULL; +int (*real_mkstemp)(char*) = NULL; +int (*real_mkdir)(const char*, mode_t) = NULL; +int (*real_rmdir)(const char*) = NULL; +ssize_t (*real_read)(int, void*, size_t) = NULL; +ssize_t (*real_write)(int, const void*, size_t) = NULL; +ssize_t (*real_pread)(int, void*, size_t, off_t) = NULL; +ssize_t (*real_pwrite)(int, const void*, size_t, off_t) = NULL; +ssize_t (*real_pread64)(int, void*, size_t, off_t) = NULL; +ssize_t (*real_pwrite64)(int, const void*, size_t, off_t) = NULL; +off_t (*real_lseek)(int, off_t, int) = NULL; +off64_t (*real_lseek64)(int, off64_t, int) = NULL; +int (*real_stat)(int, char*, struct stat*) = NULL; +int (*real_xstat64)(int, const char*, struct stat64*) = NULL; +int (*real_lstat)(int, char*, struct stat*) = NULL; +int (*real_lxstat64)(int, const char*, struct stat64*) = NULL; +int (*real_fstat)(int, int, struct stat*) = NULL; +int (*real_fxstat64)(int, int, 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_rename)(const char*, const char*) = NULL; +int (*real_unlink)(const char*) = NULL; +int (*real_remove)(char*) = NULL; +int (*real_statx)(int, const char*, int, unsigned int, struct statx*) = NULL; + +// Directory API +DIR* (*real_opendir)(char*) = NULL; +DIR* (*real_opendir64)(char*) = NULL; +int (*real_closedir)(DIR*) = NULL; +long (*real_telldir)(DIR*) = NULL; +void (*real_seekdir)(DIR*, long) = NULL; +struct dirent* (*real_readdir)(DIR*) = NULL; +struct dirent64* (*real_readdir64)(DIR*) = NULL; + +// Proccess API +int (*real_fork)(void) = NULL; +int (*real_pipe)(int*) = NULL; +int (*real_dup)(int) = NULL; +int (*real_dup2)(int, int) = NULL; +void (*real_exit)(int) = NULL; +int (*real_chdir)(char*) = NULL; +int (*real_chmod)(char*, mode_t) = NULL; +int (*real_fchmod)(int, mode_t) = NULL; +int (*real_chown)(char*, uid_t, gid_t) = NULL; +int (*real_fcntl)(int, int, long) = NULL; +int (*real_access)(const char*, int) = NULL; +char* (*real_realpath)(const char*, char*) = NULL; +int (*real_fsync)(int) = NULL; +int (*real_flock)(int, int) = NULL; +void* (*real_mmap)(void*, size_t, int, int, int, off_t) = NULL; +int (*real_clone)(int(void*), void*, int, void*, pid_t*, void*, pid_t*) = NULL; + +void +initializeGekko() { + // if the activated is false call init + // Create a global mutex + /* + if(!activated and !initializing) { + debug_info("[BYPASS] >> DEACTIVATED GEKKOFS.... \n"); + initializing = true; + init_libc(); + activated = true; + initializing = false; + debug_info("[BYPASS] >> ACTIVATED GEKKOFS.... \n"); + } + */ +} +int +dlsym_open(char* path, int flags) { + + + if(real_open == NULL) { + real_open = (int (*)(char*, int, mode_t)) dlsym(RTLD_NEXT, "open"); + } + + int fd = real_open((char*) path, flags, 0); + + + return fd; +} + +int +dlsym_open2(char* path, int flags, mode_t mode) { + + if(real_open == NULL) { + real_open = (int (*)(char*, int, mode_t)) dlsym(RTLD_NEXT, "open"); + } + + int fd = real_open((char*) path, flags, mode); + + return fd; +} + +int +dlsym_openat(int fd, char* path, int flags, mode_t mode) { + + if(real_openat == NULL) { + real_openat = + (int (*)(int, char*, int, mode_t)) dlsym(RTLD_NEXT, "openat"); + } + + int fd2 = real_openat(fd, (char*) path, flags, mode); + + + return fd2; +} + +int +dlsym_open64(char* path, int flags, mode_t mode) { + + + if(real_open64 == NULL) { + real_open64 = (int (*)(char*, int, mode_t)) dlsym(RTLD_NEXT, "open64"); + } + + int fd = real_open64((char*) path, flags, mode); + + + return fd; +} + +int +dlsym___open_2(char* path, int flags) { + + + if(real___open_2 == NULL) { + real___open_2 = (int (*)(char*, int)) dlsym(RTLD_NEXT, "__open"); + } + + int fd = real___open_2((char*) path, flags); + + + return fd; +} + +int +dlsym_close(int fd) { + + + if(real_close == NULL) { + real_close = (int (*)(int)) dlsym(RTLD_NEXT, "close"); + } + + int ret = real_close(fd); + + + return ret; +} + +int +dlsym_close_range(unsigned int low, unsigned int high, int flags) { + if(real_close_range == NULL) { + real_close_range = (int (*)(unsigned int, unsigned int, int)) dlsym( + RTLD_NEXT, "close_range"); + } + + int ret = real_close_range(low, high, flags); + return ret; +} + +int +dlsym_creat(const char* path, mode_t mode) { + if(real_creat == NULL) { + real_creat = (int (*)(const char*, mode_t)) dlsym(RTLD_NEXT, "creat"); + } + + int fd = real_creat((char*) path, mode); + + return fd; +} + +int +dlsym_ftruncate(int fd, off_t length) { + if(real_ftruncate == NULL) { + real_ftruncate = (int (*)(int, off_t)) dlsym(RTLD_NEXT, "ftruncate"); + } + + int ret = real_ftruncate(fd, length); + + return ret; +} + +ssize_t +dlsym_read(int fd, void* buf, size_t nbyte) { + if(real_read == NULL) { + real_read = (ssize_t(*)(int, void*, size_t)) dlsym(RTLD_NEXT, "read"); + } + + ssize_t ret = real_read(fd, buf, nbyte); + + return ret; +} + +ssize_t +dlsym_write(int fd, const void* buf, size_t nbyte) { + + + if(real_write == NULL) { + real_write = (ssize_t(*)(int, const void*, size_t)) dlsym(RTLD_NEXT, + "write"); + } + + ssize_t ret = real_write(fd, buf, nbyte); + + + return ret; +} + +int +dlsym_mkdir(const char* path, mode_t mode) { + + if(real_mkdir == NULL) { + real_mkdir = (int (*)(const char*, mode_t)) dlsym(RTLD_NEXT, "mkdir"); + } + + int ret = real_mkdir(path, mode); + + return ret; +} + +int +dlsym_rmdir(const char* path) { + + if(real_rmdir == NULL) { + real_rmdir = (int (*)(const char*)) dlsym(RTLD_NEXT, "rmdir"); + } + + int ret = real_rmdir(path); + + return ret; +} + +ssize_t +dlsym_pread(int fd, void* buf, size_t count, off_t offset) { + if(real_pread == NULL) { + real_pread = (ssize_t(*)(int, void*, size_t, off_t)) dlsym(RTLD_NEXT, + "pread"); + } + + ssize_t ret = real_pread(fd, buf, count, offset); + + return ret; +} + +ssize_t +dlsym_pwrite(int fd, const void* buf, size_t count, off_t offset) { + if(real_pwrite == NULL) { + real_pwrite = (ssize_t(*)(int, const void*, size_t, off_t)) dlsym( + RTLD_NEXT, "pwrite"); + } + + ssize_t ret = real_pwrite(fd, buf, count, offset); + + return ret; +} + +ssize_t +dlsym_pread64(int fd, void* buf, size_t count, off_t offset) { + + if(real_pread64 == NULL) { + real_pread64 = (ssize_t(*)(int, void*, size_t, off_t)) dlsym(RTLD_NEXT, + "pread64"); + } + + ssize_t ret = real_pread64(fd, buf, count, offset); + + return ret; +} + +ssize_t +dlsym_pwrite64(int fd, const void* buf, size_t count, off_t offset) { + + if(real_pwrite64 == NULL) { + real_pwrite64 = (ssize_t(*)(int, const void*, size_t, off_t)) dlsym( + RTLD_NEXT, "pwrite64"); + } + + ssize_t ret = real_pwrite64(fd, buf, count, offset); + + return ret; +} + +int +dlsym_mkstemp(char* templates) { + + if(real_mkstemp == NULL) { + real_mkstemp = (int (*)(char*)) dlsym(RTLD_NEXT, "mkstemp"); + } + + int ret = real_mkstemp(templates); + + return ret; +} + +off_t +dlsym_lseek(int fd, off_t offset, int whence) { + + if(real_lseek == NULL) { + real_lseek = (off_t(*)(int, off_t, int)) dlsym(RTLD_NEXT, "lseek"); + } + + off_t ret = real_lseek(fd, offset, whence); + + return ret; +} + +off64_t +dlsym_lseek64(int fd, off64_t offset, int whence) { + + if(real_lseek64 == NULL) { + real_lseek64 = + (off64_t(*)(int, off64_t, int)) dlsym(RTLD_NEXT, "lseek64"); + } + + off64_t ret = real_lseek64(fd, offset, whence); + + return ret; +} + +int +dlsym_lxstat64(int ver, const char* path, struct stat64* buf) { + + + if(real_lxstat64 == NULL) { + real_lxstat64 = (int (*)(int, const char*, struct stat64*)) dlsym( + RTLD_NEXT, "__lxstat64"); + } + + int ret = real_lxstat64(ver, (char*) path, buf); + + + return ret; +} + +int +dlsym_xstat64(int ver, const char* path, struct stat64* buf) { + + + if(real_xstat64 == NULL) { + real_xstat64 = (int (*)(int, const char*, struct stat64*)) dlsym( + RTLD_NEXT, "__xstat64"); + } + + int ret = real_xstat64(ver, (char*) path, buf); + + + return ret; +} + +int +dlsym_fxstat64(int ver, int fd, struct stat64* buf) { + + + if(real_fxstat64 == NULL) { + real_fxstat64 = (int (*)(int, int, struct stat64*)) dlsym(RTLD_NEXT, + "__fxstat64"); + } + + int ret = real_fxstat64(ver, fd, buf); + + + return ret; +} + +int +dlsym_lstat(int ver, const char* path, struct stat* buf) { + + + if(real_lstat == NULL) { + real_lstat = (int (*)(int, char*, struct stat*)) dlsym(RTLD_NEXT, + "__lxstat"); + } + + int ret = real_lstat(ver, (char*) path, buf); + + + return ret; +} + +int +dlsym_stat(int ver, const char* path, struct stat* buf) { + + + if(real_stat == NULL) { + real_stat = + (int (*)(int, char*, struct stat*)) dlsym(RTLD_NEXT, "__xstat"); + } + + int ret = real_stat(ver, (char*) path, buf); + + + return ret; +} + +int +dlsym_fstat(int ver, int fd, struct stat* buf) { + + + if(real_fstat == NULL) { + real_fstat = + (int (*)(int, int, struct stat*)) dlsym(RTLD_NEXT, "__fxstat"); + } + + int ret = real_fstat(ver, fd, buf); + + + return ret; +} + +int +dlsym_fstatat(int dfd, const char* path, struct stat* buf, int flags) { + + + if(real_fstatat == NULL) { + real_fstatat = (int (*)(int, const char*, struct stat*, int)) dlsym( + RTLD_NEXT, "fstatat"); + } + + int ret = real_fstatat(dfd, (char*) path, buf, flags); + + + return ret; +} + +int +dlsym_fstatat64(int dfd, const char* path, struct stat64* buf, int flags) { + + + if(real_fstatat64 == NULL) { + real_fstatat64 = (int (*)(int, const char*, struct stat64*, int)) dlsym( + RTLD_NEXT, "fstatat64"); + } + + int ret = real_fstatat64(dfd, (char*) path, buf, flags); + + + return ret; +} + +int +dlsym_statx(int dirfd, const char* path, int flags, unsigned int mask, + struct statx* buf) { + if(real_statx == NULL) { + real_statx = (int (*)(int, const char*, int, unsigned int, + struct statx*)) dlsym(RTLD_NEXT, "statx"); + } + int ret = real_statx(dirfd, path, flags, mask, buf); + return ret; +} + +int +dlsym_rename(const char* oldpath, const char* newpath) { + + if(real_rename == NULL) { + real_rename = + (int (*)(const char*, const char*)) dlsym(RTLD_NEXT, "rename"); + } + + int ret = real_rename(oldpath, newpath); + + return ret; +} + +// generate remove +int +dlsym_remove(char* path) { + if(real_remove == NULL) { + real_remove = (int (*)(char*)) dlsym(RTLD_NEXT, "remove"); + } + + int ret = real_remove(path); + + return ret; +} + + +// generate unlink +int +dlsym_unlink(const char* path) { + if(real_unlink == NULL) { + real_unlink = (int (*)(const char*)) dlsym(RTLD_NEXT, "unlink"); + } + + int ret = real_unlink(path); + + return ret; +} + +// opendir +// Directory API +DIR* +dlsym_opendir(char* dirname) { + + if(real_opendir == NULL) { + real_opendir = (DIR * (*) (char*) ) dlsym(RTLD_NEXT, "opendir"); + } + + DIR* ret = real_opendir((char*) dirname); + + return ret; +} + +DIR* +dlsym_opendir64(char* dirname) { + + + if(real_opendir64 == NULL) { + real_opendir64 = (DIR * (*) (char*) ) dlsym(RTLD_NEXT, "opendir64"); + } + + DIR* ret = real_opendir64((char*) dirname); + + + return ret; +} + +// readdir +struct dirent* +dlsym_readdir(DIR* dirp) { + + if(real_readdir == NULL) { + real_readdir = + (struct dirent * (*) (DIR*) ) dlsym(RTLD_NEXT, "readdir"); + } + + struct dirent* ret = real_readdir(dirp); + + return ret; +} + +struct dirent64* +dlsym_readdir64(DIR* dirp) { + + + if(real_readdir64 == NULL) { + real_readdir64 = + (struct dirent64 * (*) (DIR*) ) dlsym(RTLD_NEXT, "readdir64"); + } + + struct dirent64* ret = real_readdir64(dirp); + + + return ret; +} + +// closedir +int +dlsym_closedir(DIR* dirp) { + + + if(real_closedir == NULL) { + real_closedir = (int (*)(DIR*)) dlsym(RTLD_NEXT, "closedir"); + } + + int ret = real_closedir(dirp); + + + return ret; +} + +// telldir +long +dlsym_telldir(DIR* dirp) { + debug_info("[SYSCALL_PROXIES] [dlsym_telldir] >> Begin\n"); + + if(real_telldir == NULL) { + real_telldir = (long (*)(DIR*)) dlsym(RTLD_NEXT, "telldir"); + } + + long ret = real_telldir(dirp); + + debug_info("[SYSCALL_PROXIES] [dlsym_telldir] >> End\n"); + + return ret; +} + + +// Proccess API +int +dlsym_fork(void) { + debug_info("[SYSCALL_PROXIES] [dlsym_fork] >> Begin\n"); + + if(real_fork == NULL) { + real_fork = (int (*)()) dlsym(RTLD_NEXT, "fork"); + } + + int ret = real_fork(); + + debug_info("[SYSCALL_PROXIES] [dlsym_fork] >> End\n"); + + return ret; +} + +int +dlsym_pipe(int pipefd[2]) { + debug_info("[SYSCALL_PROXIES] [dlsym_pipe] >> Begin\n"); + + if(real_pipe == NULL) { + real_pipe = (int (*)(int*)) dlsym(RTLD_NEXT, "pipe"); + } + + int ret = real_pipe(pipefd); + + debug_info("[SYSCALL_PROXIES] [dlsym_pipe] >> End\n"); + + return ret; +} + +int +dlsym_dup(int fd) { + debug_info("[SYSCALL_PROXIES] [dlsym_dup] >> Begin\n"); + + if(real_dup == NULL) { + real_dup = (int (*)(int)) dlsym(RTLD_NEXT, "dup"); + } + + int ret = real_dup(fd); + + debug_info("[SYSCALL_PROXIES] [dlsym_dup] >> End\n"); + + return ret; +} + +int +dlsym_dup2(int fd, int fd2) { + debug_info("[SYSCALL_PROXIES] [dlsym_dup2] >> Begin\n"); + + if(real_dup2 == NULL) { + real_dup2 = (int (*)(int, int)) dlsym(RTLD_NEXT, "dup2"); + } + + int ret = real_dup2(fd, fd2); + + debug_info("[SYSCALL_PROXIES] [dlsym_dup2] >> End\n"); + + return ret; +} + +void +dlsym_exit(int status) { + debug_info("[SYSCALL_PROXIES] [dlsym_exit] >> Begin\n"); + + if(real_exit == NULL) { + real_exit = (void (*)(int)) dlsym(RTLD_NEXT, "exit"); + } + + real_exit(status); + + debug_info("[SYSCALL_PROXIES] [dlsym_exit] >> End\n"); +} + +// File/Directory Metadata API +int +dlsym_chdir(char* path) { + debug_info("[SYSCALL_PROXIES] [dlsym_chdir] >> Begin\n"); + + if(real_chdir == NULL) { + real_chdir = (int (*)(char*)) dlsym(RTLD_NEXT, "chdir"); + } + + int ret = real_chdir((char*) path); + + debug_info("[SYSCALL_PROXIES] [dlsym_chdir] >> End\n"); + + return ret; +} + +int +dlsym_chmod(char* path, mode_t mode) { + debug_info("[SYSCALL_PROXIES] [dlsym_chmod] >> Begin\n"); + + if(real_chmod == NULL) { + real_chmod = (int (*)(char*, mode_t)) dlsym(RTLD_NEXT, "chmod"); + } + + int ret = real_chmod((char*) path, mode); + + debug_info("[SYSCALL_PROXIES] [dlsym_chmod] >> End\n"); + + return ret; +} + +int +dlsym_fchmod(int fd, mode_t mode) { + debug_info("[SYSCALL_PROXIES] [dlsym_fchmod] >> Begin\n"); + + if(real_fchmod == NULL) { + real_fchmod = (int (*)(int, mode_t)) dlsym(RTLD_NEXT, "fchmod"); + } + + int ret = real_fchmod(fd, mode); + + debug_info("[SYSCALL_PROXIES] [dlsym_fchmod] >> End\n"); + + return ret; +} + +int +dlsym_chown(char* path, uid_t owner, gid_t group) { + debug_info("[SYSCALL_PROXIES] [dlsym_chown] >> Begin\n"); + + if(real_chown == NULL) { + real_chown = (int (*)(char*, uid_t, gid_t)) dlsym(RTLD_NEXT, "chown"); + } + + int ret = real_chown((char*) path, owner, group); + + debug_info("[SYSCALL_PROXIES] [dlsym_chown] >> End\n"); + + return ret; +} + +int +dlsym_fcntl(int fd, int cmd, long arg) { + debug_info("[SYSCALL_PROXIES] [dlsym_fcntl] >> Begin\n"); + + if(real_fcntl == NULL) { + real_fcntl = (int (*)(int, int, long)) dlsym(RTLD_NEXT, "fcntl"); + } + + int ret = real_fcntl(fd, cmd, arg); + + debug_info("[SYSCALL_PROXIES] [dlsym_fcntl] >> End\n"); + + return ret; +} + +int +dlsym_access(const char* path, int mode) { + + + if(real_access == NULL) { + real_access = (int (*)(const char*, int)) dlsym(RTLD_NEXT, "access"); + } + + int ret = real_access((char*) path, mode); + + + return ret; +} + +char* +dlsym_realpath(const char* path, char* resolved_path) { + debug_info("[SYSCALL_PROXIES] [dlsym_realpath] >> Begin\n"); + + if(real_realpath == NULL) { + real_realpath = + (char* (*) (const char*, char*) ) dlsym(RTLD_NEXT, "realpath"); + } + + char* ret = real_realpath((char*) path, (char*) resolved_path); + + debug_info("[SYSCALL_PROXIES] [dlsym_realpath] >> End\n"); + + return ret; +} + +int +dlsym_fsync(int fd) { + debug_info("[SYSCALL_PROXIES] [dlsym_fsync] >> Begin\n"); + + if(real_fsync == NULL) { + real_fsync = (int (*)(int)) dlsym(RTLD_NEXT, "fsync"); + } + + int ret = real_fsync(fd); + + debug_info("[SYSCALL_PROXIES] [dlsym_fsync] >> End\n"); + + return ret; +} + +int +dlsym_flock(int fd, int operation) { + debug_info("[SYSCALL_PROXIES] [dlsym_flock] >> Begin\n"); + + if(real_flock == NULL) { + real_flock = (int (*)(int, int)) dlsym(RTLD_NEXT, "fsync"); + } + + int ret = real_flock(fd, operation); + + debug_info("[SYSCALL_PROXIES] [dlsym_flock] >> End\n"); + + return ret; +} + +// Memory API +void* +dlsym_mmap(void* addr, size_t length, int prot, int flags, int fd, + off_t offset) { + debug_info("[SYSCALL_PROXIES] [dlsym_mmap] >> Begin\n"); + + if(real_mmap == NULL) { + real_mmap = (void* (*) (void*, size_t, int, int, int, off_t)) dlsym( + RTLD_NEXT, "mmap"); + } + + void* ret = real_mmap(addr, length, prot, flags, fd, offset); + + debug_info("[SYSCALL_PROXIES] [dlsym_mmap] >> End\n"); + + return ret; +} + + +/** + * stat management + */ +int +stat_to_stat64(struct stat64* buf, struct stat* st) { + buf->st_dev = (__dev_t) st->st_dev; + buf->st_ino = (__ino64_t) st->st_ino; + buf->st_mode = (__mode_t) st->st_mode; + buf->st_nlink = (__nlink_t) st->st_nlink; + buf->st_uid = (__uid_t) st->st_uid; + buf->st_gid = (__gid_t) st->st_gid; + buf->st_rdev = (__dev_t) st->st_rdev; + buf->st_size = (__off64_t) st->st_size; + buf->st_blksize = (__blksize_t) st->st_blksize; + buf->st_blocks = (__blkcnt64_t) st->st_blocks; + buf->st_atime = (__time_t) st->st_atime; + buf->st_mtime = (__time_t) st->st_mtime; + buf->st_ctime = (__time_t) st->st_ctime; + + return 0; +} + +int +stat64_to_stat(struct stat* buf, struct stat64* st) { + buf->st_dev = (__dev_t) st->st_dev; + buf->st_ino = (__ino_t) st->st_ino; + buf->st_mode = (__mode_t) st->st_mode; + buf->st_nlink = (__nlink_t) st->st_nlink; + buf->st_uid = (__uid_t) st->st_uid; + buf->st_gid = (__gid_t) st->st_gid; + buf->st_rdev = (__dev_t) st->st_rdev; + buf->st_size = (__off_t) st->st_size; + buf->st_blksize = (__blksize_t) st->st_blksize; + buf->st_blocks = (__blkcnt_t) st->st_blocks; + buf->st_atime = (__time_t) st->st_atime; + buf->st_mtime = (__time_t) st->st_mtime; + buf->st_ctime = (__time_t) st->st_ctime; + + return 0; +} + +// File API +int +open(const char* path, int flags, ...) { + int ret, fd; + va_list ap; + mode_t mode = 0; + + va_start(ap, flags); + + mode = va_arg(ap, mode_t); + initializeGekko(); + if(CTX->interception_enabled()) { + std::string resolved; + auto rstatus = CTX->relativize_fd_path(AT_FDCWD, path, resolved); + switch(rstatus) { + + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + va_end(ap); + return -ENOTDIR; + + case gkfs::preload::RelativizeStatus::internal: + fd = gkfs::syscall::gkfs_open(resolved, mode, flags); + va_end(ap); + debug_info("[BYPASS] >> End open.... %s %d\n", path, fd); + return fd; + default: + // Try normal open. + break; + } + } + + ret = dlsym_open2((char*) path, flags, mode); + va_end(ap); + + + return ret; +} + + +int +open64(const char* path, int flags, ...) { + int fd, ret; + va_list ap; + mode_t mode = 0; + initializeGekko(); + va_start(ap, flags); + + mode = va_arg(ap, mode_t); + + if(CTX->interception_enabled()) { + std::string resolved; + auto rstatus = CTX->relativize_fd_path(AT_FDCWD, path, resolved); + switch(rstatus) { + + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + va_end(ap); + return -ENOTDIR; + + case gkfs::preload::RelativizeStatus::internal: + debug_info("[GEKKO] >> Begin open64.... %s %d %o %o %o\n", path, + fd, flags, mode, flags & O_CREAT); + fd = gkfs::syscall::gkfs_open(resolved, mode, flags); + + debug_info("[GEKKO] >> End open64.... %s %d %o %o\n", path, fd, + flags, mode); + va_end(ap); + return fd; + default: + // Try normal open. + break; + } + } + + ret = dlsym_open64((char*) path, flags, mode); + + va_end(ap); + + return ret; +} + + +int +openat(int dirfd, const char* path, int flags, ...) { + debug_info("[BYPASS] >> openat.... %s %o\n", path, flags); + int ret, fd; + va_list ap; + mode_t mode = 0; + initializeGekko(); + va_start(ap, flags); + + mode = va_arg(ap, mode_t); + + if(CTX->interception_enabled()) { + std::string resolved; + auto rstatus = CTX->relativize_fd_path(AT_FDCWD, path, resolved); + switch(rstatus) { + + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case gkfs::preload::RelativizeStatus::internal: + fd = gkfs::syscall::gkfs_open(resolved, mode, flags); + va_end(ap); + debug_info("[BYPASS] >> End openat.... %s %d\n", path, fd); + return fd; + default: + // Try normal open. + break; + } + } else { + std::string p = path; + + debug_info("[BYPASS] >> Begin openat. ERROR...%s\n", path); + if(p.find("mnt") != std::string::npos) { + gkfs::preload::init_environment(); + CTX->enable_interception(); + debug_info("[BYPASS] >> Reinited. ERROR...%s %d\n", path, + CTX->interception_enabled()); + return openat(dirfd, (char*) path, flags, mode); + } + } + + ret = dlsym_openat(dirfd, (char*) path, flags, mode); + va_end(ap); + + + return ret; +} + +int +openat64(int dirfd, const char* path, int flags, ...) { + va_list ap; + mode_t mode = 0; + initializeGekko(); + va_start(ap, flags); + + mode = va_arg(ap, mode_t); + va_end(ap); + return openat(dirfd, path, flags, mode); +} + +// Generate the rest of the functions to build a libc io interception +int +close(int fd) { + initializeGekko(); + // Is fd from gekkofs ? + if(CTX->interception_enabled()) { + + if(CTX->file_map()->exist(fd)) { + return gkfs::syscall::gkfs_close(fd); + } + + } else { + debug_info("%d [BYPASS] >> close not intercepted...%d\n", gettid(), fd); + } + + // Try normal close. + auto ret = dlsym_close(fd); + + return ret; +} + +int +close_range(unsigned low, unsigned high, int flags) { + + // Is fd from gekkofs ? + for(unsigned int i = low; i <= high; i++) { + if(i > GKFS_MAX_OPEN_FDS) + break; + if(CTX->file_map()->exist(i)) { + gkfs::syscall::gkfs_close(i); + } + return 0; + } + + debug_info("[BYPASS]\t dlsym_close_range (%d)\n", low); + + // Try normal close. + auto ret = dlsym_close_range(low, high, flags); + + debug_info("[BYPASS]\t dlsym_close_range (%d) -> %d\n", low, ret); + + return ret; +} + +int +creat(const char* path, mode_t mode) { + debug_info("[BYPASS] >> Begin creat....%s %o\n", path, mode); + + // Is path from gekkofs? + std::string resolved; + auto rstatus = CTX->relativize_fd_path(AT_FDCWD, path, resolved); + switch(rstatus) { + + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case gkfs::preload::RelativizeStatus::internal: + return gkfs::syscall::gkfs_create(resolved, mode); + + default: + // Try normal open. + break; + } + + debug_info("[BYPASS]\t dlsym_creat (%s,%o)\n", path, mode); + + + int ret = dlsym_creat(path, mode); + + debug_info("[BYPASS] << After creat....\n"); + + return ret; +} + +int +ftruncate(int fd, off_t length) { + debug_info("[BYPASS] >> Begin ftruncate.... %d %ld\n", fd, length); + + int ret = dlsym_ftruncate(fd, length); + + debug_info("[BYPASS] << After ftruncate....\n"); + + return ret; +} + +ssize_t +read(int fd, void* buf, size_t nbyte) { + initializeGekko(); + if(CTX->file_map()->exist(fd)) { + debug_info("[READ from GKFS]....%d %ld\n", fd, nbyte); + return gkfs::syscall::gkfs_read(fd, buf, nbyte); + } + + ssize_t ret = dlsym_read(fd, buf, nbyte); + + + return ret; +} + +ssize_t +write(int fd, const void* buf, size_t nbyte) { + initializeGekko(); + if(CTX->file_map()->exist(fd)) { + debug_info("[WRITE from GKFS]....%d \n", fd); + return gkfs::syscall::gkfs_write(fd, buf, nbyte); + } + + ssize_t ret = dlsym_write(fd, buf, nbyte); + + return ret; +} + +// add mkdir +int +mkdir(const char* path, mode_t mode) { + debug_info("[BYPASS] >> Begin mkdir....%s\n", path); + int ret = 0; + initializeGekko(); + if(CTX->interception_enabled()) { + std::string resolved; + + auto rstatus = CTX->relativize_fd_path(AT_FDCWD, path, resolved); + switch(rstatus) { + + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case gkfs::preload::RelativizeStatus::internal: + ret = gkfs::syscall::gkfs_create(resolved, mode | S_IFDIR); + debug_info("[BYPASS] >> End mkdir.... %s\n", path); + return ret; + default: + // Try normal open. + break; + } + } + + ret = dlsym_mkdir(path, mode); + + + return ret; +} + +// add rmdir +int +rmdir(const char* path) { + debug_info("[BYPASS] >> Begin rmdir.... %s\n", path); + + return unlink(path); + /* int ret = dlsym_rmdir(path); + */ + + // return ret; +} + + +// Add pread +ssize_t +pread(int fd, void* buf, size_t count, off_t offset) { + debug_info("[BYPASS] >> Begin pread....%d\n", fd); + + // Is fd from GekkoFS? + if(CTX->file_map()->exist(fd)) { + debug_info("[PREAD from GKFS]....%d \n", fd); + return gkfs::syscall::gkfs_pread(fd, buf, count, offset); + } + + debug_info("[BYPASS]\t dlsym_pread (%d,%p,%zu,%ld)\n", fd, buf, count, + offset); + + ssize_t ret = dlsym_pread(fd, buf, count, offset); + + debug_info("[BYPASS] << After pread....\n"); + + return ret; +} + +// Add pwrite +ssize_t +pwrite(int fd, const void* buf, size_t count, off_t offset) { + debug_info("[BYPASS] >> Begin pwrite....%d\n", fd); + + // Is fd from GekkoFS? + if(CTX->file_map()->exist(fd)) { + debug_info("[PWRITE from GKFS]....%d \n", fd); + return gkfs::syscall::gkfs_pwrite(fd, buf, count, offset); + } + + debug_info("[BYPASS]\t dlsym_pwrite (%d,%p,%zu,%ld)\n", fd, buf, count, + offset); + + ssize_t ret = dlsym_pwrite(fd, buf, count, offset); + + debug_info("[BYPASS] << After pwrite....\n"); + + return ret; +} + +// Add mkstemp +int +mkstemp(char* templates) { + debug_info("[BYPASS] >> Begin mkstemp....\n"); + debug_info("[BYPASS] 1) templates => %s\n", templates); + + int ret = dlsym_mkstemp(templates); + + debug_info("[BYPASS] << After mkstemp....\n"); + + return ret; +} + +// Add lseek +off_t +lseek(int fd, off_t offset, int whence) { + initializeGekko(); + // Is fd from GekkoFS? + if(CTX->file_map()->exist(fd)) { + debug_info("[xLSEEK GEKKO]....%ld %d\n", offset, whence); + return gkfs::syscall::gkfs_lseek(fd, offset, whence); + } + + off_t ret = dlsym_lseek(fd, offset, whence); + + return ret; +} + +// Add lseek64 +off64_t +lseek64(int fd, off64_t offset, int whence) { + // Is fd from GekkoFS? + if(CTX->file_map()->exist(fd)) { + debug_info("[LSEEK64 GEKKO]... %d.%ld %d\n", fd, offset, whence); + return gkfs::syscall::gkfs_lseek(fd, offset, whence); + } + + off64_t ret = dlsym_lseek64(fd, offset, whence); + + return ret; +} + +// add pread64 +ssize_t +pread64(int fd, void* buf, size_t count, off_t offset) { + debug_info("[BYPASS] >> Begin pread64....\n"); + debug_info("[BYPASS] 1) fd => %d\n", fd); + + // Is fd from GekkoFS? + if(CTX->file_map()->exist(fd)) { + debug_info("[PREAD64 from GKFS]....%d \n", fd); + return gkfs::syscall::gkfs_pread(fd, buf, count, offset); + } + + debug_info("[BYPASS]\t dlsym_pread64 (%d,%p,%zu,%ld)\n", fd, buf, count, + offset); + + ssize_t ret = dlsym_pread64(fd, buf, count, offset); + + debug_info("[BYPASS] << After pread64....\n"); + + return ret; +} + +// add pwrite64 +ssize_t +pwrite64(int fd, const void* buf, size_t count, off_t offset) { + debug_info("[BYPASS] >> Begin pwrite64....\n"); + debug_info("[BYPASS] 1) fd => %d\n", fd); + + // Is fd from GekkoFS? + if(CTX->file_map()->exist(fd)) { + debug_info("[PWRITE64 from GKFS]....%d \n", fd); + return gkfs::syscall::gkfs_pwrite(fd, buf, count, offset); + } + + debug_info("[BYPASS]\t dlsym_pwrite64 (%d,%p,%zu,%ld)\n", fd, buf, count, + offset); + + ssize_t ret = dlsym_pwrite64(fd, buf, count, offset); + + debug_info("[BYPASS] << After pwrite64....\n"); + + return ret; +} + + +int +unlink(const char* path) { + + debug_info("[BYPASS] >> Begin unlink....%s\n", path); + initializeGekko(); + int ret = 0; + // if path is inside gekkofs + if(CTX->interception_enabled()) { + std::string resolved; + + auto rstatus = CTX->relativize_fd_path(AT_FDCWD, path, resolved); + switch(rstatus) { + + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case gkfs::preload::RelativizeStatus::internal: + ret = gkfs::syscall::gkfs_remove(resolved); + debug_info("[BYPASS] >> End unlink.... %s\n", path); + return ret; + default: + // Try normal open. + break; + } + } + + ret = dlsym_unlink(path); + + debug_info("[BYPASS] << After unlink....\n"); + + return ret; +} + +// fill missing stat functions +int +__xstat(int ver, const char* path, struct stat* buf) { + debug_info("[BYPASS] >> Begin __xstat....%s\n", path); + initializeGekko(); + // Is path from GekkoFS? + if(CTX->interception_enabled()) { + std::string resolved; + + auto rstatus = CTX->relativize_fd_path(AT_FDCWD, path, resolved); + switch(rstatus) { + + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case gkfs::preload::RelativizeStatus::internal: + debug_info("[_xSTAT from GKFS]....%s \n", resolved.c_str()); + return gkfs::syscall::gkfs_stat(resolved, buf); + + default: + // Try normal open. + break; + } + } else { + std::string p = path; + + debug_info("[BYPASS] >> Begin stat. ERROR...%s\n", path); + } + + + int ret = dlsym_stat(ver, path, buf); + + return ret; +} + +int +statx(int dirfd, const char* path, int flags, unsigned int mask, + struct statx* statxbuf) { + + + debug_info("%d [BYPASS] >> Begin statx....%s\n", gettid(), path); + initializeGekko(); + // Is path from GekkoFS? + if(CTX->interception_enabled()) { + std::string resolved; + + auto rstatus = CTX->relativize_fd_path(AT_FDCWD, path, resolved); + switch(rstatus) { + + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case gkfs::preload::RelativizeStatus::internal: + debug_info("[STATx from GKFS]....%s -> %s \n", path, + resolved.c_str()); + return gkfs::syscall::gkfs_statx(dirfd, resolved, flags, mask, + statxbuf); + + default: + // Try normal open. + break; + } + } else { + std::string p = path; + debug_info("[BYPASS] >> Begin statx. ERROR...%s\n", path); + } + + + int ret = dlsym_statx(dirfd, path, flags, mask, statxbuf); + + return ret; +} + +int +__lxstat(int ver, const char* path, struct stat* buf) { + debug_info("[BYPASS] >> Begin __lxstat....%s\n", path); + int res; + + initializeGekko(); + // Is path from GekkoFS? + if(CTX->interception_enabled()) { + std::string resolved; + + auto rstatus = CTX->relativize_fd_path(AT_FDCWD, path, resolved); + switch(rstatus) { + + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case gkfs::preload::RelativizeStatus::internal: + debug_info("[__lxstat64 from GKFS]....%s \n", resolved.c_str()); + res = gkfs::syscall::gkfs_stat(resolved, buf); + return res; + + default: + // Try normal open. + break; + } + } + + res = dlsym_lstat(ver, (const char*) path, buf); + return res; +} + +int +__lxstat64(int ver, const char* path, struct stat64* buf) { + debug_info("[BYPASS] >> Begin __lxstat64....%s\n", path); + int res; + + initializeGekko(); + // Is path from GekkoFS? + if(CTX->interception_enabled()) { + std::string resolved; + + auto rstatus = CTX->relativize_fd_path(AT_FDCWD, path, resolved); + switch(rstatus) { + + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case gkfs::preload::RelativizeStatus::internal: + debug_info("[__lxstat64 from GKFS]....%s \n", resolved.c_str()); + struct stat st; + + res = gkfs::syscall::gkfs_stat(resolved, &st); + stat_to_stat64(buf, &st); + return res; + + default: + // Try normal open. + break; + } + } + + res = dlsym_lxstat64(ver, (const char*) path, buf); + return res; +} + +int +__fxstat(int ver, int fd, struct stat* buf) { + debug_info("[BYPASS] >> Begin __fxstat....%d\n", fd); + int res; + + initializeGekko(); + // Is path from GekkoFS? + if(CTX->interception_enabled()) { + if(CTX->file_map()->exist(fd)) { + + debug_info("[__fxstat from GKFS]....%d \n", fd); + return gkfs::syscall::gkfs_stat(CTX->file_map()->get(fd)->path(), + buf); + return res; + } + } + + res = dlsym_fstat(ver, fd, buf); + return res; +} + + +int +__fxstatat(int ver, int dfd, const char* path, struct stat* buf, int flags) { + debug_info("[BYPASS] >> Begin __fxstatat....%s\n", path); + // Is path from GekkoFS? + if(CTX->interception_enabled()) { + std::string resolved; + + auto rstatus = CTX->relativize_fd_path(dfd, path, resolved, flags); + switch(rstatus) { + + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case gkfs::preload::RelativizeStatus::fd_unknown: + return -EBADF; + + case gkfs::preload::RelativizeStatus::internal: + return gkfs::syscall::gkfs_stat(resolved, buf); + + default: + // Try normal open. + break; + } + } + + int ret = dlsym_fstatat(dfd, path, buf, flags); + return ret; +} + +int +__fxstat64(int ver, int fd, struct stat64* buf) { + debug_info("[BYPASS] >> Begin __fxstat64....%d\n", fd); + int res; + + initializeGekko(); + // Is path from GekkoFS? + if(CTX->interception_enabled()) { + if(CTX->file_map()->exist(fd)) { + + debug_info("[__fxstat64 from GKFS]....%d \n", fd); + struct stat st; + + res = gkfs::syscall::gkfs_stat(CTX->file_map()->get(fd)->path(), + &st); + stat_to_stat64(buf, &st); + return res; + } + } + + res = dlsym_fxstat64(ver, fd, buf); + return res; +} + +int +__fxstatat64(int ver, int dfd, const char* path, struct stat64* buf, + int flags) { + debug_info("[BYPASS] >> Begin __fxstatat....%s\n", path); + // Is path from GekkoFS? + if(CTX->interception_enabled()) { + std::string resolved; + int res; + auto rstatus = CTX->relativize_fd_path(dfd, path, resolved, flags); + switch(rstatus) { + + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case gkfs::preload::RelativizeStatus::fd_unknown: + return -EBADF; + + case gkfs::preload::RelativizeStatus::internal: + struct stat st; + res = gkfs::syscall::gkfs_stat(resolved, &st); + stat_to_stat64(buf, &st); + return res; + + default: + // Try normal open. + break; + } + } + + int ret = dlsym_fstatat64(dfd, path, buf, flags); + return ret; +} + +int +__xstat64(int ver, const char* path, struct stat64* buf) { + + int res; + + initializeGekko(); + // Is path from GekkoFS? + if(CTX->interception_enabled()) { + std::string resolved; + + auto rstatus = CTX->relativize_fd_path(AT_FDCWD, path, resolved); + switch(rstatus) { + + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case gkfs::preload::RelativizeStatus::internal: + struct stat st; + + res = gkfs::syscall::gkfs_stat(resolved, &st); + stat_to_stat64(buf, &st); + return res; + + default: + // Try normal open. + break; + } + } + + res = dlsym_xstat64(ver, (const char*) path, buf); + return res; +} + + +int +statvfs(const char* path, struct statvfs* buf) { + debug_info("[BYPASS] >> Begin statvfs....%s\n", path); + + buf->f_bsize = 4096; + buf->f_blocks = 1024; + buf->f_bfree = 1024; + buf->f_bavail = 1024; + buf->f_files = 0; + buf->f_ffree = 0; + buf->f_favail = 0; + buf->f_fsid = 0; + buf->f_namemax = 4096; + buf->f_frsize = 0; + buf->f_flag = 0; + + return 0; +} +int +fstatvfs(int fd, struct statvfs* buf) { + debug_info("[BYPASS] >> Begin fstatvfs....%d\n", fd); + buf->f_bsize = 4096; + buf->f_blocks = 1024; + buf->f_bfree = 1024; + buf->f_bavail = 1024; + buf->f_files = 0; + buf->f_ffree = 0; + buf->f_favail = 0; + buf->f_fsid = 0; + buf->f_namemax = 4096; + buf->f_frsize = 0; + buf->f_flag = 0; + return 0; +} + +int +stat(const char* path, struct stat* buf) { + debug_info("%d [BYPASS] >> Begin stat....%s\n", gettid(), path); + initializeGekko(); + // Is path from GekkoFS? + if(CTX->interception_enabled()) { + std::string resolved; + + auto rstatus = CTX->relativize_fd_path(AT_FDCWD, path, resolved); + switch(rstatus) { + + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case gkfs::preload::RelativizeStatus::internal: + debug_info("[STAT from GKFS]....%s \n", resolved.c_str()); + return gkfs::syscall::gkfs_stat(resolved, buf); + + default: + // Try normal open. + break; + } + } else { + std::string p = path; + + debug_info("[BYPASS] >> Begin stat. ERROR...%s\n", path); + } + + + int ret = dlsym_stat(_STAT_VER, path, buf); + + return ret; +} + +// add fstat +int +fstat(int fd, struct stat* buf) { + debug_info("[BYPASS] >> Begin fstat....%d\n", fd); + initializeGekko(); + // Is fd from GekkoFS? + if(CTX->file_map()->exist(fd)) { + debug_info("[FSTAT from GKFS]....%d \n", fd); + return gkfs::syscall::gkfs_stat(CTX->file_map()->get(fd)->path(), buf); + } + + int ret = dlsym_fstat(_STAT_VER, fd, buf); + + debug_info("[BYPASS] << After fstat....\n"); + + return ret; +} + + +int +rename(const char* oldpath, const char* newpath) { + debug_info("[BYPASS] >> Begin rename....%s %s\n", oldpath, newpath); + + // Is path from GekkoFS? + if(CTX->interception_enabled()) { + std::string resolved_old; + std::string resolved_new; + + auto rstatus_old = + CTX->relativize_fd_path(AT_FDCWD, oldpath, resolved_old); + auto rstatus_new = + CTX->relativize_fd_path(AT_FDCWD, newpath, resolved_new); + + switch(rstatus_old) { + + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case gkfs::preload::RelativizeStatus::internal: + switch(rstatus_new) { + + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case gkfs::preload::RelativizeStatus::internal: + return -ENOTDIR; + // return + // gkfs::syscall::gkfs_rename(resolved_old, + // resolved_new); + + default: + // Try normal open. + break; + } + default: + // Try normal open. + break; + } + } + + int ret = dlsym_rename(oldpath, newpath); + + debug_info("[BYPASS] << After rename....\n"); + + return ret; +} + +pid_t +fork(void) { + int ret = -1; + initializeGekko(); + debug_info("[BYPASS] >> Begin fork()\n"); + + ret = dlsym_fork(); + if(0 == ret) { + // We want the children to be initialized + debug_info("I am the child\n"); + + initializeGekko(); + } + + debug_info("%d -> %d [BYPASS] << After fork()\n", ret, gettid()); + + return ret; +} + +int +pipe(int pipefd[2]) { + debug_info("[BYPASS] >> Begin pipe() %d - %d\n", pipefd[0], pipefd[1]); + initializeGekko(); + int ret = dlsym_pipe(pipefd); + + debug_info("[BYPASS]\t dlsym_pipe -> %d\n", ret); + + + return ret; +} + +int +dup(int fd) { + debug_info("[BYPASS] >> Begin dup... %d\n", fd); + initializeGekko(); + int ret = -1; + // check if fd is from gekkofs + if(CTX->file_map()->exist(fd)) { + + ret = gkfs::syscall::gkfs_dup(fd); + debug_info("[dup from GKFS]....%d -> %d \n", fd, ret); + return ret; + } + + // call the real dup function + ret = dlsym_dup(fd); + + debug_info("[BYPASS] << After dup()\n"); + + return ret; +} + +int +dup2(int fd, int fd2) { + debug_info("[BYPASS] >> Begin dup2...%d -> %d\n", fd, fd2); + initializeGekko(); + int ret = -1; + // check if fd is from gekkofs + if(CTX->file_map()->exist(fd)) { + ret = gkfs::syscall::gkfs_dup2(fd, fd2); + debug_info("[dup2 from GKFS]....%d -> %d \n", fd, fd2); + return ret; + } + + // call the real dup2 function + ret = dlsym_dup2(fd, fd2); + + debug_info("[BYPASS] << After dup2()\n"); + + + return ret; +} + +void +exit(int status) { + debug_info("[BYPASS] >> Begin exit...\n"); + debug_info("[BYPASS] 1) status %d\n", status); + + + debug_info("[BYPASS] dlsym_exit\n"); + + dlsym_exit(status); + __builtin_unreachable(); + + debug_info("[BYPASS] << After exit()\n"); +} + +// Manager API + +int +chdir(const char* path) { + debug_info("[BYPASS] >> Begin chdir...\n"); + debug_info("[BYPASS] 1) path %s\n", path); + + int ret = -1; + + // is the path from gekkofs + if(CTX->interception_enabled()) { + std::string resolved; + + auto rstatus = CTX->relativize_fd_path(AT_FDCWD, path, resolved); + switch(rstatus) { + + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case gkfs::preload::RelativizeStatus::internal: + return -ENOTDIR; + + default: + // Try normal open. + break; + } + } + + // call the real chdir function + ret = dlsym_chdir((char*) path); + + debug_info("[BYPASS] << After chdir()\n"); + + return ret; +} + + +int +fcntl(int fd, int cmd, long arg) // TODO +{ + debug_info("[BYPASS] >> Begin fcntl... %d , %d ,%ld\n", fd, cmd, arg); + + int ret = -1; + initializeGekko(); + + // is from gekkofs? + if(CTX->file_map()->exist(fd)) { + switch(cmd) { + + case F_DUPFD: + debug_info("dupfd\n"); + + return gkfs::syscall::gkfs_dup(fd); + + case F_DUPFD_CLOEXEC: + debug_info("dupfd_cloexec\n"); + + ret = gkfs::syscall::gkfs_dup(fd); + if(ret == -1) { + return -errno; + } + CTX->file_map()->get(fd)->set_flag( + gkfs::filemap::OpenFile_flags::cloexec, true); + return ret; + + case F_GETFD: + debug_info("getfd\n"); + if(CTX->file_map()->get(fd)->get_flag( + gkfs::filemap::OpenFile_flags::cloexec)) { + return FD_CLOEXEC; + } + return 0; + + case F_GETFL: + debug_info("getfl\n"); + ret = 0; + if(CTX->file_map()->get(fd)->get_flag( + gkfs::filemap::OpenFile_flags::rdonly)) { + ret |= O_RDONLY; + } + if(CTX->file_map()->get(fd)->get_flag( + gkfs::filemap::OpenFile_flags::wronly)) { + ret |= O_WRONLY; + } + if(CTX->file_map()->get(fd)->get_flag( + gkfs::filemap::OpenFile_flags::rdwr)) { + ret |= O_RDWR; + } + return ret; + + case F_SETFD: + debug_info("setfd\n"); + CTX->file_map()->get(fd)->set_flag( + gkfs::filemap::OpenFile_flags::cloexec, + (arg & FD_CLOEXEC)); + return 0; + + case F_GETLK: + + return 0; + + case F_SETLK: + + return 0; + + default: + + return -ENOTSUP; + } + } + + // call the real fcntl function + ret = dlsym_fcntl(fd, cmd, arg); + debug_info("[BYPASS] << After fcntl()\n"); + + return ret; +} + +int +access(const char* path, int mode) { + + initializeGekko(); + + int ret = -1; + + // is gekkofs + if(CTX->interception_enabled()) { + std::string resolved; + + auto rstatus = CTX->relativize_fd_path(AT_FDCWD, path, resolved); + switch(rstatus) { + + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + break; + case gkfs::preload::RelativizeStatus::internal: + debug_info("[GekkoFS Access] %s\n", resolved.c_str()); + ret = gkfs::syscall::gkfs_access(resolved, mode, true); + return ret; + break; + default: + // try normal + break; + } + } + + // call the real access function + ret = dlsym_access((char*) path, mode); + + return ret; +} + +char* +realpath(const char* path, char* resolved_path) { + debug_info("[BYPASS] >> Begin realpath... %s\n", path); + // is gekkofs + if(CTX->interception_enabled()) { + std::string resolved; + + auto rstatus = CTX->relativize_fd_path(AT_FDCWD, path, resolved); + switch(rstatus) { + + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + return nullptr; + + case gkfs::preload::RelativizeStatus::internal: + return nullptr; + + default: + strcpy(resolved_path, resolved.c_str()); + return resolved_path; + } + } + + // call the real realpath function + char* ret = dlsym_realpath((char*) path, resolved_path); + + return ret; +} + +char* +__realpath_chk(const char* path, char* resolved_path, + __attribute__((__unused__)) size_t resolved_len) { + debug_info("[BYPASS] >> Begin __realpath_chk...\n"); + debug_info("[BYPASS] 1) Path %s\n", path); + + + debug_info("[BYPASS] Begin dlsym_realpath...\n"); + + return dlsym_realpath(path, resolved_path); +} + +int +fsync(int fd) // TODO +{ + debug_info("[BYPASS] >> Begin fsync...\n"); + debug_info("[BYPASS] 1) fd %d\n", fd); + int ret; + + ret = dlsym_fsync(fd); + + debug_info("[BYPASS]\t dlsym_fsync -> %d\n", ret); + + + return ret; +} + +int +flock(int fd, int operation) { + int ret = -1; + + debug_info("[BYPASS] >> Begin flock...\n"); + debug_info("[BYPASS] * fd=%d\n", fd); + debug_info("[BYPASS] * operation=%d\n", operation); + + + debug_info("[BYPASS]\t try to dlsym_flock %d,%d\n", fd, operation); + + ret = dlsym_flock(fd, operation); + + + debug_info("[BYPASS] << After flock...\n"); + + return ret; +} + + +DIR* +opendir(const char* dirname) { + DIR* ret; + + initializeGekko(); + if(CTX->interception_enabled()) { + int fd; + std::string resolved; + auto rstatus = CTX->relativize_fd_path(AT_FDCWD, dirname, resolved); + switch(rstatus) { + + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + debug_info("[BYPASS] >> opendir GKFS NOT A DIR.... %s\n", + dirname); + errno = ENOTDIR; + return NULL; + case gkfs::preload::RelativizeStatus::internal: + // debug_info("[BYPASS] >> opendir GKFS.... %s\n", dirname); + + // check if resolved is a dir with gkfs_stat + // if not, return NULL + struct stat st; + if(gkfs::syscall::gkfs_stat(resolved, &st) != 0 or + S_ISREG(st.st_mode)) { + debug_info("[BYPASS] >> opendir GKFS NOT A DIR.... %s\n", + dirname); + errno = ENOTDIR; + return NULL; + } + fd = gkfs::syscall::gkfs_opendir(resolved); + + + ret = (DIR*) malloc(sizeof(DIR)); + + // fill the dirp info + ret->fd = fd; + ret->path = strdup(resolved.c_str()); + // debug_info("[BYPASS] >> End opendir.... %p %s %d\n", + // (void*) ret, dirname, fd); + return ret; + default: + // Try normal open. + break; + } + } + + ret = dlsym_opendir((char*) dirname); + return ret; +} + +// opendir64 +DIR* +opendir64(const char* dirname) { + DIR* ret; + + initializeGekko(); + if(CTX->interception_enabled()) { + int fd; + std::string resolved; + auto rstatus = CTX->relativize_fd_path(AT_FDCWD, dirname, resolved); + switch(rstatus) { + case gkfs::preload::RelativizeStatus::fd_not_a_dir: + debug_info("[BYPASS] >> opendir64 GKFS NOT A DIR.... %s\n", + dirname); + errno = ENOTDIR; + return NULL; + + case gkfs::preload::RelativizeStatus::internal: + // debug_info("[BYPASS] >> opendir64 GKFS.... %s\n", + // dirname); + // check if resolved is a dir with gkfs_stat + // if not, return NULL + struct stat st; + if(gkfs::syscall::gkfs_stat(resolved, &st) != 0 or + S_ISREG(st.st_mode)) { + debug_info("[BYPASS] >> opendir64 GKFS NOT A DIR.... %s\n", + dirname); + errno = ENOTDIR; + return NULL; + } + + fd = gkfs::syscall::gkfs_opendir(resolved); + + + ret = (DIR*) malloc(sizeof(DIR)); + + // fill the dirp info + ret->fd = fd; + ret->path = strdup(resolved.c_str()); + // debug_info("[BYPASS] >> End opendir64.... %p %s %d\n", + // (void*) ret, dirname, fd); + return ret; + default: + // Try normal open. + break; + } + } + + ret = dlsym_opendir64((char*) dirname); + return ret; +} +#define ALIGN(x, a) __ALIGN_KERNEL((x), (a)) +// readdir +struct dirent* +readdir(DIR* dirp) { + struct dirent* ret; + + if(CTX->interception_enabled()) { + if(CTX->file_map()->exist(dirp->fd)) { + // call gekko getdents + // debug_info("[BYPASS] >> readdir GKFS.... %p\n", (void*) dirp); + ret = (struct dirent*) malloc(sizeof(dirent) * 1); + auto open_dir = CTX->file_map()->get_dir(dirp->fd); + if(open_dir == nullptr) { + // Cast did not succeeded: open_file is a regular file + errno = EBADF; + free((void*) ret); + return NULL; + } + + // get directory position of which entries to return + auto pos = open_dir->pos(); + if(pos >= open_dir->size()) { + free((void*) ret); + return NULL; + } + + + auto de = open_dir->getdent(pos); + auto total_size = ALIGN(offsetof(struct dirent, d_name) + + de.name().size() + 3, + sizeof(long)); + // fill ret with data + ret->d_ino = std::hash()(open_dir->path() + "/" + + de.name()); + ret->d_reclen = total_size; + ret->d_type = + ((de.type() == gkfs::filemap::FileType::regular) ? DT_REG + : DT_DIR); + std::strcpy(&(ret->d_name[0]), de.name().c_str()); + + open_dir->pos(pos + 1); + return ret; + } + } + + ret = dlsym_readdir(dirp); + return ret; +} + + +// readdir64 +struct dirent64* +readdir64(DIR* dirp) { + struct dirent64* ret; + if(CTX->interception_enabled()) { + if(CTX->file_map()->exist(dirp->fd)) { + // call gekko getdents + // debug_info("[BYPASS] >> readdir64 GKFS.... %p\n", (void*) dirp); + ret = (struct dirent64*) malloc(sizeof(dirent64) * 1); + auto open_dir = CTX->file_map()->get_dir(dirp->fd); + if(open_dir == nullptr) { + // Cast did not succeeded: open_file is a regular file + errno = EBADF; + free((void*) ret); + return NULL; + } + + // get directory position of which entries to return + auto pos = open_dir->pos(); + if(pos >= open_dir->size()) { + free((void*) ret); + return NULL; + } + + + auto de = open_dir->getdent(pos); + auto total_size = ALIGN(offsetof(struct dirent64, d_name) + + de.name().size() + 3, + sizeof(long)); + // fill ret with data + ret->d_ino = std::hash()(open_dir->path() + "/" + + de.name()); + ret->d_reclen = total_size; + ret->d_type = + ((de.type() == gkfs::filemap::FileType::regular) ? DT_REG + : DT_DIR); + std::strcpy(&(ret->d_name[0]), de.name().c_str()); + + open_dir->pos(pos + 1); + return ret; + } + } + + ret = dlsym_readdir64(dirp); + return ret; +} + +// closedir +int +closedir(DIR* dirp) { + int ret; + if(CTX->interception_enabled()) { + if(CTX->file_map()->exist(dirp->fd)) { + // debug_info("[BYPASS] >> closedir GKFS.... %p\n", (void*) dirp); + ret = gkfs::syscall::gkfs_close(dirp->fd); + free(dirp->path); + free(dirp); + return ret; + } + } + + ret = dlsym_closedir(dirp); + return ret; +} + +// telldir +long +telldir(DIR* dirp) { + debug_info("[BYPASS] >> telldir.... %p\n", (void*) dirp); + long ret; + if(CTX->interception_enabled()) { + if(CTX->file_map()->exist(dirp->fd)) { + debug_info("[BYPASS] >> telldir GKFS not implemented.... %p\n", + (void*) dirp); + ret = 0; + // ret = gkfs::syscall::gkfs_telldir(dirp->fd); + return ret; + } + } + + ret = dlsym_telldir(dirp); + return ret; +} + +// seekdir +void +seekdir(DIR* dirp, long loc) { + debug_info("[BYPASS] >> seekdir.... %p %ld\n", (void*) dirp, loc); + if(CTX->interception_enabled()) { + if(CTX->file_map()->exist(dirp->fd)) { + debug_info("[BYPASS] >> seekdir GKFS no implemented.... %p %ld\n", + (void*) dirp, loc); + return; + } + } + + dlsym_seekdir(dirp, loc); +} + +/* +// getdents +ssize_t +getdents(int fd, struct dirent* dirp, unsigned int count) { + debug_info("[BYPASS] >> getdents.... %d %p %u\n", fd, dirp, count); + ssize_t ret; + if(CTX->interception_enabled()) { + if(dirp->d_name != NULL) { + ret = gkfs::syscall::gkfs_getdents(fd, dirp, count); + return ret; + } + } + + ret = dlsym_getdents(fd, dirp, count); + return ret; +} + +// getdents64 +ssize_t +getdents64(int fd, struct dirent64* dirp, unsigned int count) { + debug_info("[BYPASS] >> getdents64.... %d %p %u\n", fd, dirp, count); + ssize_t ret; + if(CTX->interception_enabled()) { + if(dirp->d_name != NULL) { + ret = gkfs::syscall::gkfs_getdents64(fd, dirp, count); + return ret; + } + } + + ret = dlsym_getdents64(fd, dirp, count); + return ret; +} +*/ diff --git a/src/client/intercept.cpp b/src/client/intercept.cpp index 1086010e884214ecbcadb1e83790e54a57b52b2b..9993c17806f475333eab6387bc89e6369c6853e2 100644 --- a/src/client/intercept.cpp +++ b/src/client/intercept.cpp @@ -31,7 +31,7 @@ #include #include #include - +#include #include #include @@ -408,7 +408,23 @@ hook_internal(long syscall_number, long arg0, long arg1, long arg2, long arg3, CTX->unregister_internal_fd(arg0); } break; +#ifdef SYS_close_range + case SYS_close_range: + *result = syscall_no_intercept_wrapper( + syscall_number, static_cast(arg0), + static_cast(arg1), static_cast(arg2)); + if(*result >= 0) { + for(auto i = arg0; i < arg1; i++) { + if(arg1 == 2147483647) { + if(i >= GKFS_MAX_INTERNAL_FDS) + break; + } + CTX->unregister_internal_fd(i); + } + } + break; +#endif default: // ignore any other syscalls, i.e.: pass them on to the kernel // (syscalls forwarded to the kernel that return are logged in @@ -486,6 +502,19 @@ hook(long syscall_number, long arg0, long arg1, long arg2, long arg3, long arg4, case SYS_close: *result = gkfs::hook::hook_close(static_cast(arg0)); break; +#ifdef SYS_close_range + case SYS_close_range: + for(auto i = arg0; i <= arg1; i++) { + if(i >= GKFS_MAX_OPEN_FDS) + break; + if(CTX->file_map()->exist(i)) { + gkfs::syscall::gkfs_close(i); + } + *result = 0; + } + *result = 0; + break; +#endif // SYS_close_range #ifdef SYS_stat case SYS_stat: *result = diff --git a/src/client/open_file_map.cpp b/src/client/open_file_map.cpp index 60f0c47813704634e3e5ec4d56fbca6dfaf0efd9..45cadeed351aecb61ee9d5025b2b7255b6239b8d 100644 --- a/src/client/open_file_map.cpp +++ b/src/client/open_file_map.cpp @@ -132,22 +132,29 @@ OpenFileMap::exist(const int fd) { int OpenFileMap::safe_generate_fd_idx_() { - auto fd = generate_fd_idx(); - /* - * Check if fd is still in use and generate another if yes - * Note that this can only happen once the all fd indices within the int has - * been used to the int::max Once this limit is exceeded, we set fd_idx back - * to 3 and begin anew. Only then, if a file was open for a long time will - * we have to generate another index. - * - * This situation can only occur when all fd indices have been given away - * once and we start again, in which case the fd_validation_needed flag is - * set. fd_validation is set to false, if - */ - if(fd_validation_needed) { - while(exist(fd)) { - fd = generate_fd_idx(); + int fd = 0; + + if(CTX->protect_fds()) { + fd = generate_fd_idx(); + /* + * Check if fd is still in use and generate another if yes + * Note that this can only happen once the all fd indices within the int + * has been used to the int::max Once this limit is exceeded, we set + * fd_idx back to 3 and begin anew. Only then, if a file was open for a + * long time will we have to generate another index. + * + * This situation can only occur when all fd indices have been given + * away once and we start again, in which case the fd_validation_needed + * flag is set. fd_validation is set to false, if + */ + if(fd_validation_needed) { + while(exist(fd)) { + fd = generate_fd_idx(); + } } + } else { + fd = syscall_no_intercept(SYS_open, "/dev/null", O_RDWR, + S_IRUSR | S_IWUSR); } return fd; } @@ -168,6 +175,10 @@ OpenFileMap::remove(const int fd) { return false; } files_.erase(fd); + if(!CTX->protect_fds()) { + // We close the dev null fd + close(fd); + } if(fd_validation_needed && files_.empty()) { fd_validation_needed = false; LOG(DEBUG, "fd_validation flag reset"); @@ -227,7 +238,7 @@ OpenFileMap::generate_fd_idx() { * which tells can tell the OpenFileMap that it should check if this fd * is really safe to use. */ - fd_idx = 100000; + fd_idx = 10000; fd_validation_needed = true; } return fd_idx++; diff --git a/src/client/preload.cpp b/src/client/preload.cpp index 67926fbb329b25e7a1ffe3193e41da9cb0b05c60..30d94365c2ddaf93d058f0fef4a3c9c478fbca0c 100644 --- a/src/client/preload.cpp +++ b/src/client/preload.cpp @@ -364,7 +364,9 @@ init_preload() { // To prevent this for our internal // initialization code, we forcefully occupy the user fd range to force // such modules to create fds in our private range. - CTX->protect_user_fds(); + if(CTX->protect_fds()) { + CTX->protect_user_fds(); + } log_prog_name(); gkfs::path::init_cwd(); @@ -374,7 +376,8 @@ init_preload() { gkfs::preload::init_environment(); CTX->enable_interception(); - CTX->unprotect_user_fds(); + if(CTX->protect_fds()) + CTX->unprotect_user_fds(); auto forwarding_map_file = gkfs::env::get_var( gkfs::env::FORWARDING_MAP_FILE, gkfs::config::forwarding_file_path); @@ -459,3 +462,32 @@ gkfs_end() { return 0; } + + +/** + * @brief Automatically launch init/destroy + * TODO: Check if this works with the user library! + */ + +void +init_libc() { + + CTX->init_logging(); + + // from here ownwards it is safe to print messages + LOG(DEBUG, "Logging subsystem initialized"); + + gkfs::preload::init_environment(); + CTX->enable_interception(); +} + +void +destroy_libc() { + CTX->clear_hosts(); + LOG(DEBUG, "Peer information deleted"); + + ld_network_service.reset(); + LOG(DEBUG, "RPC subsystem shut down"); + + LOG(INFO, "All subsystems shut down. Client shutdown complete."); +} diff --git a/src/client/preload_context.cpp b/src/client/preload_context.cpp index ff38514923a10134e4ace0864f0b3ad9f6608bca..b0707f8aaa10a4ea406d5043201b0325249bdfc5 100644 --- a/src/client/preload_context.cpp +++ b/src/client/preload_context.cpp @@ -469,11 +469,22 @@ PreloadContext::interception_enabled() const { return interception_enabled_; } +bool +PreloadContext::protect_fds() const { + return protect_fds_; +} + +void +PreloadContext::protect_fds(bool protect) { + protect_fds_ = protect; +} + int PreloadContext::register_internal_fd(int fd) { assert(fd >= 0); - + if(!protect_fds()) + return fd; if(!internal_fds_must_relocate_) { LOG(DEBUG, "registering fd {} as internal (no relocation needed)", fd); assert(fd >= MIN_INTERNAL_FD); @@ -541,7 +552,11 @@ PreloadContext::register_internal_fd(int fd) { void PreloadContext::unregister_internal_fd(int fd) { - LOG(DEBUG, "unregistering internal fd {}", fd); + if(!protect_fds()) + return; + + LOG(DEBUG, "unregistering internal fd {} >= {} -> {}'", fd, MIN_INTERNAL_FD, + fd >= MIN_INTERNAL_FD); assert(fd >= MIN_INTERNAL_FD); diff --git a/src/client/syscalls/detail/syscall_info.c b/src/client/syscalls/detail/syscall_info.c index 8c6ca4feecffebf0788e490eeea9adbdc56556e7..954486f54cfeb7d1d3a1a94cb42acd36303a278e 100644 --- a/src/client/syscalls/detail/syscall_info.c +++ b/src/client/syscalls/detail/syscall_info.c @@ -478,9 +478,6 @@ SYSCALL(getpmsg, 5, S_RET(rdec), S_NARG(arg, "arg0"), SYSCALL(readlinkat, 4, S_RET(rdec), S_NARG(atfd, "dfd"), S_NARG(cstr, "pathname"), S_NARG(ptr, "buf"), S_NARG(arg, "bufsiz")), SYSCALL(fchmodat, 3, S_RET(rdec), S_NARG(atfd, "dfd"), S_NARG(cstr, "filename"), S_NARG(octal_mode, "mode")), SYSCALL(faccessat, 3, S_RET(rdec), S_NARG(atfd, "dfd"), S_NARG(cstr, "pathname"), S_NARG(octal_mode, "mode")), -#ifdef SYS_faccessat2 - SYSCALL(faccessat2, 4, S_RET(rdec), S_NARG(atfd, "dfd"), S_NARG(cstr, "pathname"), S_NARG(octal_mode, "mode"), S_NARG(arg, "flags")), -#endif SYSCALL(pselect6, 6, S_RET(rdec), S_NARG(dec, "nfds"), S_NARG(ptr, "readfds"), S_NARG(ptr, "writefds"), S_NARG(ptr, "exceptfds"), S_NARG(ptr, "timeval"), S_NARG(ptr, "sigmask")), SYSCALL(ppoll, 5, S_RET(rdec), S_NARG(ptr, "fds"), S_NARG(dec, "nfds"), S_NARG(ptr, "tmo_p"), S_NARG(ptr, "sigmask"), S_NARG(dec, "sigsetsize")), SYSCALL(unshare, 1, S_RET(rdec), S_NARG(arg, "unshare_flags")), @@ -596,8 +593,108 @@ SYSCALL(getpmsg, 5, S_RET(rdec), S_NARG(arg, "arg0"), #endif // SYS_io_pgetevents #ifdef SYS_rseq - SYSCALL(rseq, 4, S_RET(rdec), S_NARG(ptr, "rseq"), S_NARG(dec, "rseq_len"), S_NARG(arg, "flags"), S_NARG(signum, "sig")) + SYSCALL(rseq, 4, S_RET(rdec), S_NARG(ptr, "rseq"), S_NARG(dec, "rseq_len"), S_NARG(arg, "flags"), S_NARG(signum, "sig")), #endif // SYS_rseq +// ifdef the next syscalls +#ifdef SYS_pidfd_send_signal + SYSCALL(pidfd_send_signal, 3, S_RET(rdec), S_NARG(dec, "pidfd"), S_NARG(signum, "sig"), S_NARG(arg, "flags")), +#endif +#ifdef SYS_io_uring_setup + SYSCALL(io_uring_setup, 2, S_RET(rdec), S_NARG(arg, "entries"), S_NARG(ptr, "ring_addr")), +#endif +#ifdef SYS_io_uring_enter + SYSCALL(io_uring_enter, 4, S_RET(rdec), S_NARG(arg, "ring_fd"), S_NARG(dec, "to_submit"), S_NARG(dec, "min_complete"), S_NARG(arg, "flags")), +#endif +#ifdef SYS_io_uring_register + SYSCALL(io_uring_register, 4, S_RET(rdec), S_NARG(arg, "ring_fd"), S_NARG(arg, "opcode"), S_NARG(ptr, "arg"), S_NARG(arg, "nr_args")), +#endif +#ifdef SYS_open_tree + SYSCALL(open_tree, 2, S_RET(rdec), S_NARG(cstr, "pathname"), S_NARG(open_flags, "flags")), +#endif +#ifdef SYS_move_mount + SYSCALL(move_mount, 3, S_RET(rdec), S_NARG(cstr, "src"), S_NARG(cstr, "dst"), S_NARG(arg, "flags")), +#endif +#ifdef SYS_fsopen + SYSCALL(fsopen, 3, S_RET(rdec), S_NARG(cstr, "fs_type"), S_NARG(cstr, "pathname"), S_NARG(open_flags, "flags")), +#endif +#ifdef SYS_fsconfig + SYSCALL(fsconfig, 3, S_RET(rdec), S_NARG(arg, "cmd"), S_NARG(ptr, "argp"), S_NARG(ptr, "resp")), +#endif +#ifdef SYS_fsmount + SYSCALL(fsmount, 5, S_RET(rdec), S_NARG(cstr, "fs_type"), S_NARG(cstr, "pathname"), S_NARG(cstr, "type"), S_NARG(arg, "flags"), S_NARG(ptr, "data")), +#endif +#ifdef SYS_fspick + SYSCALL(fspick, 4, S_RET(rdec), S_NARG(arg, "arg0"), S_NARG(arg, "arg1"), S_NARG(arg, "arg2"), S_NARG(arg, "arg3")), +#endif +#ifdef SYS_pidfd_open + SYSCALL(pidfd_open, 2, S_RET(rdec), S_NARG(dec, "pid"), S_NARG(arg, "flags")), +#endif +#ifdef SYS_clone3 + SYSCALL(clone3, 4, S_RET(rdec), S_NARG(arg, "flags"), S_NARG(ptr, "child_tid"), S_NARG(ptr, "parent_tid"), S_NARG(ptr, "tls")), +#endif +#ifdef SYS_close_range + SYSCALL(close_range, 3, S_RET(rdec), S_NARG(dec, "low"), S_NARG(dec, "high"), S_NARG(arg, "flags")), +#endif +#ifdef SYS_openat2 + SYSCALL(openat2, 4, S_RET(rdec), S_NARG(atfd, "dfd"), S_NARG(cstr, "pathname"), S_NARG(open_flags, "flags"), S_NARG(ptr, "how")), +#endif +#ifdef SYS_pidfd_getfd + SYSCALL(pidfd_getfd, 3, S_RET(rdec), S_NARG(dec, "pidfd"), S_NARG(arg, "fd"), S_NARG(arg, "flags")), +#endif +#ifdef SYS_faccessat2 + SYSCALL(faccessat2, 4, S_RET(rdec), S_NARG(atfd, "dfd"), S_NARG(cstr, "pathname"), S_NARG(octal_mode, "mode"), S_NARG(arg, "flags")), +#endif +#ifdef SYS_process_madvise + SYSCALL(process_madvise, 4, S_RET(rdec), S_NARG(dec, "pid"), S_NARG(ptr, "addr"), S_NARG(dec, "length"), S_NARG(arg, "advice")), +#endif +#ifdef SYS_epoll_pwait2 + SYSCALL(epoll_pwait2, 6, S_RET(rdec), S_NARG(fd, "epfd"), S_NARG(ptr, "events"), S_NARG(dec, "maxevents"), S_NARG(dec, "timeout"), S_NARG(ptr, "sigmask"), S_NARG(dec, "sigsetsize")), +#endif +#ifdef SYS_mount_setattr + SYSCALL(mount_setattr, 3, S_RET(rdec), S_NARG(cstr, "path"), S_NARG(ptr, "attr"), S_NARG(arg, "flags")), +#endif +#ifdef SYS_quotactl_fd + SYSCALL(quotactl_fd, 4, S_RET(rdec), S_NARG(arg, "cmd"), S_NARG(fd, "fd"), S_NARG(arg, "id"), S_NARG(ptr, "addr")), +#endif +#ifdef SYS_landlock_create_ruleset + SYSCALL(landlock_create_ruleset, 1, S_RET(rdec), S_NARG(arg, "flags")), +#endif +#ifdef SYS_landlock_add_rule + SYSCALL(landlock_add_rule, 3, S_RET(rdec), S_NARG(dec, "ruleset"), S_NARG(arg, "rule"), S_NARG(arg, "flags")), +#endif +#ifdef SYS_landlock_restrict_self + SYSCALL(landlock_restrict_self, 1, S_RET(rdec), S_NARG(dec, "ruleset")), +#endif +#ifdef SYS_memfd_secret + SYSCALL(memfd_secret, 3, S_RET(rdec), S_NARG(cstr, "name"), S_NARG(arg, "flags"), S_NARG(ptr, "secret")), +#endif +#ifdef SYS_process_mrelease + SYSCALL(process_mrelease, 2, S_RET(rdec), S_NARG(dec, "pid"), S_NARG(ptr, "addr")), +#endif +#ifdef SYS_futex_waitv + SYSCALL(futex_waitv, 5, S_RET(rdec), S_NARG(ptr, "uaddr"), S_NARG(arg, "op"), S_NARG(ptr, "val"), S_NARG(ptr, "timeout"), S_NARG(dec, "flags")), +#endif +#ifdef SYS_set_mempolicy_home_node + SYSCALL(set_mempolicy_home_node, 1, S_RET(rdec), S_NARG(arg, "node")), +#endif +#ifdef SYS_cachestat + SYSCALL(cachestat, 1, S_RET(rdec), S_NARG(ptr, "cs")), +#endif +#ifdef SYS_fchmodat2 + SYSCALL(fchmodat2, 4, S_RET(rdec), S_NARG(atfd, "dfd"), S_NARG(cstr, "pathname"), S_NARG(octal_mode, "mode"), S_NARG(arg, "flags")), +#endif +#ifdef SYS_map_shadow_stack + SYSCALL(map_shadow_stack, 1, S_RET(rdec), S_NARG(arg, "flags")), +#endif +#ifdef SYS_futex_wake + SYSCALL(futex_wake, 3, S_RET(rdec), S_NARG(ptr, "uaddr"), S_NARG(dec, "nr_wake"), S_NARG(arg, "flags")), +#endif +#ifdef SYS_futex_wait + SYSCALL(futex_wait, 4, S_RET(rdec), S_NARG(ptr, "uaddr"), S_NARG(arg, "op"), S_NARG(ptr, "val"), S_NARG(ptr, "timeout")), +#endif +#ifdef SYS_futex_requeue + SYSCALL(futex_requeue, 5, S_RET(rdec), S_NARG(ptr, "uaddr1"), S_NARG(ptr, "uaddr2"), S_NARG(arg, "op"), S_NARG(ptr, "val"), S_NARG(ptr, "timeout")) +#endif }; static const struct syscall_info unknown_syscall = { @@ -742,7 +839,13 @@ const struct named_syscall_entry syscalls_by_name[] = { SYSCALL_BY_NAME(clock_nanosleep), SYSCALL_BY_NAME(clock_settime), SYSCALL_BY_NAME(clone), +#ifdef SYS_clone3 + SYSCALL_BY_NAME(clone3), +#endif SYSCALL_BY_NAME(close), +#ifdef SYS_close_range + SYSCALL_BY_NAME(close_range), +#endif SYSCALL_BY_NAME(connect), #ifdef SYS_copy_file_range SYSCALL_BY_NAME(copy_file_range), diff --git a/tests/integration/syscalls/test_error_operations.py b/tests/integration/syscalls/test_error_operations.py index 97ae68889b3dc2ca86ff762b9fce194422799c9c..f8c3285cb878de555e9ceb4f728f058dd95946d7 100644 --- a/tests/integration/syscalls/test_error_operations.py +++ b/tests/integration/syscalls/test_error_operations.py @@ -46,8 +46,8 @@ def test_open_error(gkfs_daemon, gkfs_client): file = gkfs_daemon.mountdir / "file" file2 = gkfs_daemon.mountdir / "file2" file3 = gkfs_daemon.mountdir / "file3" - - flags = [os.O_PATH, os.O_CREAT | os.O_DIRECTORY] + # O_PATH is now supported as cp uses it.. + flags = [os.O_CREAT | os.O_DIRECTORY] # create a file in gekkofs for flag in flags: