diff --git a/src/common/capio/config.hpp b/src/common/capio/config.hpp new file mode 100644 index 000000000..194fdae87 --- /dev/null +++ b/src/common/capio/config.hpp @@ -0,0 +1,33 @@ +#ifndef CAPIO_CONFIG_HPP +#define CAPIO_CONFIG_HPP +#include "constants.hpp" +#include + +#include + +struct CapioConfig { + std::string CAPIO_APP_NAME = CAPIO_DEFAULT_APP_NAME; + std::string CAPIO_WORKFLOW_NAME = CAPIO_DEFAULT_WORKFLOW_NAME; + std::string CAPIO_DIR = std::getenv("PWD"); + std::string CAPIO_LOG_PREFIX = CAPIO_LOG_POSIX_DEFAULT_LOG_FILE_PREFIX; + std::filesystem::path CAPIO_LOG_DIR = CAPIO_DEFAULT_LOG_FOLDER; + std::filesystem::path CAPIO_METADATA_DIR = CAPIO_DIR; + size_t CAPIO_WRITE_CACHE_SIZE = CAPIO_CACHE_LINE_SIZE_DEFAULT; + size_t CAPIO_CACHE_LINES = CAPIO_CACHE_LINES_DEFAULT; + size_t CAPIO_CACHE_LINE_SIZE = CAPIO_CACHE_LINE_SIZE_DEFAULT; + size_t CAPIO_POSIX_CACHE_LINE_SIZE = CAPIO_CACHE_LINE_SIZE; + int CAPIO_LOG_LEVEL = -1; + bool CAPIO_STORE_ONLY_IN_MEMORY = false; + bool _initialized = false; +}; + +CapioConfig *capio_config; + +void fill_capio_cofiguration() { + auto capio_app_name = std::getenv("CAPIO_APP_NAME"); + auto capio_workflow_name = std::getenv("CAPIO_WORKFLOW_NAME"); + + capio_config->_initialized = true; +} + +#endif // CAPIO_CONFIG_HPP diff --git a/src/common/capio/constants.hpp b/src/common/capio/constants.hpp index 9bac78642..f75d7e5be 100644 --- a/src/common/capio/constants.hpp +++ b/src/common/capio/constants.hpp @@ -150,6 +150,8 @@ constexpr char CAPIO_SERVER_ARG_PARSER_CONFIG_NCONTINUE_ON_ERROR_HELP[] = "specified, and a fatal termination point is reached, the behaviour of capio is undefined and " "should not be taken as valid"; +constexpr char CAPIO_SERVER_ARG_PARSER_REDIS_OPT_HELP[] = "Use redis to store configurations. pass with option
: of redis-server instance"; + constexpr char CAPIO_LOG_SERVER_CLI_CONT_ON_ERR_WARNING[] = "[ \033[1;33m SERVER \033[0m ]\033[1;31m " "|==================================================================|\033[0m\n" diff --git a/src/common/capio/env.hpp b/src/common/capio/env.hpp deleted file mode 100644 index ebc49bf99..000000000 --- a/src/common/capio/env.hpp +++ /dev/null @@ -1,99 +0,0 @@ -#ifndef CAPIO_COMMON_ENV_HPP -#define CAPIO_COMMON_ENV_HPP - -#include -#include -#include -#include -#include - -#include - -#include "logger.hpp" -#include "syscall.hpp" - -inline const std::filesystem::path &get_capio_dir() { - static std::filesystem::path capio_dir{}; - START_LOG(capio_syscall(SYS_gettid), "call()"); - // TODO: if CAPIO_DIR is not set, it should be left as null - - if (capio_dir.empty()) { - const char *val = std::getenv("CAPIO_DIR"); - auto buf = std::unique_ptr(new char[PATH_MAX]); - - if (val == nullptr) { - ERR_EXIT("Fatal: CAPIO_DIR not provided!"); - - } else { - - const char *realpath_res = capio_realpath(val, buf.get()); - if (realpath_res == nullptr) { - ERR_EXIT("error CAPIO_DIR: directory %s does not " - "exist. [buf=%s]", - val, buf.get()); - } - } - capio_dir = std::filesystem::path(buf.get()); - for (auto &forbidden_path : CAPIO_DIR_FORBIDDEN_PATHS) { - if (capio_dir.native().rfind(forbidden_path, 0) == 0) { - ERR_EXIT("CAPIO_DIR inside %s file system is not supported", forbidden_path); - } - } - } - LOG("CAPIO_DIR=%s", capio_dir.c_str()); - - return capio_dir; -} - -inline const std::filesystem::path &get_capio_metadata_path() { - static std::filesystem::path metadata_path{}; - START_LOG(capio_syscall(SYS_gettid), "call()"); - if (metadata_path.empty()) { - const char *val = std::getenv("CAPIO_METADATA_DIR"); - auto buf = std::unique_ptr(new char[PATH_MAX]); - - if (val == nullptr) { - metadata_path = get_capio_dir() / ".capio_metadata"; - } else { - metadata_path = std::filesystem::path(val) / ".capio_metadata"; - } - - if (!std::filesystem::exists(metadata_path)) { - std::filesystem::create_directories(metadata_path); - } - } - LOG("CAPIO_METADATA_DIR=%s", metadata_path.c_str()); - - return metadata_path; -} - -inline int get_capio_log_level() { - static int level = -2; - if (level == -2) { - char *log_level = std::getenv("CAPIO_LOG_LEVEL"); - if (log_level == nullptr) { - level = 0; - } else { - auto [ptr, ec] = std::from_chars(log_level, log_level + strlen(log_level), level); - if (ec != std::errc()) { - level = 0; - } - } - } - return level; -} - -inline std::string get_capio_workflow_name() { - static std::string name; - if (name.empty()) { - auto tmp = std::getenv("CAPIO_WORKFLOW_NAME"); - if (tmp != nullptr) { - name = tmp; - } else { - name = CAPIO_DEFAULT_WORKFLOW_NAME; - } - } - return name; -} - -#endif // CAPIO_COMMON_ENV_HPP diff --git a/src/common/capio/filesystem.hpp b/src/common/capio/filesystem.hpp index bd295df86..2ea5774ec 100644 --- a/src/common/capio/filesystem.hpp +++ b/src/common/capio/filesystem.hpp @@ -10,7 +10,6 @@ #include -#include "env.hpp" #include "logger.hpp" #include "syscall.hpp" @@ -61,7 +60,7 @@ inline bool is_forbidden_path(const std::string_view &path) { inline bool is_capio_dir(const std::filesystem::path &path_to_check) { START_LOG(capio_syscall(SYS_gettid), "call(path_to_check=%s)", path_to_check.c_str()); - const auto res = get_capio_dir().compare(path_to_check) == 0; + const auto res = capio_config->CAPIO_DIR.compare(path_to_check) == 0; LOG("is_capio_dir:%s", res ? "yes" : "no"); return res; } @@ -70,7 +69,7 @@ inline bool is_capio_path(const std::filesystem::path &path_to_check) { START_LOG(capio_syscall(SYS_gettid), "call(path_to_check=%s)", path_to_check.c_str()); // check if path_to_check begins with CAPIO_DIR - const auto res = is_prefix(get_capio_dir(), path_to_check); + const auto res = is_prefix(capio_config->CAPIO_DIR, path_to_check); LOG("is_capio_path:%s", res ? "yes" : "no"); return res; } diff --git a/src/common/capio/logger.hpp b/src/common/capio/logger.hpp index 43534871e..e78435542 100644 --- a/src/common/capio/logger.hpp +++ b/src/common/capio/logger.hpp @@ -10,6 +10,8 @@ #include #include +#include "capio/config.hpp" + #include "constants.hpp" #include "syscall.hpp" @@ -39,8 +41,6 @@ inline thread_local bool logging_syscall = #define CAPIO_MAX_LOG_LEVEL -1 #endif -inline int CAPIO_LOG_LEVEL = CAPIO_MAX_LOG_LEVEL; - #ifndef __CAPIO_POSIX inline auto open_server_logfile() { auto hostname = new char[HOST_NAME_MAX]; @@ -70,39 +70,14 @@ inline auto get_hostname() { return hostname_prefix; } -inline auto get_log_dir() { - static char *posix_log_master_dir_name = nullptr; - if (posix_log_master_dir_name == nullptr) { - posix_log_master_dir_name = std::getenv("CAPIO_LOG_DIR"); - if (posix_log_master_dir_name == nullptr) { - posix_log_master_dir_name = new char[strlen(CAPIO_DEFAULT_LOG_FOLDER)]; - strcpy(posix_log_master_dir_name, CAPIO_DEFAULT_LOG_FOLDER); - } - } - return posix_log_master_dir_name; -} - -inline auto get_log_prefix() { - static char *posix_logfile_prefix = nullptr; - if (posix_logfile_prefix == nullptr) { - posix_logfile_prefix = std::getenv("CAPIO_LOG_PREFIX"); - if (posix_logfile_prefix == nullptr) { - posix_logfile_prefix = new char[strlen(CAPIO_LOG_POSIX_DEFAULT_LOG_FILE_PREFIX)]; - strcpy(posix_logfile_prefix, CAPIO_LOG_POSIX_DEFAULT_LOG_FILE_PREFIX); - } - } - return posix_logfile_prefix; -} - inline auto get_posix_log_dir() { static char *posix_log_dir_path = nullptr; if (posix_log_dir_path == nullptr) { // allocate space for a path in the following structure (including 10 digits for thread id - // max - // log_master_dir_name/posix/hostname/logfile_prefix_.log - auto len = strlen(get_log_dir()) + 7; + // max log_master_dir_name/posix/hostname/logfile_prefix_.log + auto len = strlen(capio_config->CAPIO_LOG_DIR.c_str()) + 7; posix_log_dir_path = new char[len]{0}; - sprintf(posix_log_dir_path, "%s/posix", get_log_dir()); + sprintf(posix_log_dir_path, "%s/posix", capio_config->CAPIO_LOG_DIR.c_str()); } return posix_log_dir_path; } @@ -111,8 +86,7 @@ inline auto get_host_log_dir() { static char *host_log_dir_path = nullptr; if (host_log_dir_path == nullptr) { // allocate space for a path in the following structure (including 10 digits for thread id - // max - // log_master_dir_name/posix/hostname/logfile_prefix_.log + // max log_master_dir_name/posix/hostname/logfile_prefix_.log auto len = strlen(get_posix_log_dir()) + HOST_NAME_MAX; host_log_dir_path = new char[len]{0}; sprintf(host_log_dir_path, "%s/%s", get_posix_log_dir(), get_hostname()); @@ -122,8 +96,8 @@ inline auto get_host_log_dir() { inline void setup_posix_log_filename() { if (logfile_path[0] == '\0') { - sprintf(logfile_path, "%s/%s%ld.log", get_host_log_dir(), get_log_prefix(), - capio_syscall(SYS_gettid)); + sprintf(logfile_path, "%s/%s%ld.log", get_host_log_dir(), + capio_config->CAPIO_LOG_PREFIX.c_str(), capio_syscall(SYS_gettid)); } } #endif @@ -147,7 +121,7 @@ inline void log_write_to(char *buffer, size_t bufflen) { capio_syscall(SYS_write, logfileFD, "\n", 1); } #else - if (current_log_level < CAPIO_LOG_LEVEL || CAPIO_LOG_LEVEL < 0) { + if (current_log_level < capio_config->CAPIO_LOG_LEVEL || capio_config->CAPIO_LOG_LEVEL < 0) { logfile << buffer << std::endl; logfile.flush(); } @@ -191,11 +165,11 @@ class Logger { setup_posix_log_filename(); current_log_level = 0; // reset after clone log level, so to not inherit it #if defined(SYS_mkdir) - capio_syscall(SYS_mkdir, get_log_dir(), 0755); + capio_syscall(SYS_mkdir, capio_config->CAPIO_LOG_DIR.c_str(), 0755); capio_syscall(SYS_mkdir, get_posix_log_dir(), 0755); capio_syscall(SYS_mkdir, get_host_log_dir(), 0755); #elif defined(SYS_mkdirat) - capio_syscall(SYS_mkdirat, AT_FDCWD, get_log_dir(), 0755); + capio_syscall(SYS_mkdirat, AT_FDCWD, capio_config->CAPIO_LOG_DIR.c_str(), 0755); capio_syscall(SYS_mkdirat, AT_FDCWD, get_posix_log_dir(), 0755); capio_syscall(SYS_mkdirat, AT_FDCWD, get_host_log_dir(), 0755); #endif diff --git a/src/common/capio/queue.hpp b/src/common/capio/queue.hpp index 1854657d8..3124716a1 100644 --- a/src/common/capio/queue.hpp +++ b/src/common/capio/queue.hpp @@ -6,7 +6,6 @@ #include -#include "capio/env.hpp" #include "capio/logger.hpp" #include "capio/semaphore.hpp" #include "capio/shm.hpp" @@ -52,7 +51,7 @@ template class Queue { public: Queue(const std::string &shm_name, const long int max_num_elems, const long int elem_size, - const std::string &workflow_name = get_capio_workflow_name(), bool cleanup = true) + const std::string &workflow_name = capio_config->CAPIO_WORKFLOW_NAME, bool cleanup = true) : _max_num_elems(max_num_elems), _elem_size(elem_size), _buff_size(_max_num_elems * _elem_size), _shm_name(workflow_name + "_" + shm_name), _first_elem_name(workflow_name + SHM_FIRST_ELEM + shm_name), diff --git a/src/common/capio/shm.hpp b/src/common/capio/shm.hpp index 3c86741be..1cda4eea7 100644 --- a/src/common/capio/shm.hpp +++ b/src/common/capio/shm.hpp @@ -55,7 +55,7 @@ class CapioShmCanary { explicit CapioShmCanary(std::string capio_workflow_name) : _canary_name(capio_workflow_name) { START_LOG(capio_syscall(SYS_gettid), "call(capio_workflow_name: %s)", _canary_name.data()); if (_canary_name.empty()) { - _canary_name = get_capio_workflow_name(); + _canary_name = capio_config->CAPIO_WORKFLOW_NAME; } _shm_id = shm_open(_canary_name.data(), O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); if (_shm_id == -1) { diff --git a/src/posix/handlers/stat.hpp b/src/posix/handlers/stat.hpp index d16b326b9..b65be9b1d 100644 --- a/src/posix/handlers/stat.hpp +++ b/src/posix/handlers/stat.hpp @@ -3,7 +3,6 @@ #include -#include "capio/env.hpp" #include "utils/common.hpp" #include "utils/filesystem.hpp" diff --git a/src/posix/libcapio_posix.cpp b/src/posix/libcapio_posix.cpp index 93dc776eb..7034d956e 100644 --- a/src/posix/libcapio_posix.cpp +++ b/src/posix/libcapio_posix.cpp @@ -7,6 +7,8 @@ #include #include +#include "capio/config.hpp" + #include "capio/syscall.hpp" #include "utils/clone.hpp" @@ -389,10 +391,6 @@ static int hook(long syscall_number, long arg0, long arg1, long arg2, long arg3, return 1; } -#ifdef CAPIO_LOG - CAPIO_LOG_LEVEL = get_capio_log_level(); -#endif - START_LOG(syscall_no_intercept(SYS_gettid), "call(syscall_number=%ld)", syscall_number); // If the syscall_number is higher than the maximum @@ -413,6 +411,9 @@ static int hook(long syscall_number, long arg0, long arg1, long arg2, long arg3, } static __attribute__((constructor)) void init() { + + capio_config = new CapioConfig(); + init_client(); init_filesystem(); init_threading_support(); diff --git a/src/posix/utils/cache.hpp b/src/posix/utils/cache.hpp index 7c2d6c083..c3f5d06e3 100644 --- a/src/posix/utils/cache.hpp +++ b/src/posix/utils/cache.hpp @@ -1,7 +1,6 @@ #ifndef CAPIO_CACHE_HPP #define CAPIO_CACHE_HPP #include "capio/requests.hpp" -#include "env.hpp" #include "cache/consent_request_cache.hpp" #include "cache/read_request_cache_fs.hpp" diff --git a/src/posix/utils/cache/read_request_cache_mem.hpp b/src/posix/utils/cache/read_request_cache_mem.hpp index a49465ba4..1fce589b6 100644 --- a/src/posix/utils/cache/read_request_cache_mem.hpp +++ b/src/posix/utils/cache/read_request_cache_mem.hpp @@ -59,7 +59,7 @@ class ReadRequestCacheMEM { } public: - explicit ReadRequestCacheMEM(const long line_size = get_posix_read_cache_line_size()) + explicit ReadRequestCacheMEM(const long line_size = capio_config->CAPIO_POSIX_CACHE_LINE_SIZE) : _cache(nullptr), _tid(capio_syscall(SYS_gettid)), _fd(-1), _max_line_size(line_size), _actual_size(0), _cache_offset(0), _last_read_end(-1) { _cache = new char[_max_line_size]; diff --git a/src/posix/utils/cache/write_request_cache_fs.hpp b/src/posix/utils/cache/write_request_cache_fs.hpp index 129cc6197..932ca41ad 100644 --- a/src/posix/utils/cache/write_request_cache_fs.hpp +++ b/src/posix/utils/cache/write_request_cache_fs.hpp @@ -20,7 +20,7 @@ class WriteRequestCacheFS { } public: - explicit WriteRequestCacheFS() : _max_size(get_capio_write_cache_size()) {} + explicit WriteRequestCacheFS() : _max_size(capio_config->CAPIO_WRITE_CACHE_SIZE) {} ~WriteRequestCacheFS() { this->flush(capio_syscall(SYS_gettid)); } diff --git a/src/posix/utils/cache/write_request_cache_mem.hpp b/src/posix/utils/cache/write_request_cache_mem.hpp index 741de6bc7..464bf29e5 100644 --- a/src/posix/utils/cache/write_request_cache_mem.hpp +++ b/src/posix/utils/cache/write_request_cache_mem.hpp @@ -34,7 +34,7 @@ class WriteRequestCacheMEM { } public: - explicit WriteRequestCacheMEM(off64_t line_size = get_cache_line_size()) + explicit WriteRequestCacheMEM(off64_t line_size = capio_config->CAPIO_CACHE_LINE_SIZE) : _cache(nullptr), _tid(capio_syscall(SYS_gettid)), _fd(-1), _max_line_size(line_size), _actual_size(0), _last_write_end(-1), _last_write_begin(0) {} diff --git a/src/posix/utils/clone.hpp b/src/posix/utils/clone.hpp index 306401f98..b5f95c695 100644 --- a/src/posix/utils/clone.hpp +++ b/src/posix/utils/clone.hpp @@ -41,7 +41,7 @@ inline void init_process(pid_t tid) { LOG("Created request response buffer with name: %s", (SHM_COMM_CHAN_NAME_RESP + std::to_string(tid)).c_str()); - const char *capio_app_name = get_capio_app_name(); + const char *capio_app_name = capio_config->CAPIO_APP_NAME.c_str(); auto pid = static_cast(syscall_no_intercept(SYS_gettid)); /** diff --git a/src/posix/utils/env.hpp b/src/posix/utils/env.hpp deleted file mode 100644 index 65b912bd4..000000000 --- a/src/posix/utils/env.hpp +++ /dev/null @@ -1,99 +0,0 @@ -#ifndef CAPIO_POSIX_UTILS_ENV_HPP -#define CAPIO_POSIX_UTILS_ENV_HPP - -#include -#include - -#include "capio/logger.hpp" - -inline const char *get_capio_app_name() { - static char *capio_app_name = std::getenv("CAPIO_APP_NAME"); - - if (capio_app_name == nullptr) { - return CAPIO_DEFAULT_APP_NAME; - } - return capio_app_name; -} - -inline capio_off64_t get_capio_write_cache_size() { - static char *cache_size_str = std::getenv("CAPIO_WRITER_CACHE_SIZE"); - - static capio_off64_t cache_size = cache_size_str == nullptr - ? CAPIO_CACHE_LINE_SIZE_DEFAULT - : std::strtoull(cache_size_str, nullptr, 10); - return cache_size; -} - -inline long get_cache_lines() { - START_LOG(capio_syscall(SYS_gettid), "call()"); - static long data_bufs_size = -1; - if (data_bufs_size == -1) { - LOG("Value not set. getting value"); - char *value = std::getenv("CAPIO_CACHE_LINES"); - if (value != nullptr) { - LOG("Getting value from environment variable"); - data_bufs_size = strtol(value, nullptr, 10); - } else { - LOG("Getting default value"); - data_bufs_size = CAPIO_CACHE_LINES_DEFAULT; - } - } - LOG("data_bufs_size=%ld", data_bufs_size); - return data_bufs_size; -} - -inline long get_cache_line_size() { - START_LOG(capio_syscall(SYS_gettid), "call()"); - static long data_bufs_count = -1; - if (data_bufs_count == -1) { - LOG("Value not set. getting value"); - char *value = std::getenv("CAPIO_CACHE_LINE_SIZE"); - if (value != nullptr) { - LOG("Getting value from environment variable"); - data_bufs_count = strtol(value, nullptr, 10); - } else { - LOG("Getting default value"); - data_bufs_count = CAPIO_CACHE_LINE_SIZE_DEFAULT; - } - } - LOG("data_bufs_count=%ld", data_bufs_count); - return data_bufs_count; -} - -inline long get_posix_read_cache_line_size() { - START_LOG(capio_syscall(SYS_gettid), "call()"); - static long data_bufs_count = -1; - if (data_bufs_count == -1) { - LOG("Value not set. getting value"); - char *value = std::getenv("CAPIO_POSIX_CACHE_LINE_SIZE"); - if (value != nullptr) { - LOG("Getting value from environment variable"); - data_bufs_count = strtol(value, nullptr, 10); - } else { - LOG("Getting default value"); - data_bufs_count = CAPIO_CACHE_LINE_SIZE_DEFAULT; - } - } - LOG("data_bufs_count=%ld", data_bufs_count); - return data_bufs_count; -} - -inline bool store_in_memory_only() { - START_LOG(capio_syscall(SYS_gettid), "call()"); - static bool *store_in_memory = nullptr; - - if (store_in_memory == nullptr) { - store_in_memory = new bool; - char *value = std::getenv("CAPIO_STORE_ONLY_MEMORY"); - if (value != nullptr) { - *store_in_memory = strcmp("ON", value) == 0; - } else { - *store_in_memory = false; - } - } - - LOG("Store files exclusively in memory? %s", *store_in_memory ? "YES" : "NO"); - return *store_in_memory; -} - -#endif // CAPIO_POSIX_UTILS_ENV_HPP diff --git a/src/posix/utils/filesystem.hpp b/src/posix/utils/filesystem.hpp index c2f09b31a..b26dfd9ce 100644 --- a/src/posix/utils/filesystem.hpp +++ b/src/posix/utils/filesystem.hpp @@ -10,7 +10,6 @@ #include -#include "capio/env.hpp" #include "capio/filesystem.hpp" #include "capio/logger.hpp" #include "capio/syscall.hpp" diff --git a/src/posix/utils/requests.hpp b/src/posix/utils/requests.hpp index 28041de17..9803a3ef2 100644 --- a/src/posix/utils/requests.hpp +++ b/src/posix/utils/requests.hpp @@ -5,7 +5,6 @@ #include "capio/requests.hpp" -#include "env.hpp" #include "filesystem.hpp" #include "types.hpp" @@ -45,10 +44,10 @@ inline void handshake_request(const long tid, const long pid, const std::string buf_requests->write(req, CAPIO_REQ_MAX_SIZE); LOG("Sent handshake request"); - cts_queue = new SPSCQueue("queue-" + std::to_string(tid) + ".cts", get_cache_lines(), - get_cache_line_size()); - stc_queue = new SPSCQueue("queue-" + std::to_string(tid) + ".stc", get_cache_lines(), - get_cache_line_size()); + cts_queue = new SPSCQueue("queue-" + std::to_string(tid) + ".cts", + capio_config->CAPIO_CACHE_LINES, capio_config->CAPIO_CACHE_LINE_SIZE); + stc_queue = new SPSCQueue("queue-" + std::to_string(tid) + ".stc", + capio_config->CAPIO_CACHE_LINES, capio_config->CAPIO_CACHE_LINE_SIZE); LOG("Initialized data transfer queues"); } diff --git a/src/server/CMakeLists.txt b/src/server/CMakeLists.txt index 612791f88..ca3ea96bf 100644 --- a/src/server/CMakeLists.txt +++ b/src/server/CMakeLists.txt @@ -26,6 +26,12 @@ FetchContent_Declare( GIT_TAG fbd8aa924b916c6578963af315fdb5f10c3969ad ) +FetchContent_Declare( + hiredis + GIT_REPOSITORY https://github.com/redis/hiredis.git + GIT_TAG 60e5075d4ac77424809f855ba3e398df7aacefe8 +) + ##################################### # Add MTCL dependencies ##################################### @@ -47,7 +53,7 @@ FetchContent_Declare( # message(STATUS "Warning: MPI has not been found, and as such it will not be an available MTCL backend.") #endif () -FetchContent_MakeAvailable(args simdjson mtcl) +FetchContent_MakeAvailable(args simdjson mtcl hiredis) ##################################### # Target definition @@ -68,12 +74,13 @@ target_include_directories(${TARGET_NAME} PRIVATE ${args_SOURCE_DIR} ${simdjson_SOURCE_DIR} ${mtcl_SOURCE_DIR}/include + ${hiredis_SOURCE_DIR} ) ##################################### # Link libraries ##################################### -target_link_libraries(${TARGET_NAME} PRIVATE ${MPI_LIBRARIES} pthread rt stdc++fs) +target_link_libraries(${TARGET_NAME} PRIVATE ${MPI_LIBRARIES} pthread rt stdc++fs hiredis) ##################################### # Install rules diff --git a/src/server/capio-cl-engine/capio_cl_engine.hpp b/src/server/capio-cl-engine/capio_cl_engine.hpp index 0cda7f548..17b6cd2d0 100644 --- a/src/server/capio-cl-engine/capio_cl_engine.hpp +++ b/src/server/capio-cl-engine/capio_cl_engine.hpp @@ -124,15 +124,15 @@ class CapioCLEngine { static bool fileToBeHandled(std::filesystem::path::iterator::reference path) { START_LOG(gettid(), "call(path=%s)", path.c_str()); - if (path == get_capio_dir()) { + if (path == capio_config->CAPIO_DIR) { LOG("Path is capio_dir. Ignoring."); return false; } LOG("Parent path=%s", path.parent_path().c_str()); LOG("Path %s be handled by CAPIO", - path.parent_path().string().rfind(get_capio_dir(), 0) == 0 ? "SHOULD" : "SHOULD NOT"); - return path.parent_path().string().rfind(get_capio_dir(), 0) == 0; + path.parent_path().string().rfind(capio_config->CAPIO_DIR, 0) == 0 ? "SHOULD" : "SHOULD NOT"); + return path.parent_path().string().rfind(capio_config->CAPIO_DIR, 0) == 0; }; /** diff --git a/src/server/capio-cl-engine/json_parser.hpp b/src/server/capio-cl-engine/json_parser.hpp index e52bff5e9..b19dd2c64 100644 --- a/src/server/capio-cl-engine/json_parser.hpp +++ b/src/server/capio-cl-engine/json_parser.hpp @@ -50,12 +50,11 @@ class JsonParser { */ static CapioCLEngine *parse(const std::filesystem::path &source) { auto locations = new CapioCLEngine(); - const auto &capio_dir = get_capio_dir(); + const auto &capio_dir = capio_config->CAPIO_DIR.c_str(); - START_LOG(gettid(), "call(config_file='%s', capio_dir='%s')", source.c_str(), - capio_dir.c_str()); + START_LOG(gettid(), "call(config_file='%s', capio_dir='%s')", source.c_str(), capio_dir); - locations->newFile(get_capio_dir()); + locations->newFile(capio_config->CAPIO_DIR); if (source.empty()) { return locations; } @@ -112,7 +111,8 @@ class JsonParser { std::filesystem::path file(itm.get_string().take_value()); std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name << " ] " << "Found file : " << file << std::endl; - if (file.is_relative() || first_is_subpath_of_second(file, get_capio_dir())) { + if (file.is_relative() || + first_is_subpath_of_second(file, capio_config->CAPIO_DIR)) { std::string appname(app_name); std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name << " ] " << "File : " << file << " added to app: " << app_name @@ -143,7 +143,8 @@ class JsonParser { } else { for (auto itm : output_stream) { std::filesystem::path file(itm.get_string().take_value()); - if (file.is_relative() || first_is_subpath_of_second(file, get_capio_dir())) { + if (file.is_relative() || + first_is_subpath_of_second(file, capio_config->CAPIO_DIR)) { std::string appname(app_name); std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name << " ] " << "Adding file: " << file << " to app: " << app_name @@ -195,7 +196,7 @@ class JsonParser { LOG("Found name: %s", std::string(elem).c_str()); std::filesystem::path file_fs(elem); if (file_fs.is_relative() || - first_is_subpath_of_second(file_fs, get_capio_dir())) { + first_is_subpath_of_second(file_fs, capio_config->CAPIO_DIR)) { LOG("Saving file %s to locations", std::string(elem).c_str()); streaming_names.emplace_back(elem); } @@ -250,7 +251,8 @@ class JsonParser { name_tmp = itm.get_string().value(); std::filesystem::path computed_path(name_tmp); computed_path = computed_path.is_relative() - ? (get_capio_dir() / computed_path) + ? (std::filesystem::path(capio_config->CAPIO_DIR) / + computed_path) : computed_path; std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name << " ] " @@ -340,7 +342,7 @@ class JsonParser { path = (capio_dir / path).lexically_normal(); } // TODO: check for globs - if (first_is_subpath_of_second(path, get_capio_dir())) { + if (first_is_subpath_of_second(path, capio_config->CAPIO_DIR)) { locations->setPermanent(name.data(), true); } } @@ -370,7 +372,7 @@ class JsonParser { path = (capio_dir / path).lexically_normal(); } // TODO: check for globs - if (first_is_subpath_of_second(path, get_capio_dir())) { + if (first_is_subpath_of_second(path, capio_config->CAPIO_DIR)) { locations->setExclude(name.data(), true); } } diff --git a/src/server/capio_server.cpp b/src/server/capio_server.cpp index bfe86594d..0145eb06d 100644 --- a/src/server/capio_server.cpp +++ b/src/server/capio_server.cpp @@ -23,9 +23,11 @@ std::string workflow_name; char node_name[HOST_NAME_MAX]; +#include "capio/config.hpp" + +#include "utils/redis.hpp" #include "utils/types.hpp" -#include "capio/env.hpp" #include "capio/logger.hpp" #include "capio/semaphore.hpp" @@ -65,6 +67,9 @@ std::string parseCLI(int argc, char **argv) { args::ValueFlag backend_port(arguments, "port", CAPIO_SERVER_ARG_PARSER_BACKEND_PORT_OPT_HELP, {'p', "port"}); + args::ValueFlag redis(arguments, "server:port", + CAPIO_SERVER_ARG_PARSER_REDIS_OPT_HELP, {"use-redis"}); + args::Flag continueOnErrorFlag(arguments, "continue-on-error", CAPIO_SERVER_ARG_PARSER_CONFIG_NCONTINUE_ON_ERROR_HELP, {"continue-on-error"}); @@ -84,6 +89,14 @@ std::string parseCLI(int argc, char **argv) { exit(EXIT_FAILURE); } + if (redis) { + use_redis = true; + auto endpoint = args::get(redis); + auto ip = endpoint.substr(0, endpoint.find(":")); + auto port = std::stoi(endpoint.substr(endpoint.find(":") + 1, endpoint.size())); + redis_connector = new RedisConnector(ip, port); + } + if (continueOnErrorFlag) { #ifdef CAPIO_LOG continue_on_error = true; @@ -134,12 +147,11 @@ std::string parseCLI(int argc, char **argv) { << "parsing config file: " << token << std::endl; // TODO: pass config file path } else if (noConfigFile) { - workflow_name = std::string_view(get_capio_workflow_name()); + workflow_name = std::string_view(capio_config->CAPIO_WORKFLOW_NAME); std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_WARNING << " [ " << node_name << " ] " << "skipping config file parsing." << std::endl << CAPIO_LOG_SERVER_CLI_LEVEL_WARNING << " [ " << node_name << " ] " - << "Obtained from environment variable current workflow name: " - << workflow_name.data() << std::endl; + << "Obtained current workflow name: " << workflow_name.data() << std::endl; } else { std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_ERROR << " [ " << node_name << " ] " @@ -152,14 +164,13 @@ std::string parseCLI(int argc, char **argv) { } std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_INFO << " [ " << node_name << " ] " - << "CAPIO_DIR=" << get_capio_dir().c_str() << std::endl; + << "CAPIO_DIR=" << capio_config->CAPIO_DIR << std::endl; #ifdef CAPIO_LOG - CAPIO_LOG_LEVEL = get_capio_log_level(); std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_INFO << " [ " << node_name << " ] " - << "LOG_LEVEL set to: " << CAPIO_LOG_LEVEL << std::endl; + << "LOG_LEVEL set to: " << capio_config->CAPIO_LOG_LEVEL << std::endl; std::cout << CAPIO_LOG_SERVER_CLI_LOGGING_ENABLED_WARNING; - log->log("LOG_LEVEL set to: %d", CAPIO_LOG_LEVEL); + log->log("LOG_LEVEL set to: %d", capio_config->CAPIO_LOG_LEVEL); delete log; #else if (std::getenv("CAPIO_LOG_LEVEL") != nullptr) { @@ -218,6 +229,7 @@ int main(int argc, char **argv) { std::cout << CAPIO_LOG_SERVER_BANNER; gethostname(node_name, HOST_NAME_MAX); + capio_config = new CapioConfig(); const std::string config_path = parseCLI(argc, argv); START_LOG(gettid(), "call()"); diff --git a/src/server/client-manager/request_handler_engine.hpp b/src/server/client-manager/request_handler_engine.hpp index fc96a0857..97c828617 100644 --- a/src/server/client-manager/request_handler_engine.hpp +++ b/src/server/client-manager/request_handler_engine.hpp @@ -1,6 +1,8 @@ #ifndef CAPIO_CL_ENGINE_MAIN_HPP #define CAPIO_CL_ENGINE_MAIN_HPP +#include + #include "capio-cl-engine/capio_cl_engine.hpp" #include "capio-cl-engine/json_parser.hpp" #include "capio/requests.hpp" diff --git a/src/server/file-manager/file_manager_impl.hpp b/src/server/file-manager/file_manager_impl.hpp index 362ef5360..b408bfa22 100644 --- a/src/server/file-manager/file_manager_impl.hpp +++ b/src/server/file-manager/file_manager_impl.hpp @@ -1,6 +1,6 @@ #ifndef FILE_MANAGER_HPP #define FILE_MANAGER_HPP -#include "capio/env.hpp" + #include "client-manager/client_manager.hpp" #include "file_manager.hpp" #include "storage-service/capio_storage_service.hpp" @@ -20,7 +20,8 @@ inline std::string CapioFileManager::getAndCreateMetadataPath(const std::string static std::unordered_map metadata_paths; if (metadata_paths.find(path) == metadata_paths.end()) { std::filesystem::path result = - get_capio_metadata_path() / (path.substr(path.find(get_capio_dir()) + 1) + ".capio"); + std::filesystem::path(capio_config->CAPIO_METADATA_DIR) / + (path.substr(path.find(capio_config->CAPIO_DIR) + 1) + ".capio"); metadata_paths.emplace(path, result); LOG("Creating metadata directory (%s)", result.parent_path().c_str()); std::filesystem::create_directories(result.parent_path()); diff --git a/src/server/storage-service/capio_storage_service.hpp b/src/server/storage-service/capio_storage_service.hpp index d9d34a9e8..812ba1028 100644 --- a/src/server/storage-service/capio_storage_service.hpp +++ b/src/server/storage-service/capio_storage_service.hpp @@ -1,7 +1,6 @@ #ifndef CAPIO_STORAGE_SERVICE_H #define CAPIO_STORAGE_SERVICE_H -#include "../../posix/utils/env.hpp" #include "CapioFile/CapioFile.hpp" #include "CapioFile/CapioMemoryFile.hpp" @@ -114,11 +113,13 @@ class CapioStorageService { void register_client(const std::string &app_name, const pid_t pid) const { START_LOG(gettid(), "call(app_name=%s)", app_name.c_str()); _client_to_server_queue->emplace( - pid, new SPSCQueue("queue-" + std::to_string(pid) + +".cts", CAPIO_MAX_SPSQUEUE_ELEMS, - CAPIO_MAX_SPSCQUEUE_ELEM_SIZE, get_capio_workflow_name(), false)); + pid, + new SPSCQueue("queue-" + std::to_string(pid) + +".cts", CAPIO_MAX_SPSQUEUE_ELEMS, + CAPIO_MAX_SPSCQUEUE_ELEM_SIZE, capio_config->CAPIO_WORKFLOW_NAME, false)); _server_to_clien_queue->emplace( - pid, new SPSCQueue("queue-" + std::to_string(pid) + +".stc", CAPIO_MAX_SPSQUEUE_ELEMS, - CAPIO_MAX_SPSCQUEUE_ELEM_SIZE, get_capio_workflow_name(), false)); + pid, + new SPSCQueue("queue-" + std::to_string(pid) + +".stc", CAPIO_MAX_SPSQUEUE_ELEMS, + CAPIO_MAX_SPSCQUEUE_ELEM_SIZE, capio_config->CAPIO_WORKFLOW_NAME, false)); LOG("Created communication queues"); } diff --git a/src/server/utils/redis.hpp b/src/server/utils/redis.hpp new file mode 100644 index 000000000..5ededa8e8 --- /dev/null +++ b/src/server/utils/redis.hpp @@ -0,0 +1,76 @@ +#ifndef REDIS_HPP +#define REDIS_HPP + +bool use_redis = false; + +#include "capio/logger.hpp" + +#include + +class RedisConnector { + + redisContext *context; + + std::string get_key(const std::string &key) const { + if (const redisReply *reply = + static_cast(redisCommand(context, "GET %s", key.c_str())); + reply != nullptr && reply->type == REDIS_REPLY_STRING) { + return reply->str; + } + return ""; + } + + public: + RedisConnector(const std::string &address, const int port) { + START_LOG(gettid(), "call(addr=%s, port=%ld)", address.c_str(), port); + std::cout << CAPIO_SERVER_CLI_LOG_SERVER_WARNING << " [ " << node_name << " ] " + << "RedisConnector: connecting to " << address << ":" << port << std::endl; + + context = redisConnect(address.c_str(), port); + if (context == NULL || context->err) { + if (context) { + ERR_EXIT("Redis connect error: %s\n", context->errstr); + } else { + ERR_EXIT("Can't allocate redis context\n"); + } + } + + std::cout << CAPIO_SERVER_CLI_LOG_SERVER << " [ " << node_name << " ] " + << "RedisConnector initialization completed." << std::endl; + }; + + ~RedisConnector() { redisFree(context); } + + std::filesystem::path get_capio_dir() const { + START_LOG(gettid(), "call()"); + return get_key("CAPIO_DIR"); + } + + std::string get_workflow_name() const { + START_LOG(gettid(), "call()"); + if (auto name = get_key("WORKFLOW_NAME"); !name.empty()) { + return name; + } + return CAPIO_DEFAULT_WORKFLOW_NAME; + } + + std::string get_log_level() const { + START_LOG(gettid(), "call()"); + if (auto level = get_key("CAPIO_LOG_LEVEL"); !level.empty()) { + return level; + } + return "-1"; + } + + std::filesystem::path get_metadata_path() const { + START_LOG(gettid(), "call()"); + if (auto path = get_key("CAPIO_METADATA_DIR"); !path.empty()) { + return path; + } + return get_capio_dir() / ".capio_metadata"; + } +}; + +RedisConnector *redis_connector; + +#endif // REDIS_HPP diff --git a/tests/multinode/backend/src/main.cpp b/tests/multinode/backend/src/main.cpp index 85422f163..e1f458816 100644 --- a/tests/multinode/backend/src/main.cpp +++ b/tests/multinode/backend/src/main.cpp @@ -8,5 +8,7 @@ std::string node_name; int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); + capio_config = new CapioConfig(); + return RUN_ALL_TESTS(); } diff --git a/tests/unit/posix/src/realpath.cpp b/tests/unit/posix/src/realpath.cpp index cfa38e8ae..bf2db4db6 100644 --- a/tests/unit/posix/src/realpath.cpp +++ b/tests/unit/posix/src/realpath.cpp @@ -4,17 +4,22 @@ #include +#include + #include "utils/filesystem.hpp" class RealpathPosixTest : public testing::Test { protected: - static void SetUpTestSuite() { init_filesystem(); } + static void SetUpTestSuite() { + capio_config = new CapioConfig(); + init_filesystem(); + } static void TearDownTestSuite() { destroy_filesystem(); } }; TEST_F(RealpathPosixTest, TestAbsolutePathsInCapioDirWhenPathExists) { - const std::filesystem::path PATHNAME = get_capio_dir() / "test"; + const std::filesystem::path PATHNAME = std::filesystem::path(capio_config->CAPIO_DIR) / "test"; EXPECT_NE(mkdir(PATHNAME.c_str(), S_IRWXU), -1); EXPECT_EQ(access(PATHNAME.c_str(), F_OK), 0); EXPECT_EQ(capio_posix_realpath(PATHNAME), PATHNAME); @@ -23,7 +28,7 @@ TEST_F(RealpathPosixTest, TestAbsolutePathsInCapioDirWhenPathExists) { } TEST_F(RealpathPosixTest, TestAbsolutePathsInCapioDirWhenPathDoesNotExist) { - const std::filesystem::path PATHNAME = get_capio_dir() / "test"; + const std::filesystem::path PATHNAME = std::filesystem::path(capio_config->CAPIO_DIR) / "test"; EXPECT_EQ(capio_posix_realpath(PATHNAME), PATHNAME); } @@ -42,7 +47,7 @@ TEST_F(RealpathPosixTest, TestAbsolutePathOutsideCapioDirWhenPathDoesNotExist) { } TEST_F(RealpathPosixTest, TestRelativePathsInCapioDirWhenCwdIsCapioDir) { - const std::filesystem::path &capio_dir = get_capio_dir(); + const std::filesystem::path &capio_dir = std::filesystem::path(capio_config->CAPIO_DIR); const std::filesystem::path PATHNAME = capio_dir / "test"; set_current_dir(capio_dir); EXPECT_NE(mkdir(PATHNAME.c_str(), S_IRWXU), -1); @@ -53,7 +58,7 @@ TEST_F(RealpathPosixTest, TestRelativePathsInCapioDirWhenCwdIsCapioDir) { } TEST_F(RealpathPosixTest, TestRelativePathsInCapioDirWhenCwdIsParentOfCapioDir) { - const std::filesystem::path &capio_dir = get_capio_dir(); + const std::filesystem::path &capio_dir = std::filesystem::path(capio_config->CAPIO_DIR); const std::filesystem::path PATHNAME = capio_dir / "test"; set_current_dir(capio_dir.parent_path()); EXPECT_NE(mkdir(PATHNAME.c_str(), S_IRWXU), -1); diff --git a/tests/unit/server/src/CapioCacheSPSCQueueTests.hpp b/tests/unit/server/src/CapioCacheSPSCQueueTests.hpp index 4a61a4de6..9d3890ef4 100644 --- a/tests/unit/server/src/CapioCacheSPSCQueueTests.hpp +++ b/tests/unit/server/src/CapioCacheSPSCQueueTests.hpp @@ -1,7 +1,9 @@ #ifndef CAPIOCACHESPSCQUEUETESTS_HPP #define CAPIOCACHESPSCQUEUETESTS_HPP -#include "../posix/utils/env.hpp" +#include + +#include "../common/capio/config.hpp" #include "../posix/utils/filesystem.hpp" #include "../posix/utils/types.hpp" #include "storage-service/CapioFile/CapioMemoryFile.hpp" @@ -25,8 +27,10 @@ void init_server_data_structures() { bufs_response = new CPBufResponse_t; files = new CPFiles_t(); capio_files_descriptors = new CPFileDescriptors_t(); - cts_queue = new SPSCQueue("queue-tests.cts", get_cache_lines(), get_cache_line_size()); - stc_queue = new SPSCQueue("queue-tests.stc", get_cache_lines(), get_cache_line_size()); + cts_queue = new SPSCQueue("queue-tests.cts", capio_config->CAPIO_CACHE_LINES, + capio_config->CAPIO_CACHE_LINE_SIZE); + stc_queue = new SPSCQueue("queue-tests.stc", capio_config->CAPIO_CACHE_LINES, + capio_config->CAPIO_CACHE_LINE_SIZE); buf_requests = new CircularBuffer(SHM_COMM_CHAN_NAME, CAPIO_REQ_BUFF_CNT, CAPIO_REQ_MAX_SIZE); diff --git a/tests/unit/server/src/main.cpp b/tests/unit/server/src/main.cpp index b3c3f3534..d10208f1c 100644 --- a/tests/unit/server/src/main.cpp +++ b/tests/unit/server/src/main.cpp @@ -9,5 +9,7 @@ std::string node_name; int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); + capio_config = new CapioConfig(); + return RUN_ALL_TESTS(); } diff --git a/tests/unit/syscall/src/main.cpp b/tests/unit/syscall/src/main.cpp index 954fb51aa..db8c3782e 100644 --- a/tests/unit/syscall/src/main.cpp +++ b/tests/unit/syscall/src/main.cpp @@ -1,3 +1,5 @@ +#include "capio/config.hpp" + #include char **build_args() { @@ -43,7 +45,7 @@ class CapioServerEnvironment : public testing::Environment { public: explicit CapioServerEnvironment(char **envp) - : args(build_args()), envp(build_env(envp)), server_pid(-1){}; + : args(build_args()), envp(build_env(envp)), server_pid(-1) {}; ~CapioServerEnvironment() override { for (int i = 0; args[i] != nullptr; i++) { @@ -83,5 +85,7 @@ int main(int argc, char **argv, char **envp) { testing::InitGoogleTest(&argc, argv); testing::AddGlobalTestEnvironment(new CapioServerEnvironment(envp)); + capio_config = new CapioConfig(); + return RUN_ALL_TESTS(); }