From d8285f73a1ba3ed0625d881afc730d8f0fe2c341 Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Mon, 28 Jul 2025 06:26:13 +0000 Subject: [PATCH 1/9] Improved readdir --- src/posix/handlers/posix_readdir.hpp | 98 +++++++++---------- .../CapioCommunicationService.hpp | 2 + 2 files changed, 51 insertions(+), 49 deletions(-) diff --git a/src/posix/handlers/posix_readdir.hpp b/src/posix/handlers/posix_readdir.hpp index 978a183c7..19f4cffbe 100644 --- a/src/posix/handlers/posix_readdir.hpp +++ b/src/posix/handlers/posix_readdir.hpp @@ -17,15 +17,17 @@ inline std::unordered_map *> *directory_ite inline std::unordered_map directory_commit_token_path; -inline int count_files_in_directory(const char *path) { - static struct dirent64 *(*real_readdir64)(DIR *) = NULL; - static DIR *(*real_opendir)(const char *) = NULL; - static int (*real_closedir)(DIR *) = NULL; +inline timespec dirent_await_sleep_time{0, 100 * 1000000L}; // 100ms + +inline int load_files_from_directory(const char *path) { + static dirent64 *(*real_readdir64)(DIR *) = nullptr; + static DIR *(*real_opendir)(const char *) = nullptr; + static int (*real_closedir)(DIR *) = nullptr; START_LOG(capio_syscall(SYS_gettid), "call(path=%s)", path); syscall_no_intercept_flag = true; if (!real_readdir64) { - real_readdir64 = (struct dirent64 * (*) (DIR *) ) dlsym(RTLD_NEXT, "readdir64"); + real_readdir64 = (dirent64 * (*) (DIR *) ) dlsym(RTLD_NEXT, "readdir64"); } if (!real_opendir) { @@ -36,7 +38,7 @@ inline int count_files_in_directory(const char *path) { real_closedir = (int (*)(DIR *)) dlsym(RTLD_NEXT, "closedir"); } - struct dirent64 *entry; + dirent64 *entry; DIR *dir = real_opendir(path); int count = 0; @@ -89,54 +91,44 @@ inline struct dirent64 *capio_internal_readdir(DIR *dirp, long pid) { auto directory_path = std::get<0>(opened_directory->at(reinterpret_cast(dirp))); - if (directory_commit_token_path.find(directory_path) == directory_commit_token_path.end()) { - LOG("Commit token path was not found for path %s", directory_path.c_str()); - auto token_path = new char[PATH_MAX]{0}; - posix_directory_committed_request(pid, directory_path, token_path); - LOG("Inserting token path %s", token_path); - directory_commit_token_path.insert({directory_path, token_path}); - } - - const auto token_path = directory_commit_token_path.at(directory_path); + const auto &committed_directory_toke_path = directory_commit_token_path.at(directory_path); if (const auto item = opened_directory->find(reinterpret_cast(dirp)); - item != opened_directory->end() || std::filesystem::exists(token_path)) { + item != opened_directory->end() || std::filesystem::exists(committed_directory_toke_path)) { LOG("Found dirp."); const auto dir_path_name = std::get<0>(item->second); const auto capio_internal_offset = std::get<1>(item->second); - auto files_in_directory = count_files_in_directory(dir_path_name.c_str()); - LOG("There are %ld files inside %s", files_in_directory, dir_path_name.c_str()); - while (files_in_directory <= capio_internal_offset) { - LOG("Not enough files: expected %ld, got %ld... waiting", files_in_directory, - capio_internal_offset); - LOG("Checking for commit token existence (%s)", token_path.c_str()); - syscall_no_intercept_flag = true; - bool is_committed = std::filesystem::exists(token_path); - syscall_no_intercept_flag = false; - LOG("File %s committed", is_committed ? "is" : "is not"); - if (is_committed) { - LOG("Returning NULL as result"); - errno = 0; - return NULL; + LOG("Getting files inside directory %s", dir_path_name.c_str()); + + if (capio_internal_offset >= directory_items->at(dir_path_name)->size()) { + LOG("Internal offset for dir reached end of vector. Loading files from FS."); + auto loaded_files = load_files_from_directory(dir_path_name.c_str()); + LOG("There are %ld files inside %s", loaded_files, dir_path_name.c_str()); + while (loaded_files <= capio_internal_offset) { + LOG("Not enough files: expected %ld, got %ld... waiting", loaded_files, + capio_internal_offset); + LOG("Checking for commit token existence (%s)", + committed_directory_toke_path.c_str()); + syscall_no_intercept_flag = true; + bool is_committed = std::filesystem::exists(committed_directory_toke_path); + syscall_no_intercept_flag = false; + LOG("File %s committed", is_committed ? "is" : "is not"); + if (is_committed) { + LOG("Returning NULL as result"); + errno = 0; + return NULL; + } + + syscall_no_intercept(SYS_nanosleep, &dirent_await_sleep_time, NULL); + loaded_files = load_files_from_directory(dir_path_name.c_str()); + LOG("There are %ld files inside %s", loaded_files, dir_path_name.c_str()); } - - struct timespec req{0}; - req.tv_sec = 0; - req.tv_nsec = 100 * 1000000L; // 100 ms - syscall_no_intercept(SYS_nanosleep, &req, NULL); - files_in_directory = count_files_in_directory(dir_path_name.c_str()); - LOG("There are %ld files inside %s", files_in_directory, dir_path_name.c_str()); } LOG("Returning item %d", std::get<1>(item->second)); - char real_path[PATH_MAX]; - capio_realpath(dir_path_name.c_str(), real_path); - - LOG("Getting files inside directory %s", real_path); - - const auto return_value = directory_items->at(real_path)->at(std::get<1>(item->second)); + const auto return_value = directory_items->at(dir_path_name)->at(std::get<1>(item->second)); std::get<1>(item->second)++; LOG("Returned dirent structure:"); @@ -197,6 +189,14 @@ DIR *opendir(const char *name) { auto dir = real_opendir(absolute_path.c_str()); syscall_no_intercept_flag = false; + if (directory_commit_token_path.find(absolute_path) == directory_commit_token_path.end()) { + LOG("Commit token path was not found for path %s", absolute_path.c_str()); + auto token_path = new char[PATH_MAX]{0}; + posix_directory_committed_request(capio_syscall(SYS_gettid), absolute_path, token_path); + LOG("Inserting token path %s", token_path); + directory_commit_token_path.insert({absolute_path, token_path}); + } + LOG("Opened directory with offset %ld", dir); opened_directory->insert( {reinterpret_cast(dir), {std::string(absolute_path), 0}}); @@ -250,25 +250,25 @@ struct dirent *readdir(DIR *dirp) { long pid = capio_syscall(SYS_gettid); START_LOG(pid, "call(dir=%ld)", dirp); - static struct dirent *(*real_readdir)(DIR *) = NULL; + static dirent *(*real_readdir)(DIR *) = nullptr; if (!real_readdir) { LOG("Loading real glibc method"); syscall_no_intercept_flag = true; - real_readdir = (struct dirent * (*) (DIR *) ) dlsym(RTLD_NEXT, "readdir"); + real_readdir = (dirent * (*) (DIR *) ) dlsym(RTLD_NEXT, "readdir"); syscall_no_intercept_flag = false; } if (opened_directory->find(reinterpret_cast(dirp)) == opened_directory->end()) { - LOG("Directory is not handled by CAPIO. Returning false"); + LOG("Directory is not handled by CAPIO. Returning read readdir"); syscall_no_intercept_flag = true; - auto result = real_readdir(dirp); + const auto result = real_readdir(dirp); syscall_no_intercept_flag = false; return result; } - struct dirent64 *capio_internal_dirent64 = capio_internal_readdir(dirp, pid); + dirent64 *capio_internal_dirent64 = capio_internal_readdir(dirp, pid); LOG("return value == NULL ? %s", capio_internal_dirent64 == NULL ? "TRUE" : "FALSE"); return reinterpret_cast(capio_internal_dirent64); } @@ -287,7 +287,7 @@ struct dirent64 *readdir64(DIR *dirp) { if (opened_directory->find(reinterpret_cast(dirp)) == opened_directory->end()) { - LOG("Directory is not handled by CAPIO. Returning false"); + LOG("Directory is not handled by CAPIO. Returning read readdir"); syscall_no_intercept_flag = true; auto result = real_readdir64(dirp); syscall_no_intercept_flag = false; diff --git a/src/server/communication-service/CapioCommunicationService.hpp b/src/server/communication-service/CapioCommunicationService.hpp index 9e24f9c04..1478e2897 100644 --- a/src/server/communication-service/CapioCommunicationService.hpp +++ b/src/server/communication-service/CapioCommunicationService.hpp @@ -4,6 +4,8 @@ #include "BackendInterface.hpp" #include "MTCL_backend.hpp" +#include + class CapioCommunicationService { char ownHostname[HOST_NAME_MAX] = {0}; From b3b33c798dbdb24f97b5a919d90d8af4c96353c7 Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Mon, 28 Jul 2025 08:29:00 +0000 Subject: [PATCH 2/9] improv --- src/posix/handlers/posix_readdir.hpp | 59 ++++++++++++++++++---------- src/posix/libcapio_posix.cpp | 1 + 2 files changed, 40 insertions(+), 20 deletions(-) diff --git a/src/posix/handlers/posix_readdir.hpp b/src/posix/handlers/posix_readdir.hpp index 19f4cffbe..07d2d3875 100644 --- a/src/posix/handlers/posix_readdir.hpp +++ b/src/posix/handlers/posix_readdir.hpp @@ -19,12 +19,14 @@ inline std::unordered_map directory_commit_token_path; inline timespec dirent_await_sleep_time{0, 100 * 1000000L}; // 100ms -inline int load_files_from_directory(const char *path) { - static dirent64 *(*real_readdir64)(DIR *) = nullptr; - static DIR *(*real_opendir)(const char *) = nullptr; - static int (*real_closedir)(DIR *) = nullptr; +static dirent64 *(*real_readdir64)(DIR *) = nullptr; +static DIR *(*real_opendir)(const char *) = nullptr; +static int (*real_closedir)(DIR *) = nullptr; - START_LOG(capio_syscall(SYS_gettid), "call(path=%s)", path); +inline dirent64 *dirent_curr_dir; +inline dirent64 *dirent_parent_dir; + +inline void init_posix_dirent() { syscall_no_intercept_flag = true; if (!real_readdir64) { real_readdir64 = (dirent64 * (*) (DIR *) ) dlsym(RTLD_NEXT, "readdir64"); @@ -38,24 +40,45 @@ inline int load_files_from_directory(const char *path) { real_closedir = (int (*)(DIR *)) dlsym(RTLD_NEXT, "closedir"); } + dirent_curr_dir = new dirent64(); + dirent_parent_dir = new dirent64(); + + dirent_curr_dir->d_type = DT_DIR; + dirent_parent_dir->d_type = DT_DIR; + + memcpy(dirent_curr_dir->d_name, ".\0", 2); + memcpy(dirent_parent_dir->d_name, "..\0", 3); + + syscall_no_intercept_flag = false; +} + +inline int load_files_from_directory(const char *path) { + + START_LOG(capio_syscall(SYS_gettid), "call(path=%s)", path); + + syscall_no_intercept_flag = true; dirent64 *entry; DIR *dir = real_opendir(path); int count = 0; - while ((entry = real_readdir64(dir)) != NULL) { + if (directory_items->find(path) == directory_items->end()) { + LOG("Directory vector not present. Adding it at path %s", path); + directory_items->emplace(path, new std::vector()); + directory_items->at(path)->emplace_back(dirent_curr_dir); + directory_items->at(path)->emplace_back(dirent_parent_dir); + } + while ((entry = real_readdir64(dir)) != NULL) { std::filesystem::path dir_abs_path(entry->d_name); - if (!(strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)) { - LOG("Entry name is %s. computing absolute path", entry->d_name); - dir_abs_path = std::filesystem::path(path) / entry->d_name; - LOG("Directory abs path = %s", dir_abs_path.c_str()); + if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) { + LOG("Skipping entry %s", entry->d_name); + continue; } - if (directory_items->find(path) == directory_items->end()) { - LOG("Directory vector not present. Adding it at path %s", path); - directory_items->emplace(path, new std::vector()); - } + LOG("Entry name is %s. computing absolute path", entry->d_name); + dir_abs_path = std::filesystem::path(path) / entry->d_name; + LOG("Directory abs path = %s", dir_abs_path.c_str()); auto directory_object = directory_items->at(path); @@ -67,12 +90,8 @@ inline int load_files_from_directory(const char *path) { if (itm == directory_object->end()) { LOG("Item %s is not stored within internal capio data structure. adding it", dir_abs_path.c_str()); - auto *new_entry = new dirent64(); - memcpy(new_entry->d_name, entry->d_name, sizeof(entry->d_name)); - new_entry->d_ino = entry->d_ino; - new_entry->d_off = entry->d_off; - new_entry->d_reclen = entry->d_reclen; - new_entry->d_type = entry->d_type; + auto new_entry = new dirent64(); + memcpy(new_entry, entry, sizeof(dirent64)); directory_object->emplace_back(new_entry); } count++; diff --git a/src/posix/libcapio_posix.cpp b/src/posix/libcapio_posix.cpp index df309375d..4676ee24f 100644 --- a/src/posix/libcapio_posix.cpp +++ b/src/posix/libcapio_posix.cpp @@ -438,6 +438,7 @@ static __attribute__((constructor)) void init() { init_client(); init_filesystem(); init_threading_support(); + init_posix_dirent(); long tid = syscall_no_intercept(SYS_gettid); From 27d0d1dd7b059ebbab07aee0a7484747af1f891a Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Mon, 28 Jul 2025 09:21:29 +0000 Subject: [PATCH 3/9] improv --- src/common/capio/constants.hpp | 5 +++-- src/posix/handlers/open.hpp | 15 ++++++++++++++ src/posix/handlers/posix_readdir.hpp | 8 ++++++++ src/posix/handlers/stat.hpp | 29 ++++++++++++++-------------- 4 files changed, 40 insertions(+), 17 deletions(-) diff --git a/src/common/capio/constants.hpp b/src/common/capio/constants.hpp index aaade0322..333a347c8 100644 --- a/src/common/capio/constants.hpp +++ b/src/common/capio/constants.hpp @@ -13,8 +13,9 @@ typedef unsigned long long int capio_off64_t; // CAPIO files constants constexpr size_t CAPIO_DEFAULT_DIR_INITIAL_SIZE = 1024L * 1024 * 1024; constexpr off64_t CAPIO_DEFAULT_FILE_INITIAL_SIZE = 1024L * 1024 * 1024 * 4; -constexpr std::array CAPIO_DIR_FORBIDDEN_PATHS = {std::string_view{"/proc/"}, - std::string_view{"/sys/"}}; +constexpr std::array CAPIO_DIR_FORBIDDEN_PATHS = { + std::string_view{"/proc/"}, std::string_view{"/sys/"}, std::string_view{"/boot/"}, + std::string_view{"/dev/"}, std::string_view{"/var/"}, std::string_view{"/run/"}}; // CAPIO default values for shared memory constexpr char CAPIO_DEFAULT_WORKFLOW_NAME[] = "CAPIO"; diff --git a/src/posix/handlers/open.hpp b/src/posix/handlers/open.hpp index f8424a25d..f62d7cf6c 100644 --- a/src/posix/handlers/open.hpp +++ b/src/posix/handlers/open.hpp @@ -40,6 +40,11 @@ int creat_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long ar mode_t mode = static_cast(arg2); START_LOG(tid, "call(path=%s, flags=%d, mode=%d)", pathname.data(), flags, mode); + if (is_forbidden_path(pathname)) { + LOG("Path %s is forbidden: skip", pathname.data()); + return CAPIO_POSIX_SYSCALL_REQUEST_SKIP; + } + std::string path = compute_abs_path(pathname.data(), -1); if (is_capio_path(path)) { @@ -69,6 +74,11 @@ int open_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long arg auto tid = static_cast(syscall_no_intercept(SYS_gettid)); START_LOG(tid, "call(path=%s, flags=%d, mode=%d)", pathname.data(), flags, mode); + if (is_forbidden_path(pathname)) { + LOG("Path %s is forbidden: skip", pathname.data()); + return CAPIO_POSIX_SYSCALL_REQUEST_SKIP; + } + std::string path = compute_abs_path(pathname.data(), -1); if (is_capio_path(path)) { @@ -106,6 +116,11 @@ int openat_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long a START_LOG(tid, "call(dirfd=%ld, path=%s, flags=%d, mode=%d)", dirfd, pathname.data(), flags, mode); + if (is_forbidden_path(pathname)) { + LOG("Path %s is forbidden: skip", pathname.data()); + return CAPIO_POSIX_SYSCALL_REQUEST_SKIP; + } + std::string path = compute_abs_path(pathname.data(), dirfd); if (is_capio_path(path)) { diff --git a/src/posix/handlers/posix_readdir.hpp b/src/posix/handlers/posix_readdir.hpp index 07d2d3875..b2468650b 100644 --- a/src/posix/handlers/posix_readdir.hpp +++ b/src/posix/handlers/posix_readdir.hpp @@ -169,6 +169,14 @@ DIR *opendir(const char *name) { START_LOG(capio_syscall(SYS_gettid), "call(path=%s)", tmp.c_str()); + if (is_forbidden_path(name)) { + LOG("Path %s is forbidden: skip", name); + syscall_no_intercept_flag = true; + auto res = real_opendir(name); + syscall_no_intercept_flag = false; + return res; + } + auto absolute_path = capio_absolute(name); LOG("Resolved absolute path = %s", absolute_path.c_str()); diff --git a/src/posix/handlers/stat.hpp b/src/posix/handlers/stat.hpp index d16b326b9..76e8ffd73 100644 --- a/src/posix/handlers/stat.hpp +++ b/src/posix/handlers/stat.hpp @@ -63,28 +63,27 @@ inline int capio_fstatat(int dirfd, const std::string_view &pathname, struct sta if (path.empty() && (flags & AT_EMPTY_PATH) == AT_EMPTY_PATH) { if (dirfd == AT_FDCWD) { // operate on currdir return capio_lstat(get_current_dir().native(), statbuf, tid); - } else { // operate on dirfd. in this case dirfd can refer to any type of file - return capio_fstat(dirfd, statbuf, tid); } - } else if (path.is_relative()) { + // operate on dirfd. in this case dirfd can refer to any type of file + return capio_fstat(dirfd, statbuf, tid); + } + if (path.is_relative()) { if (dirfd == AT_FDCWD) { // pathname is interpreted relative to currdir return capio_lstat_wrapper(path.native(), statbuf, tid); - } else { - if (!is_directory(dirfd)) { - errno = ENOTDIR; - return CAPIO_POSIX_SYSCALL_ERRNO; - } - const std::filesystem::path dir_path = get_dir_path(dirfd); - if (dir_path.empty()) { - return CAPIO_POSIX_SYSCALL_REQUEST_SKIP; - } - path = (dir_path / path).lexically_normal(); - return capio_lstat(path.native(), statbuf, tid); } - } else { + if (!is_directory(dirfd)) { + errno = ENOTDIR; + return CAPIO_POSIX_SYSCALL_ERRNO; + } + const std::filesystem::path dir_path = get_dir_path(dirfd); + if (dir_path.empty()) { + return CAPIO_POSIX_SYSCALL_REQUEST_SKIP; + } + path = (dir_path / path).lexically_normal(); return capio_lstat(path.native(), statbuf, tid); } + return capio_lstat(path.native(), statbuf, tid); } #if defined(SYS_fstat) || defined(SYS_fstat64) From ccec756f79ededba068b1dc40bcab1b8e8c213c2 Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Mon, 28 Jul 2025 09:31:11 +0000 Subject: [PATCH 4/9] test --- src/common/capio/constants.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/common/capio/constants.hpp b/src/common/capio/constants.hpp index 333a347c8..3248ab2ba 100644 --- a/src/common/capio/constants.hpp +++ b/src/common/capio/constants.hpp @@ -15,7 +15,8 @@ constexpr size_t CAPIO_DEFAULT_DIR_INITIAL_SIZE = 1024L * 1024 * 1024; constexpr off64_t CAPIO_DEFAULT_FILE_INITIAL_SIZE = 1024L * 1024 * 1024 * 4; constexpr std::array CAPIO_DIR_FORBIDDEN_PATHS = { std::string_view{"/proc/"}, std::string_view{"/sys/"}, std::string_view{"/boot/"}, - std::string_view{"/dev/"}, std::string_view{"/var/"}, std::string_view{"/run/"}}; + std::string_view{"/dev/"}, std::string_view{"/var/"}, std::string_view{"/run/"}, + std::string_view("/beegfs/home/msantima/spack/opt/spack/")}; // CAPIO default values for shared memory constexpr char CAPIO_DEFAULT_WORKFLOW_NAME[] = "CAPIO"; From a725aca8dc66d59ad781e9a0626b8ba7c00e1dfd Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Mon, 28 Jul 2025 09:37:07 +0000 Subject: [PATCH 5/9] test --- src/posix/handlers/posix_readdir.hpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/posix/handlers/posix_readdir.hpp b/src/posix/handlers/posix_readdir.hpp index b2468650b..bbe2bba6c 100644 --- a/src/posix/handlers/posix_readdir.hpp +++ b/src/posix/handlers/posix_readdir.hpp @@ -19,14 +19,15 @@ inline std::unordered_map directory_commit_token_path; inline timespec dirent_await_sleep_time{0, 100 * 1000000L}; // 100ms -static dirent64 *(*real_readdir64)(DIR *) = nullptr; -static DIR *(*real_opendir)(const char *) = nullptr; -static int (*real_closedir)(DIR *) = nullptr; +inline dirent64 *(*real_readdir64)(DIR *) = nullptr; +inline DIR *(*real_opendir)(const char *) = nullptr; +inline int (*real_closedir)(DIR *) = nullptr; inline dirent64 *dirent_curr_dir; inline dirent64 *dirent_parent_dir; inline void init_posix_dirent() { + START_LOG(capio_syscall(SYS_gettid), "call()"); syscall_no_intercept_flag = true; if (!real_readdir64) { real_readdir64 = (dirent64 * (*) (DIR *) ) dlsym(RTLD_NEXT, "readdir64"); From 3616c3b0cf1ac0d4cafb7af7d8e3b27e4291aa14 Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Mon, 28 Jul 2025 09:43:06 +0000 Subject: [PATCH 6/9] test --- src/posix/handlers/posix_readdir.hpp | 38 ++++++++-------------------- 1 file changed, 10 insertions(+), 28 deletions(-) diff --git a/src/posix/handlers/posix_readdir.hpp b/src/posix/handlers/posix_readdir.hpp index bbe2bba6c..364d24db3 100644 --- a/src/posix/handlers/posix_readdir.hpp +++ b/src/posix/handlers/posix_readdir.hpp @@ -20,6 +20,7 @@ inline std::unordered_map directory_commit_token_path; inline timespec dirent_await_sleep_time{0, 100 * 1000000L}; // 100ms inline dirent64 *(*real_readdir64)(DIR *) = nullptr; +inline dirent *(*real_readdir)(DIR *) = nullptr; inline DIR *(*real_opendir)(const char *) = nullptr; inline int (*real_closedir)(DIR *) = nullptr; @@ -30,17 +31,25 @@ inline void init_posix_dirent() { START_LOG(capio_syscall(SYS_gettid), "call()"); syscall_no_intercept_flag = true; if (!real_readdir64) { + LOG("Loading real readdir64 method"); real_readdir64 = (dirent64 * (*) (DIR *) ) dlsym(RTLD_NEXT, "readdir64"); } if (!real_opendir) { + LOG("Loading real opendir method"); real_opendir = (DIR * (*) (const char *) ) dlsym(RTLD_NEXT, "opendir"); } if (!real_closedir) { + LOG("Loading real closedir method"); real_closedir = (int (*)(DIR *)) dlsym(RTLD_NEXT, "closedir"); } + if (!real_readdir) { + LOG("Loading real readdir method"); + real_readdir = (dirent * (*) (DIR *) ) dlsym(RTLD_NEXT, "readdir"); + } + dirent_curr_dir = new dirent64(); dirent_parent_dir = new dirent64(); @@ -173,7 +182,7 @@ DIR *opendir(const char *name) { if (is_forbidden_path(name)) { LOG("Path %s is forbidden: skip", name); syscall_no_intercept_flag = true; - auto res = real_opendir(name); + auto res = real_opendir(name); syscall_no_intercept_flag = false; return res; } @@ -182,17 +191,6 @@ DIR *opendir(const char *name) { LOG("Resolved absolute path = %s", absolute_path.c_str()); - static DIR *(*real_opendir)(const char *) = NULL; - - if (!real_opendir) { - syscall_no_intercept_flag = true; - real_opendir = (DIR * (*) (const char *) ) dlsym(RTLD_NEXT, "opendir"); - syscall_no_intercept_flag = false; - if (!real_opendir) { - ERR_EXIT("Failed to find original opendir: %s\n", dlerror()); - } - } - if (directory_items == nullptr) { directory_items = new std::unordered_map *>(); } @@ -278,14 +276,6 @@ struct dirent *readdir(DIR *dirp) { long pid = capio_syscall(SYS_gettid); START_LOG(pid, "call(dir=%ld)", dirp); - static dirent *(*real_readdir)(DIR *) = nullptr; - if (!real_readdir) { - LOG("Loading real glibc method"); - syscall_no_intercept_flag = true; - real_readdir = (dirent * (*) (DIR *) ) dlsym(RTLD_NEXT, "readdir"); - syscall_no_intercept_flag = false; - } - if (opened_directory->find(reinterpret_cast(dirp)) == opened_directory->end()) { LOG("Directory is not handled by CAPIO. Returning read readdir"); @@ -305,14 +295,6 @@ struct dirent64 *readdir64(DIR *dirp) { long pid = capio_syscall(SYS_gettid); START_LOG(pid, "call(dir=%ld)", dirp); - static struct dirent64 *(*real_readdir64)(DIR *) = NULL; - if (!real_readdir64) { - LOG("Loading real glibc method"); - syscall_no_intercept_flag = true; - real_readdir64 = (struct dirent64 * (*) (DIR *) ) dlsym(RTLD_NEXT, "readdir64"); - syscall_no_intercept_flag = false; - } - if (opened_directory->find(reinterpret_cast(dirp)) == opened_directory->end()) { LOG("Directory is not handled by CAPIO. Returning read readdir"); From 3d8d1c6bac14c96b45e2857abc50c592e23617ba Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Mon, 28 Jul 2025 09:52:37 +0000 Subject: [PATCH 7/9] test --- src/posix/handlers/posix_readdir.hpp | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/posix/handlers/posix_readdir.hpp b/src/posix/handlers/posix_readdir.hpp index 364d24db3..9a852596e 100644 --- a/src/posix/handlers/posix_readdir.hpp +++ b/src/posix/handlers/posix_readdir.hpp @@ -50,6 +50,9 @@ inline void init_posix_dirent() { real_readdir = (dirent * (*) (DIR *) ) dlsym(RTLD_NEXT, "readdir"); } + directory_items = new std::unordered_map *>(); + opened_directory = new std::unordered_map>(); + dirent_curr_dir = new dirent64(); dirent_parent_dir = new dirent64(); @@ -175,9 +178,7 @@ inline struct dirent64 *capio_internal_readdir(DIR *dirp, long pid) { DIR *opendir(const char *name) { - auto tmp = std::string(name); - - START_LOG(capio_syscall(SYS_gettid), "call(path=%s)", tmp.c_str()); + START_LOG(capio_syscall(SYS_gettid), "call(path=%s)", name); if (is_forbidden_path(name)) { LOG("Path %s is forbidden: skip", name); @@ -191,14 +192,6 @@ DIR *opendir(const char *name) { LOG("Resolved absolute path = %s", absolute_path.c_str()); - if (directory_items == nullptr) { - directory_items = new std::unordered_map *>(); - } - - if (opened_directory == nullptr) { - opened_directory = new std::unordered_map>(); - } - if (!is_capio_path(absolute_path)) { LOG("Not a CAPIO path. continuing execution"); syscall_no_intercept_flag = true; From 637ec5580dc5c688d81df01927a3fd1f0196b736 Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Mon, 28 Jul 2025 11:16:53 +0000 Subject: [PATCH 8/9] fix --- src/common/capio/constants.hpp | 2 +- src/common/capio/filesystem.hpp | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/common/capio/constants.hpp b/src/common/capio/constants.hpp index 3248ab2ba..d2f43044e 100644 --- a/src/common/capio/constants.hpp +++ b/src/common/capio/constants.hpp @@ -16,7 +16,7 @@ constexpr off64_t CAPIO_DEFAULT_FILE_INITIAL_SIZE = 1024L * 1024 * 1024 * 4; constexpr std::array CAPIO_DIR_FORBIDDEN_PATHS = { std::string_view{"/proc/"}, std::string_view{"/sys/"}, std::string_view{"/boot/"}, std::string_view{"/dev/"}, std::string_view{"/var/"}, std::string_view{"/run/"}, - std::string_view("/beegfs/home/msantima/spack/opt/spack/")}; + std::string_view("/spack/")}; // CAPIO default values for shared memory constexpr char CAPIO_DEFAULT_WORKFLOW_NAME[] = "CAPIO"; diff --git a/src/common/capio/filesystem.hpp b/src/common/capio/filesystem.hpp index eafdb1018..14bf1bb22 100644 --- a/src/common/capio/filesystem.hpp +++ b/src/common/capio/filesystem.hpp @@ -51,10 +51,13 @@ inline bool is_prefix(const std::filesystem::path &path_1, const std::filesystem return !relpath.empty() && relpath.native().rfind("..", 0) != 0; } +/* + * Returns true if any of the paths in the list contains any of the forbidden paths. + */ inline bool is_forbidden_path(const std::string_view &path) { return std::any_of(CAPIO_DIR_FORBIDDEN_PATHS.cbegin(), CAPIO_DIR_FORBIDDEN_PATHS.cend(), [&path](const std::string_view &forbidden_path) { - return path.rfind(forbidden_path, 0) == 0; + return path.find(forbidden_path) != std::string_view::npos; }); } From 316ceda12293ead64aa871319df4cfdc530461be Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Mon, 28 Jul 2025 11:18:26 +0000 Subject: [PATCH 9/9] fix --- src/server/client-manager/request_handler_engine.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/client-manager/request_handler_engine.hpp b/src/server/client-manager/request_handler_engine.hpp index 3fa5d5472..9f292e069 100644 --- a/src/server/client-manager/request_handler_engine.hpp +++ b/src/server/client-manager/request_handler_engine.hpp @@ -73,7 +73,7 @@ class RequestHandlerEngine { << "Received invalid code: " << code << std::endl; std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_ERROR << " [ " << node_name << " ] " << "Offending request: " << ptr << " / " << req << std::endl; - ERR_EXIT("Invalid request %d%s", code, ptr); + ERR_EXIT("Invalid request %d:%s", code, ptr); } return code; }