From 1963eee89d4b3ab68132b3ebb4f7755a42dcc4b9 Mon Sep 17 00:00:00 2001 From: Tommaso Tocci Date: Fri, 7 Sep 2018 16:38:43 +0200 Subject: [PATCH 01/25] syscall_intercept --- CMake/FindSyscall_intercept.cmake | 41 + CMakeLists.txt | 1 + include/client/hooks.hpp | 22 + include/client/intercept.hpp | 26 + include/client/passthrough.hpp | 131 --- include/client/syscall_names.hpp | 353 +++++++ scripts/compile_dep.sh | 7 + scripts/dl_dep.sh | 2 + src/client/CMakeLists.txt | 10 +- src/client/hooks.cpp | 71 ++ src/client/intcp_functions.cpp | 1510 ----------------------------- src/client/intercept.cpp | 107 ++ src/client/passthrough.cpp | 265 ----- src/client/preload.cpp | 6 +- src/client/resolve.cpp | 16 +- 15 files changed, 648 insertions(+), 1920 deletions(-) create mode 100644 CMake/FindSyscall_intercept.cmake create mode 100644 include/client/hooks.hpp create mode 100644 include/client/intercept.hpp delete mode 100644 include/client/passthrough.hpp create mode 100644 include/client/syscall_names.hpp create mode 100644 src/client/hooks.cpp delete mode 100644 src/client/intcp_functions.cpp create mode 100644 src/client/intercept.cpp delete mode 100644 src/client/passthrough.cpp diff --git a/CMake/FindSyscall_intercept.cmake b/CMake/FindSyscall_intercept.cmake new file mode 100644 index 000000000..5aff4b176 --- /dev/null +++ b/CMake/FindSyscall_intercept.cmake @@ -0,0 +1,41 @@ +find_package(PkgConfig) +pkg_check_modules(PC_Syscall_intercept QUIET libsyscall_intercept) + +find_path(Syscall_intercept_INCLUDE_DIR + NAMES libsyscall_intercept_hook_point.h + PATHS ${PC_Syscall_intercept_INCLUDE_DIRS} +) + +find_library(Syscall_intercept_LIBRARY + NAMES syscall_intercept + PATHS ${PC_Syscall_intercept_LIBRARY_DIRS} +) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args( + Syscall_intercept + DEFAULT_MSG + Syscall_intercept_INCLUDE_DIR + Syscall_intercept_LIBRARY +) + +if(Syscall_intercept_FOUND) + set(Syscall_intercept_LIBRARIES ${Syscall_intercept_LIBRARY}) + set(Syscall_intercept_INCLUDE_DIRS ${Syscall_intercept_INCLUDE_DIR}) + set(Syscall_intercept_DEFINITIONS ${PC_Syscall_intercept_CFLAGS_OTHER}) + + if(NOT TARGET Syscall_intercept::Syscall_intercept) + add_library(Syscall_intercept::Syscall_intercept UNKNOWN IMPORTED) + set_target_properties(Syscall_intercept::Syscall_intercept PROPERTIES + IMPORTED_LOCATION "${Syscall_intercept_LIBRARY}" + INTERFACE_COMPILE_OPTIONS "${PC_Syscall_intercept_CFLAGS_OTHER}" + INTERFACE_INCLUDE_DIRECTORIES "${Syscall_intercept_INCLUDE_DIR}" + ) + endif() +endif() + + +mark_as_advanced( + Syscall_intercept_INCLUDE_DIR + Syscall_intercept_LIBRARY +) diff --git a/CMakeLists.txt b/CMakeLists.txt index 52420d4b5..0817e8ff2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -83,6 +83,7 @@ find_package(RocksDB REQUIRED) find_package(Mercury REQUIRED) find_package(Abt REQUIRED) find_package(Margo REQUIRED) +find_package(Syscall_intercept REQUIRED) # boost dependencies, system is required for filesystem find_package(Boost 1.53 REQUIRED diff --git a/include/client/hooks.hpp b/include/client/hooks.hpp new file mode 100644 index 000000000..2fe1342f0 --- /dev/null +++ b/include/client/hooks.hpp @@ -0,0 +1,22 @@ +/* + Copyright 2018-2019, Barcelona Supercomputing Center (BSC), Spain + Copyright 2015-2019, 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: MIT +*/ + +#ifndef IFS_HOOKS_HPP +#define IFS_HOOKS_HPP + +#include + + +int hook_openat(int dirfd, const char *cpath, int flags, mode_t mode); + +#endif diff --git a/include/client/intercept.hpp b/include/client/intercept.hpp new file mode 100644 index 000000000..9ba21eeb5 --- /dev/null +++ b/include/client/intercept.hpp @@ -0,0 +1,26 @@ +/* + Copyright 2018-2019, Barcelona Supercomputing Center (BSC), Spain + Copyright 2015-2019, 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: MIT +*/ + +#ifndef IFS_INTERCEPT_HPP +#define IFS_INTERCEPT_HPP + +int +hook_guard_wrapper(long syscall_number, + long arg0, long arg1, long arg2, + long arg3, long arg4, long arg5, + long *syscall_return_value); + +void start_interception(); +void stop_interception(); + +#endif diff --git a/include/client/passthrough.hpp b/include/client/passthrough.hpp deleted file mode 100644 index 2153dbddb..000000000 --- a/include/client/passthrough.hpp +++ /dev/null @@ -1,131 +0,0 @@ -/* - Copyright 2018-2019, Barcelona Supercomputing Center (BSC), Spain - Copyright 2015-2019, 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: MIT -*/ - -#ifndef IFS_PASSTHROUGH_HPP -#define IFS_PASSTHROUGH_HPP - - -#define LIBC_FUNC_NAME(FNAME) libc_##FNAME - -#define LIBC_FUNC(FNAME, ...) \ - ((reinterpret_cast(libc_##FNAME))(__VA_ARGS__)) - - -extern void* LIBC_FUNC_NAME(open); -extern void* LIBC_FUNC_NAME(openat); - -extern void* LIBC_FUNC_NAME(fopen); -extern void* LIBC_FUNC_NAME(fopen64); -extern void* LIBC_FUNC_NAME(fread); -extern void* LIBC_FUNC_NAME(fwrite); -extern void* LIBC_FUNC_NAME(fclose); -extern void* LIBC_FUNC_NAME(clearerr); -extern void* LIBC_FUNC_NAME(feof); -extern void* LIBC_FUNC_NAME(ferror); -extern void* LIBC_FUNC_NAME(fileno); -extern void* LIBC_FUNC_NAME(fflush); -extern void* LIBC_FUNC_NAME(__fpurge); - -extern void* LIBC_FUNC_NAME(setbuf); -extern void* LIBC_FUNC_NAME(setbuffer); -extern void* LIBC_FUNC_NAME(setlinebuf); -extern void* LIBC_FUNC_NAME(setvbuf); - -extern void* LIBC_FUNC_NAME(putc); -extern void* LIBC_FUNC_NAME(fputc); -extern void* LIBC_FUNC_NAME(fputs); -extern void* LIBC_FUNC_NAME(getc); -extern void* LIBC_FUNC_NAME(fgetc); -extern void* LIBC_FUNC_NAME(fgets); -extern void* LIBC_FUNC_NAME(ungetc); - -extern void* LIBC_FUNC_NAME(fseek); - -extern void* LIBC_FUNC_NAME(mkdir); -extern void* LIBC_FUNC_NAME(mkdirat); -extern void* LIBC_FUNC_NAME(unlink); -extern void* LIBC_FUNC_NAME(unlinkat); -extern void* LIBC_FUNC_NAME(rmdir); - -extern void* LIBC_FUNC_NAME(close); - -extern void* LIBC_FUNC_NAME(access); -extern void* LIBC_FUNC_NAME(faccessat); - -extern void* LIBC_FUNC_NAME(__xstat); -extern void* LIBC_FUNC_NAME(__xstat64); -extern void* LIBC_FUNC_NAME(__fxstat); -extern void* LIBC_FUNC_NAME(__fxstat64); -extern void* LIBC_FUNC_NAME(__fxstatat); -extern void* LIBC_FUNC_NAME(__fxstatat64); -extern void* LIBC_FUNC_NAME(__lxstat); -extern void* LIBC_FUNC_NAME(__lxstat64); - -extern void* LIBC_FUNC_NAME(statfs); -extern void* LIBC_FUNC_NAME(fstatfs); -extern void* LIBC_FUNC_NAME(statvfs); -extern void* LIBC_FUNC_NAME(fstatvfs); - -extern void* LIBC_FUNC_NAME(write); -extern void* LIBC_FUNC_NAME(pwrite); -extern void* LIBC_FUNC_NAME(pwrite64); -extern void* LIBC_FUNC_NAME(writev); - -extern void* LIBC_FUNC_NAME(read); -extern void* LIBC_FUNC_NAME(pread); -extern void* LIBC_FUNC_NAME(pread64); -extern void* LIBC_FUNC_NAME(readv); - -extern void* LIBC_FUNC_NAME(lseek); -extern void* LIBC_FUNC_NAME(lseek64); -extern void* LIBC_FUNC_NAME(fsync); -extern void* LIBC_FUNC_NAME(fdatasync); - -extern void* LIBC_FUNC_NAME(truncate); -extern void* LIBC_FUNC_NAME(ftruncate); - -extern void* LIBC_FUNC_NAME(fcntl); - -extern void* LIBC_FUNC_NAME(dup); -extern void* LIBC_FUNC_NAME(dup2); -extern void* LIBC_FUNC_NAME(dup3); - -extern void* LIBC_FUNC_NAME(dirfd); -extern void* LIBC_FUNC_NAME(opendir); -extern void* LIBC_FUNC_NAME(fdopendir); -extern void* LIBC_FUNC_NAME(readdir); -extern void* LIBC_FUNC_NAME(closedir); - -extern void* LIBC_FUNC_NAME(chmod); -extern void* LIBC_FUNC_NAME(fchmod); -extern void* LIBC_FUNC_NAME(fchmodat); - -extern void* LIBC_FUNC_NAME(chdir); -extern void* LIBC_FUNC_NAME(fchdir); - -extern void* LIBC_FUNC_NAME(getcwd); -extern void* LIBC_FUNC_NAME(get_current_dir_name); - -extern void* LIBC_FUNC_NAME(link); -extern void* LIBC_FUNC_NAME(linkat); -extern void* LIBC_FUNC_NAME(symlinkat); - -extern void* LIBC_FUNC_NAME(readlinkat); - -extern void* LIBC_FUNC_NAME(realpath); - - -void init_passthrough_if_needed(); - - -#endif //IFS_PASSTHROUGH_HPP diff --git a/include/client/syscall_names.hpp b/include/client/syscall_names.hpp new file mode 100644 index 000000000..823d859a5 --- /dev/null +++ b/include/client/syscall_names.hpp @@ -0,0 +1,353 @@ +/* + Copyright 2018-2019, Barcelona Supercomputing Center (BSC), Spain + Copyright 2015-2019, 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: MIT +*/ + +#ifndef IFS_SYSCALL_NAMES_HPP +#define IFS_SYSCALL_NAMES_HPP + +const char* syscall_names[] = { +"read", +"write", +"open", +"close", +"stat", +"fstat", +"lstat", +"poll", +"lseek", +"mmap", +"mprotect", +"munmap", +"brk", +"rt_sigaction", +"rt_sigprocmask", +"rt_sigreturn", +"ioctl", +"pread64", +"pwrite64", +"readv", +"writev", +"access", +"pipe", +"select", +"sched_yield", +"mremap", +"msync", +"mincore", +"madvise", +"shmget", +"shmat", +"shmctl", +"dup", +"dup2", +"pause", +"nanosleep", +"getitimer", +"alarm", +"setitimer", +"getpid", +"sendfile", +"socket", +"connect", +"accept", +"sendto", +"recvfrom", +"sendmsg", +"recvmsg", +"shutdown", +"bind", +"listen", +"getsockname", +"getpeername", +"socketpair", +"setsockopt", +"getsockopt", +"clone", +"fork", +"vfork", +"execve", +"exit", +"wait4", +"kill", +"uname", +"semget", +"semop", +"semctl", +"shmdt", +"msgget", +"msgsnd", +"msgrcv", +"msgctl", +"fcntl", +"flock", +"fsync", +"fdatasync", +"truncate", +"ftruncate", +"getdents", +"getcwd", +"chdir", +"fchdir", +"rename", +"mkdir", +"rmdir", +"creat", +"link", +"unlink", +"symlink", +"readlink", +"chmod", +"fchmod", +"chown", +"fchown", +"lchown", +"umask", +"gettimeofday", +"getrlimit", +"getrusage", +"sysinfo", +"times", +"ptrace", +"getuid", +"syslog", +"getgid", +"setuid", +"setgid", +"geteuid", +"getegid", +"setpgid", +"getppid", +"getpgrp", +"setsid", +"setreuid", +"setregid", +"getgroups", +"setgroups", +"setresuid", +"getresuid", +"setresgid", +"getresgid", +"getpgid", +"setfsuid", +"setfsgid", +"getsid", +"capget", +"capset", +"rt_sigpending", +"rt_sigtimedwait", +"rt_sigqueueinfo", +"rt_sigsuspend", +"sigaltstack", +"utime", +"mknod", +"uselib", +"personality", +"ustat", +"statfs", +"fstatfs", +"sysfs", +"getpriority", +"setpriority", +"sched_setparam", +"sched_getparam", +"sched_setscheduler", +"sched_getscheduler", +"sched_get_priority_max", +"sched_get_priority_min", +"sched_rr_get_interval", +"mlock", +"munlock", +"mlockall", +"munlockall", +"vhangup", +"modify_ldt", +"pivot_root", +"_sysctl", +"prctl", +"arch_prctl", +"adjtimex", +"setrlimit", +"chroot", +"sync", +"acct", +"settimeofday", +"mount", +"umount2", +"swapon", +"swapoff", +"reboot", +"sethostname", +"setdomainname", +"iopl", +"ioperm", +"create_module", +"init_module", +"delete_module", +"get_kernel_syms", +"query_module", +"quotactl", +"nfsservctl", +"getpmsg", +"putpmsg", +"afs_syscall", +"tuxcall", +"security", +"gettid", +"readahead", +"setxattr", +"lsetxattr", +"fsetxattr", +"getxattr", +"lgetxattr", +"fgetxattr", +"listxattr", +"llistxattr", +"flistxattr", +"removexattr", +"lremovexattr", +"fremovexattr", +"tkill", +"time", +"futex", +"sched_setaffinity", +"sched_getaffinity", +"set_thread_area", +"io_setup", +"io_destroy", +"io_getevents", +"io_submit", +"io_cancel", +"get_thread_area", +"lookup_dcookie", +"epoll_create", +"epoll_ctl_old", +"epoll_wait_old", +"remap_file_pages", +"getdents64", +"set_tid_address", +"restart_syscall", +"semtimedop", +"fadvise64", +"timer_create", +"timer_settime", +"timer_gettime", +"timer_getoverrun", +"timer_delete", +"clock_settime", +"clock_gettime", +"clock_getres", +"clock_nanosleep", +"exit_group", +"epoll_wait", +"epoll_ctl", +"tgkill", +"utimes", +"vserver", +"mbind", +"set_mempolicy", +"get_mempolicy", +"mq_open", +"mq_unlink", +"mq_timedsend", +"mq_timedreceive", +"mq_notify", +"mq_getsetattr", +"kexec_load", +"waitid", +"add_key", +"request_key", +"keyctl", +"ioprio_set", +"ioprio_get", +"inotify_init", +"inotify_add_watch", +"inotify_rm_watch", +"migrate_pages", +"openat", +"mkdirat", +"mknodat", +"fchownat", +"futimesat", +"newfstatat", +"unlinkat", +"renameat", +"linkat", +"symlinkat", +"readlinkat", +"fchmodat", +"faccessat", +"pselect6", +"ppoll", +"unshare", +"set_robust_list", +"get_robust_list", +"splice", +"tee", +"sync_file_range", +"vmsplice", +"move_pages", +"utimensat", +"epoll_pwait", +"signalfd", +"timerfd_create", +"eventfd", +"fallocate", +"timerfd_settime", +"timerfd_gettime", +"accept4", +"signalfd4", +"eventfd2", +"epoll_create1", +"dup3", +"pipe2", +"inotify_init1", +"preadv", +"pwritev", +"rt_tgsigqueueinfo", +"perf_event_open", +"recvmmsg", +"fanotify_init", +"fanotify_mark", +"prlimit64", +"name_to_handle_at", +"open_by_handle_at", +"clock_adjtime", +"syncfs", +"sendmmsg", +"setns", +"getcpu", +"process_vm_readv", +"process_vm_writev", +"kcmp", +"finit_module", +"sched_setattr", +"sched_getattr", +"renameat2", +"seccomp", +"getrandom", +"memfd_create", +"kexec_file_load", +"bpf", +"execveat", +"userfaultfd", +"membarrier", +"mlock2", +"copy_file_range", +"preadv2", +"pwritev2", +"pkey_mprotect", +"pkey_alloc", +"pkey_free", +"statx" +}; + +#endif diff --git a/scripts/compile_dep.sh b/scripts/compile_dep.sh index 21c657d05..a63ef5714 100755 --- a/scripts/compile_dep.sh +++ b/scripts/compile_dep.sh @@ -302,4 +302,11 @@ make clean USE_RTTI=1 make -j${CORES} static_lib INSTALL_PATH=${INSTALL} make install +echo "############################################################ Installing: Syscall_intercept" +CURR=${SOURCE}/syscall_intercept +prepare_build_dir ${CURR} +cd ${CURR}/build +$CMAKE -DCMAKE_INSTALL_PREFIX=${INSTALL} -DCMAKE_BUILD_TYPE:STRING=Release -DBUILD_EXAMPLES:BOOL=OFF -DBUILD_TESTS:BOOK=OFF .. +make install + echo "Done" diff --git a/scripts/dl_dep.sh b/scripts/dl_dep.sh index a3dcdf1c8..e3b5fa1da 100755 --- a/scripts/dl_dep.sh +++ b/scripts/dl_dep.sh @@ -202,6 +202,8 @@ wgetdeps "argobots" "https://github.com/pmodels/argobots/archive/v1.0rc1.tar.gz" clonedeps "margo" "https://xgitlab.cels.anl.gov/sds/margo.git" "ad09e1e445a9275b24036e465bee3b4b75f0fb17" & # get rocksdb wgetdeps "rocksdb" "https://github.com/facebook/rocksdb/archive/v6.0.1.tar.gz" & +# get syscall_intercept +clonedeps "syscall_intercept" "https://github.com/pmem/syscall_intercept.git" "33ac1e772fb568241694906bdf93abf952d8db70" & # Wait for all download to be completed wait diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt index ac665418d..819cbf744 100644 --- a/src/client/CMakeLists.txt +++ b/src/client/CMakeLists.txt @@ -1,10 +1,10 @@ set(PRELOAD_SRC preload_context.cpp adafs_functions.cpp - intcp_functions.cpp + intercept.cpp + hooks.cpp open_file_map.cpp open_dir.cpp - passthrough.cpp preload.cpp resolve.cpp preload_util.cpp @@ -25,10 +25,11 @@ set(PRELOAD_HEADERS ../../include/global/chunk_calc_util.hpp ../../include/client/preload_context.hpp ../../include/client/adafs_functions.hpp - ../../include/client/intcp_functions.hpp + ../../include/client/intercept.hpp + ../../include/client/syscall_names.hpp + ../../include/client/hooks.hpp ../../include/client/open_file_map.hpp ../../include/client/open_dir.hpp - ../../include/client/passthrough.hpp ../../include/client/preload.hpp ../../include/client/resolve.hpp ../../include/client/preload_util.hpp @@ -45,6 +46,7 @@ target_link_libraries(gkfs_intercept distributor log_util # external + Syscall_intercept::Syscall_intercept dl ${ABT_LIBRARIES} mercury diff --git a/src/client/hooks.cpp b/src/client/hooks.cpp new file mode 100644 index 000000000..8a36acc7a --- /dev/null +++ b/src/client/hooks.cpp @@ -0,0 +1,71 @@ +/* + Copyright 2018-2019, Barcelona Supercomputing Center (BSC), Spain + Copyright 2015-2019, 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: MIT +*/ + +#include "client/hooks.hpp" +#include "client/preload.hpp" +#include "client/adafs_functions.hpp" +#include "client/resolve.hpp" +#include "client/open_dir.hpp" +#include "global/path_util.hpp" + +#include +#include +#include + + +int hook_openat(int dirfd, const char *cpath, int flags, mode_t mode) { + + if(cpath == nullptr || cpath[0] == '\0') { + CTX->log()->error("{}() path is invalid", __func__); + return -EINVAL; + } + + CTX->log()->trace("{}() called with fd: {}, path: {}, flags: {}, mode: {}", __func__, dirfd, cpath, flags, mode); + + std::string resolved; + + if((cpath[0] == PSP) || (dirfd == AT_FDCWD)) { + // cpath is absolute or relative to CWD + if (CTX->relativize_path(cpath, resolved)) { + int ret = adafs_open(resolved, mode, flags); + if(ret < 0) { + return -errno; + } + } + } else { + // cpath is relative + if(!(CTX->file_map()->exist(dirfd))) { + //TODO relative cpath could still lead to our FS + return syscall_no_intercept(SYS_openat, dirfd, cpath, flags, mode); + } + + auto dir = CTX->file_map()->get_dir(dirfd); + if(dir == nullptr) { + CTX->log()->error("{}() dirfd is not a directory ", __func__); + errno = ENOTDIR; + return -1; + } + + std::string path = CTX->mountdir(); + path.append(dir->path()); + path.push_back(PSP); + path.append(cpath); + if(resolve_path(path, resolved)) { + int ret = adafs_open(resolved, mode, flags); + if(ret < 0) { + return -errno; + } + } + } + return 0; +} diff --git a/src/client/intcp_functions.cpp b/src/client/intcp_functions.cpp deleted file mode 100644 index 0235f184c..000000000 --- a/src/client/intcp_functions.cpp +++ /dev/null @@ -1,1510 +0,0 @@ -/* - Copyright 2018-2019, Barcelona Supercomputing Center (BSC), Spain - Copyright 2015-2019, 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: MIT -*/ - -/** - * All intercepted functions are defined here - */ -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - - -using namespace std; - -void inline notsup_error_32_bit_func(const char* func = __builtin_FUNCTION()) { - CTX->log()->error("{}() is NOT SUPPORTED. According to glibc, this function should be called only on 32-bit machine", func); -} - -int intcp_open(const char* path, int flags, ...) { - init_passthrough_if_needed(); - - mode_t mode = 0; - if (flags & O_CREAT) { - va_list vl; - va_start(vl, flags); - mode = static_cast(va_arg(vl, int)); - va_end(vl); - } - if (!CTX->interception_enabled()) { - return LIBC_FUNC(open, path, flags, mode); - } - - CTX->log()->trace("{}() called with path '{}'", __func__, path); - std::string rel_path; - if (!CTX->relativize_path(path, rel_path)) { - return LIBC_FUNC(open, rel_path.c_str(), flags, mode); - } - return adafs_open(rel_path, mode, flags); -} - -#undef open64 - -int intcp_open64(const char* path, int flags, ...) { - init_passthrough_if_needed(); - mode_t mode = 0; - if (flags & O_CREAT) { - va_list ap; - va_start(ap, flags); - mode = va_arg(ap, mode_t); - va_end(ap); - } - return intcp_open(path, flags | O_LARGEFILE, mode); -} - -int intcp_openat(int dirfd, const char *cpath, int flags, ...) { - init_passthrough_if_needed(); - - mode_t mode = 0; - if (flags & O_CREAT) { - va_list vl; - va_start(vl, flags); - mode = static_cast(va_arg(vl, int)); - va_end(vl); - } - - if(!CTX->interception_enabled()) { - return LIBC_FUNC(openat, dirfd, cpath, flags, mode); - } - - CTX->log()->trace("{}() called with fd: {}, path: {}, flags: {}, mode: {}", - __func__, dirfd, cpath, flags, mode); - - //TODO handle NO_FOLLOW flag - - std::string resolved; - auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved); - switch(rstatus) { - case RelativizeStatus::fd_unknown: - return LIBC_FUNC(openat, dirfd, cpath, flags, mode); - - case RelativizeStatus::external: - return LIBC_FUNC(openat, dirfd, resolved.c_str(), flags, mode); - - case RelativizeStatus::fd_not_a_dir: - errno = ENOTDIR; - return -1; - - case RelativizeStatus::internal: - return adafs_open(resolved, mode, flags); - - default: - CTX->log()->error("{}() relativize status unknown: {}", __func__); - errno = EINVAL; - return -1; - } -} - -int intcp_openat64(int dirfd, const char *path, int flags, ...) { - init_passthrough_if_needed(); - - mode_t mode = 0; - if (flags & O_CREAT) { - va_list vl; - va_start(vl, flags); - mode = static_cast(va_arg(vl, int)); - va_end(vl); - } - - return intcp_openat(dirfd, path, flags | O_LARGEFILE, mode); -} - -/****** FILE OPS ******/ - -inline int file_to_fd(const FILE* f){ - assert(f != nullptr); - return *(reinterpret_cast(&f)); -} - -inline FILE* fd_to_file(const int fd){ - assert(fd >= 0); - return reinterpret_cast(fd); -} - -FILE* fopen(const char* path, const char* fmode) { - init_passthrough_if_needed(); - if(!CTX->interception_enabled()) { - return LIBC_FUNC(fopen, path, fmode); - } - CTX->log()->trace("{}() called with path '{}' with mode '{}'", __func__, path, fmode); - std::string rel_path; - if (!CTX->relativize_path(path, rel_path)) { - return LIBC_FUNC(fopen, rel_path.c_str(), fmode); - } - int flags = 0; - std::string str_mode(fmode); - str_mode.erase(std::remove(str_mode.begin(), str_mode.end(), 'b'), str_mode.end()); - - if(str_mode == "r") { - flags = O_RDONLY; - } else if(str_mode == "r+") { - flags = O_RDWR; - } else if(str_mode == "w") { - flags = (O_WRONLY | O_CREAT | O_TRUNC); - } else if(str_mode == "w+") { - flags = (O_RDWR | O_CREAT | O_TRUNC); - } else if(str_mode == "a") { - flags = (O_WRONLY | O_CREAT | O_APPEND); - } else if(str_mode == "a+") { - flags = (O_RDWR | O_CREAT | O_APPEND); - } else { - CTX->log()->error("{}() stream open flags NOT SUPPORTED: '{}'", __func__, str_mode); - errno = ENOTSUP; - return nullptr; - } - mode_t mode = (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); - auto fd = adafs_open(rel_path, mode, flags); - if(fd == -1){ - return nullptr; - } else { - return fd_to_file(fd); - } -} - -FILE* fopen64(const char* path, const char* fmode) { - init_passthrough_if_needed(); - if(!CTX->interception_enabled()) { - return LIBC_FUNC(fopen64, path, fmode); - } - CTX->log()->trace("{}() called with path '{}' with mode '{}'", __func__, path, fmode); - std::string rel_path; - if (!CTX->relativize_path(path, rel_path)) { - return LIBC_FUNC(fopen64, rel_path.c_str(), fmode); - } - return fopen(path, fmode); -} - -size_t intcp_fread(void *ptr, size_t size, size_t nmemb, FILE *stream) { - init_passthrough_if_needed(); - if(CTX->interception_enabled() && (stream != nullptr)) { - auto fd = file_to_fd(stream); - if (CTX->file_map()->exist(fd)) { - CTX->log()->trace("{}() called with fd {}", __func__, fd); - auto ret = adafs_read(fd, ptr, size*nmemb); - if (ret > 0) { - return ret / size; - } - return static_cast(ret); - } - } - return (reinterpret_cast(libc_fread))(ptr, size, nmemb, stream); -} - -size_t intcp_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) { - init_passthrough_if_needed(); - if(CTX->interception_enabled() && (stream != nullptr)) { - auto fd = file_to_fd(stream); - if (CTX->file_map()->exist(fd)) { - CTX->log()->trace("{}() called with fd {}", __func__, fd); - auto ret = adafs_write(fd, ptr, size*nmemb); - if (ret > 0) { - // Update offset in file descriptor in the file map - return ret / size; - } - return static_cast(ret); - } - } - return (reinterpret_cast(libc_fwrite))(ptr, size, nmemb, stream); -} - -int fclose(FILE *stream) { - init_passthrough_if_needed(); - if(CTX->interception_enabled() && (stream != nullptr)) { - auto fd = file_to_fd(stream); - if(CTX->file_map()->exist(fd)) { - // No call to the daemon is required - CTX->file_map()->remove(fd); - return 0; - } - } - return (reinterpret_cast(libc_fclose))(stream); -} - -int fileno(FILE *stream) { - init_passthrough_if_needed(); - if(CTX->interception_enabled() && (stream != nullptr)) { - auto fd = file_to_fd(stream); - if(CTX->file_map()->exist(fd)) { - CTX->log()->trace("{}() called with fd {}", __func__, fd); - return fd; - } - } - return (reinterpret_cast(libc_fileno))(stream); -} - -void clearerr(FILE *stream) { - init_passthrough_if_needed(); - if(CTX->interception_enabled() && (stream != nullptr)) { - auto fd = file_to_fd(stream); - if(CTX->file_map()->exist(fd)) { - CTX->log()->error("{}() NOT SUPPORTED", __func__); - errno = ENOTSUP; - return; - } - } - return (reinterpret_cast(libc_clearerr))(stream); -} - -int feof(FILE *stream) { - init_passthrough_if_needed(); - if(CTX->interception_enabled() && (stream != nullptr)) { - auto fd = file_to_fd(stream); - if(CTX->file_map()->exist(fd)) { - CTX->log()->error("{}() NOT SUPPORTED", __func__); - errno = ENOTSUP; - return -1; - } - } - return (reinterpret_cast(libc_feof))(stream); -} - -int ferror(FILE *stream) { - init_passthrough_if_needed(); - if(CTX->interception_enabled() && (stream != nullptr)) { - auto fd = file_to_fd(stream); - if(CTX->file_map()->exist(fd)) { - CTX->log()->error("{}() NOT SUPPORTED", __func__); - errno = ENOTSUP; - return -1; - } - } - return (reinterpret_cast(libc_ferror))(stream); -} - -int fflush(FILE *stream) { - init_passthrough_if_needed(); - if(CTX->interception_enabled() && (stream != nullptr)) { - auto fd = file_to_fd(stream); - if(CTX->file_map()->exist(fd)) { - CTX->log()->trace("{}() called with fd {}", __func__, fd); - return 0; - } - } - return (reinterpret_cast(libc_fflush))(stream); -} - -void __fpurge(FILE *stream) { - init_passthrough_if_needed(); - if(CTX->interception_enabled() && (stream != nullptr)) { - auto fd = file_to_fd(stream); - if(CTX->file_map()->exist(fd)) { - CTX->log()->trace("{}() called on fd {}", __func__, fd); - return; - } - } - return (reinterpret_cast(libc___fpurge))(stream); -} - -void setbuf(FILE *stream, char *buf) { - init_passthrough_if_needed(); - if(CTX->interception_enabled() && (stream != nullptr)) { - auto fd = file_to_fd(stream); - if(CTX->file_map()->exist(fd)) { - CTX->log()->trace("{}() called on fd {}", __func__, fd); - return; - } - } - return (reinterpret_cast(libc_setbuf))(stream, buf); -} - -void setbuffer(FILE *stream, char *buf, size_t size) { - init_passthrough_if_needed(); - if(CTX->interception_enabled() && (stream != nullptr)) { - auto fd = file_to_fd(stream); - if(CTX->file_map()->exist(fd)) { - CTX->log()->trace("{}() called on fd {}", __func__, fd); - return; - } - } - return (reinterpret_cast(libc_setbuffer))(stream, buf, size); -} - -void setlinebuf(FILE *stream) { - init_passthrough_if_needed(); - if(CTX->interception_enabled() && (stream != nullptr)) { - auto fd = file_to_fd(stream); - if(CTX->file_map()->exist(fd)) { - CTX->log()->trace("{}() called on fd {}", __func__, fd); - return; - } - } - return (reinterpret_cast(libc_setlinebuf))(stream); -} - -int setvbuf(FILE *stream, char *buf, int mode, size_t size) { - init_passthrough_if_needed(); - if(CTX->interception_enabled() && (stream != nullptr)) { - auto fd = file_to_fd(stream); - if(CTX->file_map()->exist(fd)) { - CTX->log()->trace("{}() called on fd {}", __func__, fd); - return 0; - } - } - return (reinterpret_cast(libc_setvbuf))(stream, buf, mode, size); -} - -int putc(int c, FILE *stream) { - init_passthrough_if_needed(); - if(CTX->interception_enabled() && (stream != nullptr)) { - auto fd = file_to_fd(stream); - if(CTX->file_map()->exist(fd)) { - CTX->log()->error("{}() NOT SUPPORTED", __func__); - errno = ENOTSUP; - return EOF; - } - } - return LIBC_FUNC(putc, c, stream); -} - -int fputc(int c, FILE *stream) { - init_passthrough_if_needed(); - if(CTX->interception_enabled() && (stream != nullptr)) { - auto fd = file_to_fd(stream); - if(CTX->file_map()->exist(fd)) { - CTX->log()->error("{}() NOT SUPPORTED", __func__); - errno = ENOTSUP; - return EOF; - } - } - return LIBC_FUNC(fputc, c, stream); -} - -int fputs(const char *s, FILE *stream) { - init_passthrough_if_needed(); - if(CTX->interception_enabled() && (stream != nullptr)) { - auto fd = file_to_fd(stream); - if(CTX->file_map()->exist(fd)) { - CTX->log()->error("{}() NOT SUPPORTED", __func__); - errno = ENOTSUP; - return EOF; - } - } - return LIBC_FUNC(fputs, s, stream); -} - -int getc(FILE *stream) { - init_passthrough_if_needed(); - if(CTX->interception_enabled() && (stream != nullptr)) { - auto fd = file_to_fd(stream); - if(CTX->file_map()->exist(fd)) { - CTX->log()->error("{}() NOT SUPPORTED", __func__); - errno = ENOTSUP; - return EOF; - } - } - return LIBC_FUNC(getc, stream); -} - -int fgetc(FILE *stream) { - init_passthrough_if_needed(); - if(CTX->interception_enabled() && (stream != nullptr)) { - auto fd = file_to_fd(stream); - if(CTX->file_map()->exist(fd)) { - CTX->log()->error("{}() NOT SUPPORTED", __func__); - errno = ENOTSUP; - return EOF; - } - } - return LIBC_FUNC(fgetc, stream); -} - -char* fgets(char* s, int size, FILE* stream) { - init_passthrough_if_needed(); - if(CTX->interception_enabled() && (stream != nullptr)) { - auto fd = file_to_fd(stream); - if(CTX->file_map()->exist(fd)) { - CTX->log()->trace("{}() [fd: {}, size: {}]", __func__, fd, size); - auto ret = adafs_read(fd, s, static_cast(size - 1)); - CTX->log()->debug("{}() read {} bytes", __func__, ret); - if(ret > 0) { - char* nl_ptr = static_cast(memchr(s, '\n', static_cast(size - 1))); - assert((nl_ptr - s) < size); - if(nl_ptr != nullptr) { - CTX->log()->debug("{}() found new line char at {}", __func__, (nl_ptr - s)); - nl_ptr[1] = '\0'; - } else { - s[size - 1] = '\0'; - } - return s; - } else { - return nullptr; - } - } - } - return LIBC_FUNC(fgets, s, size, stream); -} - -int ungetc(int c, FILE *stream) { - init_passthrough_if_needed(); - if(CTX->interception_enabled() && (stream != nullptr)) { - auto fd = file_to_fd(stream); - if(CTX->file_map()->exist(fd)) { - CTX->log()->error("{}() NOT SUPPORTED", __func__); - errno = ENOTSUP; - return EOF; - } - } - return LIBC_FUNC(ungetc, c, stream); -} - -int fseek(FILE *stream, long offset, int whence) { - init_passthrough_if_needed(); - if(CTX->interception_enabled() && (stream != nullptr)) { - auto fd = file_to_fd(stream); - if(CTX->file_map()->exist(fd)) { - CTX->log()->trace("{}() called [fd: {}, offset: {}, whence: {}"); - if(adafs_lseek(fd, offset, whence) == -1) { - return -1; - } else { - return 0; - } - } - } - return LIBC_FUNC(fseek, stream, offset, whence); -} - -/****** FILE OPS ******/ - -#undef creat - -int creat(const char* path, mode_t mode) { - init_passthrough_if_needed(); - if(CTX->interception_enabled()) { - CTX->log()->trace("{}() called with path '{}', mode '{}'", __func__, path, mode); - } - return open(path, O_CREAT | O_WRONLY | O_TRUNC, mode); -} - -#undef creat64 - -int creat64(const char* path, mode_t mode) { - init_passthrough_if_needed(); - if(CTX->interception_enabled()) { - CTX->log()->trace("{}() called with path '{}', mode '{}'", __func__, path, mode); - } - return open(path, O_CREAT | O_WRONLY | O_TRUNC | O_LARGEFILE, mode); -} - -int mkdir(const char* path, mode_t mode) noexcept { - init_passthrough_if_needed(); - if(!CTX->interception_enabled()) { - return LIBC_FUNC(mkdir, path, mode); - } - CTX->log()->trace("{}() called with path '{}', mode '{}'", __func__, path, mode); - std::string rel_path; - if(!CTX->relativize_path(path, rel_path)) { - return LIBC_FUNC(mkdir, rel_path.c_str(), mode); - } - auto ret = adafs_mk_node(rel_path, mode | S_IFDIR); - CTX->log()->trace("{}() ret {}", __func__, ret); - return ret; -} - -int mkdirat(int dirfd, const char* path, mode_t mode) noexcept { - init_passthrough_if_needed(); - if(CTX->interception_enabled()) { - CTX->log()->trace("{}() called with path '{}', mode {}, dirfd {}", __func__, path, mode, dirfd); - std::string rel_path; - if (CTX->relativize_path(path, rel_path)) { - // not implemented - CTX->log()->error("{}() not implemented.", __func__); - errno = ENOTSUP; - return -1; - } - } - return LIBC_FUNC(mkdirat, dirfd, path, mode); -} - - -int unlink(const char* path) noexcept { - init_passthrough_if_needed(); - if(!CTX->interception_enabled()) { - return LIBC_FUNC(unlink, path); - } - CTX->log()->trace("{}() called with path '{}'", __func__, path); - std::string rel_path; - if (!CTX->relativize_path(path, rel_path, false)) { - return LIBC_FUNC(unlink, rel_path.c_str()); - } - return adafs_rm_node(rel_path); -} - -int unlinkat(int dirfd, const char* cpath, int flags) noexcept { - init_passthrough_if_needed(); - if(!CTX->interception_enabled()) { - return LIBC_FUNC(unlinkat, dirfd, cpath, flags); - } - - CTX->log()->trace("{}() called with path '{}' dirfd {}, flags {}", __func__, cpath, dirfd, flags); - - if ((flags & ~AT_REMOVEDIR) != 0) { - CTX->log()->error("{}() Flags unknown: {}", __func__, flags); - return -EINVAL; - } - - std::string resolved; - auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved, false); - switch(rstatus) { - case RelativizeStatus::fd_unknown: - return LIBC_FUNC(unlinkat, dirfd, cpath, flags); - - case RelativizeStatus::external: - return LIBC_FUNC(unlinkat, dirfd, resolved.c_str(), flags); - - case RelativizeStatus::fd_not_a_dir: - errno = ENOTDIR; - return -1; - - case RelativizeStatus::internal: - if(flags & AT_REMOVEDIR) { - return adafs_rmdir(resolved); - } else { - return adafs_rm_node(resolved); - } - - default: - CTX->log()->error("{}() relativize status unknown: {}", __func__); - errno = EINVAL; - return -1; - } -} - -int rmdir(const char* path) noexcept { - init_passthrough_if_needed(); - if(!CTX->interception_enabled()) { - return LIBC_FUNC(rmdir, path); - } - CTX->log()->trace("{}() called with path '{}'", __func__, path); - std::string rel_path; - if (!CTX->relativize_path(path, rel_path)) { - return LIBC_FUNC(rmdir, rel_path.c_str()); - } - return adafs_rmdir(rel_path); -} - -int close(int fd) { - init_passthrough_if_needed(); - if(CTX->interception_enabled() && CTX->file_map()->exist(fd)) { - // No call to the daemon is required - CTX->file_map()->remove(fd); - return 0; - } - return LIBC_FUNC(close, fd); -} - -int __close(int fd) { - return close(fd); -} - -int remove(const char* path) { - return unlink(path); -} - -int access(const char* path, int mask) noexcept { - init_passthrough_if_needed(); - if(!CTX->interception_enabled()) { - return LIBC_FUNC(access, path, mask); - } - CTX->log()->trace("{}() called path '{}', mask {}", __func__, path, mask); - std::string rel_path; - if (!CTX->relativize_path(path, rel_path)) { - return LIBC_FUNC(access, rel_path.c_str(), mask); - } - return adafs_access(rel_path, mask); -} - -int faccessat(int dirfd, const char* cpath, int mode, int flags) noexcept { - init_passthrough_if_needed(); - if(!CTX->interception_enabled()) { - return LIBC_FUNC(faccessat, dirfd, cpath, mode, flags); - } - - CTX->log()->trace("{}() called path '{}', mode {}, dirfd {}, flags {}", __func__, cpath, mode, dirfd, flags); - - //TODO handle the AT_EACCESS flag - - std::string resolved; - bool follow_links = !(flags & AT_SYMLINK_NOFOLLOW); - auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved, follow_links); - switch(rstatus) { - case RelativizeStatus::fd_unknown: - return LIBC_FUNC(faccessat, dirfd, cpath, mode, flags); - - case RelativizeStatus::external: - return LIBC_FUNC(faccessat, dirfd, resolved.c_str(), mode, flags); - - case RelativizeStatus::fd_not_a_dir: - errno = ENOTDIR; - return -1; - - case RelativizeStatus::internal: - return adafs_access(resolved, mode, follow_links); - - default: - CTX->log()->error("{}() relativize status unknown: {}", __func__); - errno = EINVAL; - return -1; - } -} - - -int __xstat(int ver, const char* path, struct stat* buf) noexcept { - init_passthrough_if_needed(); - if(!CTX->interception_enabled()) { - return LIBC_FUNC(__xstat, ver, path, buf); - } - CTX->log()->trace("{}() called with path '{}'", __func__, path); - std::string rel_path; - if (!CTX->relativize_path(path, rel_path)) { - return LIBC_FUNC(__xstat, ver, rel_path.c_str(), buf); - } - return adafs_stat(rel_path, buf); -} - -int __xstat64(int ver, const char* path, struct stat64* buf) noexcept { - init_passthrough_if_needed(); - if(!CTX->interception_enabled()) { - return LIBC_FUNC(__xstat64, ver, path, buf); - } - CTX->log()->trace("{}() called with path '{}'", __func__, path); - std::string rel_path; - if (!CTX->relativize_path(path, rel_path)) { - return LIBC_FUNC(__xstat64, ver, rel_path.c_str(), buf); - } - notsup_error_32_bit_func(); - errno = ENOTSUP; - return -1; -} - -int __fxstat(int ver, int fd, struct stat* buf) noexcept { - init_passthrough_if_needed(); - if(CTX->interception_enabled()) { - CTX->log()->trace("{}() called with fd {}", __func__, fd); - if (CTX->file_map()->exist(fd)) { - auto path = CTX->file_map()->get(fd)->path(); - return adafs_stat(path, buf); - } - } - return LIBC_FUNC(__fxstat, ver, fd, buf); -} - -int __fxstatat(int ver, int dirfd, const char* cpath, struct stat* buf, int flags) noexcept { - init_passthrough_if_needed(); - if(!CTX->interception_enabled()) { - return LIBC_FUNC(__fxstatat, ver, dirfd, cpath, buf, flags); - } - - CTX->log()->trace("{}() called with path '{}' and fd {}", - __func__, cpath, dirfd); - - if(flags & AT_EMPTY_PATH) { - CTX->log()->error("{}() AT_EMPTY_PATH flag not supported", __func__); - errno = ENOTSUP; - return -1; - } - - std::string resolved; - bool follow_links = !(flags & AT_SYMLINK_NOFOLLOW); - auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved, follow_links); - switch(rstatus) { - case RelativizeStatus::fd_unknown: - return LIBC_FUNC(__fxstatat, ver, dirfd, cpath, buf, flags); - - case RelativizeStatus::external: - return LIBC_FUNC(__fxstatat, ver, dirfd, resolved.c_str(), buf, flags); - - case RelativizeStatus::fd_not_a_dir: - errno = ENOTDIR; - return -1; - - case RelativizeStatus::internal: - return adafs_stat(resolved, buf, follow_links); - - default: - CTX->log()->error("{}() relativize status unknown: {}", __func__); - errno = EINVAL; - return -1; - } -} - -int __fxstatat64(int ver, int dirfd, const char* path, struct stat64* buf, int flags) noexcept { - init_passthrough_if_needed(); - if(!CTX->interception_enabled()) { - return LIBC_FUNC(__fxstatat64, ver, dirfd, path, buf, flags); - } - - notsup_error_32_bit_func(); - errno = ENOTSUP; - return -1; -} - -int __fxstat64(int ver, int fd, struct stat64* buf) noexcept { - init_passthrough_if_needed(); - if(!CTX->interception_enabled()) { - return LIBC_FUNC(__fxstat64, ver, fd, buf); - } - - notsup_error_32_bit_func(); - errno = ENOTSUP; - return -1; -} - -int __lxstat(int ver, const char* path, struct stat* buf) noexcept { - init_passthrough_if_needed(); - if(!CTX->interception_enabled()) { - return LIBC_FUNC(__lxstat, ver, path, buf); - } - CTX->log()->trace("{}() called with path '{}'", __func__, path); - std::string rel_path; - if (!CTX->relativize_path(path, rel_path, false)) { - return LIBC_FUNC(__lxstat, ver, rel_path.c_str(), buf); - } - return adafs_stat(rel_path, buf, false); -} - -int __lxstat64(int ver, const char* path, struct stat64* buf) noexcept { - init_passthrough_if_needed(); - if(!CTX->interception_enabled()) { - return LIBC_FUNC(__lxstat64, ver, path, buf); - } - - notsup_error_32_bit_func(); - errno = ENOTSUP; - return -1; -} - -int intcp_statvfs(const char *path, struct statvfs *buf) noexcept { - init_passthrough_if_needed(); - CTX->log()->trace("{}() called with path '{}'", __func__, path); - if(!CTX->interception_enabled()) { - return LIBC_FUNC(statvfs, path, buf); - } - std::string rel_path; - if (!CTX->relativize_path(path, rel_path)) { - return LIBC_FUNC(statvfs, path, buf); - } - return adafs_statvfs(buf); -} - -int intcp_fstatvfs(int fd, struct statvfs *buf) noexcept { - init_passthrough_if_needed(); - if(CTX->interception_enabled()) { - CTX->log()->trace("{}() called with fd {}", __func__, fd); - if (CTX->file_map()->exist(fd)) { - return adafs_statvfs(buf); - } - } - return LIBC_FUNC(fstatvfs, fd, buf); -} - -ssize_t write(int fd, const void* buf, size_t count) { - init_passthrough_if_needed(); - if(CTX->interception_enabled()) { - CTX->log()->trace("{}() called with fd {}", __func__, fd); - if (CTX->file_map()->exist(fd)) { - return adafs_write(fd, buf, count); - } - } - return (reinterpret_cast(libc_write))(fd, buf, count); -} - -ssize_t pwrite(int fd, const void* buf, size_t count, off_t offset) { - init_passthrough_if_needed(); - if(CTX->interception_enabled()) { - CTX->log()->trace("{}() called with fd {}", __func__, fd); - if (CTX->file_map()->exist(fd)) { - return adafs_pwrite_ws(fd, buf, count, offset); - } - } - return (reinterpret_cast(libc_pwrite))(fd, buf, count, offset); -} - -ssize_t pwrite64(int fd, const void* buf, size_t count, __off64_t offset) { - init_passthrough_if_needed(); - if(CTX->interception_enabled()) { - CTX->log()->trace("{}() called with fd {}", __func__, fd); - if (CTX->file_map()->exist(fd)) { - return adafs_pwrite_ws(fd, buf, count, offset); - } - } - return (reinterpret_cast(libc_pwrite64))(fd, buf, count, offset); -} - -ssize_t writev(int fd, const struct iovec *iov, int iovcnt) { - init_passthrough_if_needed(); - if(CTX->interception_enabled()) { - CTX->log()->trace("{}() called with fd {}", __func__, fd); - if (CTX->file_map()->exist(fd)) { - return adafs_writev(fd, iov, iovcnt); - } - } - return (reinterpret_cast(libc_writev))(fd, iov, iovcnt); -} - -ssize_t readv(int fd, const struct iovec *iov, int iovcnt) { - init_passthrough_if_needed(); - if(CTX->interception_enabled()) { - CTX->log()->trace("{}() called with fd {}", __func__, fd); - if (CTX->file_map()->exist(fd)) { - CTX->log()->error("{}() NOT SUPPORTED", __func__); - errno = ENOTSUP; - return -1; - } - } - return (reinterpret_cast(libc_readv))(fd, iov, iovcnt); -} - -ssize_t read(int fd, void* buf, size_t count) { - init_passthrough_if_needed(); - if(CTX->interception_enabled()) { - CTX->log()->trace("{}() called with fd {}, count {}", __func__, fd, count); - if (CTX->file_map()->exist(fd)) { - auto ret = adafs_read(fd, buf, count); - CTX->log()->trace("{}() returning {}", __func__, ret); - return ret; - } - } - return (reinterpret_cast(libc_read))(fd, buf, count); -} - -ssize_t pread(int fd, void* buf, size_t count, off_t offset) { - init_passthrough_if_needed(); - if(CTX->interception_enabled()) { - CTX->log()->trace("{}() called with fd {}", __func__, fd); - if (CTX->file_map()->exist(fd)) { - return adafs_pread_ws(fd, buf, count, offset); - } - } - return (reinterpret_cast(libc_pread))(fd, buf, count, offset); -} - -ssize_t pread64(int fd, void* buf, size_t count, __off64_t offset) { - init_passthrough_if_needed(); - if(CTX->interception_enabled()) { - CTX->log()->trace("{}() called with fd {}", __func__, fd); - if (CTX->file_map()->exist(fd)) { - return adafs_pread_ws(fd, buf, count, offset); - } - } - return (reinterpret_cast(libc_pread64))(fd, buf, count, offset); -} - -off_t lseek(int fd, off_t offset, int whence) noexcept { - init_passthrough_if_needed(); - if(CTX->interception_enabled()) { - CTX->log()->trace("{}() called with path '{}', mode {}", __func__, fd, offset, whence); - if (CTX->file_map()->exist(fd)) { - auto off_ret = adafs_lseek(fd, static_cast(offset), whence); - if (off_ret > std::numeric_limits::max()) { - errno = EOVERFLOW; - return -1; - } else { - return off_ret; - } - } - } - return (reinterpret_cast(libc_lseek))(fd, offset, whence); -} - -#undef lseek64 - -off64_t lseek64(int fd, off64_t offset, int whence) noexcept { - init_passthrough_if_needed(); - if(CTX->interception_enabled()) { - CTX->log()->trace("{}() called with path '{}', mode {}", __func__, fd, offset, whence); - if (CTX->file_map()->exist(fd)) { - return adafs_lseek(fd, offset, whence); - } - } - return (reinterpret_cast(libc_lseek64))(fd, offset, whence); -} - -int fsync(int fd) { - init_passthrough_if_needed(); - if(CTX->interception_enabled()) { - CTX->log()->trace("{}() called with fd '{}'", __func__, fd); - if (CTX->file_map()->exist(fd)) { - return 0; // This is a noop for us atm. fsync is called implicitly because each chunk is closed after access - } - } - return (reinterpret_cast(libc_fsync))(fd); -} - -int fdatasync(int fd) { - init_passthrough_if_needed(); - if(CTX->interception_enabled()) { - CTX->log()->trace("{}() called with fd '{}'", __func__, fd); - if (CTX->file_map()->exist(fd)) { - return 0; // This is a noop for us atm. fsync is called implicitly because each chunk is closed after access - } - } - return (reinterpret_cast(libc_fdatasync))(fd); -} - -int truncate(const char* path, off_t length) noexcept { - init_passthrough_if_needed(); - if(!CTX->interception_enabled()) { - return LIBC_FUNC(truncate, path, length); - } - CTX->log()->trace("{}() called with path: {}, offset: {}", __func__, - path, length); - std::string rel_path; - if (!CTX->relativize_path(path, rel_path)) { - return LIBC_FUNC(truncate, rel_path.c_str(), length); - } - return adafs_truncate(rel_path, length); -} - -int ftruncate(int fd, off_t length) noexcept { - init_passthrough_if_needed(); - if(CTX->interception_enabled()) { - CTX->log()->trace("{}() called [fd: {}, offset: {}]", __func__, fd, length); - if (CTX->file_map()->exist(fd)) { - auto path = CTX->file_map()->get(fd)->path(); - return adafs_truncate(path, length); - } - } - return (reinterpret_cast(libc_ftruncate))(fd, length); -} - -int fcntl(int fd, int cmd, ...) { - init_passthrough_if_needed(); - va_list ap; - void *arg; - - va_start (ap, cmd); - arg = va_arg (ap, void *); - va_end (ap); - - if(CTX->interception_enabled()) { - CTX->log()->trace("{}() called with fd {}", __func__, fd); - if (CTX->file_map()->exist(fd)) { - switch(cmd) { - case F_DUPFD: - CTX->log()->trace("{}() F_DUPFD on fd {}", __func__, fd); - return adafs_dup(fd); - case F_DUPFD_CLOEXEC: { - CTX->log()->trace("{}() F_DUPFD_CLOEXEC on fd {}", __func__, fd); - auto ret = adafs_dup(fd); - if(ret == -1) { - return ret; - } - CTX->file_map()->get(fd) - ->set_flag(OpenFile_flags::cloexec, true); - return ret; - } - case F_GETFD: - CTX->log()->trace("{}() F_GETFD on fd {}", __func__, fd); - if(CTX->file_map()->get(fd) - ->get_flag(OpenFile_flags::cloexec)) { - return FD_CLOEXEC; - } else { - return 0; - } - case F_SETFD: { - va_start (ap, cmd); - int flags = va_arg (ap, int); - va_end (ap); - CTX->log()->trace("{}() [fd: {}, cmd: F_SETFD, FD_CLOEXEC: {}]", __func__, fd, (flags & FD_CLOEXEC)); - CTX->file_map()->get(fd) - ->set_flag(OpenFile_flags::cloexec, static_cast(flags & FD_CLOEXEC)); - return 0; - } - default: - CTX->log()->error("{}() unrecognized command {} on fd {}", __func__, cmd, fd); - errno = ENOTSUP; - return -1; - } - } - } - return (reinterpret_cast(libc_fcntl))(fd, cmd, arg); -} - -int dup(int oldfd) noexcept { - init_passthrough_if_needed(); - if(CTX->interception_enabled()) { - CTX->log()->trace("{}() called with oldfd {}", __func__, oldfd); - if (CTX->file_map()->exist(oldfd)) { - return adafs_dup(oldfd); - } - } - return (reinterpret_cast(libc_dup))(oldfd); -} - -int dup2(int oldfd, int newfd) noexcept { - init_passthrough_if_needed(); - if(CTX->interception_enabled()) { - CTX->log()->trace("{}() called with oldfd {} newfd {}", __func__, oldfd, newfd); - if (CTX->file_map()->exist(oldfd)) { - return adafs_dup2(oldfd, newfd); - } - } - return (reinterpret_cast(libc_dup2))(oldfd, newfd); -} - -int dup3(int oldfd, int newfd, int flags) noexcept { - init_passthrough_if_needed(); - if(CTX->interception_enabled()) { - if (CTX->file_map()->exist(oldfd)) { - // TODO implement O_CLOEXEC flag first which is used with fcntl(2) - // It is in glibc since kernel 2.9. So maybe not that important :) - CTX->log()->error("{}() Not implemented.", __func__); - errno = EBUSY; - return -1; - } - } - return (reinterpret_cast(libc_dup3))(oldfd, newfd, flags); -} - -/* Directories related calls */ - -inline int dirp_to_fd(const DIR* dirp){ - assert(dirp != nullptr); - return *(reinterpret_cast(&dirp)); -} - -inline DIR* fd_to_dirp(const int fd){ - assert(fd >= 0); - return reinterpret_cast(fd); -} - -int intcp_dirfd(DIR *dirp) { - init_passthrough_if_needed(); - if(CTX->interception_enabled()) { - if(dirp == nullptr){ - errno = EINVAL; - return -1; - } - auto fd = dirp_to_fd(dirp); - if(CTX->file_map()->exist(fd)) { - return fd; - } - } - return LIBC_FUNC(dirfd, dirp); -} - -DIR* opendir(const char* path){ - init_passthrough_if_needed(); - if(!CTX->interception_enabled()) { - return LIBC_FUNC(opendir, path); - } - CTX->log()->trace("{}() called with path '{}'", __func__, path); - std::string rel_path; - if(!CTX->relativize_path(path, rel_path)) { - return LIBC_FUNC(opendir, rel_path.c_str()); - } - - auto fd = adafs_opendir(rel_path); - if(fd < 0){ - return nullptr; - } - return fd_to_dirp(fd); -} - -DIR* fdopendir(int fd){ - init_passthrough_if_needed(); - if(CTX->interception_enabled()) { - CTX->log()->trace("{}() called with fd {}", __func__, fd); - if (CTX->file_map()->exist(fd)) { - auto open_file = CTX->file_map()->get(fd); - auto open_dir = static_pointer_cast(open_file); - if(!open_dir){ - //Cast did not succeeded: open_file is a regular file - errno = EBADF; - return nullptr; - } - return fd_to_dirp(fd); - } - } - return LIBC_FUNC(fdopendir, fd); -} - -struct dirent* intcp_readdir(DIR* dirp){ - init_passthrough_if_needed(); - if(CTX->interception_enabled()) { - if(dirp == nullptr){ - errno = EINVAL; - return nullptr; - } - auto fd = dirp_to_fd(dirp); - if(CTX->file_map()->exist(fd)) { - return adafs_readdir(fd); - } - } - return LIBC_FUNC(readdir, dirp); -} - -int intcp_closedir(DIR* dirp) { - init_passthrough_if_needed(); - if(CTX->interception_enabled()) { - if(dirp == nullptr){ - errno = EINVAL; - return -1; - } - auto fd = dirp_to_fd(dirp); - if (CTX->file_map()->exist(fd)) { - // No call to the daemon is required - CTX->file_map()->remove(fd); - return 0; - } - } - return LIBC_FUNC(closedir, dirp); -} - -int chmod(const char* path, mode_t mode) noexcept { - init_passthrough_if_needed(); - if(!CTX->interception_enabled()) { - return LIBC_FUNC(chmod, path, mode); - } - - CTX->log()->trace("{}() called with path '{}'", __func__, path); - std::string rel_path; - if (!CTX->relativize_path(path, rel_path)) { - return LIBC_FUNC(chmod, rel_path.c_str(), mode); - } - CTX->log()->warn("{}() operation not supported", __func__); - errno = ENOTSUP; - return -1; -} - -int fchmod(int fd, mode_t mode) noexcept { - init_passthrough_if_needed(); - if(CTX->interception_enabled()) { - CTX->log()->trace("{}() called [fd: {}, mode: {}]", __func__, fd, mode); - if (CTX->file_map()->exist(fd)) { - CTX->log()->warn("{}() operation not supported", __func__); - errno = ENOTSUP; - return -1; - } - } - return LIBC_FUNC(fchmod, fd, mode); -} - -int fchmodat(int dirfd, const char* cpath, mode_t mode, int flags) noexcept { - init_passthrough_if_needed(); - if(!CTX->interception_enabled()) { - return LIBC_FUNC(fchmodat, dirfd, cpath, mode, flags); - } - - CTX->log()->trace("{}() called path '{}', mode {}, dirfd {}, flags {}", __func__, cpath, mode, dirfd, flags); - - std::string resolved; - auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved, - !(flags & AT_SYMLINK_NOFOLLOW)); - switch(rstatus) { - case RelativizeStatus::fd_unknown: - return LIBC_FUNC(fchmodat, dirfd, cpath, mode, flags); - - case RelativizeStatus::external: - return LIBC_FUNC(fchmodat, dirfd, resolved.c_str(), mode, flags); - - case RelativizeStatus::fd_not_a_dir: - errno = ENOTDIR; - return -1; - - case RelativizeStatus::internal: - CTX->log()->warn("{}() operation not supported", __func__); - errno = ENOTSUP; - return -1; - - default: - CTX->log()->error("{}() relativize status unknown: {}", __func__); - errno = EINVAL; - return -1; - } -} - -int chdir(const char* path) noexcept { - init_passthrough_if_needed(); - if(!CTX->interception_enabled()) { - return LIBC_FUNC(chdir, path); - } - - CTX->log()->trace("{}() called with path '{}'", __func__, path); - std::string rel_path; - bool internal = CTX->relativize_path(path, rel_path); - if (internal) { - //path falls in our namespace - struct stat st{}; - if(adafs_stat(rel_path, &st) != 0) { - CTX->log()->error("{}() path does not exists", __func__); - errno = ENOENT; - return -1; - } - if(!S_ISDIR(st.st_mode)) { - CTX->log()->error("{}() path is not a directory", __func__); - errno = ENOTDIR; - return -1; - } - //TODO get complete path from relativize_path instead of - // removing mountdir and then adding again here - rel_path.insert(0, CTX->mountdir()); - if (has_trailing_slash(rel_path)) { - // open_dir is '/' - rel_path.pop_back(); - } - } - try { - set_cwd(rel_path, internal); - } catch (const std::system_error& se) { - return -1; - } - return 0; -} - -int fchdir(int fd) noexcept { - init_passthrough_if_needed(); - if(!CTX->interception_enabled()) { - return LIBC_FUNC(fchdir, fd); - } - CTX->log()->trace("{}() called with fd {}", __func__, fd); - if (CTX->file_map()->exist(fd)) { - auto open_file = CTX->file_map()->get(fd); - auto open_dir = static_pointer_cast(open_file); - if(!open_dir){ - //Cast did not succeeded: open_file is a regular file - CTX->log()->error("{}() file descriptor refers to a normal file: '{}'", - __func__, open_dir->path()); - errno = EBADF; - return -1; - } - - std::string new_path = CTX->mountdir() + open_dir->path(); - if (has_trailing_slash(new_path)) { - // open_dir is '/' - new_path.pop_back(); - } - try { - set_cwd(new_path, true); - } catch (const std::system_error& se) { - return -1; - } - } else { - if(LIBC_FUNC(fchdir, fd) != 0) { - CTX->log()->error("{}() failed to change dir: {}", - __func__, std::strerror(errno)); - } - unset_env_cwd(); - CTX->cwd(get_sys_cwd()); - } - return 0; -} - -char* getcwd(char* buf, size_t size) noexcept { - init_passthrough_if_needed(); - if(!CTX->interception_enabled()) { - return LIBC_FUNC(getcwd, buf, size); - } - CTX->log()->trace("{}() called with size {}", __func__, size); - - if(size == 0) { - buf = static_cast(malloc(CTX->cwd().size() + 1)); - if(buf == nullptr){ - CTX->log()->error("{}() failed to allocate buffer of size {}", __func__, CTX->cwd().size()); - errno = ENOMEM; - return nullptr; - } - } else if(CTX->cwd().size() + 1 > size) { - CTX->log()->error("{}() buffer too small to host current working dir", __func__); - errno = ERANGE; - return nullptr; - } - - strcpy(buf, CTX->cwd().c_str()); - return buf; -} - -char* get_current_dir_name() noexcept { - init_passthrough_if_needed(); - if(!CTX->interception_enabled()) { - return (reinterpret_cast(libc_dup3))(); - } - CTX->log()->error("{}() not implemented", __func__); - errno = ENOTSUP; - return nullptr; -} - - -int link(const char* oldpath, const char* newpath) noexcept { - init_passthrough_if_needed(); - if(CTX->interception_enabled()) { - CTX->log()->trace("{}() called [oldpath: '{}', newpath: '{}']", - __func__, oldpath, newpath); - CTX->log()->error("{}() not implemented", __func__); - errno = ENOTSUP; - return -1; - } - return LIBC_FUNC(link, oldpath, newpath); -} - -int linkat(int olddirfd, const char *oldpath, - int newdirfd, const char* newpath, int flags) noexcept { - init_passthrough_if_needed(); - if(CTX->interception_enabled()) { - CTX->log()->trace("{}() called [olddirfd: '{}', oldpath: '{}' newdirfd: '{}', newpath: '{}', flags: '{}']", - __func__, olddirfd, oldpath, newdirfd, newpath, flags); - CTX->log()->error("{}() not implemented", __func__); - errno = ENOTSUP; - return -1; - } - return LIBC_FUNC(linkat, olddirfd, oldpath, newdirfd, newpath, flags); -} - -int intcp_symlink(const char* oldname, const char* newname) noexcept { - return symlinkat(oldname, AT_FDCWD, newname); -} - -int intcp_symlinkat(const char* oldname, int newdfd, const char* newname) noexcept { - init_passthrough_if_needed(); - if(!CTX->interception_enabled()) { - return LIBC_FUNC(symlinkat, oldname, newdfd, newname); - } - - CTX->log()->trace("{}() called with oldname '{}', new fd {}, new name '{}'", - __func__, oldname, newdfd, newname); - - std::string oldname_resolved; - auto oldname_is_internal = CTX->relativize_path(oldname, oldname_resolved); - -#ifndef HAS_SYMLINKS - if (oldname_is_internal) { - CTX->log()->warn("{}() attempt to create link to GekkoFS namespace: operation not supported." - "Enable through compile flags `-DHAS_SYMLINKS` or" - "with the cmake option `SYMLINK_SUPPORT`.", __func__); - errno = ENOTSUP; - return -1; - } -#endif - - std::string newname_resolved; - auto new_status = CTX->relativize_fd_path(newdfd, newname, newname_resolved, false); - switch(new_status) { - case RelativizeStatus::fd_unknown: - return LIBC_FUNC(symlinkat, oldname, newdfd, newname); - - case RelativizeStatus::external: - if(oldname_is_internal) { - CTX->log()->warn("{}() attempt to create link from outside to GekkoFS namespace: operation not supported." - "Enable through compile flags `-DHAS_SYMLINKS` or" - "with the cmake option `SYMLINK_SUPPORT`.", __func__); - errno = ENOTSUP; - return -1; - } - return LIBC_FUNC(symlinkat, oldname, newdfd, newname_resolved.c_str()); - - case RelativizeStatus::fd_not_a_dir: - errno = ENOTDIR; - return -1; - - case RelativizeStatus::internal: -#ifdef HAS_SYMLINKS - if(!oldname_is_internal) { - CTX->log()->warn("{}() attempt to create link from inside GekkoFS to outside: operation not supported", __func__); - errno = ENOTSUP; - return -1; - } - return adafs_mk_symlink(newname_resolved, oldname_resolved); -#else - CTX->log()->warn("{}() attempt to create link from GekkoFS namespace: operation not supported." - "Enable through compile flags `-DHAS_SYMLINKS` or" - "with the cmake option `SYMLINK_SUPPORT`.", __func__); - errno = ENOTSUP; - return -1; -#endif - - default: - CTX->log()->error("{}() relativize status unknown", __func__); - errno = EINVAL; - return -1; - } -} - -ssize_t intcp_readlink(const char * cpath, char * buf, size_t bufsize) noexcept { - return intcp_readlinkat(AT_FDCWD, cpath, buf, bufsize); -} - -ssize_t intcp_readlinkat(int dirfd, const char * cpath, char * buf, size_t bufsize) noexcept { - init_passthrough_if_needed(); - if(!CTX->interception_enabled()) { - return LIBC_FUNC(readlinkat, dirfd, cpath, buf, bufsize); - } - - CTX->log()->trace("{}() called with path '{}' dirfd {}, bufsize {}", - __func__, cpath, dirfd, bufsize); - - std::string resolved; - auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved, false); - switch(rstatus) { - case RelativizeStatus::fd_unknown: - return LIBC_FUNC(readlinkat, dirfd, cpath, buf, bufsize); - - case RelativizeStatus::external: - return LIBC_FUNC(readlinkat, dirfd, cpath, buf, bufsize); - - case RelativizeStatus::fd_not_a_dir: - errno = ENOTDIR; - return -1; - - case RelativizeStatus::internal: -#ifdef HAS_SYMLINKS - return adafs_readlink(resolved, buf, bufsize); -#else - CTX->log()->warn("{}() symlink not supported", __func__); - errno = EINVAL; - return -1; -#endif - default: - CTX->log()->error("{}() relativize status unknown: {}", __func__); - errno = EINVAL; - return -1; - } -} - -char *realpath(const char *path, char *resolved_path) { - init_passthrough_if_needed(); - if(!CTX->interception_enabled()) { - return LIBC_FUNC(realpath, path, resolved_path); - } - - CTX->log()->trace("{}() called with path '{}'", __func__, path); - std::string rel_path; - if (!CTX->relativize_path(path, rel_path)) { - return LIBC_FUNC(realpath, rel_path.c_str(), resolved_path); - } - - auto absolute_path = CTX->mountdir() + rel_path; - if(absolute_path.size() >= PATH_MAX) { - errno = ENAMETOOLONG; - return nullptr; - } - - if(resolved_path == nullptr) { - resolved_path = static_cast(malloc(absolute_path.size() + 1)); - if(resolved_path == nullptr){ - CTX->log()->error("{}() failed to allocate buffer for called with path '{}'", __func__, path); - errno = ENOMEM; - return nullptr; - } - } - - strcpy(resolved_path, absolute_path.c_str()); - return resolved_path; -} diff --git a/src/client/intercept.cpp b/src/client/intercept.cpp new file mode 100644 index 000000000..4932b1613 --- /dev/null +++ b/src/client/intercept.cpp @@ -0,0 +1,107 @@ +/* + Copyright 2018-2019, Barcelona Supercomputing Center (BSC), Spain + Copyright 2015-2019, 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: MIT +*/ + +#include "client/intercept.hpp" +#include "client/preload.hpp" +#include "client/hooks.hpp" + +#ifndef NDEBUG +#include "client/syscall_names.hpp" +#endif + +#include +#include +#include + + +#define NOT_HOOKED 1 +#define HOOKED 0 + + +static inline int hook(long syscall_number, + long arg0, long arg1, long arg2, + long arg3, long arg4, long arg5, + long *result) +{ + + switch (syscall_number) { + + case SYS_open: + *result = hook_openat(AT_FDCWD, + reinterpret_cast(arg0), + static_cast(arg1), + static_cast(arg2)); + break; + + default: + /* + * Ignore any other syscalls + * i.e.: pass them on to the kernel + * as would normally happen. + */ + + #ifndef NDEBUG + CTX->log()->trace("Syscall [{}, {}] Passthrough", syscall_names[syscall_number], syscall_number); + #endif + return NOT_HOOKED; + } + + #ifndef NDEBUG + CTX->log()->trace("Syscall [{}, {}] Intercepted", syscall_names[syscall_number], syscall_number); + #endif + return HOOKED; +} + + +static __thread bool guard_flag; + +int +hook_guard_wrapper(long syscall_number, + long arg0, long arg1, long arg2, + long arg3, long arg4, long arg5, + long *syscall_return_value) +{ + assert(CTX->interception_enabled()); + + if (guard_flag) { + return NOT_HOOKED; + } + + int is_hooked; + + guard_flag = true; + int oerrno = errno; + is_hooked = hook(syscall_number, + arg0, arg1, arg2, arg3, arg4, arg5, + syscall_return_value); + errno = oerrno; + guard_flag = false; + + return is_hooked; +} + + +void start_interception() { + assert(CTX->interception_enabled()); +#ifndef NDEBUG + CTX->log()->debug("Activating interception of syscalls"); +#endif + // Set up the callback function pointer + intercept_hook_point = hook_guard_wrapper; +} + +void stop_interception() { + assert(CTX->interception_enabled()); + // Reset callback function pointer + intercept_hook_point = nullptr; +} diff --git a/src/client/passthrough.cpp b/src/client/passthrough.cpp deleted file mode 100644 index 93aecb513..000000000 --- a/src/client/passthrough.cpp +++ /dev/null @@ -1,265 +0,0 @@ -/* - Copyright 2018-2019, Barcelona Supercomputing Center (BSC), Spain - Copyright 2015-2019, 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: MIT -*/ - -#include "client/passthrough.hpp" - -#include -#include -#include -#include -#include - - -/* We cannot use any fprintf here because it will call the write function internally - * that we are also intercepting, and this will lead to a deadlock. - * - * Instead the write syscall needs to be called directly. - */ -#define WRITE_STDERR(str) \ - do { \ - syscall(SYS_write, 2, str, sizeof(str)); \ - } while (0) - - -#define LIBC_FUNC_LOAD(FNAME) \ - do { \ - LIBC_FUNC_NAME(FNAME) = dlsym(glibc, #FNAME); \ - if (LIBC_FUNC_NAME(FNAME) == nullptr) { \ - WRITE_STDERR("GekkoFS ERROR: failed to load glibc func symbol: '" #FNAME "'\n"); \ - exit(EXIT_FAILURE); \ - } \ - } while (0) - - -static pthread_once_t init_lib_thread = PTHREAD_ONCE_INIT; - - -void* LIBC_FUNC_NAME(open); -void* LIBC_FUNC_NAME(openat); - -void* LIBC_FUNC_NAME(fopen); -void* LIBC_FUNC_NAME(fopen64); -void* LIBC_FUNC_NAME(fread); -void* LIBC_FUNC_NAME(fwrite); -void* LIBC_FUNC_NAME(fclose); -void* LIBC_FUNC_NAME(clearerr); -void* LIBC_FUNC_NAME(feof); -void* LIBC_FUNC_NAME(ferror); -void* LIBC_FUNC_NAME(fileno); -void* LIBC_FUNC_NAME(fflush); -void* LIBC_FUNC_NAME(__fpurge); - -void* LIBC_FUNC_NAME(setbuf); -void* LIBC_FUNC_NAME(setbuffer); -void* LIBC_FUNC_NAME(setlinebuf); -void* LIBC_FUNC_NAME(setvbuf); - -void* LIBC_FUNC_NAME(putc); -void* LIBC_FUNC_NAME(fputc); -void* LIBC_FUNC_NAME(fputs); -void* LIBC_FUNC_NAME(getc); -void* LIBC_FUNC_NAME(fgetc); -void* LIBC_FUNC_NAME(fgets); -void* LIBC_FUNC_NAME(ungetc); - -void* LIBC_FUNC_NAME(fseek); - -void* LIBC_FUNC_NAME(mkdir); -void* LIBC_FUNC_NAME(mkdirat); -void* LIBC_FUNC_NAME(unlink); -void* LIBC_FUNC_NAME(unlinkat); -void* LIBC_FUNC_NAME(rmdir); - -void* LIBC_FUNC_NAME(close); - -void* LIBC_FUNC_NAME(access); -void* LIBC_FUNC_NAME(faccessat); - -void* LIBC_FUNC_NAME(__xstat); -void* LIBC_FUNC_NAME(__xstat64); -void* LIBC_FUNC_NAME(__fxstat); -void* LIBC_FUNC_NAME(__fxstat64); -void* LIBC_FUNC_NAME(__fxstatat); -void* LIBC_FUNC_NAME(__fxstatat64); -void* LIBC_FUNC_NAME(__lxstat); -void* LIBC_FUNC_NAME(__lxstat64); - -void* LIBC_FUNC_NAME(statfs); -void* LIBC_FUNC_NAME(fstatfs); -void* LIBC_FUNC_NAME(statvfs); -void* LIBC_FUNC_NAME(fstatvfs); - -void* LIBC_FUNC_NAME(write); -void* LIBC_FUNC_NAME(pwrite); -void* LIBC_FUNC_NAME(pwrite64); -void* LIBC_FUNC_NAME(writev); - -void* LIBC_FUNC_NAME(read); -void* LIBC_FUNC_NAME(pread); -void* LIBC_FUNC_NAME(pread64); -void* LIBC_FUNC_NAME(readv); - -void* LIBC_FUNC_NAME(lseek); -void* LIBC_FUNC_NAME(lseek64); - -void* LIBC_FUNC_NAME(fsync); -void* LIBC_FUNC_NAME(fdatasync); - -void* LIBC_FUNC_NAME(truncate); -void* LIBC_FUNC_NAME(ftruncate); - -void* LIBC_FUNC_NAME(fcntl); - -void* LIBC_FUNC_NAME(dup); -void* LIBC_FUNC_NAME(dup2); -void* LIBC_FUNC_NAME(dup3); - -void* LIBC_FUNC_NAME(dirfd); -void* LIBC_FUNC_NAME(opendir); -void* LIBC_FUNC_NAME(fdopendir); -void* LIBC_FUNC_NAME(readdir); -void* LIBC_FUNC_NAME(closedir); - -void* LIBC_FUNC_NAME(chmod); -void* LIBC_FUNC_NAME(fchmod); -void* LIBC_FUNC_NAME(fchmodat); - -void* LIBC_FUNC_NAME(chdir); -void* LIBC_FUNC_NAME(fchdir); - -void* LIBC_FUNC_NAME(getcwd); -void* LIBC_FUNC_NAME(get_current_dir_name); - -void* LIBC_FUNC_NAME(link); -void* LIBC_FUNC_NAME(linkat); -void* LIBC_FUNC_NAME(symlinkat); - -void* LIBC_FUNC_NAME(readlinkat); -void* LIBC_FUNC_NAME(realpath); - - -void init_passthrough_() { - auto glibc = dlopen("libc.so.6", RTLD_LAZY); - if(glibc == nullptr) { - WRITE_STDERR("GekkoFS ERROR: failed to load glibc\n"); \ - exit(EXIT_FAILURE); - } - - LIBC_FUNC_LOAD(open); - LIBC_FUNC_LOAD(openat); - - LIBC_FUNC_LOAD(fopen); - LIBC_FUNC_LOAD(fopen64); - LIBC_FUNC_LOAD(fread); - LIBC_FUNC_LOAD(fwrite); - LIBC_FUNC_LOAD(fclose); - LIBC_FUNC_LOAD(clearerr); - LIBC_FUNC_LOAD(feof); - LIBC_FUNC_LOAD(ferror); - LIBC_FUNC_LOAD(fileno); - LIBC_FUNC_LOAD(fflush); - LIBC_FUNC_LOAD(__fpurge); - - LIBC_FUNC_LOAD(setbuf); - LIBC_FUNC_LOAD(setbuffer); - LIBC_FUNC_LOAD(setlinebuf); - LIBC_FUNC_LOAD(setvbuf); - - LIBC_FUNC_LOAD(putc); - LIBC_FUNC_LOAD(fputc); - LIBC_FUNC_LOAD(fputs); - LIBC_FUNC_LOAD(getc); - LIBC_FUNC_LOAD(fgetc); - LIBC_FUNC_LOAD(fgets); - LIBC_FUNC_LOAD(ungetc); - - LIBC_FUNC_LOAD(fseek); - - LIBC_FUNC_LOAD(mkdir); - LIBC_FUNC_LOAD(mkdirat); - - LIBC_FUNC_LOAD(unlink); - LIBC_FUNC_LOAD(unlinkat); - LIBC_FUNC_LOAD(rmdir); - - LIBC_FUNC_LOAD(close); - - LIBC_FUNC_LOAD(access); - LIBC_FUNC_LOAD(faccessat); - - LIBC_FUNC_LOAD(__xstat); - LIBC_FUNC_LOAD(__xstat64); - LIBC_FUNC_LOAD(__fxstat); - LIBC_FUNC_LOAD(__fxstat64); - LIBC_FUNC_LOAD(__fxstatat); - LIBC_FUNC_LOAD(__fxstatat64); - LIBC_FUNC_LOAD(__lxstat); - LIBC_FUNC_LOAD(__lxstat64); - - LIBC_FUNC_LOAD(statfs); - LIBC_FUNC_LOAD(fstatfs); - LIBC_FUNC_LOAD(statvfs); - LIBC_FUNC_LOAD(fstatvfs); - - LIBC_FUNC_LOAD(write); - LIBC_FUNC_LOAD(pwrite); - LIBC_FUNC_LOAD(pwrite64); - LIBC_FUNC_LOAD(writev); - - LIBC_FUNC_LOAD(read); - LIBC_FUNC_LOAD(pread); - LIBC_FUNC_LOAD(pread64); - LIBC_FUNC_LOAD(readv); - - LIBC_FUNC_LOAD(lseek); - LIBC_FUNC_LOAD(lseek64); - LIBC_FUNC_LOAD(fsync); - LIBC_FUNC_LOAD(fdatasync); - - LIBC_FUNC_LOAD(truncate); - LIBC_FUNC_LOAD(ftruncate); - - LIBC_FUNC_LOAD(fcntl); - - LIBC_FUNC_LOAD(dup); - LIBC_FUNC_LOAD(dup2); - LIBC_FUNC_LOAD(dup3); - - LIBC_FUNC_LOAD(dirfd); - LIBC_FUNC_LOAD(opendir); - LIBC_FUNC_LOAD(fdopendir); - LIBC_FUNC_LOAD(readdir); - LIBC_FUNC_LOAD(closedir); - - LIBC_FUNC_LOAD(chmod); - LIBC_FUNC_LOAD(fchmod); - LIBC_FUNC_LOAD(fchmodat); - - LIBC_FUNC_LOAD(chdir); - LIBC_FUNC_LOAD(fchdir); - - LIBC_FUNC_LOAD(getcwd); - LIBC_FUNC_LOAD(get_current_dir_name); - - LIBC_FUNC_LOAD(link); - LIBC_FUNC_LOAD(linkat); - LIBC_FUNC_LOAD(symlinkat); - - LIBC_FUNC_LOAD(readlinkat); - - LIBC_FUNC_LOAD(realpath); -} - -void init_passthrough_if_needed() { - pthread_once(&init_lib_thread, init_passthrough_); -} \ No newline at end of file diff --git a/src/client/preload.cpp b/src/client/preload.cpp index 6386708c6..4eabfc519 100644 --- a/src/client/preload.cpp +++ b/src/client/preload.cpp @@ -20,8 +20,8 @@ #include #include "global/rpc/rpc_types.hpp" #include -#include #include +#include #include @@ -224,7 +224,6 @@ void log_prog_name() { * Called initially ONCE when preload library is used with the LD_PRELOAD environment variable */ void init_preload() { - init_passthrough_if_needed(); init_logging(); CTX->log()->debug("Initialized logging subsystem"); log_prog_name(); @@ -237,14 +236,17 @@ void init_preload() { } else { CTX->log()->info("{}() mountdir '{}' loaded", __func__, CTX->mountdir()); } + init_ld_env_if_needed(); CTX->enable_interception(); CTX->log()->debug("{}() exit", __func__); + start_interception(); } /** * Called last when preload library is used with the LD_PRELOAD environment variable */ void destroy_preload() { + stop_interception(); CTX->disable_interception(); if (ld_margo_rpc_id == nullptr) { CTX->log()->debug("{}() No services in preload library used. Nothing to shut down.", __func__); diff --git a/src/client/resolve.cpp b/src/client/resolve.cpp index 5b57d9766..673d7322c 100644 --- a/src/client/resolve.cpp +++ b/src/client/resolve.cpp @@ -16,10 +16,10 @@ #include #include #include +#include #include "global/path_util.hpp" #include "global/configure.hpp" -#include "client/passthrough.hpp" #include "client/preload.hpp" @@ -148,7 +148,7 @@ unsigned int path_match_components(const std::string& path, unsigned int &path_c path.compare(start, comp_size, mnt_components.at(matched_components)) == 0) { ++matched_components; } - if (LIBC_FUNC(__lxstat, _STAT_VER, resolved.c_str(), &st) < 0) { + if (lstat(resolved.c_str(), &st) < 0) { #ifndef NDEBUG CTX->log()->debug("{}() path does not exists: '{}'", __func__, resolved.c_str()); #endif @@ -160,7 +160,7 @@ unsigned int path_match_components(const std::string& path, unsigned int &path_c continue; } auto link_resolved = std::unique_ptr(new char[PATH_MAX]); - if (LIBC_FUNC(realpath, resolved.c_str(), link_resolved.get()) == nullptr) { + if (realpath(resolved.c_str(), link_resolved.get()) == nullptr) { CTX->log()->error("{}() Failed to get realpath for link '{}'. Error: {}", __func__, resolved, strerror(errno)); resolved.append(path, end, std::string::npos); return false; @@ -197,8 +197,8 @@ unsigned int path_match_components(const std::string& path, unsigned int &path_c std::string get_sys_cwd() { char temp[PATH_MAX_LEN]; - if(LIBC_FUNC(getcwd, temp, PATH_MAX_LEN) == NULL) { - throw std::system_error(errno, + if (long ret = syscall_no_intercept(SYS_getcwd, temp, PATH_MAX_LEN) < 0) { + throw std::system_error(syscall_error_code(ret), std::system_category(), "Failed to retrieve current working directory"); } @@ -212,10 +212,10 @@ std::string get_sys_cwd() { void set_sys_cwd(const std::string& path) { CTX->log()->debug("{}() to '{}'", __func__, path); - if (LIBC_FUNC(chdir, path.c_str())) { + if (long ret = syscall_no_intercept(SYS_chdir, path.c_str())) { CTX->log()->error("{}() failed to set system current working directory: {}", - __func__, std::strerror(errno)); - throw std::system_error(errno, + __func__, std::strerror(syscall_error_code(ret))); + throw std::system_error(syscall_error_code(ret), std::system_category(), "Failed to set system current working directory"); } -- GitLab From ea945910157fe986709a224c45f276fe04a72399 Mon Sep 17 00:00:00 2001 From: Tommaso Tocci Date: Fri, 14 Sep 2018 10:39:32 +0200 Subject: [PATCH 02/25] avoids checks on environment initialization --- src/client/adafs_functions.cpp | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/src/client/adafs_functions.cpp b/src/client/adafs_functions.cpp index d84c24018..fa8dcbbd7 100644 --- a/src/client/adafs_functions.cpp +++ b/src/client/adafs_functions.cpp @@ -26,7 +26,6 @@ using namespace std; int adafs_open(const std::string& path, mode_t mode, int flags) { - init_ld_env_if_needed(); if(flags & O_PATH){ CTX->log()->error("{}() `O_PATH` flag is not supported", __func__); @@ -112,7 +111,6 @@ int adafs_open(const std::string& path, mode_t mode, int flags) { } int adafs_mk_node(const std::string& path, mode_t mode) { - init_ld_env_if_needed(); //file type must be set switch (mode & S_IFMT) { @@ -156,7 +154,6 @@ int adafs_mk_node(const std::string& path, mode_t mode) { * @return */ int adafs_rm_node(const std::string& path) { - init_ld_env_if_needed(); auto md = adafs_metadata(path); if (!md) { return -1; @@ -166,7 +163,6 @@ int adafs_rm_node(const std::string& path) { } int adafs_access(const std::string& path, const int mask, bool follow_links) { - init_ld_env_if_needed(); auto md = adafs_metadata(path, follow_links); if (!md) { errno = ENOENT; @@ -176,7 +172,6 @@ int adafs_access(const std::string& path, const int mask, bool follow_links) { } int adafs_stat(const string& path, struct stat* buf, bool follow_links) { - init_ld_env_if_needed(); auto md = adafs_metadata(path, follow_links); if (!md) { return -1; @@ -207,7 +202,6 @@ std::shared_ptr adafs_metadata(const string& path, bool follow_links) } int adafs_statfs(struct statfs* buf) { - init_ld_env_if_needed(); CTX->log()->trace("{}() called", __func__); auto blk_stat = rpc_send::chunk_stat(); buf->f_type = 0; @@ -244,12 +238,10 @@ int adafs_statvfs(struct statvfs* buf) { } off64_t adafs_lseek(int fd, off64_t offset, int whence) { - init_ld_env_if_needed(); return adafs_lseek(CTX->file_map()->get(fd), offset, whence); } off64_t adafs_lseek(shared_ptr adafs_fd, off64_t offset, int whence) { - init_ld_env_if_needed(); switch (whence) { case SEEK_SET: adafs_fd->pos(offset); @@ -311,7 +303,6 @@ int adafs_truncate(const std::string& path, off_t length) { * adafs_trunc_data, some more data could have been added to the file and the * length increased. */ - init_ld_env_if_needed(); if(length < 0) { CTX->log()->debug("{}() length is negative: {}", __func__, length); errno = EINVAL; @@ -341,7 +332,6 @@ int adafs_dup2(const int oldfd, const int newfd) { } ssize_t adafs_pwrite(std::shared_ptr file, const char * buf, size_t count, off64_t offset) { - init_ld_env_if_needed(); if (file->type() != FileType::regular) { assert(file->type() == FileType::directory); CTX->log()->warn("{}() cannot read from directory", __func__); @@ -367,7 +357,6 @@ ssize_t adafs_pwrite(std::shared_ptr file, const char * buf, size_t co } ssize_t adafs_pwrite_ws(int fd, const void* buf, size_t count, off64_t offset) { - init_ld_env_if_needed(); auto file = CTX->file_map()->get(fd); return adafs_pwrite(file, reinterpret_cast(buf), count, offset); } @@ -391,7 +380,6 @@ ssize_t adafs_write(int fd, const void * buf, size_t count) { } ssize_t adafs_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset) { - init_ld_env_if_needed(); CTX->log()->trace("{}() called with fd {}, op num {}, offset {}", __func__, fd, iovcnt, offset); @@ -438,7 +426,6 @@ ssize_t adafs_writev(int fd, const struct iovec * iov, int iovcnt) { } ssize_t adafs_pread(std::shared_ptr file, char * buf, size_t count, off64_t offset) { - init_ld_env_if_needed(); if (file->type() != FileType::regular) { assert(file->type() == FileType::directory); CTX->log()->warn("{}() cannot read from directory", __func__); @@ -459,7 +446,6 @@ ssize_t adafs_pread(std::shared_ptr file, char * buf, size_t count, of } ssize_t adafs_read(int fd, void* buf, size_t count) { - init_ld_env_if_needed(); auto adafs_fd = CTX->file_map()->get(fd); auto pos = adafs_fd->pos(); //retrieve the current offset auto ret = adafs_pread(adafs_fd, reinterpret_cast(buf), count, pos); @@ -471,13 +457,11 @@ ssize_t adafs_read(int fd, void* buf, size_t count) { } ssize_t adafs_pread_ws(int fd, void* buf, size_t count, off64_t offset) { - init_ld_env_if_needed(); auto adafs_fd = CTX->file_map()->get(fd); return adafs_pread(adafs_fd, reinterpret_cast(buf), count, offset); } int adafs_opendir(const std::string& path) { - init_ld_env_if_needed(); auto md = adafs_metadata(path); if (!md) { @@ -495,8 +479,6 @@ int adafs_opendir(const std::string& path) { } int adafs_rmdir(const std::string& path) { - init_ld_env_if_needed(); - auto md = adafs_metadata(path); if (!md) { CTX->log()->debug("{}() path does not exists: '{}'", __func__, path); @@ -519,7 +501,6 @@ int adafs_rmdir(const std::string& path) { } struct dirent * adafs_readdir(int fd){ - init_ld_env_if_needed(); CTX->log()->trace("{}() called on fd: {}", __func__, fd); auto open_file = CTX->file_map()->get(fd); assert(open_file != nullptr); -- GitLab From 2d79889075eff35a45f8e83ad15d6e9fa3e7ec71 Mon Sep 17 00:00:00 2001 From: Tommaso Tocci Date: Thu, 20 Sep 2018 14:42:56 +0200 Subject: [PATCH 03/25] introduce with_errno helper --- src/client/hooks.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/client/hooks.cpp b/src/client/hooks.cpp index 8a36acc7a..14d54327d 100644 --- a/src/client/hooks.cpp +++ b/src/client/hooks.cpp @@ -23,6 +23,11 @@ #include +static inline int with_errno(int ret) { + return (ret < 0)? -errno : ret; +} + + int hook_openat(int dirfd, const char *cpath, int flags, mode_t mode) { if(cpath == nullptr || cpath[0] == '\0') { -- GitLab From 3b930bbb3dbc1c3701402a7f8d5a55e99460eab4 Mon Sep 17 00:00:00 2001 From: Tommaso Tocci Date: Wed, 12 Sep 2018 17:30:17 +0200 Subject: [PATCH 04/25] intercept basic syscalls --- include/client/hooks.hpp | 6 +++ src/client/hooks.cpp | 101 ++++++++++++++++++++++++++------------- src/client/intercept.cpp | 32 +++++++++++++ 3 files changed, 106 insertions(+), 33 deletions(-) diff --git a/include/client/hooks.hpp b/include/client/hooks.hpp index 2fe1342f0..a7ab7fb54 100644 --- a/include/client/hooks.hpp +++ b/include/client/hooks.hpp @@ -18,5 +18,11 @@ int hook_openat(int dirfd, const char *cpath, int flags, mode_t mode); +int hook_close(int fd); +int hook_stat(const char* path, struct stat* buf); +int hook_read(int fd, void* buf, size_t count); +int hook_write(int fd, void* buf, size_t count); +int hook_unlink(const char* path); + #endif diff --git a/src/client/hooks.cpp b/src/client/hooks.cpp index 14d54327d..a3843ffc9 100644 --- a/src/client/hooks.cpp +++ b/src/client/hooks.cpp @@ -30,47 +30,82 @@ static inline int with_errno(int ret) { int hook_openat(int dirfd, const char *cpath, int flags, mode_t mode) { - if(cpath == nullptr || cpath[0] == '\0') { - CTX->log()->error("{}() path is invalid", __func__); - return -EINVAL; + CTX->log()->trace("{}() called with fd: {}, path: {}, flags: {}, mode: {}", + __func__, dirfd, cpath, flags, mode); + + std::string resolved; + auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved); + switch(rstatus) { + case RelativizeStatus::fd_unknown: + return syscall_no_intercept(SYS_openat, dirfd, cpath, flags, mode); + + case RelativizeStatus::external: + return syscall_no_intercept(SYS_openat, dirfd, resolved.c_str(), flags, mode); + + case RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case RelativizeStatus::internal: + return with_errno(adafs_open(resolved, mode, flags)); + + default: + CTX->log()->error("{}() relativize status unknown: {}", __func__); + return -EINVAL; } +} - CTX->log()->trace("{}() called with fd: {}, path: {}, flags: {}, mode: {}", __func__, dirfd, cpath, flags, mode); +int hook_close(int fd) { + CTX->log()->trace("{}() called with fd {}", __func__, fd); + if(CTX->file_map()->exist(fd)) { + // No call to the daemon is required + CTX->file_map()->remove(fd); + return 0; + } + return syscall_no_intercept(SYS_close, fd); +} - std::string resolved; +int hook_stat(const char* path, struct stat* buf) { + CTX->log()->trace("{}() called with path '{}'", __func__, path); + std::string rel_path; + if (CTX->relativize_path(path, rel_path, false)) { + return with_errno(adafs_stat(rel_path, buf)); + } + return syscall_no_intercept(SYS_stat, rel_path.c_str(), buf); +} - if((cpath[0] == PSP) || (dirfd == AT_FDCWD)) { - // cpath is absolute or relative to CWD - if (CTX->relativize_path(cpath, resolved)) { - int ret = adafs_open(resolved, mode, flags); - if(ret < 0) { - return -errno; - } - } - } else { - // cpath is relative - if(!(CTX->file_map()->exist(dirfd))) { - //TODO relative cpath could still lead to our FS - return syscall_no_intercept(SYS_openat, dirfd, cpath, flags, mode); +int hook_read(int fd, void* buf, size_t count) { + CTX->log()->trace("{}() called with fd {}, count {}", __func__, fd, count); + if (CTX->file_map()->exist(fd)) { + auto ret = adafs_read(fd, buf, count); + if(ret < 0) { + return -errno; } + return ret; + } + return syscall_no_intercept(SYS_read, fd, buf, count); +} - auto dir = CTX->file_map()->get_dir(dirfd); - if(dir == nullptr) { - CTX->log()->error("{}() dirfd is not a directory ", __func__); - errno = ENOTDIR; - return -1; +int hook_write(int fd, void* buf, size_t count) { + CTX->log()->trace("{}() called with fd {}, count {}", __func__, fd, count); + if (CTX->file_map()->exist(fd)) { + auto ret = adafs_write(fd, buf, count); + if(ret < 0) { + return -errno; } + return ret; + } + return syscall_no_intercept(SYS_write, fd, buf, count); +} - std::string path = CTX->mountdir(); - path.append(dir->path()); - path.push_back(PSP); - path.append(cpath); - if(resolve_path(path, resolved)) { - int ret = adafs_open(resolved, mode, flags); - if(ret < 0) { - return -errno; - } +int hook_unlink(const char* path) { + CTX->log()->trace("{}() called with path '{}'", __func__, path); + std::string rel_path; + if (CTX->relativize_path(path, rel_path)) { + auto ret = adafs_rm_node(rel_path); + if(ret < 0) { + return -errno; } + return ret; } - return 0; + return syscall_no_intercept(SYS_unlink, rel_path.c_str()); } diff --git a/src/client/intercept.cpp b/src/client/intercept.cpp index 4932b1613..6b281ca32 100644 --- a/src/client/intercept.cpp +++ b/src/client/intercept.cpp @@ -43,6 +43,38 @@ static inline int hook(long syscall_number, static_cast(arg2)); break; + case SYS_openat: + *result = hook_openat(static_cast(arg0), + reinterpret_cast(arg1), + static_cast(arg2), + static_cast(arg3)); + break; + + case SYS_close: + *result = hook_close(static_cast(arg0)); + break; + + case SYS_stat: + *result = hook_stat(reinterpret_cast(arg0), + reinterpret_cast(arg1)); + break; + + case SYS_read: + *result = hook_read(static_cast(arg0), + reinterpret_cast(arg1), + static_cast(arg2)); + break; + + case SYS_write: + *result = hook_write(static_cast(arg0), + reinterpret_cast(arg1), + static_cast(arg2)); + break; + + case SYS_unlink: + *result = hook_unlink(reinterpret_cast(arg0)); + break; + default: /* * Ignore any other syscalls -- GitLab From b0fa8e120fd240ed8108516c76fa2f1adba526d8 Mon Sep 17 00:00:00 2001 From: Tommaso Tocci Date: Thu, 13 Sep 2018 18:22:00 +0200 Subject: [PATCH 05/25] Intercept access & lseek --- include/client/hooks.hpp | 2 ++ src/client/adafs_functions.cpp | 6 ++++++ src/client/hooks.cpp | 29 +++++++++++++++++++++++++++++ src/client/intercept.cpp | 12 +++++++++++- 4 files changed, 48 insertions(+), 1 deletion(-) diff --git a/include/client/hooks.hpp b/include/client/hooks.hpp index a7ab7fb54..886ef8b8f 100644 --- a/include/client/hooks.hpp +++ b/include/client/hooks.hpp @@ -23,6 +23,8 @@ int hook_stat(const char* path, struct stat* buf); int hook_read(int fd, void* buf, size_t count); int hook_write(int fd, void* buf, size_t count); int hook_unlink(const char* path); +int hook_access(const char* path, int mask); +int hook_lseek(unsigned int fd, off_t offset, unsigned int whence); #endif diff --git a/src/client/adafs_functions.cpp b/src/client/adafs_functions.cpp index fa8dcbbd7..3b786f138 100644 --- a/src/client/adafs_functions.cpp +++ b/src/client/adafs_functions.cpp @@ -244,12 +244,15 @@ off64_t adafs_lseek(int fd, off64_t offset, int whence) { off64_t adafs_lseek(shared_ptr adafs_fd, off64_t offset, int whence) { switch (whence) { case SEEK_SET: + CTX->log()->debug("{}() whence is SEEK_SET", __func__); adafs_fd->pos(offset); break; case SEEK_CUR: + CTX->log()->debug("{}() whence is SEEK_CUR", __func__); adafs_fd->pos(adafs_fd->pos() + offset); break; case SEEK_END: { + CTX->log()->debug("{}() whence is SEEK_END", __func__); off64_t file_size; auto err = rpc_send::get_metadentry_size(adafs_fd->path(), file_size); if (err < 0) { @@ -260,14 +263,17 @@ off64_t adafs_lseek(shared_ptr adafs_fd, off64_t offset, int whence) { break; } case SEEK_DATA: + CTX->log()->warn("{}() SEEK_DATA whence is not supported", __func__); // We do not support this whence yet errno = EINVAL; return -1; case SEEK_HOLE: + CTX->log()->warn("{}() SEEK_HOLE whence is not supported", __func__); // We do not support this whence yet errno = EINVAL; return -1; default: + CTX->log()->warn("{}() unknown whence {}", __func__, whence); errno = EINVAL; return -1; } diff --git a/src/client/hooks.cpp b/src/client/hooks.cpp index a3843ffc9..fc7d6cf66 100644 --- a/src/client/hooks.cpp +++ b/src/client/hooks.cpp @@ -109,3 +109,32 @@ int hook_unlink(const char* path) { } return syscall_no_intercept(SYS_unlink, rel_path.c_str()); } + +int hook_access(const char* path, int mask) { + CTX->log()->trace("{}() called path '{}', mask {}", __func__, path, mask); + std::string rel_path; + if (CTX->relativize_path(path, rel_path)) { + auto ret = adafs_access(rel_path, mask); + if(ret < 0) { + return -errno; + } + return ret; + } + return syscall_no_intercept(SYS_access, rel_path.c_str(), mask); +} + +int hook_lseek(unsigned int fd, off_t offset, unsigned int whence) { + CTX->log()->trace("{}() called with fd {}, offset {}, whence {}", __func__, fd, offset, whence); + if (CTX->file_map()->exist(fd)) { + auto off_ret = adafs_lseek(fd, static_cast(offset), whence); + if (off_ret > std::numeric_limits::max()) { + return -EOVERFLOW; + } else if(off_ret < 0) { + return -errno; + } + CTX->log()->trace("{}() returning {}", __func__, off_ret); + return off_ret; + } + return syscall_no_intercept(SYS_lseek, fd, offset, whence); +} + diff --git a/src/client/intercept.cpp b/src/client/intercept.cpp index 6b281ca32..72f0af9ed 100644 --- a/src/client/intercept.cpp +++ b/src/client/intercept.cpp @@ -75,7 +75,17 @@ static inline int hook(long syscall_number, *result = hook_unlink(reinterpret_cast(arg0)); break; - default: + case SYS_access: + *result = hook_access(reinterpret_cast(arg0), + static_cast(arg1)); + break; + + case SYS_lseek: + *result = hook_lseek(static_cast(arg0), + static_cast(arg1), + static_cast(arg2)); + break; + /* * Ignore any other syscalls * i.e.: pass them on to the kernel -- GitLab From c294d9e0752d90aabade4fb303c74fb786f7e422 Mon Sep 17 00:00:00 2001 From: Tommaso Tocci Date: Thu, 20 Sep 2018 14:44:21 +0200 Subject: [PATCH 06/25] intercept lstat, fstat --- include/client/hooks.hpp | 2 ++ src/client/hooks.cpp | 18 ++++++++++++++++++ src/client/intercept.cpp | 10 ++++++++++ 3 files changed, 30 insertions(+) diff --git a/include/client/hooks.hpp b/include/client/hooks.hpp index 886ef8b8f..ffeb4927e 100644 --- a/include/client/hooks.hpp +++ b/include/client/hooks.hpp @@ -20,6 +20,8 @@ int hook_openat(int dirfd, const char *cpath, int flags, mode_t mode); int hook_close(int fd); int hook_stat(const char* path, struct stat* buf); +int hook_lstat(const char* path, struct stat* buf); +int hook_fstat(unsigned int, struct stat* buf); int hook_read(int fd, void* buf, size_t count); int hook_write(int fd, void* buf, size_t count); int hook_unlink(const char* path); diff --git a/src/client/hooks.cpp b/src/client/hooks.cpp index fc7d6cf66..b2ba89dd1 100644 --- a/src/client/hooks.cpp +++ b/src/client/hooks.cpp @@ -73,6 +73,24 @@ int hook_stat(const char* path, struct stat* buf) { return syscall_no_intercept(SYS_stat, rel_path.c_str(), buf); } +int hook_lstat(const char* path, struct stat* buf) { + CTX->log()->trace("{}() called with path '{}'", __func__, path); + std::string rel_path; + if (CTX->relativize_path(path, rel_path)) { + return with_errno(adafs_stat(rel_path, buf)); + } + return syscall_no_intercept(SYS_lstat, rel_path.c_str(), buf); +} + +int hook_fstat(unsigned int fd, struct stat* buf) { + CTX->log()->trace("{}() called with fd '{}'", __func__, fd); + if (CTX->file_map()->exist(fd)) { + auto path = CTX->file_map()->get(fd)->path(); + return with_errno(adafs_stat(path, buf)); + } + return syscall_no_intercept(SYS_fstat, fd, buf); +} + int hook_read(int fd, void* buf, size_t count) { CTX->log()->trace("{}() called with fd {}, count {}", __func__, fd, count); if (CTX->file_map()->exist(fd)) { diff --git a/src/client/intercept.cpp b/src/client/intercept.cpp index 72f0af9ed..29c72aec5 100644 --- a/src/client/intercept.cpp +++ b/src/client/intercept.cpp @@ -59,6 +59,16 @@ static inline int hook(long syscall_number, reinterpret_cast(arg1)); break; + case SYS_lstat: + *result = hook_lstat(reinterpret_cast(arg0), + reinterpret_cast(arg1)); + break; + + case SYS_fstat: + *result = hook_fstat(static_cast(arg0), + reinterpret_cast(arg1)); + break; + case SYS_read: *result = hook_read(static_cast(arg0), reinterpret_cast(arg1), -- GitLab From 303c661996223118423ecddfa24e72dc501fbbdf Mon Sep 17 00:00:00 2001 From: Tommaso Tocci Date: Thu, 20 Sep 2018 14:44:56 +0200 Subject: [PATCH 07/25] intercept dup, dup2, dup3 --- include/client/hooks.hpp | 3 +++ src/client/hooks.cpp | 25 +++++++++++++++++++++++++ src/client/intercept.cpp | 16 ++++++++++++++++ 3 files changed, 44 insertions(+) diff --git a/include/client/hooks.hpp b/include/client/hooks.hpp index ffeb4927e..6380b7411 100644 --- a/include/client/hooks.hpp +++ b/include/client/hooks.hpp @@ -27,6 +27,9 @@ int hook_write(int fd, void* buf, size_t count); int hook_unlink(const char* path); int hook_access(const char* path, int mask); int hook_lseek(unsigned int fd, off_t offset, unsigned int whence); +int hook_dup(unsigned int fd); +int hook_dup2(unsigned int oldfd, unsigned int newfd); +int hook_dup3(unsigned int oldfd, unsigned int newfd, int flags); #endif diff --git a/src/client/hooks.cpp b/src/client/hooks.cpp index b2ba89dd1..e69b0cca2 100644 --- a/src/client/hooks.cpp +++ b/src/client/hooks.cpp @@ -156,3 +156,28 @@ int hook_lseek(unsigned int fd, off_t offset, unsigned int whence) { return syscall_no_intercept(SYS_lseek, fd, offset, whence); } +int hook_dup(unsigned int fd) { + CTX->log()->trace("{}() called with oldfd {}", __func__, fd); + if (CTX->file_map()->exist(fd)) { + return with_errno(adafs_dup(fd)); + } + return syscall_no_intercept(SYS_dup, fd); +} + +int hook_dup2(unsigned int oldfd, unsigned int newfd) { + CTX->log()->trace("{}() called with fd {} newfd {}", __func__, oldfd, newfd); + if (CTX->file_map()->exist(oldfd)) { + return with_errno(adafs_dup2(oldfd, newfd)); + } + return syscall_no_intercept(SYS_dup2, oldfd, newfd); +} + +int hook_dup3(unsigned int oldfd, unsigned int newfd, int flags) { + if (CTX->file_map()->exist(oldfd)) { + // TODO implement O_CLOEXEC flag first which is used with fcntl(2) + // It is in glibc since kernel 2.9. So maybe not that important :) + CTX->log()->warn("{}() Not supported", __func__); + return -ENOTSUP; + } + return syscall_no_intercept(SYS_dup3, oldfd, newfd, flags); +} diff --git a/src/client/intercept.cpp b/src/client/intercept.cpp index 29c72aec5..1f84bfb4f 100644 --- a/src/client/intercept.cpp +++ b/src/client/intercept.cpp @@ -96,6 +96,22 @@ static inline int hook(long syscall_number, static_cast(arg2)); break; + case SYS_dup: + *result = hook_dup(static_cast(arg0)); + break; + + case SYS_dup2: + *result = hook_dup2(static_cast(arg0), + static_cast(arg1)); + break; + + case SYS_dup3: + *result = hook_dup3(static_cast(arg0), + static_cast(arg1), + static_cast(arg2)); + break; + + default: /* * Ignore any other syscalls * i.e.: pass them on to the kernel -- GitLab From 47388a1d172174e1ee701bf23946a09a5a28c0c0 Mon Sep 17 00:00:00 2001 From: Tommaso Tocci Date: Tue, 18 Sep 2018 08:54:42 +0200 Subject: [PATCH 08/25] intercept getdents --- include/client/adafs_functions.hpp | 4 +- include/client/hooks.hpp | 1 + include/client/open_dir.hpp | 25 +++++------ src/client/adafs_functions.cpp | 69 ++++++++++++++++++++++++++---- src/client/hooks.cpp | 8 ++++ src/client/intercept.cpp | 6 +++ src/client/open_dir.cpp | 50 +++++++--------------- 7 files changed, 105 insertions(+), 58 deletions(-) diff --git a/include/client/adafs_functions.hpp b/include/client/adafs_functions.hpp index 0e628511f..3e24f4796 100644 --- a/include/client/adafs_functions.hpp +++ b/include/client/adafs_functions.hpp @@ -65,7 +65,9 @@ ssize_t adafs_read(int fd, void* buf, size_t count); int adafs_opendir(const std::string& path); -struct dirent * adafs_readdir(int fd); +int getdents(unsigned int fd, + struct linux_dirent *dirp, + unsigned int count); int adafs_rmdir(const std::string& path); diff --git a/include/client/hooks.hpp b/include/client/hooks.hpp index 6380b7411..334fff066 100644 --- a/include/client/hooks.hpp +++ b/include/client/hooks.hpp @@ -30,6 +30,7 @@ int hook_lseek(unsigned int fd, off_t offset, unsigned int whence); int hook_dup(unsigned int fd); int hook_dup2(unsigned int oldfd, unsigned int newfd); int hook_dup3(unsigned int oldfd, unsigned int newfd, int flags); +int hook_getdents(unsigned int fd, struct linux_dirent *dirp, unsigned int count); #endif diff --git a/include/client/open_dir.hpp b/include/client/open_dir.hpp index 5dfda56c6..33b43fd50 100644 --- a/include/client/open_dir.hpp +++ b/include/client/open_dir.hpp @@ -23,28 +23,25 @@ #include -class OpenDir: public OpenFile { +class DirEntry { private: + std::string name_; + FileType type_; + public: + DirEntry(const std::string& name, const FileType type); + const std::string& name(); + FileType type(); +}; - class DirEntry { - public: - std::string name; - FileType type; - - DirEntry(const std::string& name, const FileType type); - }; - +class OpenDir: public OpenFile { + private: std::vector entries; - struct dirent dirent_; - bool is_dirent_valid; - - void update_dirent(unsigned int pos); public: OpenDir(const std::string& path); void add(const std::string& name, const FileType& type); - struct dirent * readdir(); + const DirEntry& getdent(unsigned int pos); size_t size(); }; diff --git a/src/client/adafs_functions.cpp b/src/client/adafs_functions.cpp index 3b786f138..c3014d287 100644 --- a/src/client/adafs_functions.cpp +++ b/src/client/adafs_functions.cpp @@ -23,6 +23,20 @@ #include #include +#include + + +#define __ALIGN_KERNEL_MASK(x, mask) (((x) + (mask)) & ~(mask)) +#define __ALIGN_KERNEL(x, a) __ALIGN_KERNEL_MASK(x, (typeof(x))(a) - 1) +#define ALIGN(x, a) __ALIGN_KERNEL((x), (a)) + +struct linux_dirent { + unsigned long d_ino; + unsigned long d_off; + unsigned short d_reclen; + char d_name[1]; +}; + using namespace std; int adafs_open(const std::string& path, mode_t mode, int flags) { @@ -506,17 +520,56 @@ int adafs_rmdir(const std::string& path) { return rpc_send::rm_node(path, true); } -struct dirent * adafs_readdir(int fd){ - CTX->log()->trace("{}() called on fd: {}", __func__, fd); - auto open_file = CTX->file_map()->get(fd); - assert(open_file != nullptr); - auto open_dir = static_pointer_cast(open_file); - if(!open_dir){ + +int getdents(unsigned int fd, + struct linux_dirent *dirp, + unsigned int count) { + CTX->log()->trace("{}() called on fd: {}, count {}", __func__, fd, count); + auto open_dir = CTX->file_map()->get_dir(fd); + if(open_dir == nullptr){ //Cast did not succeeded: open_file is a regular file errno = EBADF; - return nullptr; + return -1; + } + + auto pos = open_dir->pos(); + if (pos >= open_dir->size()) { + return 0; } - return open_dir->readdir(); + + unsigned int written = 0; + struct linux_dirent * current_dirp = nullptr; + while(pos < open_dir->size()) { + DirEntry de = open_dir->getdent(pos); + auto total_size = ALIGN(offsetof(struct linux_dirent, d_name) + + de.name().size() + 3, sizeof(long)); + if (total_size > (count - written)) { + //no enough space left on user buffer to insert next dirent + break; + } + current_dirp = reinterpret_cast( + reinterpret_cast(dirp) + written); + current_dirp->d_ino = std::hash()( + open_dir->path() + "/" + de.name()); + + current_dirp->d_reclen = total_size; + + *(reinterpret_cast(current_dirp) + total_size - 1) = + ((de.type() == FileType::regular)? DT_REG : DT_DIR); + + CTX->log()->trace("{}() name {}: {}", __func__, pos, de.name()); + std::strcpy(&(current_dirp->d_name[0]), de.name().c_str()); + ++pos; + current_dirp->d_off = pos; + written += total_size; + } + + if (written == 0) { + errno = EINVAL; + return -1; + } + open_dir->pos(pos); + return written; } #ifdef HAS_SYMLINKS diff --git a/src/client/hooks.cpp b/src/client/hooks.cpp index e69b0cca2..3757be124 100644 --- a/src/client/hooks.cpp +++ b/src/client/hooks.cpp @@ -181,3 +181,11 @@ int hook_dup3(unsigned int oldfd, unsigned int newfd, int flags) { } return syscall_no_intercept(SYS_dup3, oldfd, newfd, flags); } + +int hook_getdents(unsigned int fd, struct linux_dirent *dirp, unsigned int count) { + CTX->log()->trace("{}() called with fd {}, count {}", __func__, fd, count); + if (CTX->file_map()->exist(fd)) { + return with_errno(getdents(fd, dirp, count)); + } + return syscall_no_intercept(SYS_getdents, fd, dirp, count); +} diff --git a/src/client/intercept.cpp b/src/client/intercept.cpp index 1f84bfb4f..ffedb8567 100644 --- a/src/client/intercept.cpp +++ b/src/client/intercept.cpp @@ -111,6 +111,12 @@ static inline int hook(long syscall_number, static_cast(arg2)); break; + case SYS_getdents: + *result = hook_getdents(static_cast(arg0), + reinterpret_cast(arg1), + static_cast(arg2)); + break; + default: /* * Ignore any other syscalls diff --git a/src/client/open_dir.cpp b/src/client/open_dir.cpp index a14eb0232..3ce503c74 100644 --- a/src/client/open_dir.cpp +++ b/src/client/open_dir.cpp @@ -17,52 +17,32 @@ #include -OpenDir::DirEntry::DirEntry(const std::string& name, const FileType type): - name(name), type(type) { +DirEntry::DirEntry(const std::string& name, const FileType type): + name_(name), type_(type) { } - -OpenDir::OpenDir(const std::string& path) : - OpenFile(path, 0, FileType::directory) { - is_dirent_valid = false; +const std::string& DirEntry::name() { + return name_; } -void OpenDir::add(const std::string& name, const FileType& type){ - entries.push_back(DirEntry(name, type)); +FileType DirEntry::type() { + return type_; } -void OpenDir::update_dirent(unsigned int pos){ - DirEntry entry = entries.at(pos); - std::string entry_absolute_path = path_ + "/" + entry.name; - dirent_.d_ino = std::hash()(entry_absolute_path); - dirent_.d_off = pos_; - dirent_.d_type = ((entry.type == FileType::regular)? DT_REG : DT_DIR); - assert(sizeof(dirent_.d_name) >= strlen(entry.name.c_str())); - strcpy(dirent_.d_name, entry.name.c_str()); - dirent_.d_reclen = sizeof(dirent_); -} -struct dirent * OpenDir::readdir(){ - unsigned int next_pos; +OpenDir::OpenDir(const std::string& path) : + OpenFile(path, 0, FileType::directory) { +} - if(!is_dirent_valid){ - next_pos = 0; - }else{ - next_pos = pos_ + 1; - } - //We reached the end of entries list - if( next_pos >= entries.size()){ - is_dirent_valid = false; - return NULL; - } +void OpenDir::add(const std::string& name, const FileType& type) { + entries.push_back(DirEntry(name, type)); +} - update_dirent(next_pos); - pos_ = next_pos; - is_dirent_valid = true; - return &dirent_; +const DirEntry& OpenDir::getdent(unsigned int pos) { + return entries.at(pos); } -size_t OpenDir::size(){ +size_t OpenDir::size() { return entries.size(); } -- GitLab From d0eabbd296a468d9c0b0e318089347384e64c5e1 Mon Sep 17 00:00:00 2001 From: Tommaso Tocci Date: Tue, 18 Sep 2018 09:21:20 +0200 Subject: [PATCH 09/25] intercept mkdir/mkdirat --- include/client/hooks.hpp | 1 + src/client/hooks.cpp | 25 +++++++++++++++++++++++++ src/client/intercept.cpp | 12 ++++++++++++ 3 files changed, 38 insertions(+) diff --git a/include/client/hooks.hpp b/include/client/hooks.hpp index 334fff066..fd36631b9 100644 --- a/include/client/hooks.hpp +++ b/include/client/hooks.hpp @@ -31,6 +31,7 @@ int hook_dup(unsigned int fd); int hook_dup2(unsigned int oldfd, unsigned int newfd); int hook_dup3(unsigned int oldfd, unsigned int newfd, int flags); int hook_getdents(unsigned int fd, struct linux_dirent *dirp, unsigned int count); +int hook_mkdirat(int dirfd, const char * cpath, mode_t mode); #endif diff --git a/src/client/hooks.cpp b/src/client/hooks.cpp index 3757be124..8d708688d 100644 --- a/src/client/hooks.cpp +++ b/src/client/hooks.cpp @@ -189,3 +189,28 @@ int hook_getdents(unsigned int fd, struct linux_dirent *dirp, unsigned int count } return syscall_no_intercept(SYS_getdents, fd, dirp, count); } + +int hook_mkdirat(int dirfd, const char * cpath, mode_t mode) { + CTX->log()->trace("{}() called with fd: {}, path: {}, mode: {}", + __func__, dirfd, cpath, mode); + + std::string resolved; + auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved); + switch(rstatus) { + case RelativizeStatus::external: + return syscall_no_intercept(SYS_mkdirat, dirfd, resolved.c_str(), mode); + + case RelativizeStatus::fd_unknown: + return syscall_no_intercept(SYS_mkdirat, dirfd, cpath, mode); + + case RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case RelativizeStatus::internal: + return with_errno(adafs_mk_node(resolved, mode | S_IFDIR)); + + default: + CTX->log()->error("{}() relativize status unknown: {}", __func__); + return -EINVAL; + } +} diff --git a/src/client/intercept.cpp b/src/client/intercept.cpp index ffedb8567..703ba0e01 100644 --- a/src/client/intercept.cpp +++ b/src/client/intercept.cpp @@ -117,6 +117,18 @@ static inline int hook(long syscall_number, static_cast(arg2)); break; + case SYS_mkdirat: + *result = hook_mkdirat(static_cast(arg0), + reinterpret_cast(arg1), + static_cast(arg2)); + break; + + case SYS_mkdir: + *result = hook_mkdirat(AT_FDCWD, + reinterpret_cast(arg0), + static_cast(arg1)); + break; + default: /* * Ignore any other syscalls -- GitLab From 5000d3e0ffc8bf0dbfd81f08deaf43152dd7556a Mon Sep 17 00:00:00 2001 From: Tommaso Tocci Date: Thu, 20 Sep 2018 15:37:18 +0200 Subject: [PATCH 10/25] intercept unlinkat --- include/client/hooks.hpp | 2 +- src/client/hooks.cpp | 41 ++++++++++++++++++++++++++++++---------- src/client/intercept.cpp | 10 +++++++++- 3 files changed, 41 insertions(+), 12 deletions(-) diff --git a/include/client/hooks.hpp b/include/client/hooks.hpp index fd36631b9..9971fc0e5 100644 --- a/include/client/hooks.hpp +++ b/include/client/hooks.hpp @@ -24,7 +24,7 @@ int hook_lstat(const char* path, struct stat* buf); int hook_fstat(unsigned int, struct stat* buf); int hook_read(int fd, void* buf, size_t count); int hook_write(int fd, void* buf, size_t count); -int hook_unlink(const char* path); +int hook_unlinkat(int dirfd, const char * cpath, int flags); int hook_access(const char* path, int mask); int hook_lseek(unsigned int fd, off_t offset, unsigned int whence); int hook_dup(unsigned int fd); diff --git a/src/client/hooks.cpp b/src/client/hooks.cpp index 8d708688d..3d1ca3008 100644 --- a/src/client/hooks.cpp +++ b/src/client/hooks.cpp @@ -115,17 +115,38 @@ int hook_write(int fd, void* buf, size_t count) { return syscall_no_intercept(SYS_write, fd, buf, count); } -int hook_unlink(const char* path) { - CTX->log()->trace("{}() called with path '{}'", __func__, path); - std::string rel_path; - if (CTX->relativize_path(path, rel_path)) { - auto ret = adafs_rm_node(rel_path); - if(ret < 0) { - return -errno; - } - return ret; +int hook_unlinkat(int dirfd, const char * cpath, int flags) { + CTX->log()->trace("{}() called with path '{}' dirfd {}, flags {}", + __func__, cpath, dirfd, flags); + + if ((flags & ~AT_REMOVEDIR) != 0) { + CTX->log()->error("{}() Flags unknown: {}", __func__, flags); + return -EINVAL; + } + + std::string resolved; + auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved, false); + switch(rstatus) { + case RelativizeStatus::fd_unknown: + return syscall_no_intercept(SYS_unlinkat, dirfd, cpath, flags); + + case RelativizeStatus::external: + return syscall_no_intercept(SYS_unlinkat, dirfd, resolved.c_str(), flags); + + case RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case RelativizeStatus::internal: + if(flags & AT_REMOVEDIR) { + return with_errno(adafs_rmdir(resolved)); + } else { + return with_errno(adafs_rm_node(resolved)); + } + + default: + CTX->log()->error("{}() relativize status unknown: {}", __func__); + return -EINVAL; } - return syscall_no_intercept(SYS_unlink, rel_path.c_str()); } int hook_access(const char* path, int mask) { diff --git a/src/client/intercept.cpp b/src/client/intercept.cpp index 703ba0e01..845cd4d77 100644 --- a/src/client/intercept.cpp +++ b/src/client/intercept.cpp @@ -82,7 +82,15 @@ static inline int hook(long syscall_number, break; case SYS_unlink: - *result = hook_unlink(reinterpret_cast(arg0)); + *result = hook_unlinkat(AT_FDCWD, + reinterpret_cast(arg0), + 0); + break; + + case SYS_unlinkat: + *result = hook_unlinkat(static_cast(arg0), + reinterpret_cast(arg1), + static_cast(arg2)); break; case SYS_access: -- GitLab From 95052b4fff8586d7f129a973dbe12eb4ac160c84 Mon Sep 17 00:00:00 2001 From: Tommaso Tocci Date: Tue, 18 Sep 2018 12:53:42 +0200 Subject: [PATCH 11/25] intercept writev --- include/client/hooks.hpp | 9 +++++-- src/client/hooks.cpp | 55 +++++++++++++++++++++++++++++++--------- src/client/intercept.cpp | 33 +++++++++++++++++++++--- 3 files changed, 80 insertions(+), 17 deletions(-) diff --git a/include/client/hooks.hpp b/include/client/hooks.hpp index 9971fc0e5..f0966bb27 100644 --- a/include/client/hooks.hpp +++ b/include/client/hooks.hpp @@ -22,8 +22,13 @@ int hook_close(int fd); int hook_stat(const char* path, struct stat* buf); int hook_lstat(const char* path, struct stat* buf); int hook_fstat(unsigned int, struct stat* buf); -int hook_read(int fd, void* buf, size_t count); -int hook_write(int fd, void* buf, size_t count); +int hook_read(unsigned int fd, void* buf, size_t count); +int hook_pread(unsigned int fd, char * buf, size_t count, loff_t pos); +int hook_write(unsigned int fd, const char * buf, size_t count); +int hook_pwrite(unsigned int fd, const char * buf, size_t count, loff_t pos); +int hook_writev(unsigned long fd, const struct iovec * iov, unsigned long iovcnt); +int hook_pwritev(unsigned long fd, const struct iovec * iov, unsigned long iovcnt, + unsigned long pos_l, unsigned long pos_h); int hook_unlinkat(int dirfd, const char * cpath, int flags); int hook_access(const char* path, int mask); int hook_lseek(unsigned int fd, off_t offset, unsigned int whence); diff --git a/src/client/hooks.cpp b/src/client/hooks.cpp index 3d1ca3008..6303f8d1e 100644 --- a/src/client/hooks.cpp +++ b/src/client/hooks.cpp @@ -91,30 +91,61 @@ int hook_fstat(unsigned int fd, struct stat* buf) { return syscall_no_intercept(SYS_fstat, fd, buf); } -int hook_read(int fd, void* buf, size_t count) { +int hook_read(unsigned int fd, void* buf, size_t count) { CTX->log()->trace("{}() called with fd {}, count {}", __func__, fd, count); if (CTX->file_map()->exist(fd)) { - auto ret = adafs_read(fd, buf, count); - if(ret < 0) { - return -errno; - } - return ret; + return with_errno(adafs_read(fd, buf, count)); } return syscall_no_intercept(SYS_read, fd, buf, count); } -int hook_write(int fd, void* buf, size_t count) { +int hook_pread(unsigned int fd, char * buf, size_t count, loff_t pos) { + CTX->log()->trace("{}() called with fd {}, count {}, pos {}", + __func__, fd, count, pos); + if (CTX->file_map()->exist(fd)) { + return with_errno(adafs_pread_ws(fd, buf, count, pos)); + } + /* Since kernel 2.6: pread() became pread64(), and pwrite() became pwrite64(). */ + return syscall_no_intercept(SYS_pread64, fd, buf, count, pos); +} + +int hook_write(unsigned int fd, const char * buf, size_t count) { CTX->log()->trace("{}() called with fd {}, count {}", __func__, fd, count); if (CTX->file_map()->exist(fd)) { - auto ret = adafs_write(fd, buf, count); - if(ret < 0) { - return -errno; - } - return ret; + return with_errno(adafs_write(fd, buf, count)); } return syscall_no_intercept(SYS_write, fd, buf, count); } +int hook_pwrite(unsigned int fd, const char * buf, size_t count, loff_t pos) { + CTX->log()->trace("{}() called with fd {}, count {}, pos {}", + __func__, fd, count, pos); + if (CTX->file_map()->exist(fd)) { + return with_errno(adafs_pwrite_ws(fd, buf, count, pos)); + } + /* Since kernel 2.6: pread() became pread64(), and pwrite() became pwrite64(). */ + return syscall_no_intercept(SYS_pwrite64, fd, buf, count, pos); +} + +int hook_writev(unsigned long fd, const struct iovec * iov, unsigned long iovcnt) { + CTX->log()->trace("{}() called with fd {}, ops_num {}", __func__, fd, iovcnt); + if (CTX->file_map()->exist(fd)) { + return with_errno(adafs_writev(fd, iov, iovcnt)); + } + return syscall_no_intercept(SYS_writev, fd, iov, iovcnt); +} + +int hook_pwritev(unsigned long fd, const struct iovec * iov, unsigned long iovcnt, + unsigned long pos_l, unsigned long pos_h) { + CTX->log()->trace("{}() called with fd {}, ops_num {}, low position {}," + "high postion {}", __func__, fd, iovcnt, pos_l, pos_h); + if (CTX->file_map()->exist(fd)) { + CTX->log()->warn("{}() Not supported", __func__); + return -ENOTSUP; + } + return syscall_no_intercept(SYS_pwritev, fd, iov, iovcnt); +} + int hook_unlinkat(int dirfd, const char * cpath, int flags) { CTX->log()->trace("{}() called with path '{}' dirfd {}, flags {}", __func__, cpath, dirfd, flags); diff --git a/src/client/intercept.cpp b/src/client/intercept.cpp index 845cd4d77..cd9fe1da9 100644 --- a/src/client/intercept.cpp +++ b/src/client/intercept.cpp @@ -70,17 +70,44 @@ static inline int hook(long syscall_number, break; case SYS_read: - *result = hook_read(static_cast(arg0), + *result = hook_read(static_cast(arg0), reinterpret_cast(arg1), static_cast(arg2)); break; + case SYS_pread64: + *result = hook_pread(static_cast(arg0), + reinterpret_cast(arg1), + static_cast(arg2), + static_cast(arg3)); + break; + + case SYS_pwrite64: + *result = hook_pwrite(static_cast(arg0), + reinterpret_cast(arg1), + static_cast(arg2), + static_cast(arg3)); + break; case SYS_write: - *result = hook_write(static_cast(arg0), - reinterpret_cast(arg1), + *result = hook_write(static_cast(arg0), + reinterpret_cast(arg1), static_cast(arg2)); break; + case SYS_writev: + *result = hook_writev(static_cast(arg0), + reinterpret_cast(arg1), + static_cast(arg2)); + break; + + case SYS_pwritev: + *result = hook_pwritev(static_cast(arg0), + reinterpret_cast(arg1), + static_cast(arg2), + static_cast(arg3), + static_cast(arg4)); + break; + case SYS_unlink: *result = hook_unlinkat(AT_FDCWD, reinterpret_cast(arg0), -- GitLab From 5c3f5cf09f965bae032b3277395ad555eeb93204 Mon Sep 17 00:00:00 2001 From: Tommaso Tocci Date: Tue, 18 Sep 2018 12:54:04 +0200 Subject: [PATCH 12/25] intercept chdir,fchdir,getcwd --- include/client/hooks.hpp | 3 ++ src/client/hooks.cpp | 78 +++++++++++++++++++++++++++++++++++++++- src/client/intercept.cpp | 13 +++++++ 3 files changed, 93 insertions(+), 1 deletion(-) diff --git a/include/client/hooks.hpp b/include/client/hooks.hpp index f0966bb27..0e45e23a4 100644 --- a/include/client/hooks.hpp +++ b/include/client/hooks.hpp @@ -37,6 +37,9 @@ int hook_dup2(unsigned int oldfd, unsigned int newfd); int hook_dup3(unsigned int oldfd, unsigned int newfd, int flags); int hook_getdents(unsigned int fd, struct linux_dirent *dirp, unsigned int count); int hook_mkdirat(int dirfd, const char * cpath, mode_t mode); +int hook_chdir(const char* path); +int hook_fchdir(unsigned int fd); +int hook_getcwd(char * buf, unsigned long size); #endif diff --git a/src/client/hooks.cpp b/src/client/hooks.cpp index 6303f8d1e..f5622e87e 100644 --- a/src/client/hooks.cpp +++ b/src/client/hooks.cpp @@ -21,7 +21,7 @@ #include #include #include - +#include static inline int with_errno(int ret) { return (ret < 0)? -errno : ret; @@ -266,3 +266,79 @@ int hook_mkdirat(int dirfd, const char * cpath, mode_t mode) { return -EINVAL; } } + +int hook_chdir(const char * path) { + CTX->log()->trace("{}() called with path '{}'", __func__, path); + std::string rel_path; + bool internal = CTX->relativize_path(path, rel_path); + if (internal) { + //path falls in our namespace + auto md = adafs_metadata(rel_path); + if (md == nullptr) { + CTX->log()->error("{}() path does not exists", __func__); + return -ENOENT; + } + if(!S_ISDIR(md->mode())) { + CTX->log()->error("{}() path is not a directory", __func__); + return -ENOTDIR; + } + //TODO get complete path from relativize_path instead of + // removing mountdir and then adding again here + rel_path.insert(0, CTX->mountdir()); + if (has_trailing_slash(rel_path)) { + // open_dir is '/' + rel_path.pop_back(); + } + } + try { + set_cwd(rel_path, internal); + } catch (const std::system_error& se) { + return -(se.code().value()); + } + return 0; +} + +int hook_fchdir(unsigned int fd) { + CTX->log()->trace("{}() called with fd {}", __func__, fd); + if (CTX->file_map()->exist(fd)) { + auto open_dir = CTX->file_map()->get_dir(fd); + if (open_dir == nullptr) { + //Cast did not succeeded: open_file is a regular file + CTX->log()->error("{}() file descriptor refers to a normal file: '{}'", + __func__, open_dir->path()); + return -EBADF; + } + + std::string new_path = CTX->mountdir() + open_dir->path(); + if (has_trailing_slash(new_path)) { + // open_dir is '/' + new_path.pop_back(); + } + try { + set_cwd(new_path, true); + } catch (const std::system_error& se) { + return -(se.code().value()); + } + } else { + long ret = syscall_no_intercept(SYS_fchdir, fd); + if (ret < 0) { + throw std::system_error(syscall_error_code(ret), + std::system_category(), + "Failed to change directory (fchdir syscall)"); + } + unset_env_cwd(); + CTX->cwd(get_sys_cwd()); + } + return 0; +} + +int hook_getcwd(char * buf, unsigned long size) { + CTX->log()->trace("{}() called with size {}", __func__, size); + if(CTX->cwd().size() + 1 > size) { + CTX->log()->error("{}() buffer too small to host current working dir", __func__); + return -ERANGE; + } + + strcpy(buf, CTX->cwd().c_str()); + return (CTX->cwd().size() + 1); +} diff --git a/src/client/intercept.cpp b/src/client/intercept.cpp index cd9fe1da9..3d3449047 100644 --- a/src/client/intercept.cpp +++ b/src/client/intercept.cpp @@ -164,6 +164,19 @@ static inline int hook(long syscall_number, static_cast(arg1)); break; + case SYS_chdir: + *result = hook_chdir(reinterpret_cast(arg0)); + break; + + case SYS_fchdir: + *result = hook_fchdir(static_cast(arg0)); + break; + + case SYS_getcwd: + *result = hook_getcwd(reinterpret_cast(arg0), + static_cast(arg1)); + break; + default: /* * Ignore any other syscalls -- GitLab From 48592d5f4f807cfd653f8e0f193ea02be265e5da Mon Sep 17 00:00:00 2001 From: Tommaso Tocci Date: Thu, 20 Sep 2018 15:00:20 +0200 Subject: [PATCH 13/25] intercept fstat --- include/client/hooks.hpp | 3 ++- src/client/hooks.cpp | 29 +++++++++++++++++++++++++++++ src/client/intercept.cpp | 7 +++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/include/client/hooks.hpp b/include/client/hooks.hpp index 0e45e23a4..e63cc5011 100644 --- a/include/client/hooks.hpp +++ b/include/client/hooks.hpp @@ -21,7 +21,8 @@ int hook_openat(int dirfd, const char *cpath, int flags, mode_t mode); int hook_close(int fd); int hook_stat(const char* path, struct stat* buf); int hook_lstat(const char* path, struct stat* buf); -int hook_fstat(unsigned int, struct stat* buf); +int hook_fstat(unsigned int fd, struct stat* buf); +int hook_fstatat(int dirfd, const char * cpath, struct stat * buf, int flags); int hook_read(unsigned int fd, void* buf, size_t count); int hook_pread(unsigned int fd, char * buf, size_t count, loff_t pos); int hook_write(unsigned int fd, const char * buf, size_t count); diff --git a/src/client/hooks.cpp b/src/client/hooks.cpp index f5622e87e..a7fcf9df3 100644 --- a/src/client/hooks.cpp +++ b/src/client/hooks.cpp @@ -91,6 +91,35 @@ int hook_fstat(unsigned int fd, struct stat* buf) { return syscall_no_intercept(SYS_fstat, fd, buf); } +int hook_fstatat(int dirfd, const char * cpath, struct stat * buf, int flags) { + CTX->log()->trace("{}() called with path '{}' and fd {}", __func__, cpath, dirfd); + + if(flags & AT_EMPTY_PATH) { + CTX->log()->error("{}() AT_EMPTY_PATH flag not supported", __func__); + return -ENOTSUP; + } + + std::string resolved; + auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved); + switch(rstatus) { + case RelativizeStatus::fd_unknown: + return syscall_no_intercept(SYS_newfstatat, dirfd, cpath, buf, flags); + + case RelativizeStatus::external: + return syscall_no_intercept(SYS_newfstatat, dirfd, resolved.c_str(), buf, flags); + + case RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case RelativizeStatus::internal: + return with_errno(adafs_stat(resolved, buf)); + + default: + CTX->log()->error("{}() relativize status unknown: {}", __func__); + return -EINVAL; + } +} + int hook_read(unsigned int fd, void* buf, size_t count) { CTX->log()->trace("{}() called with fd {}, count {}", __func__, fd, count); if (CTX->file_map()->exist(fd)) { diff --git a/src/client/intercept.cpp b/src/client/intercept.cpp index 3d3449047..0158cee85 100644 --- a/src/client/intercept.cpp +++ b/src/client/intercept.cpp @@ -69,6 +69,13 @@ static inline int hook(long syscall_number, reinterpret_cast(arg1)); break; + case SYS_newfstatat: + *result = hook_fstatat(static_cast(arg0), + reinterpret_cast(arg1), + reinterpret_cast(arg2), + static_cast(arg3)); + break; + case SYS_read: *result = hook_read(static_cast(arg0), reinterpret_cast(arg1), -- GitLab From 72dc750dfb7f01ee0bc3098948de151e652ae35a Mon Sep 17 00:00:00 2001 From: Tommaso Tocci Date: Thu, 20 Sep 2018 15:01:24 +0200 Subject: [PATCH 14/25] intercept fcntl --- include/client/hooks.hpp | 1 + src/client/hooks.cpp | 61 ++++++++++++++++++++++++++++++++++++++++ src/client/intercept.cpp | 6 ++++ 3 files changed, 68 insertions(+) diff --git a/include/client/hooks.hpp b/include/client/hooks.hpp index e63cc5011..e5a3c60f9 100644 --- a/include/client/hooks.hpp +++ b/include/client/hooks.hpp @@ -41,6 +41,7 @@ int hook_mkdirat(int dirfd, const char * cpath, mode_t mode); int hook_chdir(const char* path); int hook_fchdir(unsigned int fd); int hook_getcwd(char * buf, unsigned long size); +int hook_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg); #endif diff --git a/src/client/hooks.cpp b/src/client/hooks.cpp index a7fcf9df3..85dc6d835 100644 --- a/src/client/hooks.cpp +++ b/src/client/hooks.cpp @@ -371,3 +371,64 @@ int hook_getcwd(char * buf, unsigned long size) { strcpy(buf, CTX->cwd().c_str()); return (CTX->cwd().size() + 1); } + +int hook_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg) { + CTX->log()->trace("{}() called with fd {}, cmd {}, arg {}", __func__, fd, cmd, arg); + if (!CTX->file_map()->exist(fd)) { + return syscall_no_intercept(SYS_fcntl, fd, cmd, arg); + } + int ret; + switch (cmd) { + + case F_DUPFD: + CTX->log()->trace("{}() F_DUPFD on fd {}", __func__, fd); + return with_errno(adafs_dup(fd)); + + case F_DUPFD_CLOEXEC: + CTX->log()->trace("{}() F_DUPFD_CLOEXEC on fd {}", __func__, fd); + ret = adafs_dup(fd); + if(ret == -1) { + return -errno; + } + CTX->file_map()->get(fd)->set_flag(OpenFile_flags::cloexec, true); + return ret; + + case F_GETFD: + CTX->log()->trace("{}() F_GETFD on fd {}", __func__, fd); + if(CTX->file_map()->get(fd) + ->get_flag(OpenFile_flags::cloexec)) { + return FD_CLOEXEC; + } + return 0; + + case F_GETFL: + CTX->log()->trace("{}() F_GETFL on fd {}", __func__, fd); + ret = 0; + if(CTX->file_map()->get(fd) + ->get_flag(OpenFile_flags::rdonly)) { + ret |= O_RDONLY; + } + if(CTX->file_map()->get(fd) + ->get_flag(OpenFile_flags::wronly)) { + ret |= O_WRONLY; + } + if(CTX->file_map()->get(fd) + ->get_flag(OpenFile_flags::rdwr)) { + ret |= O_RDWR; + } + return ret; + + case F_SETFD: + CTX->log()->trace("{}() [fd: {}, cmd: F_SETFD, FD_CLOEXEC: {}]", + __func__, fd, (arg & FD_CLOEXEC)); + CTX->file_map()->get(fd) + ->set_flag(OpenFile_flags::cloexec, (arg & FD_CLOEXEC)); + return 0; + + + default: + CTX->log()->error("{}() unrecognized command {} on fd {}", + __func__, cmd, fd); + return -ENOTSUP; + } +} diff --git a/src/client/intercept.cpp b/src/client/intercept.cpp index 0158cee85..9b87fb14f 100644 --- a/src/client/intercept.cpp +++ b/src/client/intercept.cpp @@ -184,6 +184,12 @@ static inline int hook(long syscall_number, static_cast(arg1)); break; + case SYS_fcntl: + *result = hook_fcntl(static_cast(arg0), + static_cast(arg1), + static_cast(arg2)); + break; + default: /* * Ignore any other syscalls -- GitLab From e77d0fcefe852749dfcbf43c220221076d34e619 Mon Sep 17 00:00:00 2001 From: Tommaso Tocci Date: Thu, 20 Sep 2018 15:03:10 +0200 Subject: [PATCH 15/25] intercept truncate, ftruncate --- include/client/hooks.hpp | 2 ++ src/client/hooks.cpp | 19 +++++++++++++++++++ src/client/intercept.cpp | 10 ++++++++++ 3 files changed, 31 insertions(+) diff --git a/include/client/hooks.hpp b/include/client/hooks.hpp index e5a3c60f9..8b04180b6 100644 --- a/include/client/hooks.hpp +++ b/include/client/hooks.hpp @@ -33,6 +33,8 @@ int hook_pwritev(unsigned long fd, const struct iovec * iov, unsigned long iovcn int hook_unlinkat(int dirfd, const char * cpath, int flags); int hook_access(const char* path, int mask); int hook_lseek(unsigned int fd, off_t offset, unsigned int whence); +int hook_truncate(const char *path, long length); +int hook_ftruncate(unsigned int fd, unsigned long length); int hook_dup(unsigned int fd); int hook_dup2(unsigned int oldfd, unsigned int newfd); int hook_dup3(unsigned int oldfd, unsigned int newfd, int flags); diff --git a/src/client/hooks.cpp b/src/client/hooks.cpp index 85dc6d835..4e5209556 100644 --- a/src/client/hooks.cpp +++ b/src/client/hooks.cpp @@ -237,6 +237,24 @@ int hook_lseek(unsigned int fd, off_t offset, unsigned int whence) { return syscall_no_intercept(SYS_lseek, fd, offset, whence); } +int hook_truncate(const char* path, long length) { + CTX->log()->trace("{}() called with path: {}, offset: {}", __func__, path, length); + std::string rel_path; + if (CTX->relativize_path(path, rel_path)) { + return with_errno(adafs_truncate(rel_path, length)); + } + return syscall_no_intercept(SYS_truncate, rel_path.c_str(), length); +} + +int hook_ftruncate(unsigned int fd, unsigned long length) { + CTX->log()->trace("{}() called [fd: {}, offset: {}]", __func__, fd, length); + if (CTX->file_map()->exist(fd)) { + auto path = CTX->file_map()->get(fd)->path(); + return with_errno(adafs_truncate(path, length)); + } + return syscall_no_intercept(SYS_ftruncate, fd, length); +} + int hook_dup(unsigned int fd) { CTX->log()->trace("{}() called with oldfd {}", __func__, fd); if (CTX->file_map()->exist(fd)) { @@ -296,6 +314,7 @@ int hook_mkdirat(int dirfd, const char * cpath, mode_t mode) { } } + std::string resolved; int hook_chdir(const char * path) { CTX->log()->trace("{}() called with path '{}'", __func__, path); std::string rel_path; diff --git a/src/client/intercept.cpp b/src/client/intercept.cpp index 9b87fb14f..1a77a625d 100644 --- a/src/client/intercept.cpp +++ b/src/client/intercept.cpp @@ -138,6 +138,16 @@ static inline int hook(long syscall_number, static_cast(arg2)); break; + case SYS_truncate: + *result = hook_truncate(reinterpret_cast(arg0), + static_cast(arg1)); + break; + + case SYS_ftruncate: + *result = hook_ftruncate(static_cast(arg0), + static_cast(arg1)); + break; + case SYS_dup: *result = hook_dup(static_cast(arg0)); break; -- GitLab From 7091baf06c89f30a8e015c5a74efb786a63e87a8 Mon Sep 17 00:00:00 2001 From: Tommaso Tocci Date: Thu, 20 Sep 2018 15:37:08 +0200 Subject: [PATCH 16/25] intercept chmod,fchmod,fchmodat --- include/client/hooks.hpp | 2 ++ src/client/hooks.cpp | 33 +++++++++++++++++++++++++++++++++ src/client/intercept.cpp | 17 +++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/include/client/hooks.hpp b/include/client/hooks.hpp index 8b04180b6..f7e474daa 100644 --- a/include/client/hooks.hpp +++ b/include/client/hooks.hpp @@ -40,6 +40,8 @@ int hook_dup2(unsigned int oldfd, unsigned int newfd); int hook_dup3(unsigned int oldfd, unsigned int newfd, int flags); int hook_getdents(unsigned int fd, struct linux_dirent *dirp, unsigned int count); int hook_mkdirat(int dirfd, const char * cpath, mode_t mode); +int hook_fchmodat(int dirfd, const char* path, mode_t mode); +int hook_fchmod(unsigned int dirfd, mode_t mode); int hook_chdir(const char* path); int hook_fchdir(unsigned int fd); int hook_getcwd(char * buf, unsigned long size); diff --git a/src/client/hooks.cpp b/src/client/hooks.cpp index 4e5209556..d9d7847cc 100644 --- a/src/client/hooks.cpp +++ b/src/client/hooks.cpp @@ -314,7 +314,40 @@ int hook_mkdirat(int dirfd, const char * cpath, mode_t mode) { } } +int hook_fchmodat(int dirfd, const char * cpath, mode_t mode) { + CTX->log()->trace("{}() called dirfd {}, path '{}', mode {}", __func__, dirfd, cpath, mode); + std::string resolved; + auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved); + switch(rstatus) { + case RelativizeStatus::fd_unknown: + return syscall_no_intercept(SYS_fchmodat, dirfd, cpath, mode); + + case RelativizeStatus::external: + return syscall_no_intercept(SYS_fchmodat, dirfd, resolved.c_str(), mode); + + case RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case RelativizeStatus::internal: + CTX->log()->warn("{}() operation not supported", __func__); + return -ENOTSUP; + + default: + CTX->log()->error("{}() relativize status unknown: {}", __func__); + return -EINVAL; + } +} + +int hook_fchmod(unsigned int fd, mode_t mode) { + CTX->log()->trace("{}() called with fd {}, mode {}", __func__, fd, mode); + if (CTX->file_map()->exist(fd)) { + CTX->log()->warn("{}() operation not supported", __func__); + return -ENOTSUP; + } + return syscall_no_intercept(SYS_fchmod, fd, mode); +} + int hook_chdir(const char * path) { CTX->log()->trace("{}() called with path '{}'", __func__, path); std::string rel_path; diff --git a/src/client/intercept.cpp b/src/client/intercept.cpp index 1a77a625d..cb4473c3b 100644 --- a/src/client/intercept.cpp +++ b/src/client/intercept.cpp @@ -181,6 +181,23 @@ static inline int hook(long syscall_number, static_cast(arg1)); break; + case SYS_chmod: + *result = hook_fchmodat(AT_FDCWD, + reinterpret_cast(arg0), + static_cast(arg1)); + break; + + case SYS_fchmod: + *result = hook_fchmod(static_cast(arg0), + static_cast(arg1)); + break; + + case SYS_fchmodat: + *result = hook_fchmodat(static_cast(arg0), + reinterpret_cast(arg1), + static_cast(arg2)); + break; + case SYS_chdir: *result = hook_chdir(reinterpret_cast(arg0)); break; -- GitLab From 373e88decd75b4f072d885fad7237a90890b3c10 Mon Sep 17 00:00:00 2001 From: Tommaso Tocci Date: Thu, 20 Sep 2018 15:50:29 +0200 Subject: [PATCH 17/25] intercept faccessat --- include/client/hooks.hpp | 1 + src/client/hooks.cpp | 25 +++++++++++++++++++++++++ src/client/intercept.cpp | 8 +++++++- 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/include/client/hooks.hpp b/include/client/hooks.hpp index f7e474daa..5b29ee4a7 100644 --- a/include/client/hooks.hpp +++ b/include/client/hooks.hpp @@ -32,6 +32,7 @@ int hook_pwritev(unsigned long fd, const struct iovec * iov, unsigned long iovcn unsigned long pos_l, unsigned long pos_h); int hook_unlinkat(int dirfd, const char * cpath, int flags); int hook_access(const char* path, int mask); +int hook_faccessat(int dirfd, const char * cpath, int mode); int hook_lseek(unsigned int fd, off_t offset, unsigned int whence); int hook_truncate(const char *path, long length); int hook_ftruncate(unsigned int fd, unsigned long length); diff --git a/src/client/hooks.cpp b/src/client/hooks.cpp index d9d7847cc..2f376ecfe 100644 --- a/src/client/hooks.cpp +++ b/src/client/hooks.cpp @@ -222,6 +222,31 @@ int hook_access(const char* path, int mask) { return syscall_no_intercept(SYS_access, rel_path.c_str(), mask); } +int hook_faccessat(int dirfd, const char * cpath, int mode) { + CTX->log()->trace("{}() called with path '{}' dirfd {}, mode {}", + __func__, cpath, dirfd, mode); + + std::string resolved; + auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved); + switch(rstatus) { + case RelativizeStatus::fd_unknown: + return syscall_no_intercept(SYS_faccessat, dirfd, cpath, mode); + + case RelativizeStatus::external: + return syscall_no_intercept(SYS_faccessat, dirfd, resolved.c_str(), mode); + + case RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case RelativizeStatus::internal: + return with_errno(adafs_access(resolved, mode)); + + default: + CTX->log()->error("{}() relativize status unknown: {}", __func__); + return -EINVAL; + } +} + int hook_lseek(unsigned int fd, off_t offset, unsigned int whence) { CTX->log()->trace("{}() called with fd {}, offset {}, whence {}", __func__, fd, offset, whence); if (CTX->file_map()->exist(fd)) { diff --git a/src/client/intercept.cpp b/src/client/intercept.cpp index cb4473c3b..1160724e8 100644 --- a/src/client/intercept.cpp +++ b/src/client/intercept.cpp @@ -128,10 +128,16 @@ static inline int hook(long syscall_number, break; case SYS_access: - *result = hook_access(reinterpret_cast(arg0), + *result = hook_access(reinterpret_cast(arg0), static_cast(arg1)); break; + case SYS_faccessat: + *result = hook_faccessat(static_cast(arg0), + reinterpret_cast(arg1), + static_cast(arg2)); + break; + case SYS_lseek: *result = hook_lseek(static_cast(arg0), static_cast(arg1), -- GitLab From 6639956716f0b0de3eb76ff5e581df369c1641d3 Mon Sep 17 00:00:00 2001 From: Tommaso Tocci Date: Thu, 20 Sep 2018 15:50:46 +0200 Subject: [PATCH 18/25] intercept readlinkat --- include/client/hooks.hpp | 1 + src/client/hooks.cpp | 26 ++++++++++++++++++++++++++ src/client/intercept.cpp | 14 ++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/include/client/hooks.hpp b/include/client/hooks.hpp index 5b29ee4a7..b1134f87b 100644 --- a/include/client/hooks.hpp +++ b/include/client/hooks.hpp @@ -46,6 +46,7 @@ int hook_fchmod(unsigned int dirfd, mode_t mode); int hook_chdir(const char* path); int hook_fchdir(unsigned int fd); int hook_getcwd(char * buf, unsigned long size); +int hook_readlinkat(int dirfd, const char * cpath, char * buf, int bufsiz); int hook_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg); diff --git a/src/client/hooks.cpp b/src/client/hooks.cpp index 2f376ecfe..82bce3876 100644 --- a/src/client/hooks.cpp +++ b/src/client/hooks.cpp @@ -449,6 +449,32 @@ int hook_getcwd(char * buf, unsigned long size) { return (CTX->cwd().size() + 1); } +int hook_readlinkat(int dirfd, const char * cpath, char * buf, int bufsiz) { + CTX->log()->trace("{}() called with path '{}' dirfd {}, bufsize {}", + __func__, cpath, dirfd, bufsiz); + + std::string resolved; + auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved, false); + switch(rstatus) { + case RelativizeStatus::fd_unknown: + return syscall_no_intercept(SYS_readlinkat, dirfd, cpath, buf, bufsiz); + + case RelativizeStatus::external: + return syscall_no_intercept(SYS_readlinkat, dirfd, resolved.c_str(), buf, bufsiz); + + case RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case RelativizeStatus::internal: + CTX->log()->warn("{}() not supported", __func__); + return -ENOTSUP; + + default: + CTX->log()->error("{}() relativize status unknown: {}", __func__); + return -EINVAL; + } +} + int hook_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg) { CTX->log()->trace("{}() called with fd {}, cmd {}, arg {}", __func__, fd, cmd, arg); if (!CTX->file_map()->exist(fd)) { diff --git a/src/client/intercept.cpp b/src/client/intercept.cpp index 1160724e8..d9d4d60ed 100644 --- a/src/client/intercept.cpp +++ b/src/client/intercept.cpp @@ -217,6 +217,20 @@ static inline int hook(long syscall_number, static_cast(arg1)); break; + case SYS_readlink: + *result = hook_readlinkat(AT_FDCWD, + reinterpret_cast(arg0), + reinterpret_cast(arg1), + static_cast(arg2)); + break; + + case SYS_readlinkat: + *result = hook_readlinkat(static_cast(arg0), + reinterpret_cast(arg1), + reinterpret_cast(arg2), + static_cast(arg3)); + break; + case SYS_fcntl: *result = hook_fcntl(static_cast(arg0), static_cast(arg1), -- GitLab From 2f851f37428661ea676acf15459cd2ed32074f40 Mon Sep 17 00:00:00 2001 From: Tommaso Tocci Date: Thu, 20 Sep 2018 17:19:44 +0200 Subject: [PATCH 19/25] intercept rmdir --- src/client/intercept.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/client/intercept.cpp b/src/client/intercept.cpp index d9d4d60ed..951d94f32 100644 --- a/src/client/intercept.cpp +++ b/src/client/intercept.cpp @@ -127,6 +127,12 @@ static inline int hook(long syscall_number, static_cast(arg2)); break; + case SYS_rmdir: + *result = hook_unlinkat(AT_FDCWD, + reinterpret_cast(arg0), + AT_REMOVEDIR); + break; + case SYS_access: *result = hook_access(reinterpret_cast(arg0), static_cast(arg1)); -- GitLab From 7e73302cc4bcc158e002bd8677b39ee2045aaf8f Mon Sep 17 00:00:00 2001 From: Tommaso Tocci Date: Thu, 27 Sep 2018 09:56:41 +0200 Subject: [PATCH 20/25] intercept symlinkat --- include/client/hooks.hpp | 1 + src/client/hooks.cpp | 33 +++++++++++++++++++++++++++++++++ src/client/intercept.cpp | 12 ++++++++++++ 3 files changed, 46 insertions(+) diff --git a/include/client/hooks.hpp b/include/client/hooks.hpp index b1134f87b..280fab917 100644 --- a/include/client/hooks.hpp +++ b/include/client/hooks.hpp @@ -31,6 +31,7 @@ int hook_writev(unsigned long fd, const struct iovec * iov, unsigned long iovcnt int hook_pwritev(unsigned long fd, const struct iovec * iov, unsigned long iovcnt, unsigned long pos_l, unsigned long pos_h); int hook_unlinkat(int dirfd, const char * cpath, int flags); +int hook_symlinkat(const char * oldname, int newdfd, const char * newname); int hook_access(const char* path, int mask); int hook_faccessat(int dirfd, const char * cpath, int mode); int hook_lseek(unsigned int fd, off_t offset, unsigned int whence); diff --git a/src/client/hooks.cpp b/src/client/hooks.cpp index 82bce3876..83b382e7f 100644 --- a/src/client/hooks.cpp +++ b/src/client/hooks.cpp @@ -209,6 +209,39 @@ int hook_unlinkat(int dirfd, const char * cpath, int flags) { } } +int hook_symlinkat(const char * oldname, int newdfd, const char * newname) { + CTX->log()->trace("{}() called with oldname '{}', new fd {}, new name '{}'", + __func__, oldname, newdfd, newname); + + std::string oldname_resolved; + if (CTX->relativize_path(oldname, oldname_resolved)) { + CTX->log()->warn("{}() operation not supported", __func__); + return -ENOTSUP; + } + + std::string newname_resolved; + auto rstatus = CTX->relativize_fd_path(newdfd, newname, newname_resolved, false); + switch(rstatus) { + case RelativizeStatus::fd_unknown: + return syscall_no_intercept(SYS_symlinkat, oldname, newdfd, newname); + + case RelativizeStatus::external: + return syscall_no_intercept(SYS_symlinkat, oldname, newdfd, newname_resolved.c_str()); + + case RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case RelativizeStatus::internal: + CTX->log()->warn("{}() operation not supported", __func__); + return -ENOTSUP; + + default: + CTX->log()->error("{}() relativize status unknown", __func__); + return -EINVAL; + } +} + + int hook_access(const char* path, int mask) { CTX->log()->trace("{}() called path '{}', mask {}", __func__, path, mask); std::string rel_path; diff --git a/src/client/intercept.cpp b/src/client/intercept.cpp index 951d94f32..81f13a18a 100644 --- a/src/client/intercept.cpp +++ b/src/client/intercept.cpp @@ -133,6 +133,18 @@ static inline int hook(long syscall_number, AT_REMOVEDIR); break; + case SYS_symlink: + *result = hook_symlinkat(reinterpret_cast(arg0), + AT_FDCWD, + reinterpret_cast(arg1)); + break; + + case SYS_symlinkat: + *result = hook_symlinkat(reinterpret_cast(arg0), + static_cast(arg1), + reinterpret_cast(arg2)); + break; + case SYS_access: *result = hook_access(reinterpret_cast(arg0), static_cast(arg1)); -- GitLab From 5987cd83479fbe8b95fe97901855b030691905fc Mon Sep 17 00:00:00 2001 From: Tommaso Tocci Date: Thu, 27 Sep 2018 09:57:16 +0200 Subject: [PATCH 21/25] intercept renameat --- include/client/hooks.hpp | 2 ++ src/client/hooks.cpp | 58 ++++++++++++++++++++++++++++++++++++++++ src/client/intercept.cpp | 24 +++++++++++++++++ 3 files changed, 84 insertions(+) diff --git a/include/client/hooks.hpp b/include/client/hooks.hpp index 280fab917..d5a573360 100644 --- a/include/client/hooks.hpp +++ b/include/client/hooks.hpp @@ -49,6 +49,8 @@ int hook_fchdir(unsigned int fd); int hook_getcwd(char * buf, unsigned long size); int hook_readlinkat(int dirfd, const char * cpath, char * buf, int bufsiz); int hook_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg); +int hook_renameat(int olddfd, const char * oldname, int newdfd, const char * newname, + unsigned int flags); #endif diff --git a/src/client/hooks.cpp b/src/client/hooks.cpp index 83b382e7f..a5e2394a1 100644 --- a/src/client/hooks.cpp +++ b/src/client/hooks.cpp @@ -568,3 +568,61 @@ int hook_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg) { return -ENOTSUP; } } + +int hook_renameat(int olddfd, const char * oldname, + int newdfd, const char * newname, + unsigned int flags) { + + CTX->log()->trace("{}() called with olddfd {}, oldname: '{}', newfd {}, newname '{}', flags {}", + __func__, olddfd, oldname, newdfd, newname, flags); + + const char * oldpath_pass; + std::string oldpath_resolved; + auto oldpath_status = CTX->relativize_fd_path(olddfd, oldname, oldpath_resolved); + switch(oldpath_status) { + case RelativizeStatus::fd_unknown: + oldpath_pass = oldname; + break; + + case RelativizeStatus::external: + oldpath_pass = oldpath_resolved.c_str(); + break; + + case RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case RelativizeStatus::internal: + CTX->log()->warn("{}() not supported", __func__); + return -ENOTSUP; + + default: + CTX->log()->error("{}() relativize status unknown", __func__); + return -EINVAL; + } + + const char * newpath_pass; + std::string newpath_resolved; + auto newpath_status = CTX->relativize_fd_path(newdfd, newname, newpath_resolved); + switch(newpath_status) { + case RelativizeStatus::fd_unknown: + newpath_pass = newname; + break; + + case RelativizeStatus::external: + newpath_pass = newpath_resolved.c_str(); + break; + + case RelativizeStatus::fd_not_a_dir: + return -ENOTDIR; + + case RelativizeStatus::internal: + CTX->log()->warn("{}() not supported", __func__); + return -ENOTSUP; + + default: + CTX->log()->error("{}() relativize status unknown", __func__); + return -EINVAL; + } + + return syscall_no_intercept(SYS_renameat2, olddfd, oldpath_pass, newdfd, newpath_pass, flags); +} diff --git a/src/client/intercept.cpp b/src/client/intercept.cpp index 81f13a18a..667946adf 100644 --- a/src/client/intercept.cpp +++ b/src/client/intercept.cpp @@ -255,6 +255,30 @@ static inline int hook(long syscall_number, static_cast(arg2)); break; + case SYS_rename: + *result = hook_renameat(AT_FDCWD, + reinterpret_cast(arg0), + AT_FDCWD, + reinterpret_cast(arg1), + 0); + break; + + case SYS_renameat: + *result = hook_renameat(static_cast(arg0), + reinterpret_cast(arg1), + static_cast(arg2), + reinterpret_cast(arg3), + 0); + break; + + case SYS_renameat2: + *result = hook_renameat(static_cast(arg0), + reinterpret_cast(arg1), + static_cast(arg2), + reinterpret_cast(arg3), + static_cast(arg4)); + break; + default: /* * Ignore any other syscalls -- GitLab From 39d9fb59bc075f4179870a1019a912360da7383b Mon Sep 17 00:00:00 2001 From: Tommaso Tocci Date: Thu, 27 Sep 2018 16:20:00 +0200 Subject: [PATCH 22/25] intercept creat --- src/client/intercept.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/client/intercept.cpp b/src/client/intercept.cpp index 667946adf..c737cc2b8 100644 --- a/src/client/intercept.cpp +++ b/src/client/intercept.cpp @@ -43,6 +43,13 @@ static inline int hook(long syscall_number, static_cast(arg2)); break; + case SYS_creat: + *result = hook_openat(AT_FDCWD, + reinterpret_cast(arg0), + O_WRONLY | O_CREAT | O_TRUNC, + static_cast(arg1)); + break; + case SYS_openat: *result = hook_openat(static_cast(arg0), reinterpret_cast(arg1), -- GitLab From 082f4bbb99f7ccbad52dd735444c777760c7bc8d Mon Sep 17 00:00:00 2001 From: Tommaso Tocci Date: Fri, 1 Mar 2019 11:50:51 +0100 Subject: [PATCH 23/25] intercept statfs --- include/client/hooks.hpp | 2 ++ src/client/hooks.cpp | 17 +++++++++++++++++ src/client/intercept.cpp | 12 +++++++++++- 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/include/client/hooks.hpp b/include/client/hooks.hpp index d5a573360..474190338 100644 --- a/include/client/hooks.hpp +++ b/include/client/hooks.hpp @@ -51,6 +51,8 @@ int hook_readlinkat(int dirfd, const char * cpath, char * buf, int bufsiz); int hook_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg); int hook_renameat(int olddfd, const char * oldname, int newdfd, const char * newname, unsigned int flags); +int hook_statfs(const char * path, struct statfs * buf); +int hook_fstatfs(unsigned int fd, struct statfs * buf); #endif diff --git a/src/client/hooks.cpp b/src/client/hooks.cpp index a5e2394a1..e5128856e 100644 --- a/src/client/hooks.cpp +++ b/src/client/hooks.cpp @@ -626,3 +626,20 @@ int hook_renameat(int olddfd, const char * oldname, return syscall_no_intercept(SYS_renameat2, olddfd, oldpath_pass, newdfd, newpath_pass, flags); } + +int hook_statfs(const char * path, struct statfs * buf) { + CTX->log()->trace("{}() called with path: {}", __func__, path); + std::string rel_path; + if (CTX->relativize_path(path, rel_path)) { + return with_errno(adafs_statfs(buf)); + } + return syscall_no_intercept(SYS_statfs, rel_path.c_str(), buf); +} + +int hook_fstatfs(unsigned int fd, struct statfs * buf) { + CTX->log()->trace("{}() called with fs: {}", __func__, fd); + if (CTX->file_map()->exist(fd)) { + return with_errno(adafs_statfs(buf)); + } + return syscall_no_intercept(SYS_fstatfs, fd, buf); +} diff --git a/src/client/intercept.cpp b/src/client/intercept.cpp index c737cc2b8..af8a59ccb 100644 --- a/src/client/intercept.cpp +++ b/src/client/intercept.cpp @@ -285,7 +285,17 @@ static inline int hook(long syscall_number, reinterpret_cast(arg3), static_cast(arg4)); break; - + + case SYS_fstatfs: + *result = hook_fstatfs(static_cast(arg0), + reinterpret_cast(arg1)); + break; + + case SYS_statfs: + *result = hook_statfs(reinterpret_cast(arg0), + reinterpret_cast(arg1)); + break; + default: /* * Ignore any other syscalls -- GitLab From ad1f61379932c5a575918403d95428c7d550ce32 Mon Sep 17 00:00:00 2001 From: Tommaso Tocci Date: Thu, 27 Sep 2018 20:45:56 +0200 Subject: [PATCH 24/25] file position is unsigned --- include/client/open_file_map.hpp | 6 +++--- src/client/open_file_map.cpp | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/client/open_file_map.hpp b/include/client/open_file_map.hpp index 738ba49ec..b7c4b1265 100644 --- a/include/client/open_file_map.hpp +++ b/include/client/open_file_map.hpp @@ -45,7 +45,7 @@ protected: FileType type_; std::string path_; std::array(OpenFile_flags::flag_count)> flags_ = {false}; - off64_t pos_; + unsigned long pos_; std::mutex pos_mutex_; std::mutex flag_mutex_; @@ -61,9 +61,9 @@ public: void path(const std::string& path_); - off64_t pos(); + unsigned long pos(); - void pos(off64_t pos_); + void pos(unsigned long pos_); bool get_flag(OpenFile_flags flag); diff --git a/src/client/open_file_map.cpp b/src/client/open_file_map.cpp index 98cd98a56..5a13e8b28 100644 --- a/src/client/open_file_map.cpp +++ b/src/client/open_file_map.cpp @@ -58,12 +58,12 @@ void OpenFile::path(const string& path_) { OpenFile::path_ = path_; } -off64_t OpenFile::pos() { +unsigned long OpenFile::pos() { lock_guard lock(pos_mutex_); return pos_; } -void OpenFile::pos(off64_t pos_) { +void OpenFile::pos(unsigned long pos_) { lock_guard lock(pos_mutex_); OpenFile::pos_ = pos_; } -- GitLab From 015435b602cd6ebcc9e581b8553c62ccda61d79e Mon Sep 17 00:00:00 2001 From: Ramon Nou Date: Thu, 25 Apr 2019 12:21:44 +0000 Subject: [PATCH 25/25] Update README.md / typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f2fd9adc1..b0a1dc2dd 100644 --- a/README.md +++ b/README.md @@ -135,7 +135,7 @@ GKFS_LOG_LEVEL={off,critical,err,warn,info,debug,trace} to set the trace level v Numbers from 0-6 may also be used where as 0 is off and 6 represents trace. -### Acknoledgment +### Acknowledgment This software was partially supported by the EC H2020 funded project NEXTGenIO (Project ID: 671951, www.nextgenio.eu). -- GitLab