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: