From efd659a4cbe9ba8864a07958908a0a745304bcfa Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Wed, 9 Apr 2025 11:43:14 +0200 Subject: [PATCH 01/33] Fixed mechanism to send memory storage regex --- src/posix/utils/requests.hpp | 6 +++--- src/server/capio-cl-engine/capio_cl_engine.hpp | 10 ++++------ src/server/storage-service/capio_storage_service.hpp | 8 +++++--- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/posix/utils/requests.hpp b/src/posix/utils/requests.hpp index 97b236236..70134e6e7 100644 --- a/src/posix/utils/requests.hpp +++ b/src/posix/utils/requests.hpp @@ -65,9 +65,9 @@ inline std::vector *file_in_memory_request(const long pid) { LOG("Need to read %llu files from data queues", files_to_read_from_queue); const auto regex_vector = new std::vector; for (int i = 0; i < files_to_read_from_queue; i++) { - LOG("Reading %d file", i); - auto file = new char[CAPIO_MAX_SPSCQUEUE_ELEM_SIZE]{}; - stc_queue->read(file, CAPIO_MAX_SPSCQUEUE_ELEM_SIZE); + LOG("Reading file number %d", i); + auto file = new char[PATH_MAX]{}; + stc_queue->read(file, PATH_MAX); LOG("Obtained path %s", file); regex_vector->emplace_back(generateCapioRegex(file)); delete[] file; diff --git a/src/server/capio-cl-engine/capio_cl_engine.hpp b/src/server/capio-cl-engine/capio_cl_engine.hpp index 0cda7f548..9aaac8517 100644 --- a/src/server/capio-cl-engine/capio_cl_engine.hpp +++ b/src/server/capio-cl-engine/capio_cl_engine.hpp @@ -403,15 +403,13 @@ class CapioCLEngine { } void setStoreFileInMemory(const std::filesystem::path &path) { - if (const auto itm = _locations.find(path); itm != _locations.end()) { - std::get<11>(itm->second) = true; - } + this->newFile(path); + std::get<11>(_locations.at(path)) = true; } void setStoreFileInFileSystem(const std::filesystem::path &path) { - if (const auto itm = _locations.find(path); itm != _locations.end()) { - std::get<11>(itm->second) = false; - } + this->newFile(path); + std::get<11>(_locations.at(path)) = false; } bool storeFileInMemory(const std::filesystem::path &path) { diff --git a/src/server/storage-service/capio_storage_service.hpp b/src/server/storage-service/capio_storage_service.hpp index d9d34a9e8..5d304c084 100644 --- a/src/server/storage-service/capio_storage_service.hpp +++ b/src/server/storage-service/capio_storage_service.hpp @@ -115,10 +115,10 @@ class CapioStorageService { 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)); + CAPIO_MAX_SPSCQUEUE_ELEM_SIZE, 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)); + CAPIO_MAX_SPSCQUEUE_ELEM_SIZE, workflow_name, false)); LOG("Created communication queues"); } @@ -168,7 +168,9 @@ class CapioStorageService { auto files_to_store_in_mem = capio_cl_engine->getFileToStoreInMemory(); for (const auto &file : files_to_store_in_mem) { LOG("Sending file %s", file.c_str()); - _server_to_clien_queue->at(pid)->write(file.c_str()); + char f[PATH_MAX+1]{0}; + memcpy(f, file.c_str(), file.size()); + _server_to_clien_queue->at(pid)->write(f, PATH_MAX); } LOG("Return value=%llu", files_to_store_in_mem.size()); From 498bda5818bc448608d546811f140003c885bfd7 Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Thu, 10 Apr 2025 16:33:43 +0200 Subject: [PATCH 02/33] Fixed mechanism to send memory storage regex --- src/posix/handlers/write.hpp | 4 ++-- src/posix/utils/cache/write_request_cache_mem.hpp | 2 +- src/server/storage-service/capio_storage_service.hpp | 7 ++++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/posix/handlers/write.hpp b/src/posix/handlers/write.hpp index 18769c179..92c60ee72 100644 --- a/src/posix/handlers/write.hpp +++ b/src/posix/handlers/write.hpp @@ -13,9 +13,9 @@ inline off64_t capio_write_fs(int fd, capio_off64_t count, pid_t tid) { } inline off64_t capio_write_mem(int fd, char *buffer, capio_off64_t count, pid_t tid) { - START_LOG(tid, "call(fd=%d, count=%ld)", fd, count); - return 0; + write_request_cache_mem->write(fd, buffer, count); + return CAPIO_POSIX_SYSCALL_SUCCESS; } #if defined(SYS_write) diff --git a/src/posix/utils/cache/write_request_cache_mem.hpp b/src/posix/utils/cache/write_request_cache_mem.hpp index 741de6bc7..926ca48bd 100644 --- a/src/posix/utils/cache/write_request_cache_mem.hpp +++ b/src/posix/utils/cache/write_request_cache_mem.hpp @@ -41,7 +41,7 @@ class WriteRequestCacheMEM { void flush() { START_LOG(capio_syscall(SYS_gettid), "call()"); if (_actual_size != 0) { - write_request(_fd, _actual_size, get_capio_fd_path(_fd).c_str(), _last_write_begin); + write_request(_actual_size, _tid, get_capio_fd_path(_fd).c_str(), _last_write_begin); _cache = nullptr; _actual_size = 0; } diff --git a/src/server/storage-service/capio_storage_service.hpp b/src/server/storage-service/capio_storage_service.hpp index 5d304c084..ccd58f9df 100644 --- a/src/server/storage-service/capio_storage_service.hpp +++ b/src/server/storage-service/capio_storage_service.hpp @@ -148,8 +148,9 @@ class CapioStorageService { off64_t size) const { START_LOG(gettid(), "call(tid=%d, file=%s, offset=%lld, size=%lld)", tid, file.c_str(), offset, size); - - getFile(file)->readFromQueue(*_client_to_server_queue->at(tid), offset, size); + const auto f = getFile(file); + const auto queue = _client_to_server_queue->at(tid); + f->readFromQueue(*queue, offset, size); } void remove_client(const pid_t pid) const { @@ -168,7 +169,7 @@ class CapioStorageService { auto files_to_store_in_mem = capio_cl_engine->getFileToStoreInMemory(); for (const auto &file : files_to_store_in_mem) { LOG("Sending file %s", file.c_str()); - char f[PATH_MAX+1]{0}; + char f[PATH_MAX + 1]{0}; memcpy(f, file.c_str(), file.size()); _server_to_clien_queue->at(pid)->write(f, PATH_MAX); } From b8fd13cb4bf8517ac195e66362dc861913e66ed1 Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Thu, 24 Apr 2025 09:47:26 +0000 Subject: [PATCH 03/33] Added flag to store everything in memory --- src/common/capio/constants.hpp | 3 +++ src/server/capio_server.cpp | 11 ++++++++++- src/server/storage-service/CapioFile/CapioFile.hpp | 2 ++ .../storage-service/capio_storage_service.hpp | 14 +++++++++++++- 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/common/capio/constants.hpp b/src/common/capio/constants.hpp index 9bac78642..75b35d71c 100644 --- a/src/common/capio/constants.hpp +++ b/src/common/capio/constants.hpp @@ -144,6 +144,9 @@ constexpr char CAPIO_SERVER_ARG_PARSER_BACKEND_PORT_OPT_HELP[] = "A valid PORT for the Communication backend"; constexpr char CAPIO_SERVER_ARG_PARSER_CONFIG_NO_CONF_FILE_HELP[] = "If specified, server application will start without a config file, using default settings."; +constexpr char CAPIO_SERVER_ARG_PARSER_MEM_STORAGE_ONLY_HELP[] = + "If set, all files will be stored inside the home node server memory and never on file system " + "(unless memory limit is reached, or server instance terminates)."; constexpr char CAPIO_SERVER_ARG_PARSER_CONFIG_NCONTINUE_ON_ERROR_HELP[] = "If specified, Capio will try to continue its execution to continue even if it has reached a " "fatal termination point. This flag should be used only to debug capio. If this flag is " diff --git a/src/server/capio_server.cpp b/src/server/capio_server.cpp index bfe86594d..1a6a4c9eb 100644 --- a/src/server/capio_server.cpp +++ b/src/server/capio_server.cpp @@ -66,9 +66,12 @@ std::string parseCLI(int argc, char **argv) { CAPIO_SERVER_ARG_PARSER_BACKEND_PORT_OPT_HELP, {'p', "port"}); args::Flag continueOnErrorFlag(arguments, "continue-on-error", - CAPIO_SERVER_ARG_PARSER_CONFIG_NCONTINUE_ON_ERROR_HELP, + CAPIO_SERVER_ARG_PARSER_MEM_STORAGE_ONLY_HELP, {"continue-on-error"}); + args::Flag memStorageOnly(arguments, "mem-storage-only", + CAPIO_SERVER_ARG_PARSER_CONFIG_NCONTINUE_ON_ERROR_HELP, {"mem-only"}); + try { parser.ParseCLI(argc, argv); } catch (args::Help &) { @@ -96,6 +99,12 @@ std::string parseCLI(int argc, char **argv) { #endif } + if (memStorageOnly) { + StoreOnlyInMemory = true; + std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_INFO << " [ " << node_name << " ] " + << "All files will be stored in memory whenever possible." << std::endl; + } + if (logfile_folder) { #ifdef CAPIO_LOG log_master_dir_name = args::get(logfile_folder); diff --git a/src/server/storage-service/CapioFile/CapioFile.hpp b/src/server/storage-service/CapioFile/CapioFile.hpp index 3eac56b38..c2ecb36fc 100644 --- a/src/server/storage-service/CapioFile/CapioFile.hpp +++ b/src/server/storage-service/CapioFile/CapioFile.hpp @@ -1,6 +1,8 @@ #ifndef CAPIOFILE_HPP #define CAPIOFILE_HPP +inline bool StoreOnlyInMemory = false; + class CapioFile { protected: const std::string fileName; diff --git a/src/server/storage-service/capio_storage_service.hpp b/src/server/storage-service/capio_storage_service.hpp index ccd58f9df..a48c33044 100644 --- a/src/server/storage-service/capio_storage_service.hpp +++ b/src/server/storage-service/capio_storage_service.hpp @@ -148,7 +148,7 @@ class CapioStorageService { off64_t size) const { START_LOG(gettid(), "call(tid=%d, file=%s, offset=%lld, size=%lld)", tid, file.c_str(), offset, size); - const auto f = getFile(file); + const auto f = getFile(file); const auto queue = _client_to_server_queue->at(tid); f->readFromQueue(*queue, offset, size); } @@ -166,6 +166,18 @@ class CapioStorageService { */ [[nodiscard]] size_t sendFilesToStoreInMemory(const long pid) const { START_LOG(gettid(), "call(pid=%d)", pid); + + if (StoreOnlyInMemory) { + LOG("All files should be handled in memory. sending * wildcard"); + char f[PATH_MAX + 1]{0}; + auto c_dir = get_capio_dir().string(); + memcpy(f, c_dir.c_str(), c_dir.length()); + memcpy(f + c_dir.size(), "/*", 2); + _server_to_clien_queue->at(pid)->write(f, PATH_MAX); + LOG("Return value=%llu", 1); + return 1; + } + auto files_to_store_in_mem = capio_cl_engine->getFileToStoreInMemory(); for (const auto &file : files_to_store_in_mem) { LOG("Sending file %s", file.c_str()); From bf1d4ba1698b0ab85b98ec81a85e9d8413979217 Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Thu, 24 Apr 2025 10:32:06 +0000 Subject: [PATCH 04/33] Added request for memory file in init_client() --- src/posix/utils/clone.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/posix/utils/clone.hpp b/src/posix/utils/clone.hpp index 0795c8c0d..76393620d 100644 --- a/src/posix/utils/clone.hpp +++ b/src/posix/utils/clone.hpp @@ -54,6 +54,11 @@ inline void init_process(pid_t tid) { */ handshake_request(tid, pid, capio_app_name); + /* + * Request which files need to be handled in memory instead of file system + */ + file_in_memory_request(tid); + syscall_no_intercept_flag = false; } From a59f2b97c0e32f1d35b18bb497b8742b6600556e Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Fri, 25 Apr 2025 08:37:24 +0000 Subject: [PATCH 05/33] fixed an issue in return value for posix in memory write handler, and fixed an issue for initialization of map of files to handle in memory --- src/posix/handlers/write.hpp | 4 +++- src/posix/utils/clone.hpp | 2 +- src/server/capio_server.cpp | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/posix/handlers/write.hpp b/src/posix/handlers/write.hpp index 92c60ee72..c0c57faae 100644 --- a/src/posix/handlers/write.hpp +++ b/src/posix/handlers/write.hpp @@ -15,7 +15,7 @@ inline off64_t capio_write_fs(int fd, capio_off64_t count, pid_t tid) { inline off64_t capio_write_mem(int fd, char *buffer, capio_off64_t count, pid_t tid) { START_LOG(tid, "call(fd=%d, count=%ld)", fd, count); write_request_cache_mem->write(fd, buffer, count); - return CAPIO_POSIX_SYSCALL_SUCCESS; + return count; } #if defined(SYS_write) @@ -34,6 +34,8 @@ int write_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long ar ? capio_write_mem(fd, buffer, count, tid) : capio_write_fs(fd, count, tid); + LOG("Write result: %ld", write_result); + return posix_return_value(write_result, result); } #endif // SYS_write diff --git a/src/posix/utils/clone.hpp b/src/posix/utils/clone.hpp index 76393620d..c4ba9554b 100644 --- a/src/posix/utils/clone.hpp +++ b/src/posix/utils/clone.hpp @@ -57,7 +57,7 @@ inline void init_process(pid_t tid) { /* * Request which files need to be handled in memory instead of file system */ - file_in_memory_request(tid); + paths_to_store_in_memory = file_in_memory_request(tid); syscall_no_intercept_flag = false; } diff --git a/src/server/capio_server.cpp b/src/server/capio_server.cpp index 1a6a4c9eb..bfa6135a6 100644 --- a/src/server/capio_server.cpp +++ b/src/server/capio_server.cpp @@ -133,8 +133,8 @@ std::string parseCLI(int argc, char **argv) { #ifdef CAPIO_LOG auto logname = open_server_logfile(); log = new Logger(__func__, __FILE__, __LINE__, gettid(), "Created new log file"); - std::cout << CAPIO_SERVER_CLI_LOG_SERVER << "started logging to logfile " << logname - << std::endl; + std::cout << CAPIO_SERVER_CLI_LOG_SERVER << " [ " << node_name << " ] " + << "started logging to logfile " << logname << std::endl; #endif if (config) { From a260dded68f11dcb7f38ff8e4581b9be2bceeeb6 Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Fri, 25 Apr 2025 09:10:04 +0000 Subject: [PATCH 06/33] Fixed write in memory for simple test --- src/posix/handlers/close.hpp | 1 + src/posix/handlers/exit.hpp | 10 +++++++--- src/posix/utils/cache/consent_request_cache.hpp | 5 ++++- src/posix/utils/cache/read_request_cache_fs.hpp | 5 ++++- src/posix/utils/cache/read_request_cache_mem.hpp | 5 ++++- src/posix/utils/cache/write_request_cache_fs.hpp | 5 ++++- src/posix/utils/cache/write_request_cache_mem.hpp | 7 +++++++ 7 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/posix/handlers/close.hpp b/src/posix/handlers/close.hpp index f909b407f..1107e47fc 100644 --- a/src/posix/handlers/close.hpp +++ b/src/posix/handlers/close.hpp @@ -12,6 +12,7 @@ int close_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long ar if (exists_capio_fd(fd)) { close_request(get_capio_fd_path(fd), tid); + write_request_cache_mem->flush(); delete_capio_fd(fd); } diff --git a/src/posix/handlers/exit.hpp b/src/posix/handlers/exit.hpp index 75732bccf..4a8e49541 100644 --- a/src/posix/handlers/exit.hpp +++ b/src/posix/handlers/exit.hpp @@ -18,6 +18,11 @@ int exit_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()"); + syscall_no_intercept_flag = true; + + delete_caches(); + LOG("Removed caches"); + if (is_capio_tid(tid)) { LOG("Thread %d is a CAPIO thread: clean up", tid); exit_group_request(tid); @@ -30,13 +35,12 @@ int exit_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long arg LOG("Removed response buffer"); } - delete_caches(); - LOG("Removed caches"); - delete stc_queue; delete cts_queue; LOG("Removed data queues"); + syscall_no_intercept_flag = false; + return CAPIO_POSIX_SYSCALL_SKIP; } diff --git a/src/posix/utils/cache/consent_request_cache.hpp b/src/posix/utils/cache/consent_request_cache.hpp index 022eab605..bf5cced10 100644 --- a/src/posix/utils/cache/consent_request_cache.hpp +++ b/src/posix/utils/cache/consent_request_cache.hpp @@ -24,7 +24,10 @@ class ConsentRequestCache { available_consent = new std::unordered_map; }; - ~ConsentRequestCache() { delete available_consent; }; + ~ConsentRequestCache() { + START_LOG(capio_syscall(SYS_gettid), "call()"); + delete available_consent; + }; void consent_request(const std::filesystem::path &path, long tid, const std::string &source_func) const { diff --git a/src/posix/utils/cache/read_request_cache_fs.hpp b/src/posix/utils/cache/read_request_cache_fs.hpp index 4e1d184ff..d8a6f07c2 100644 --- a/src/posix/utils/cache/read_request_cache_fs.hpp +++ b/src/posix/utils/cache/read_request_cache_fs.hpp @@ -26,7 +26,10 @@ class ReadRequestCacheFS { available_read_cache = new std::unordered_map; }; - ~ReadRequestCacheFS() { delete available_read_cache; }; + ~ReadRequestCacheFS() { + START_LOG(capio_syscall(SYS_gettid), "call()"); + delete available_read_cache; + }; void read_request(std::filesystem::path path, const long end_of_read, int tid, const int fd) { START_LOG(capio_syscall(SYS_gettid), "[cache] call(path=%s, end_of_read=%ld, tid=%ld)", diff --git a/src/posix/utils/cache/read_request_cache_mem.hpp b/src/posix/utils/cache/read_request_cache_mem.hpp index 29930efb2..15b7ab0f9 100644 --- a/src/posix/utils/cache/read_request_cache_mem.hpp +++ b/src/posix/utils/cache/read_request_cache_mem.hpp @@ -64,7 +64,10 @@ class ReadRequestCacheMEM { _cache = new char[_max_line_size]; } - ~ReadRequestCacheMEM() { delete[] _cache; } + ~ReadRequestCacheMEM() { + START_LOG(capio_syscall(SYS_gettid), "call()"); + delete[] _cache; + } inline void flush() { START_LOG(capio_syscall(SYS_gettid), "call()"); diff --git a/src/posix/utils/cache/write_request_cache_fs.hpp b/src/posix/utils/cache/write_request_cache_fs.hpp index 129cc6197..096c5a941 100644 --- a/src/posix/utils/cache/write_request_cache_fs.hpp +++ b/src/posix/utils/cache/write_request_cache_fs.hpp @@ -22,7 +22,10 @@ class WriteRequestCacheFS { public: explicit WriteRequestCacheFS() : _max_size(get_capio_write_cache_size()) {} - ~WriteRequestCacheFS() { this->flush(capio_syscall(SYS_gettid)); } + ~WriteRequestCacheFS() { + START_LOG(capio_syscall(SYS_gettid), "call()"); + this->flush(capio_syscall(SYS_gettid)); + } void write_request(std::filesystem::path path, int tid, int fd, long count) { START_LOG(capio_syscall(SYS_gettid), "call(path=%s, tid=%ld, fd=%ld, count=%ld)", diff --git a/src/posix/utils/cache/write_request_cache_mem.hpp b/src/posix/utils/cache/write_request_cache_mem.hpp index 926ca48bd..ffa1f3647 100644 --- a/src/posix/utils/cache/write_request_cache_mem.hpp +++ b/src/posix/utils/cache/write_request_cache_mem.hpp @@ -38,13 +38,20 @@ class WriteRequestCacheMEM { : _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) {} + ~WriteRequestCacheMEM() { + START_LOG(capio_syscall(SYS_gettid), "call()"); + this->flush(); + } + void flush() { START_LOG(capio_syscall(SYS_gettid), "call()"); if (_actual_size != 0) { + LOG("Actual size: %ld", _actual_size); write_request(_actual_size, _tid, get_capio_fd_path(_fd).c_str(), _last_write_begin); _cache = nullptr; _actual_size = 0; } + LOG("Flush completed"); } void write(int fd, const void *buffer, off64_t count) { From 7194357007916668039229007fc00f9a8b91aae7 Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Fri, 25 Apr 2025 10:13:05 +0000 Subject: [PATCH 07/33] began work on integrating read from memory --- src/posix/handlers/read.hpp | 40 +++++++++++++++---- .../utils/cache/read_request_cache_mem.hpp | 3 +- src/server/capio-cl-engine/json_parser.hpp | 5 +++ src/server/capio_server.cpp | 5 +++ src/server/client-manager/handlers/read.hpp | 6 ++- .../storage-service/CapioFile/CapioFile.hpp | 2 - 6 files changed, 49 insertions(+), 12 deletions(-) diff --git a/src/posix/handlers/read.hpp b/src/posix/handlers/read.hpp index e53ed49b0..3cc84d96d 100644 --- a/src/posix/handlers/read.hpp +++ b/src/posix/handlers/read.hpp @@ -1,26 +1,52 @@ #ifndef CAPIO_POSIX_HANDLERS_READ_HPP #define CAPIO_POSIX_HANDLERS_READ_HPP -#if defined(SYS_read) -int read_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, long *result) { - int fd = static_cast(arg0); - auto count = static_cast(arg2); - auto tid = static_cast(syscall_no_intercept(SYS_gettid)); +inline off64_t capio_read_fs(int fd, size_t count, pid_t tid) { + START_LOG(capio_syscall(SYS_gettid), "call(fd=%d, count=%ld, tid=%ld)", fd, count, tid); + if (exists_capio_fd(fd)) { + auto computed_offset = get_capio_fd_offset(fd) + count; - START_LOG(capio_syscall(SYS_gettid), "call(fd=%d, tid=%d, count=%ld)", fd, tid, count); + LOG("Handling read on file %s up to byte %ld", get_capio_fd_path(fd).c_str(), + computed_offset); + + read_request_cache_fs->read_request(get_capio_fd_path(fd), computed_offset, tid, fd); + + set_capio_fd_offset(fd, computed_offset); + } + return CAPIO_POSIX_SYSCALL_REQUEST_SKIP; +} +inline off64_t capio_read_mem(int fd, size_t count, void *buffer, long* result) { + START_LOG(capio_syscall(SYS_gettid), "call(fd=%d, count=%ld)", fd, count); if (exists_capio_fd(fd)) { auto computed_offset = get_capio_fd_offset(fd) + count; LOG("Handling read on file %s up to byte %ld", get_capio_fd_path(fd).c_str(), computed_offset); - read_request_cache_fs->read_request(get_capio_fd_path(fd), computed_offset, tid, fd); + *result = read_request_cache_mem->read(fd, buffer, count); set_capio_fd_offset(fd, computed_offset); } return CAPIO_POSIX_SYSCALL_REQUEST_SKIP; } + +#if defined(SYS_read) +int read_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, long *result) { + int fd = static_cast(arg0); + auto count = static_cast(arg2); + auto buffer = reinterpret_cast(arg1); + auto tid = static_cast(syscall_no_intercept(SYS_gettid)); + + START_LOG(capio_syscall(SYS_gettid), "call(fd=%d, tid=%d, count=%ld)", fd, tid, count); + + auto read_result = store_file_in_memory(get_capio_fd_path(fd), tid) + ? capio_read_mem(fd, count, buffer, result) + : capio_read_fs(fd, count, tid); + + LOG("read result: %ld", read_result); + return read_result; +} #endif // SYS_read #if defined(SYS_readv) diff --git a/src/posix/utils/cache/read_request_cache_mem.hpp b/src/posix/utils/cache/read_request_cache_mem.hpp index 15b7ab0f9..95441cdc0 100644 --- a/src/posix/utils/cache/read_request_cache_mem.hpp +++ b/src/posix/utils/cache/read_request_cache_mem.hpp @@ -76,7 +76,7 @@ class ReadRequestCacheMEM { } } - void read(const int fd, void *buffer, off64_t count) { + long read(const int fd, void *buffer, off64_t count) { START_LOG(capio_syscall(SYS_gettid), "call(fd=%d, count=%ld)", fd, count); if (_fd != fd) { LOG("changed fd from %d to %d: flushing", _fd, fd); @@ -132,6 +132,7 @@ class ReadRequestCacheMEM { _last_read_end = get_capio_fd_offset(_fd) + count; set_capio_fd_offset(fd, _last_read_end); + return _last_read_end; } }; #endif // READ_REQUEST_CACHE_MEM_HPP diff --git a/src/server/capio-cl-engine/json_parser.hpp b/src/server/capio-cl-engine/json_parser.hpp index e52bff5e9..0e64b2818 100644 --- a/src/server/capio-cl-engine/json_parser.hpp +++ b/src/server/capio-cl-engine/json_parser.hpp @@ -56,6 +56,11 @@ class JsonParser { capio_dir.c_str()); locations->newFile(get_capio_dir()); + locations->setDirectory(get_capio_dir()); + if (StoreOnlyInMemory) { + locations->setStoreFileInMemory(get_capio_dir()); + } + if (source.empty()) { return locations; } diff --git a/src/server/capio_server.cpp b/src/server/capio_server.cpp index bfa6135a6..367b35991 100644 --- a/src/server/capio_server.cpp +++ b/src/server/capio_server.cpp @@ -20,7 +20,12 @@ #include #include +/* + * Variables required to be globally available + * to all classes and subclasses. + */ std::string workflow_name; +inline bool StoreOnlyInMemory = false; char node_name[HOST_NAME_MAX]; #include "utils/types.hpp" diff --git a/src/server/client-manager/handlers/read.hpp b/src/server/client-manager/handlers/read.hpp index 32cdaa1b3..25e079b17 100644 --- a/src/server/client-manager/handlers/read.hpp +++ b/src/server/client-manager/handlers/read.hpp @@ -65,8 +65,10 @@ inline void read_mem_handler(const char *const str) { "path=%s)", tid, read_begin_offset, read_size, client_cache_line_size, path); - if (storage_service->sizeOf(path) < read_begin_offset + read_size) { - LOG("File is not yet ready to be consumed as there is not enough data"); + if (storage_service->sizeOf(path) < read_begin_offset + read_size && + !file_manager->isCommitted(path)) { + LOG("File is not yet ready to be consumed as there is not enough data, and is not " + "committed"); storage_service->addThreadWaitingForData(tid, path, read_begin_offset, read_size); return; } diff --git a/src/server/storage-service/CapioFile/CapioFile.hpp b/src/server/storage-service/CapioFile/CapioFile.hpp index c2ecb36fc..3eac56b38 100644 --- a/src/server/storage-service/CapioFile/CapioFile.hpp +++ b/src/server/storage-service/CapioFile/CapioFile.hpp @@ -1,8 +1,6 @@ #ifndef CAPIOFILE_HPP #define CAPIOFILE_HPP -inline bool StoreOnlyInMemory = false; - class CapioFile { protected: const std::string fileName; From 3df961d81a52bd54a6207e2cb658c82ebe7ed386 Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Sun, 27 Apr 2025 17:14:33 +0000 Subject: [PATCH 08/33] Fixes on deadlock when reading in memory --- .../utils/cache/read_request_cache_mem.hpp | 39 ++++++++++++++++--- src/posix/utils/filesystem.hpp | 18 ++++----- src/server/client-manager/handlers/read.hpp | 11 +++++- 3 files changed, 51 insertions(+), 17 deletions(-) diff --git a/src/posix/utils/cache/read_request_cache_mem.hpp b/src/posix/utils/cache/read_request_cache_mem.hpp index 95441cdc0..f4fb0e994 100644 --- a/src/posix/utils/cache/read_request_cache_mem.hpp +++ b/src/posix/utils/cache/read_request_cache_mem.hpp @@ -7,6 +7,7 @@ class ReadRequestCacheMEM { int _fd; capio_off64_t _max_line_size, _actual_size, _cache_offset; capio_off64_t _last_read_end; + bool committed = false; /** * Copy data from the cache internal buffer to target buffer @@ -39,7 +40,13 @@ class ReadRequestCacheMEM { LOG("Sending read request %s", req); buf_requests->write(req, CAPIO_REQ_MAX_SIZE); capio_off64_t stc_queue_read = bufs_response->at(tid)->read(); - LOG("Response to request is %ld", stc_queue_read); + LOG("Response to request is %llu", stc_queue_read); + + if (stc_queue_read > 0x8000000000000000) { + committed = true; + stc_queue_read -= 0x8000000000000000; + LOG("File is commmitted. Actual offset is: %ld", stc_queue_read); + } // FIXME: if count > _max_line_size, a deadlock or SEGFAULT is foreseen Fix it asap. // FIXME: still this might not occur as the read() method should protect from this event @@ -69,15 +76,19 @@ class ReadRequestCacheMEM { delete[] _cache; } - inline void flush() { + void flush() { START_LOG(capio_syscall(SYS_gettid), "call()"); if (_cache_offset != _actual_size) { _actual_size = _cache_offset = 0; } + committed = false; } long read(const int fd, void *buffer, off64_t count) { START_LOG(capio_syscall(SYS_gettid), "call(fd=%d, count=%ld)", fd, count); + + long actual_read_size = 0; + if (_fd != fd) { LOG("changed fd from %d to %d: flushing", _fd, fd); flush(); @@ -88,11 +99,13 @@ class ReadRequestCacheMEM { // Check if a seek has occurred before and in case in which case flush the cache // and update the offset to the new value if (_last_read_end != get_capio_fd_offset(_fd)) { + LOG("A seek() has occurred. Performing flush()."); flush(); _last_read_end = get_capio_fd_offset(_fd); } if (_actual_size == 0) { + LOG("No data is present locally. performing request."); const auto size = count < _max_line_size ? count : _max_line_size; read_request(_fd, size, _tid); } @@ -101,6 +114,7 @@ class ReadRequestCacheMEM { // There is enough data to perform a read LOG("The requested amount of data can be served without performing a request"); _read(buffer, count); + actual_read_size = count; } else { // There could be some data available already on the cache. Copy that first and then @@ -108,31 +122,44 @@ class ReadRequestCacheMEM { const auto first_copy_size = _max_line_size - _cache_offset; + LOG("Data (or part of it) might be already present. performing first copy of %ld", + first_copy_size); + _read(buffer, first_copy_size); set_capio_fd_offset(fd, get_capio_fd_offset(fd) + first_copy_size); + actual_read_size = first_copy_size; // Compute the remaining amount of data to send to client auto remaining_size = count - first_copy_size; capio_off64_t copy_offset = first_copy_size; - while (copy_offset < count) { - + while (copy_offset < count && !committed) { + LOG("Need to request still %ld of data from server component", count - copy_offset); // request a line from the server component through a request auto available_size = read_request(_fd, remaining_size, _tid); + + if (committed) { + LOG("File has resulted in a commit message. Exiting loop"); + break; + } + + LOG("Available size after request: %ld", available_size); // compute the amount of data that is going to be sent to the client application auto size_to_send_to_client = remaining_size < available_size ? remaining_size : available_size; + LOG("Sending %ld of data to posix application", size_to_send_to_client); _read(static_cast(buffer) + copy_offset, size_to_send_to_client); + actual_read_size += size_to_send_to_client; copy_offset += size_to_send_to_client; remaining_size -= size_to_send_to_client; } } - + LOG("Completed read operation. updating indices."); _last_read_end = get_capio_fd_offset(_fd) + count; set_capio_fd_offset(fd, _last_read_end); - return _last_read_end; + return actual_read_size; } }; #endif // READ_REQUEST_CACHE_MEM_HPP diff --git a/src/posix/utils/filesystem.hpp b/src/posix/utils/filesystem.hpp index c2f09b31a..c128b43be 100644 --- a/src/posix/utils/filesystem.hpp +++ b/src/posix/utils/filesystem.hpp @@ -83,16 +83,16 @@ inline std::filesystem::path capio_posix_realpath(const std::filesystem::path &p if (pathname.is_absolute()) { LOG("Path=%s is already absolute", pathname.c_str()); return {pathname}; - } else { - std::filesystem::path new_path = (*current_dir / pathname).lexically_normal(); - if (is_capio_path(new_path)) { - LOG("Computed absolute path = %s", new_path.c_str()); - return new_path; - } else { - LOG("file %s is not a posix file, nor a capio file!", pathname.c_str()); - return {}; - } } + + std::filesystem::path new_path = (*current_dir / pathname).lexically_normal(); + if (is_capio_path(new_path)) { + LOG("Computed absolute path = %s", new_path.c_str()); + return new_path; + } + + LOG("file %s is not a posix file, nor a capio file!", pathname.c_str()); + return {}; } // if not, then check for realpath through libc implementation diff --git a/src/server/client-manager/handlers/read.hpp b/src/server/client-manager/handlers/read.hpp index 25e079b17..ca254f2d4 100644 --- a/src/server/client-manager/handlers/read.hpp +++ b/src/server/client-manager/handlers/read.hpp @@ -75,9 +75,16 @@ inline void read_mem_handler(const char *const str) { auto size_to_send = read_size < client_cache_line_size ? read_size : client_cache_line_size; - LOG("Need to sent to client %llu bytes", size_to_send); - client_manager->reply_to_client(tid, size_to_send); + LOG("Need to sent to client %llu bytes, asking storage service to send data", size_to_send); storage_service->reply_to_client(tid, path, read_begin_offset, size_to_send); + + LOG("Sending to posix app the offset up to which read."); + if (file_manager->isCommitted(path)) { + LOG("File is committed. signaling it to posix application by setting offset MSB to 1"); + size_to_send = 0x8000000000000000 | size_to_send; + } + LOG("Sending offset: %llu", size_to_send); + client_manager->reply_to_client(tid, size_to_send); } #endif // READ_HPP From 0eb705afbae7cd302eb2c47450ceaa16206ecb61 Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Mon, 28 Apr 2025 15:51:45 +0200 Subject: [PATCH 09/33] Continuing work on fixing read in memory. now segfaults when server replies to client --- src/server/client-manager/handlers/read.hpp | 10 ++++++++-- src/server/file-manager/file_manager_impl.hpp | 20 ++++++++++++++----- .../storage-service/CapioFile/CapioFile.hpp | 17 ++++++++++------ .../CapioFile/CapioMemoryFile.hpp | 20 +++++++++++-------- 4 files changed, 46 insertions(+), 21 deletions(-) diff --git a/src/server/client-manager/handlers/read.hpp b/src/server/client-manager/handlers/read.hpp index ca254f2d4..f9f7eb5fa 100644 --- a/src/server/client-manager/handlers/read.hpp +++ b/src/server/client-manager/handlers/read.hpp @@ -73,7 +73,13 @@ inline void read_mem_handler(const char *const str) { return; } - auto size_to_send = read_size < client_cache_line_size ? read_size : client_cache_line_size; + LOG("Computing size of data to send: minimum between:"); + LOG("read_size: %llu", read_size); + LOG("client_cache_line_size: %llu", client_cache_line_size); + LOG("file_size:%llu - read_begin_offset=%llu = %llu", storage_service->sizeOf(path), + read_begin_offset, storage_service->sizeOf(path)- read_begin_offset); + auto size_to_send = std::min({read_size, client_cache_line_size, + (storage_service->sizeOf(path) - read_begin_offset)}); LOG("Need to sent to client %llu bytes, asking storage service to send data", size_to_send); storage_service->reply_to_client(tid, path, read_begin_offset, size_to_send); @@ -87,4 +93,4 @@ inline void read_mem_handler(const char *const str) { client_manager->reply_to_client(tid, size_to_send); } -#endif // READ_HPP +#endif // READ_HPP \ No newline at end of file diff --git a/src/server/file-manager/file_manager_impl.hpp b/src/server/file-manager/file_manager_impl.hpp index 362ef5360..29c509e47 100644 --- a/src/server/file-manager/file_manager_impl.hpp +++ b/src/server/file-manager/file_manager_impl.hpp @@ -111,7 +111,7 @@ inline void CapioFileManager::_unlockThreadAwaitingData( * should be triggered only if the file is a directory and the rule specified on it is * Fire No Update */ - const bool is_directory = std::filesystem::is_directory(path); + const bool is_directory = std::filesystem::is_directory(path); const uintmax_t filesize = is_directory ? ULLONG_MAX : get_file_size_if_exists(path); /* * Check for file size only if it is directory, otherwise, @@ -167,8 +167,8 @@ inline void CapioFileManager::_unlockThreadAwaitingData( */ inline void CapioFileManager::increaseCloseCount(const std::filesystem::path &path) { START_LOG(gettid(), "call(path=%s)", path.c_str()); - auto metadata_path = getAndCreateMetadataPath(path); - const auto lock = new DistributedSemaphore(metadata_path + ".lock", 300); + auto metadata_path = getAndCreateMetadataPath(path); + const auto lock = new DistributedSemaphore(metadata_path + ".lock", 300); long long close_count = 0; LOG("Gained mutual exclusive access to token file %s", (metadata_path + ".lock").c_str()); @@ -233,6 +233,7 @@ inline bool CapioFileManager::isCommitted(const std::filesystem::path &path) { static std::unordered_map committed_files; if (committed_files.find(path) != committed_files.end()) { + LOG("Committed: TRUE"); return true; } @@ -253,8 +254,10 @@ inline bool CapioFileManager::isCommitted(const std::filesystem::path &path) { if (count >= file_count) { committed_files[path] = true; + LOG("Committed: TRUE"); return true; } + LOG("Committed: FALSE"); return false; } @@ -277,6 +280,7 @@ inline bool CapioFileManager::isCommitted(const std::filesystem::path &path) { if (commit_computed) { committed_files[path] = true; } + LOG("Committed: %s", commit_computed ? "TRUE" : "FALSE"); return commit_computed; } @@ -284,7 +288,8 @@ inline bool CapioFileManager::isCommitted(const std::filesystem::path &path) { LOG("Commit rule is ON_CLOSE"); if (!std::filesystem::exists(metadata_computed_path)) { - LOG("Commit file does not yet exists. returning false"); + LOG("Commit file does not yet exists."); + LOG("Committed: FALSE"); return false; } @@ -292,6 +297,7 @@ inline bool CapioFileManager::isCommitted(const std::filesystem::path &path) { LOG("Expected close count is: %d", commit_count); if (commit_count == -1) { LOG("File needs to be closed exactly once and token exists. returning"); + LOG("Committed: TRUE"); return true; } @@ -308,7 +314,9 @@ inline bool CapioFileManager::isCommitted(const std::filesystem::path &path) { if (actual_commit_count >= commit_count) { committed_files[path] = true; return true; + LOG("Committed: TRUE"); } + LOG("Committed: FALSE"); return false; } @@ -317,8 +325,10 @@ inline bool CapioFileManager::isCommitted(const std::filesystem::path &path) { if (std::filesystem::exists(metadata_computed_path)) { committed_files[path] = true; + LOG("Committed: TRUE"); return true; } + LOG("Committed: FALSE"); return false; } @@ -372,4 +382,4 @@ inline void CapioFileManager::checkFileAwaitingData() { } } -#endif // FILE_MANAGER_HPP +#endif // FILE_MANAGER_HPP \ No newline at end of file diff --git a/src/server/storage-service/CapioFile/CapioFile.hpp b/src/server/storage-service/CapioFile/CapioFile.hpp index 3eac56b38..8829ca16b 100644 --- a/src/server/storage-service/CapioFile/CapioFile.hpp +++ b/src/server/storage-service/CapioFile/CapioFile.hpp @@ -2,15 +2,20 @@ #define CAPIOFILE_HPP class CapioFile { - protected: +protected: const std::string fileName; std::size_t totalSize; - public: - explicit CapioFile(const std::string &filePath) : fileName(filePath), totalSize(0){}; +public: + explicit CapioFile(const std::string &filePath) : fileName(filePath), totalSize(0) { + }; virtual ~CapioFile() = default; - [[nodiscard]] std::size_t getSize() const { return totalSize; } + [[nodiscard]] std::size_t getSize() const { + START_LOG(gettid(), "call()"); + return totalSize; + } + [[nodiscard]] const std::string &getFileName() const { return fileName; } /** @@ -29,7 +34,7 @@ class CapioFile { * @return number of bytes read from CapioMemoryFile */ virtual std::size_t readData(char *buffer, std::size_t file_offset, - std::size_t buffer_size) = 0; + std::size_t buffer_size) = 0; /** * Store data inside the CapioMemoryFile by reading it from a SPSCQueue object. Behaves just @@ -51,4 +56,4 @@ class CapioFile { std::size_t length) const = 0; }; -#endif // CAPIOFILE_HPP +#endif // CAPIOFILE_HPP \ No newline at end of file diff --git a/src/server/storage-service/CapioFile/CapioMemoryFile.hpp b/src/server/storage-service/CapioFile/CapioMemoryFile.hpp index 832a7133d..95186234d 100644 --- a/src/server/storage-service/CapioFile/CapioMemoryFile.hpp +++ b/src/server/storage-service/CapioFile/CapioMemoryFile.hpp @@ -16,8 +16,8 @@ class CapioMemoryFile : public CapioFile { std::map> memoryBlocks; // maps for bits - static constexpr u_int32_t _pageSizeMB = 4; - static constexpr u_int64_t _pageMask = 0xFFFFF; + static constexpr u_int32_t _pageSizeMB = 4; + static constexpr u_int64_t _pageMask = 0xFFFFF; static constexpr u_int64_t _pageSizeBytes = _pageSizeMB * 1024 * 1024; /** @@ -56,8 +56,9 @@ class CapioMemoryFile : public CapioFile { return block; } - public: - explicit CapioMemoryFile(const std::string &filePath) : CapioFile(filePath) {} +public: + explicit CapioMemoryFile(const std::string &filePath) : CapioFile(filePath) { + } /** * Write data to a file stored inside the memory @@ -101,6 +102,7 @@ class CapioMemoryFile : public CapioFile { totalSize = std::max(totalSize, buffer_offset); return totalSize; } + /** * Read from Capio File * @param buffer Buffer to read to @@ -146,18 +148,20 @@ class CapioMemoryFile : public CapioFile { const auto &[map_offset, write_offset, first_write_size] = compute_offsets(offset, length); + auto remaining_bytes = length; + auto &block = memoryBlocks[map_offset]; block.resize(_pageSizeBytes); // reserve 4MB of space queue.read(block.data() + write_offset, first_write_size); // update remaining bytes to write - length -= first_write_size; + remaining_bytes -= first_write_size; size_t map_count = 1; // start from map following the one obtained from the first write // Variable to store the read offset of the input buffer auto buffer_offset = first_write_size; - while (length > 0) { + while (remaining_bytes > 0) { auto &next_block = memoryBlocks[map_offset + map_count]; next_block.resize(_pageSizeBytes); // reserve 4MB of space // Compute the actual size of the current write @@ -166,7 +170,7 @@ class CapioMemoryFile : public CapioFile { queue.read(next_block.data(), write_size); buffer_offset += write_size; map_count++; - length -= _pageSizeBytes; + remaining_bytes -= _pageSizeBytes; } totalSize = std::max(totalSize, offset + length); @@ -206,4 +210,4 @@ class CapioMemoryFile : public CapioFile { } }; -#endif // CAPIOMEMORYFILE_HPP +#endif // CAPIOMEMORYFILE_HPP \ No newline at end of file From 2e02f2647cea230966c11ee5b72b5b7bb7f0d74f Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Mon, 28 Apr 2025 16:55:46 +0200 Subject: [PATCH 10/33] Fixed in memory read This commit fixes the read operation when file is stored in memory. TODO: fix as soon as possible the ReadRequestCacheMEM class, as right now it might contain bugs somewhere that are not clear. Also some varibles can be removed --- src/posix/handlers/read.hpp | 18 +++--- .../utils/cache/read_request_cache_mem.hpp | 59 ++++++++++++------- src/posix/utils/filesystem.hpp | 15 +++-- src/posix/utils/requests.hpp | 6 +- .../storage-service/capio_storage_service.hpp | 22 +++---- 5 files changed, 71 insertions(+), 49 deletions(-) diff --git a/src/posix/handlers/read.hpp b/src/posix/handlers/read.hpp index 3cc84d96d..d5bf3a65a 100644 --- a/src/posix/handlers/read.hpp +++ b/src/posix/handlers/read.hpp @@ -16,7 +16,7 @@ inline off64_t capio_read_fs(int fd, size_t count, pid_t tid) { return CAPIO_POSIX_SYSCALL_REQUEST_SKIP; } -inline off64_t capio_read_mem(int fd, size_t count, void *buffer, long* result) { +inline off64_t capio_read_mem(int fd, size_t count, void *buffer, long *result) { START_LOG(capio_syscall(SYS_gettid), "call(fd=%d, count=%ld)", fd, count); if (exists_capio_fd(fd)) { auto computed_offset = get_capio_fd_offset(fd) + count; @@ -25,18 +25,18 @@ inline off64_t capio_read_mem(int fd, size_t count, void *buffer, long* result) computed_offset); *result = read_request_cache_mem->read(fd, buffer, count); - - set_capio_fd_offset(fd, computed_offset); + LOG("Result of read is %lu", *result); + return CAPIO_POSIX_SYSCALL_SUCCESS; } return CAPIO_POSIX_SYSCALL_REQUEST_SKIP; } #if defined(SYS_read) int read_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, long *result) { - int fd = static_cast(arg0); - auto count = static_cast(arg2); + int fd = static_cast(arg0); + auto count = static_cast(arg2); auto buffer = reinterpret_cast(arg1); - auto tid = static_cast(syscall_no_intercept(SYS_gettid)); + auto tid = static_cast(syscall_no_intercept(SYS_gettid)); START_LOG(capio_syscall(SYS_gettid), "call(fd=%d, tid=%d, count=%ld)", fd, tid, count); @@ -51,9 +51,9 @@ int read_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long arg #if defined(SYS_readv) int readv_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, long *result) { - auto fd = static_cast(arg0); + auto fd = static_cast(arg0); auto iovcnt = static_cast(arg2); - auto tid = static_cast(syscall_no_intercept(SYS_gettid)); + auto tid = static_cast(syscall_no_intercept(SYS_gettid)); if (exists_capio_fd(fd)) { auto computed_offset = get_capio_fd_offset(fd) + iovcnt * sizeof(iovec); @@ -66,4 +66,4 @@ int readv_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long ar } #endif // SYS_readv -#endif // CAPIO_POSIX_HANDLERS_READ_HPP +#endif // CAPIO_POSIX_HANDLERS_READ_HPP \ No newline at end of file diff --git a/src/posix/utils/cache/read_request_cache_mem.hpp b/src/posix/utils/cache/read_request_cache_mem.hpp index f4fb0e994..8e7aa69f0 100644 --- a/src/posix/utils/cache/read_request_cache_mem.hpp +++ b/src/posix/utils/cache/read_request_cache_mem.hpp @@ -1,12 +1,14 @@ #ifndef READ_REQUEST_CACHE_MEM_HPP #define READ_REQUEST_CACHE_MEM_HPP + +//TODO: REFACTOR THIS MESS OF CODE + class ReadRequestCacheMEM { - private: char *_cache; long _tid; int _fd; capio_off64_t _max_line_size, _actual_size, _cache_offset; - capio_off64_t _last_read_end; + capio_off64_t _last_read_end, _end_of_file_committed_offset; bool committed = false; /** @@ -24,7 +26,7 @@ class ReadRequestCacheMEM { } } - protected: +protected: [[nodiscard]] capio_off64_t read_request(const int fd, const capio_off64_t count, const long tid) { START_LOG(capio_syscall(SYS_gettid), "call(fd=%ld, count=%llu, tid=%ld)", fd, count, tid); @@ -45,12 +47,13 @@ class ReadRequestCacheMEM { if (stc_queue_read > 0x8000000000000000) { committed = true; stc_queue_read -= 0x8000000000000000; - LOG("File is commmitted. Actual offset is: %ld", stc_queue_read); + _end_of_file_committed_offset = stc_queue_read; + LOG("File is commited. Actual offset is: %ld", stc_queue_read); } // FIXME: if count > _max_line_size, a deadlock or SEGFAULT is foreseen Fix it asap. // FIXME: still this might not occur as the read() method should protect from this event - auto read_size = count; + auto read_size = stc_queue_read; while (read_size > 0) { const capio_off64_t tmp_read_size = read_size > _max_line_size ? _max_line_size : read_size; @@ -64,7 +67,7 @@ class ReadRequestCacheMEM { return stc_queue_read; } - public: +public: explicit ReadRequestCacheMEM(const long line_size = get_posix_read_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) { @@ -82,6 +85,7 @@ class ReadRequestCacheMEM { _actual_size = _cache_offset = 0; } committed = false; + _end_of_file_committed_offset = -1; } long read(const int fd, void *buffer, off64_t count) { @@ -92,22 +96,29 @@ class ReadRequestCacheMEM { if (_fd != fd) { LOG("changed fd from %d to %d: flushing", _fd, fd); flush(); - _fd = fd; + _fd = fd; _last_read_end = get_capio_fd_offset(_fd); } // Check if a seek has occurred before and in case in which case flush the cache // and update the offset to the new value if (_last_read_end != get_capio_fd_offset(_fd)) { - LOG("A seek() has occurred. Performing flush()."); + LOG( + "A seek() has occurred (_last_read_end=%llu, get_capio_fd_offset=%llu). Performing flush().", + _last_read_end, get_capio_fd_offset(_fd)); flush(); _last_read_end = get_capio_fd_offset(_fd); } + if (committed && _end_of_file_committed_offset == _last_read_end) { + LOG("All file content has been read. Returning 0"); + return 0; + } + if (_actual_size == 0) { LOG("No data is present locally. performing request."); const auto size = count < _max_line_size ? count : _max_line_size; - read_request(_fd, size, _tid); + _actual_size = read_request(_fd, size, _tid); } if (count <= _max_line_size - _cache_offset) { @@ -115,51 +126,59 @@ class ReadRequestCacheMEM { LOG("The requested amount of data can be served without performing a request"); _read(buffer, count); actual_read_size = count; + _last_read_end = get_capio_fd_offset(_fd) + count; + set_capio_fd_offset(fd, _last_read_end); } else { // There could be some data available already on the cache. Copy that first and then // proceed to request the other missing data - const auto first_copy_size = _max_line_size - _cache_offset; + const auto first_copy_size = std::min(_max_line_size - _cache_offset, _actual_size); - LOG("Data (or part of it) might be already present. performing first copy of %ld", - first_copy_size); + LOG("Data (or part of it) might be already present. performing first copy of" + " std::min(_max_line_size(%llu) - _cache_offset(%llu), _actual_size(%llu) = %ld", + _max_line_size, _cache_offset, _actual_size, first_copy_size); _read(buffer, first_copy_size); + _last_read_end = get_capio_fd_offset(_fd) + first_copy_size; set_capio_fd_offset(fd, get_capio_fd_offset(fd) + first_copy_size); actual_read_size = first_copy_size; + LOG("actual_read_size incremented to: %ld", actual_read_size); // Compute the remaining amount of data to send to client - auto remaining_size = count - first_copy_size; + auto remaining_size = count - first_copy_size; capio_off64_t copy_offset = first_copy_size; while (copy_offset < count && !committed) { LOG("Need to request still %ld of data from server component", count - copy_offset); // request a line from the server component through a request - auto available_size = read_request(_fd, remaining_size, _tid); + _actual_size = read_request(_fd, remaining_size, _tid); if (committed) { LOG("File has resulted in a commit message. Exiting loop"); break; } - LOG("Available size after request: %ld", available_size); + LOG("Available size after request: %ld", _actual_size); // compute the amount of data that is going to be sent to the client application auto size_to_send_to_client = - remaining_size < available_size ? remaining_size : available_size; + remaining_size < _actual_size ? remaining_size : _actual_size; LOG("Sending %ld of data to posix application", size_to_send_to_client); _read(static_cast(buffer) + copy_offset, size_to_send_to_client); actual_read_size += size_to_send_to_client; + LOG("actual_read_size incremented to: %ld", actual_read_size); copy_offset += size_to_send_to_client; remaining_size -= size_to_send_to_client; + + _last_read_end = get_capio_fd_offset(_fd) + size_to_send_to_client; + set_capio_fd_offset(fd, _last_read_end); } } - LOG("Completed read operation. updating indices."); - _last_read_end = get_capio_fd_offset(_fd) + count; - set_capio_fd_offset(fd, _last_read_end); + + LOG("Read return value: %ld (_last_Read_end = %llu)", actual_read_size, _last_read_end); return actual_read_size; } }; -#endif // READ_REQUEST_CACHE_MEM_HPP +#endif // READ_REQUEST_CACHE_MEM_HPP \ No newline at end of file diff --git a/src/posix/utils/filesystem.hpp b/src/posix/utils/filesystem.hpp index c128b43be..58a5917fb 100644 --- a/src/posix/utils/filesystem.hpp +++ b/src/posix/utils/filesystem.hpp @@ -234,7 +234,7 @@ inline std::filesystem::path get_dir_path(int dirfd) { return it->second; } LOG("dirfd %d not found. Computing it through proclnk", dirfd); - char proclnk[128] = {}; + char proclnk[128] = {}; char dir_pathname[PATH_MAX] = {}; sprintf(proclnk, "/proc/self/fd/%d", dirfd); if (capio_syscall(SYS_readlinkat, AT_FDCWD, proclnk, dir_pathname, PATH_MAX) < 0) { @@ -252,10 +252,10 @@ inline std::filesystem::path get_dir_path(int dirfd) { inline void init_filesystem() { std::unique_ptr buf(new char[PATH_MAX]); capio_syscall(SYS_getcwd, buf.get(), PATH_MAX); - current_dir = std::make_unique(buf.get()); + current_dir = std::make_unique(buf.get()); capio_files_descriptors = new CPFileDescriptors_t(); - capio_files_paths = new CPFilesPaths_t(); - files = new CPFiles_t(); + capio_files_paths = new CPFilesPaths_t(); + files = new CPFiles_t(); } /** @@ -268,7 +268,7 @@ inline void rename_capio_path(const std::string &oldpath, const std::string &new START_LOG(capio_syscall(SYS_gettid), "call(oldpath=%s, newpath=%s)", oldpath.c_str(), newpath.c_str()); if (capio_files_paths->find(oldpath) != capio_files_paths->end()) { - auto entry = capio_files_paths->extract(oldpath); + auto entry = capio_files_paths->extract(oldpath); entry.key() = newpath; capio_files_paths->insert(std::move(entry)); for (auto fd : capio_files_paths->at(newpath)) { @@ -286,7 +286,10 @@ inline void rename_capio_path(const std::string &oldpath, const std::string &new * @return */ inline void set_capio_fd_offset(int fd, capio_off64_t offset) { + START_LOG(capio_syscall(SYS_gettid), "call(fd=%d, offset=%lld)", fd, offset); + LOG("Previous offset = %lld", *std::get<0>(files->at(fd))); *std::get<0>(files->at(fd)) = offset; + LOG("New offset = %lld", *std::get<0>(files->at(fd))); } /** @@ -297,4 +300,4 @@ inline void set_current_dir(const std::filesystem::path &cwd) { current_dir = std::make_unique(cwd); } -#endif // CAPIO_POSIX_UTILS_FILESYSTEM_HPP +#endif // CAPIO_POSIX_UTILS_FILESYSTEM_HPP \ No newline at end of file diff --git a/src/posix/utils/requests.hpp b/src/posix/utils/requests.hpp index 70134e6e7..e32858515 100644 --- a/src/posix/utils/requests.hpp +++ b/src/posix/utils/requests.hpp @@ -48,9 +48,9 @@ inline void handshake_request(const long tid, const long pid, const std::string LOG("Sent handshake request"); cts_queue = new SPSCQueue("queue-" + std::to_string(tid) + ".cts", get_cache_lines(), - get_cache_line_size()); + get_cache_line_size(), get_capio_workflow_name(), true); stc_queue = new SPSCQueue("queue-" + std::to_string(tid) + ".stc", get_cache_lines(), - get_cache_line_size()); + get_cache_line_size(), get_capio_workflow_name(), true); LOG("Initialized data transfer queues"); } @@ -125,4 +125,4 @@ inline void rename_request(const std::filesystem::path &old_path, #include "utils/storage.hpp" -#endif // CAPIO_POSIX_UTILS_REQUESTS_HPP +#endif // CAPIO_POSIX_UTILS_REQUESTS_HPP \ No newline at end of file diff --git a/src/server/storage-service/capio_storage_service.hpp b/src/server/storage-service/capio_storage_service.hpp index a48c33044..724bf91d7 100644 --- a/src/server/storage-service/capio_storage_service.hpp +++ b/src/server/storage-service/capio_storage_service.hpp @@ -14,7 +14,7 @@ class CapioStorageService { std::unordered_map *_stored_files; std::unordered_map>> - *_threads_waiting_for_memory_data; + *_threads_waiting_for_memory_data; /** * Return a file if exists. if not, create it and then return it @@ -28,17 +28,17 @@ class CapioStorageService { return _stored_files->at(file_name); } - public: +public: CapioStorageService() { START_LOG(gettid(), "call()"); - _stored_files = new std::unordered_map; + _stored_files = new std::unordered_map; _client_to_server_queue = new std::unordered_map; - _server_to_clien_queue = new std::unordered_map; + _server_to_clien_queue = new std::unordered_map; _threads_waiting_for_memory_data = new std::unordered_map>>; std::cout << CAPIO_SERVER_CLI_LOG_SERVER << " [ " << node_name << " ] " - << "CapioStorageService initialization completed." << std::endl; + << "CapioStorageService initialization completed." << std::endl; } ~CapioStorageService() { @@ -114,11 +114,11 @@ 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, workflow_name, false)); + pid, new SPSCQueue("queue-" + std::to_string(pid) + +".cts", get_cache_lines(), + get_cache_line_size(), 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, workflow_name, false)); + pid, new SPSCQueue("queue-" + std::to_string(pid) + +".stc", get_cache_lines(), + get_cache_line_size(), workflow_name, false)); LOG("Created communication queues"); } @@ -148,7 +148,7 @@ class CapioStorageService { off64_t size) const { START_LOG(gettid(), "call(tid=%d, file=%s, offset=%lld, size=%lld)", tid, file.c_str(), offset, size); - const auto f = getFile(file); + const auto f = getFile(file); const auto queue = _client_to_server_queue->at(tid); f->readFromQueue(*queue, offset, size); } @@ -193,4 +193,4 @@ class CapioStorageService { inline CapioStorageService *storage_service; -#endif // CAPIO_STORAGE_SERVICE_H +#endif // CAPIO_STORAGE_SERVICE_H \ No newline at end of file From cb068c549199a0b24ff9ed8ca390f27b94233ca0 Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Mon, 28 Apr 2025 17:48:45 +0200 Subject: [PATCH 11/33] Bug: data is being messed up somewhere. find where --- src/server/client-manager/handlers/read.hpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/server/client-manager/handlers/read.hpp b/src/server/client-manager/handlers/read.hpp index f9f7eb5fa..d25ba1539 100644 --- a/src/server/client-manager/handlers/read.hpp +++ b/src/server/client-manager/handlers/read.hpp @@ -85,8 +85,10 @@ inline void read_mem_handler(const char *const str) { storage_service->reply_to_client(tid, path, read_begin_offset, size_to_send); LOG("Sending to posix app the offset up to which read."); - if (file_manager->isCommitted(path)) { - LOG("File is committed. signaling it to posix application by setting offset MSB to 1"); + if (file_manager->isCommitted(path) && read_begin_offset + size_to_send >= storage_service-> + sizeOf(path)) { + LOG("File is committed, and end of read >= than file size." + " signaling it to posix application by setting offset MSB to 1"); size_to_send = 0x8000000000000000 | size_to_send; } LOG("Sending offset: %llu", size_to_send); From d9f644e45a6748e1e2a760664b6b7a536428c3f7 Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Tue, 29 Apr 2025 12:00:41 +0200 Subject: [PATCH 12/33] Fix on writev --- src/posix/handlers/write.hpp | 34 +++++++++++++------ .../utils/cache/read_request_cache_mem.hpp | 2 +- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/posix/handlers/write.hpp b/src/posix/handlers/write.hpp index c0c57faae..8ace13927 100644 --- a/src/posix/handlers/write.hpp +++ b/src/posix/handlers/write.hpp @@ -4,6 +4,7 @@ #include "utils/common.hpp" #include "utils/requests.hpp" + inline off64_t capio_write_fs(int fd, capio_off64_t count, pid_t tid) { START_LOG(tid, "call(fd=%d, count=%ld)", fd, count); @@ -20,10 +21,10 @@ inline off64_t capio_write_mem(int fd, char *buffer, capio_off64_t count, pid_t #if defined(SYS_write) int write_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, long *result) { - auto fd = static_cast(arg0); + auto fd = static_cast(arg0); auto buffer = reinterpret_cast(arg1); - auto count = static_cast(arg2); - auto tid = static_cast(syscall_no_intercept(SYS_gettid)); + auto count = static_cast(arg2); + auto tid = static_cast(syscall_no_intercept(SYS_gettid)); START_LOG(tid, "call(fd=%d, buffer=%p, count=%ld, id=%ld)", fd, buffer, count, tid); if (!exists_capio_fd(fd)) { LOG("FD %d is not handled by capio... skipping syscall", fd); @@ -42,22 +43,33 @@ int write_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long ar #if defined(SYS_writev) int writev_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, long *result) { - auto fd = static_cast(arg0); - auto buffer = reinterpret_cast(arg1); + auto fd = static_cast(arg0); + auto io_vec = reinterpret_cast(arg1); auto iovcnt = static_cast(arg2); - long tid = syscall_no_intercept(SYS_gettid); - START_LOG(tid, "call(fd=%d, buffer=%p, count=%ld, id=%ld)", fd, buffer, iovcnt, tid); + long tid = syscall_no_intercept(SYS_gettid); + START_LOG(tid, "call(fd=%d, buffer=%p, count=%ld, pid=%ld)", fd, io_vec->iov_base, + io_vec->iov_len, tid); if (!exists_capio_fd(fd)) { - LOG("FD %d is not handled by capio... skipping syscall", fd); + LOG("FD %d is not handled by CAPIO... skipping syscall", fd); return CAPIO_POSIX_SYSCALL_REQUEST_SKIP; } - auto write_result = store_file_in_memory(get_capio_fd_path(fd), tid) - ? capio_write_mem(fd, buffer, iovcnt, tid) + LOG("Need to handle %ld IOVEC objects", iovcnt); + int write_result = 0; + for (auto i = 0; i < iovcnt; ++i) { + const auto [iov_base, iov_len] = io_vec[i]; + if (iov_len == 0) { + LOG("Size of IOVEC is 0. Skipping write request"); + continue; + } + LOG("Handling IOVEC elements %d of size %ld", i, iov_len); + write_result += store_file_in_memory(get_capio_fd_path(fd), tid) + ? capio_write_mem(fd, static_cast(iov_base), iov_len, tid) : capio_write_fs(fd, iovcnt, tid); + } return posix_return_value(write_result, result); } #endif // SYS_writev -#endif // CAPIO_POSIX_HANDLERS_WRITE_HPP +#endif // CAPIO_POSIX_HANDLERS_WRITE_HPP \ No newline at end of file diff --git a/src/posix/utils/cache/read_request_cache_mem.hpp b/src/posix/utils/cache/read_request_cache_mem.hpp index 8e7aa69f0..bd197222c 100644 --- a/src/posix/utils/cache/read_request_cache_mem.hpp +++ b/src/posix/utils/cache/read_request_cache_mem.hpp @@ -44,7 +44,7 @@ class ReadRequestCacheMEM { capio_off64_t stc_queue_read = bufs_response->at(tid)->read(); LOG("Response to request is %llu", stc_queue_read); - if (stc_queue_read > 0x8000000000000000) { + if (stc_queue_read >= 0x8000000000000000) { committed = true; stc_queue_read -= 0x8000000000000000; _end_of_file_committed_offset = stc_queue_read; From 69638d068b2112ecd771748658b677a49719050c Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Wed, 30 Apr 2025 11:58:39 +0200 Subject: [PATCH 13/33] Fix on cache wrong bytes. TODO: fix wrong read size --- .../utils/cache/read_request_cache_mem.hpp | 31 +++++++++++-------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/posix/utils/cache/read_request_cache_mem.hpp b/src/posix/utils/cache/read_request_cache_mem.hpp index bd197222c..a2dd33732 100644 --- a/src/posix/utils/cache/read_request_cache_mem.hpp +++ b/src/posix/utils/cache/read_request_cache_mem.hpp @@ -8,11 +8,11 @@ class ReadRequestCacheMEM { long _tid; int _fd; capio_off64_t _max_line_size, _actual_size, _cache_offset; - capio_off64_t _last_read_end, _end_of_file_committed_offset; + capio_off64_t _last_read_end, _real_file_size_commmitted; bool committed = false; /** - * Copy data from the cache internal buffer to target buffer + * Copy data from the cache internal buffer to the target buffer * @param buffer * @param count */ @@ -32,7 +32,7 @@ class ReadRequestCacheMEM { START_LOG(capio_syscall(SYS_gettid), "call(fd=%ld, count=%llu, tid=%ld)", fd, count, tid); char req[CAPIO_REQ_MAX_SIZE]; - // send as last parameter to the server the maximum amount of data that can be read into a + // send as the last parameter to the server the maximum amount of data that can be read into a // single line of cache auto read_begin_offset = get_capio_fd_offset(fd); @@ -47,20 +47,23 @@ class ReadRequestCacheMEM { if (stc_queue_read >= 0x8000000000000000) { committed = true; stc_queue_read -= 0x8000000000000000; - _end_of_file_committed_offset = stc_queue_read; + _real_file_size_commmitted = stc_queue_read; LOG("File is commited. Actual offset is: %ld", stc_queue_read); } // FIXME: if count > _max_line_size, a deadlock or SEGFAULT is foreseen Fix it asap. // FIXME: still this might not occur as the read() method should protect from this event - auto read_size = stc_queue_read; + /*auto read_size = stc_queue_read; while (read_size > 0) { const capio_off64_t tmp_read_size = read_size > _max_line_size ? _max_line_size : read_size; stc_queue->read(_cache, tmp_read_size); _cache_offset = 0; read_size -= tmp_read_size; - } + }*/ + + stc_queue->read(_cache, stc_queue_read); + _cache_offset = 0; LOG("Completed fetch of data from server"); @@ -85,19 +88,19 @@ class ReadRequestCacheMEM { _actual_size = _cache_offset = 0; } committed = false; - _end_of_file_committed_offset = -1; + _real_file_size_commmitted = -1; } long read(const int fd, void *buffer, off64_t count) { START_LOG(capio_syscall(SYS_gettid), "call(fd=%d, count=%ld)", fd, count); - long actual_read_size = 0; + long actual_read_size = 0;\ if (_fd != fd) { LOG("changed fd from %d to %d: flushing", _fd, fd); flush(); _fd = fd; - _last_read_end = get_capio_fd_offset(_fd); + _last_read_end = get_capio_fd_offset(fd); } // Check if a seek has occurred before and in case in which case flush the cache @@ -110,7 +113,7 @@ class ReadRequestCacheMEM { _last_read_end = get_capio_fd_offset(_fd); } - if (committed && _end_of_file_committed_offset == _last_read_end) { + if (committed && _real_file_size_commmitted == _last_read_end) { LOG("All file content has been read. Returning 0"); return 0; } @@ -133,11 +136,12 @@ class ReadRequestCacheMEM { // There could be some data available already on the cache. Copy that first and then // proceed to request the other missing data - const auto first_copy_size = std::min(_max_line_size - _cache_offset, _actual_size); + const auto first_copy_size = std::min(_actual_size - _cache_offset, + static_cast(count)); LOG("Data (or part of it) might be already present. performing first copy of" - " std::min(_max_line_size(%llu) - _cache_offset(%llu), _actual_size(%llu) = %ld", - _max_line_size, _cache_offset, _actual_size, first_copy_size); + " std::min(_actual_size(%llu) - _cache_offset(%llu), count(%llu) = %ld", + _actual_size, _cache_offset, count, first_copy_size); _read(buffer, first_copy_size); _last_read_end = get_capio_fd_offset(_fd) + first_copy_size; @@ -175,6 +179,7 @@ class ReadRequestCacheMEM { _last_read_end = get_capio_fd_offset(_fd) + size_to_send_to_client; set_capio_fd_offset(fd, _last_read_end); } + } LOG("Read return value: %ld (_last_Read_end = %llu)", actual_read_size, _last_read_end); From ad61cf7fc0f1d91e80f36c44be89149eec458083 Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Wed, 30 Apr 2025 13:59:51 +0200 Subject: [PATCH 14/33] Completed IO operations on single machine --- src/posix/utils/cache/read_request_cache_mem.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/posix/utils/cache/read_request_cache_mem.hpp b/src/posix/utils/cache/read_request_cache_mem.hpp index a2dd33732..4d465b6ee 100644 --- a/src/posix/utils/cache/read_request_cache_mem.hpp +++ b/src/posix/utils/cache/read_request_cache_mem.hpp @@ -118,7 +118,8 @@ class ReadRequestCacheMEM { return 0; } - if (_actual_size == 0) { + // Check if cache is empty or if all the content of the cache has been already consumed + if (_actual_size == 0 || _actual_size == _cache_offset) { LOG("No data is present locally. performing request."); const auto size = count < _max_line_size ? count : _max_line_size; _actual_size = read_request(_fd, size, _tid); From ac1240cf4f1b5da51e3799599f4964d39eae2cc4 Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Wed, 30 Apr 2025 15:56:32 +0200 Subject: [PATCH 15/33] Added test for read and write in memory file. broken when reaching 1.3MB of data --- read_write_test.cpp | 89 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 read_write_test.cpp diff --git a/read_write_test.cpp b/read_write_test.cpp new file mode 100644 index 000000000..aab3d1a14 --- /dev/null +++ b/read_write_test.cpp @@ -0,0 +1,89 @@ +#include +#include +#include +#include + +const std::string filename = "hello.txt"; +const size_t textSize = 16 * 1024 * 1024; // 32 MBB + +// Generate a large text (e.g., repeating a pattern) +std::string generateLongText() { + std::string pattern = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n"; + std::string longText; + while (longText.size() + pattern.size() <= textSize) { + longText += pattern; + } + // If needed, pad the remaining bytes + if (longText.size() < textSize) { + longText.append(textSize - longText.size(), 'X'); + } + return longText; +} + +void writeToFile(const std::string& content) { + std::ofstream outFile(filename, std::ios::out | std::ios::binary); + if (!outFile) { + std::cout << "Error opening file for writing!\n"; + return; + } + outFile.write(content.c_str(), content.size()); + outFile.close(); + std::cout << "Successfully wrote " << content.size() << " bytes to " << filename << "\n"; +} + +void readFromFile(const std::string& expectedContent) { + std::ifstream inFile(filename, std::ios::in | std::ios::binary); + if (!inFile) { + std::cout << "Error opening file for reading!\n"; + return; + } + + std::string fileContent((std::istreambuf_iterator(inFile)), + std::istreambuf_iterator()); + inFile.close(); + + bool match = true; + size_t minLength = std::min(fileContent.size(), expectedContent.size()); + + for (size_t i = 0; i < minLength; ++i) { + if (fileContent[i] != expectedContent[i]) { + std::cout << "Mismatch at position " << i << ":\n"; + std::cout << "Expected: '" << expectedContent[i] << "' (ASCII " << static_cast(expectedContent[i]) << ")\n"; + std::cout << "Found: '" << fileContent[i] << "' (ASCII " << static_cast(fileContent[i]) << ")\n"; + match = false; + exit(-1); + } + } + + if (match) { + if (fileContent.size() != expectedContent.size()) { + std::cout << "Mismatch in size!\n"; + std::cout << "Expected size: " << expectedContent.size() << ", Found size: " << fileContent.size() << "\n"; + match = false; + } else { + std::cout << "Content matches expected text.\n"; + } + } + // std::cout << "\nFile content:\n" << fileContent << "\n"; +} + +int main(int argc, char* argv[]) { + if (argc != 2) { + std::cout << "Usage: " << argv[0] << " --write | --read\n"; + return 1; + } + + std::string longText = generateLongText(); + std::string option = argv[1]; + + if (option == "--write") { + writeToFile(longText); + } else if (option == "--read") { + readFromFile(longText); + } else { + std::cout << "Invalid option. Use --write or --read.\n"; + return 1; + } + + return 0; +} From 9abf0ffbd3d6cc171e6772d86d47c825eda70d63 Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Fri, 2 May 2025 08:22:00 +0000 Subject: [PATCH 16/33] Bugfix on offset calculation in capio memory file --- src/server/storage-service/CapioFile/CapioMemoryFile.hpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/server/storage-service/CapioFile/CapioMemoryFile.hpp b/src/server/storage-service/CapioFile/CapioMemoryFile.hpp index 95186234d..f7f94581a 100644 --- a/src/server/storage-service/CapioFile/CapioMemoryFile.hpp +++ b/src/server/storage-service/CapioFile/CapioMemoryFile.hpp @@ -15,9 +15,8 @@ class CapioMemoryFile : public CapioFile { std::map> memoryBlocks; - // maps for bits + // Static file sizes of file pages static constexpr u_int32_t _pageSizeMB = 4; - static constexpr u_int64_t _pageMask = 0xFFFFF; static constexpr u_int64_t _pageSizeBytes = _pageSizeMB * 1024 * 1024; /** @@ -28,12 +27,10 @@ class CapioMemoryFile : public CapioFile { */ static auto compute_offsets(const std::size_t offset, std::size_t length) { // Compute the offset of the memoryBlocks component. - // This is done by first obtaining the MB component of the address - // and then dividing it by the size in megabyte of the address - const auto map_offset = (offset >> 20) / _pageSizeMB; + const auto map_offset = offset / _pageSizeBytes; // Compute the first write offset relative to the first block of memory - const auto mem_block_offset = offset & _pageMask; + const auto mem_block_offset = offset % _pageSizeBytes; // compute the first write size. if the write operation is bigger than the size of the page // in bytes, then we need to perform the first write operation with size equals to the From 36bb4d630551c8ce55d2a42a029759cfb6ce3f18 Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Fri, 2 May 2025 10:15:48 +0000 Subject: [PATCH 17/33] Fixed reads on different mem pages --- read_write_test.cpp | 18 +---- .../utils/cache/read_request_cache_mem.hpp | 35 +++++----- .../CapioFile/CapioMemoryFile.hpp | 68 +++++++++++++++---- 3 files changed, 75 insertions(+), 46 deletions(-) diff --git a/read_write_test.cpp b/read_write_test.cpp index aab3d1a14..ecd575cb3 100644 --- a/read_write_test.cpp +++ b/read_write_test.cpp @@ -68,22 +68,8 @@ void readFromFile(const std::string& expectedContent) { } int main(int argc, char* argv[]) { - if (argc != 2) { - std::cout << "Usage: " << argv[0] << " --write | --read\n"; - return 1; - } - std::string longText = generateLongText(); - std::string option = argv[1]; - - if (option == "--write") { - writeToFile(longText); - } else if (option == "--read") { - readFromFile(longText); - } else { - std::cout << "Invalid option. Use --write or --read.\n"; - return 1; - } - + writeToFile(longText); + readFromFile(longText); return 0; } diff --git a/src/posix/utils/cache/read_request_cache_mem.hpp b/src/posix/utils/cache/read_request_cache_mem.hpp index 4d465b6ee..76e9fdaf4 100644 --- a/src/posix/utils/cache/read_request_cache_mem.hpp +++ b/src/posix/utils/cache/read_request_cache_mem.hpp @@ -1,7 +1,7 @@ #ifndef READ_REQUEST_CACHE_MEM_HPP #define READ_REQUEST_CACHE_MEM_HPP -//TODO: REFACTOR THIS MESS OF CODE +// TODO: REFACTOR THIS MESS OF CODE class ReadRequestCacheMEM { char *_cache; @@ -26,14 +26,14 @@ class ReadRequestCacheMEM { } } -protected: + protected: [[nodiscard]] capio_off64_t read_request(const int fd, const capio_off64_t count, const long tid) { START_LOG(capio_syscall(SYS_gettid), "call(fd=%ld, count=%llu, tid=%ld)", fd, count, tid); char req[CAPIO_REQ_MAX_SIZE]; - // send as the last parameter to the server the maximum amount of data that can be read into a - // single line of cache + // send as the last parameter to the server the maximum amount of data that can be read into + // a single line of cache auto read_begin_offset = get_capio_fd_offset(fd); @@ -51,8 +51,8 @@ class ReadRequestCacheMEM { LOG("File is commited. Actual offset is: %ld", stc_queue_read); } - // FIXME: if count > _max_line_size, a deadlock or SEGFAULT is foreseen Fix it asap. - // FIXME: still this might not occur as the read() method should protect from this event + // TODO: this code is not needed as the read size is allways at maximum the size of the + // cache line /*auto read_size = stc_queue_read; while (read_size > 0) { const capio_off64_t tmp_read_size = @@ -70,7 +70,7 @@ class ReadRequestCacheMEM { return stc_queue_read; } -public: + public: explicit ReadRequestCacheMEM(const long line_size = get_posix_read_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) { @@ -87,27 +87,27 @@ class ReadRequestCacheMEM { if (_cache_offset != _actual_size) { _actual_size = _cache_offset = 0; } - committed = false; + committed = false; _real_file_size_commmitted = -1; } long read(const int fd, void *buffer, off64_t count) { START_LOG(capio_syscall(SYS_gettid), "call(fd=%d, count=%ld)", fd, count); - long actual_read_size = 0;\ + long actual_read_size = 0; if (_fd != fd) { LOG("changed fd from %d to %d: flushing", _fd, fd); flush(); - _fd = fd; + _fd = fd; _last_read_end = get_capio_fd_offset(fd); } // Check if a seek has occurred before and in case in which case flush the cache // and update the offset to the new value if (_last_read_end != get_capio_fd_offset(_fd)) { - LOG( - "A seek() has occurred (_last_read_end=%llu, get_capio_fd_offset=%llu). Performing flush().", + LOG("A seek() has occurred (_last_read_end=%llu, get_capio_fd_offset=%llu). Performing " + "flush().", _last_read_end, get_capio_fd_offset(_fd)); flush(); _last_read_end = get_capio_fd_offset(_fd); @@ -122,7 +122,7 @@ class ReadRequestCacheMEM { if (_actual_size == 0 || _actual_size == _cache_offset) { LOG("No data is present locally. performing request."); const auto size = count < _max_line_size ? count : _max_line_size; - _actual_size = read_request(_fd, size, _tid); + _actual_size = read_request(_fd, size, _tid); } if (count <= _max_line_size - _cache_offset) { @@ -130,15 +130,15 @@ class ReadRequestCacheMEM { LOG("The requested amount of data can be served without performing a request"); _read(buffer, count); actual_read_size = count; - _last_read_end = get_capio_fd_offset(_fd) + count; + _last_read_end = get_capio_fd_offset(_fd) + count; set_capio_fd_offset(fd, _last_read_end); } else { // There could be some data available already on the cache. Copy that first and then // proceed to request the other missing data - const auto first_copy_size = std::min(_actual_size - _cache_offset, - static_cast(count)); + const auto first_copy_size = + std::min(_actual_size - _cache_offset, static_cast(count)); LOG("Data (or part of it) might be already present. performing first copy of" " std::min(_actual_size(%llu) - _cache_offset(%llu), count(%llu) = %ld", @@ -151,7 +151,7 @@ class ReadRequestCacheMEM { LOG("actual_read_size incremented to: %ld", actual_read_size); // Compute the remaining amount of data to send to client - auto remaining_size = count - first_copy_size; + auto remaining_size = count - first_copy_size; capio_off64_t copy_offset = first_copy_size; while (copy_offset < count && !committed) { @@ -180,7 +180,6 @@ class ReadRequestCacheMEM { _last_read_end = get_capio_fd_offset(_fd) + size_to_send_to_client; set_capio_fd_offset(fd, _last_read_end); } - } LOG("Read return value: %ld (_last_Read_end = %llu)", actual_read_size, _last_read_end); diff --git a/src/server/storage-service/CapioFile/CapioMemoryFile.hpp b/src/server/storage-service/CapioFile/CapioMemoryFile.hpp index f7f94581a..e2d13b280 100644 --- a/src/server/storage-service/CapioFile/CapioMemoryFile.hpp +++ b/src/server/storage-service/CapioFile/CapioMemoryFile.hpp @@ -16,7 +16,7 @@ class CapioMemoryFile : public CapioFile { std::map> memoryBlocks; // Static file sizes of file pages - static constexpr u_int32_t _pageSizeMB = 4; + static constexpr u_int32_t _pageSizeMB = 4; static constexpr u_int64_t _pageSizeBytes = _pageSizeMB * 1024 * 1024; /** @@ -26,6 +26,8 @@ class CapioMemoryFile : public CapioFile { * @return tuple */ static auto compute_offsets(const std::size_t offset, std::size_t length) { + + START_LOG(gettid(), "call(offset=%llu, length=%llu)", offset, length); // Compute the offset of the memoryBlocks component. const auto map_offset = offset / _pageSizeBytes; @@ -37,8 +39,10 @@ class CapioMemoryFile : public CapioFile { // distance between the write offset and the end of the page. otherwise it is possible to // use the given length. The returned offset starts from mem_block_offset const auto first_write_size = - length > _pageSizeBytes ? _pageSizeBytes - mem_block_offset : length; + length > _pageSizeBytes - mem_block_offset ? _pageSizeBytes - mem_block_offset : length; + LOG("Computed offsets. map_offset=%llu, mem_block_offset=%llu, first_write_size=%llu", + map_offset, mem_block_offset, first_write_size); return std::tuple(map_offset, mem_block_offset, first_write_size); } @@ -53,9 +57,8 @@ class CapioMemoryFile : public CapioFile { return block; } -public: - explicit CapioMemoryFile(const std::string &filePath) : CapioFile(filePath) { - } + public: + explicit CapioMemoryFile(const std::string &filePath) : CapioFile(filePath) {} /** * Write data to a file stored inside the memory @@ -184,17 +187,58 @@ class CapioMemoryFile : public CapioFile { std::size_t length) const override { std::size_t bytesRead = 0; - const auto &[map_offset, mem_block_offset_begin, buffer_view_size] = - compute_offsets(offset, length); + const auto offsets = compute_offsets(offset, length); + unsigned long map_offset = std::get<0>(offsets); + unsigned long mem_block_offset_begin = std::get<1>(offsets); + unsigned long buffer_view_size = std::get<2>(offsets); + + if (buffer_view_size != length) { + /* + * In this case, we have requested a view that spansa over different memory blocks and + * cannot be served in a contiguos manner. We allocate a temporary buffer that is used + * to overlap the two memory block region and then write the temporary buffer. + * This requires more memcpy but it is invoked only when the view overlaps and as such + * is not frequent. + */ + + auto buffer_view = new char[length]; + + for (auto it = memoryBlocks.lower_bound(map_offset); + it != memoryBlocks.end() && bytesRead < length; ++it) { + auto &[blockOffset, block] = *it; + + if (blockOffset >= offset + length) { + break; // Past the requested range + } + + // Copy the data to the temporary buffer + memcpy(buffer_view + bytesRead, block.data() + mem_block_offset_begin, + buffer_view_size); + + bytesRead += buffer_view_size; + + const auto updated_offsets = + compute_offsets(offset + bytesRead, length - bytesRead); + map_offset = std::get<0>(updated_offsets); + mem_block_offset_begin = std::get<1>(updated_offsets); + buffer_view_size = std::get<2>(updated_offsets); + } - // Traverse the memory blocks to read the requested data starting from the first block of - // date - for (auto it = memoryBlocks.lower_bound(map_offset); - it != memoryBlocks.end() && bytesRead < length; ++it) { + // send the temporary buffer to the application + queue.write(buffer_view, bytesRead); + + delete[] buffer_view; + return bytesRead; + } + + /* + * Here we have requested a read that spans over a single memory block. + */ + if (const auto it = memoryBlocks.lower_bound(map_offset); it != memoryBlocks.end()) { auto &[blockOffset, block] = *it; if (blockOffset >= offset + length) { - break; // Past the requested range + return bytesRead; // Past the requested range } // Copy the data to the buffer From 6221bd02f1f7a9f5609acbe6b04aea7380696e78 Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Fri, 2 May 2025 10:48:16 +0000 Subject: [PATCH 18/33] Fixed custom cache line size issues Caches now work independently of size. Increased posix read cache line size to 32K of data --- src/common/capio/constants.hpp | 2 +- src/posix/utils/cache/read_request_cache_mem.hpp | 6 ++++-- src/server/client-manager/handlers/read.hpp | 11 +++++------ 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/common/capio/constants.hpp b/src/common/capio/constants.hpp index 75b35d71c..aaade0322 100644 --- a/src/common/capio/constants.hpp +++ b/src/common/capio/constants.hpp @@ -29,7 +29,7 @@ constexpr char CAPIO_SHM_CANARY_ERROR[] = // CAPIO communication constants constexpr int CAPIO_REQ_BUFF_CNT = 512; // Max number of elements inside buffers constexpr int CAPIO_CACHE_LINES_DEFAULT = 10; -constexpr int CAPIO_CACHE_LINE_SIZE_DEFAULT = 4096; +constexpr int CAPIO_CACHE_LINE_SIZE_DEFAULT = 32768; // 32K of default size for cache lines // TODO: use that in communication only uses the file descriptor instead of the path to save on the // PATH_MAX constexpr size_t CAPIO_REQ_MAX_SIZE = (PATH_MAX + 256) * sizeof(char); diff --git a/src/posix/utils/cache/read_request_cache_mem.hpp b/src/posix/utils/cache/read_request_cache_mem.hpp index 76e9fdaf4..21efbb6af 100644 --- a/src/posix/utils/cache/read_request_cache_mem.hpp +++ b/src/posix/utils/cache/read_request_cache_mem.hpp @@ -1,8 +1,6 @@ #ifndef READ_REQUEST_CACHE_MEM_HPP #define READ_REQUEST_CACHE_MEM_HPP -// TODO: REFACTOR THIS MESS OF CODE - class ReadRequestCacheMEM { char *_cache; long _tid; @@ -123,6 +121,10 @@ class ReadRequestCacheMEM { LOG("No data is present locally. performing request."); const auto size = count < _max_line_size ? count : _max_line_size; _actual_size = read_request(_fd, size, _tid); + + // Update count for current request. If count exceeds _actual_size, resize it to not + // exceeds the available size on posix application + count = std::min(static_cast(count), _actual_size); } if (count <= _max_line_size - _cache_offset) { diff --git a/src/server/client-manager/handlers/read.hpp b/src/server/client-manager/handlers/read.hpp index d25ba1539..f80b7b44c 100644 --- a/src/server/client-manager/handlers/read.hpp +++ b/src/server/client-manager/handlers/read.hpp @@ -74,19 +74,18 @@ inline void read_mem_handler(const char *const str) { } LOG("Computing size of data to send: minimum between:"); - LOG("read_size: %llu", read_size); LOG("client_cache_line_size: %llu", client_cache_line_size); LOG("file_size:%llu - read_begin_offset=%llu = %llu", storage_service->sizeOf(path), - read_begin_offset, storage_service->sizeOf(path)- read_begin_offset); - auto size_to_send = std::min({read_size, client_cache_line_size, - (storage_service->sizeOf(path) - read_begin_offset)}); + read_begin_offset, storage_service->sizeOf(path) - read_begin_offset); + auto size_to_send = + std::min({client_cache_line_size, (storage_service->sizeOf(path) - read_begin_offset)}); LOG("Need to sent to client %llu bytes, asking storage service to send data", size_to_send); storage_service->reply_to_client(tid, path, read_begin_offset, size_to_send); LOG("Sending to posix app the offset up to which read."); - if (file_manager->isCommitted(path) && read_begin_offset + size_to_send >= storage_service-> - sizeOf(path)) { + if (file_manager->isCommitted(path) && + read_begin_offset + size_to_send >= storage_service->sizeOf(path)) { LOG("File is committed, and end of read >= than file size." " signaling it to posix application by setting offset MSB to 1"); size_to_send = 0x8000000000000000 | size_to_send; From 06859159202fb705d072931b267d24dabcb7d91f Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Fri, 2 May 2025 13:41:36 +0000 Subject: [PATCH 19/33] Fixes --- .../CapioFile/CapioMemoryFile.hpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/server/storage-service/CapioFile/CapioMemoryFile.hpp b/src/server/storage-service/CapioFile/CapioMemoryFile.hpp index e2d13b280..c38276052 100644 --- a/src/server/storage-service/CapioFile/CapioMemoryFile.hpp +++ b/src/server/storage-service/CapioFile/CapioMemoryFile.hpp @@ -19,6 +19,8 @@ class CapioMemoryFile : public CapioFile { static constexpr u_int32_t _pageSizeMB = 4; static constexpr u_int64_t _pageSizeBytes = _pageSizeMB * 1024 * 1024; + char *cross_page_buffer_view; + /** * Compute the offsets required to handle write operations onto CapioMemoryFile * @param offset Offset from the start of the file, on which the write operation will begin @@ -58,7 +60,13 @@ class CapioMemoryFile : public CapioFile { } public: - explicit CapioMemoryFile(const std::string &filePath) : CapioFile(filePath) {} + explicit CapioMemoryFile(const std::string &filePath) : CapioFile(filePath) { + cross_page_buffer_view = new char[_pageSizeBytes]; + } + + ~CapioMemoryFile() override { + delete[] cross_page_buffer_view; + } /** * Write data to a file stored inside the memory @@ -201,7 +209,6 @@ class CapioMemoryFile : public CapioFile { * is not frequent. */ - auto buffer_view = new char[length]; for (auto it = memoryBlocks.lower_bound(map_offset); it != memoryBlocks.end() && bytesRead < length; ++it) { @@ -212,7 +219,7 @@ class CapioMemoryFile : public CapioFile { } // Copy the data to the temporary buffer - memcpy(buffer_view + bytesRead, block.data() + mem_block_offset_begin, + memcpy(cross_page_buffer_view + bytesRead, block.data() + mem_block_offset_begin, buffer_view_size); bytesRead += buffer_view_size; @@ -225,9 +232,8 @@ class CapioMemoryFile : public CapioFile { } // send the temporary buffer to the application - queue.write(buffer_view, bytesRead); + queue.write(cross_page_buffer_view, bytesRead); - delete[] buffer_view; return bytesRead; } From 739ae8b8b7f6a6be275d4e07fe28499279b4bfb7 Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Mon, 5 May 2025 10:02:12 +0200 Subject: [PATCH 20/33] Improved test with bandwidth data --- read_write_test.cpp | 130 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 102 insertions(+), 28 deletions(-) diff --git a/read_write_test.cpp b/read_write_test.cpp index ecd575cb3..e508b5bd8 100644 --- a/read_write_test.cpp +++ b/read_write_test.cpp @@ -1,10 +1,11 @@ +#include #include #include #include #include const std::string filename = "hello.txt"; -const size_t textSize = 16 * 1024 * 1024; // 32 MBB +const size_t textSize = 32 * 1024 * 1024; // 32 MBB // Generate a large text (e.g., repeating a pattern) std::string generateLongText() { @@ -20,56 +21,129 @@ std::string generateLongText() { return longText; } -void writeToFile(const std::string& content) { - std::ofstream outFile(filename, std::ios::out | std::ios::binary); - if (!outFile) { - std::cout << "Error opening file for writing!\n"; + +void print_surrounding_lines(const std::string &content, std::size_t offset) { + if (offset >= content.size()) { + std::cerr << "Offset is out of range.\n"; return; } - outFile.write(content.c_str(), content.size()); - outFile.close(); - std::cout << "Successfully wrote " << content.size() << " bytes to " << filename << "\n"; + + // Find start of current line + std::size_t line_start = content.rfind('\n', offset); + line_start = (line_start == std::string::npos) ? 0 : line_start + 1; + + // Find end of current line + std::size_t line_end = content.find('\n', offset); + line_end = (line_end == std::string::npos) ? content.size() : line_end; + + // Extract current line + std::string current_line = content.substr(line_start, line_end - line_start); + + // Find previous line + if (line_start > 0) { + const std::size_t prev_end = line_start - 1; + std::size_t prev_start = content.rfind('\n', prev_end); + prev_start = (prev_start == std::string::npos) ? 0 : prev_start + 1; + const std::string prev_line = content.substr(prev_start, prev_end - prev_start + 1); + if (!prev_line.empty()) { + std::cout << "Previous line : [" << prev_start << "]" << prev_line << "\n"; + } + } else { + std::cout << "Previous line: [None]\n"; + } + + std::cout << "Offending line: [" << line_start << "] " << current_line << "\n"; + + // Find next line + if (line_end < content.size()) { + std::size_t next_start = line_end + 1; + std::size_t next_end = content.find('\n', next_start); + if (next_end == std::string::npos) + next_end = content.size(); + std::string next_line = content.substr(next_start, next_end - next_start); + + if (!next_line.empty()) { + std::cout << "Next line : [" << next_start << "]" << next_line << "\n"; + } + } else { + std::cout << "Next line: [None]\n"; + } + } -void readFromFile(const std::string& expectedContent) { + +void readFromFile(const std::string &expectedContent) { + + std::string fileContent(textSize, ' '); + + auto write_start = std::chrono::high_resolution_clock::now(); + std::ifstream inFile(filename, std::ios::in | std::ios::binary); if (!inFile) { std::cout << "Error opening file for reading!\n"; return; } - - std::string fileContent((std::istreambuf_iterator(inFile)), - std::istreambuf_iterator()); + if (!inFile.read(fileContent.data(), fileContent.size())) { + std::cerr << "Failed to read file content.\n"; + exit(-1); + } inFile.close(); + auto write_end = std::chrono::high_resolution_clock::now(); + std::chrono::duration elapsed = write_end - write_start; + double bandwidthMBps = (textSize / (1024.0 * 1024.0)) / elapsed.count(); + std::cout << "READ(): " << bandwidthMBps << " MB/s (in " << elapsed.count() << ")" << std::endl; + bool match = true; size_t minLength = std::min(fileContent.size(), expectedContent.size()); + if (fileContent.size() != expectedContent.size()) { + std::cout << "Mismatch in size!\n"; + std::cout << "Expected size: " << expectedContent.size() << ", Found size: " << + fileContent.size() << "\n"; + exit(-1); + } + for (size_t i = 0; i < minLength; ++i) { if (fileContent[i] != expectedContent[i]) { std::cout << "Mismatch at position " << i << ":\n"; - std::cout << "Expected: '" << expectedContent[i] << "' (ASCII " << static_cast(expectedContent[i]) << ")\n"; - std::cout << "Found: '" << fileContent[i] << "' (ASCII " << static_cast(fileContent[i]) << ")\n"; - match = false; + std::cout << "Expected: '" << expectedContent[i] << "' (ASCII " << static_cast( + expectedContent[i]) << ")\n"; + std::cout << "Found: '" << fileContent[i] << "' (ASCII " << static_cast( + fileContent[i]) << ")\n"; + print_surrounding_lines(fileContent, i); exit(-1); } } + std::cout << "Content matches expected text.\n"; - if (match) { - if (fileContent.size() != expectedContent.size()) { - std::cout << "Mismatch in size!\n"; - std::cout << "Expected size: " << expectedContent.size() << ", Found size: " << fileContent.size() << "\n"; - match = false; - } else { - std::cout << "Content matches expected text.\n"; - } - } - // std::cout << "\nFile content:\n" << fileContent << "\n"; } -int main(int argc, char* argv[]) { +int main(int argc, char *argv[]) { std::string longText = generateLongText(); - writeToFile(longText); + auto write_start = std::chrono::high_resolution_clock::now(); + std::ofstream outFile(filename, std::ios::out | std::ios::binary); + if (!outFile) { + std::cout << "Error opening file for writing!\n"; + exit(-1); + } + outFile.write(longText.c_str(), longText.size()); + outFile.close(); + std::cout << "Successfully wrote " << longText.size() << " bytes to " << filename << std::endl; + + /*Read a single byte to wait for caches to empty*/ + std::ifstream file(filename, std::ios::binary); + char byte; + file.read(&byte, 1); // Read a single byte + file.close(); + auto write_end = std::chrono::high_resolution_clock::now(); + + std::chrono::duration elapsed = write_end - write_start; + double bandwidthMBps = (textSize / (1024.0 * 1024.0)) / elapsed.count(); + + std::cout << "WRITE(): " << bandwidthMBps << " MB/s" << std::endl; + readFromFile(longText); + return 0; -} +} \ No newline at end of file From a8fa5227b9c201670c397e78c54ca0ed61a4aad4 Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Mon, 5 May 2025 14:20:34 +0200 Subject: [PATCH 21/33] Performance improvement for data transfer Since caches are used to improve performance for small size IO operation, when a read() operation that targets a size greater than the size of the read cache line size is issued, the cache is being bypassed and the read operation occurs directly from the shared memory segment. --- .../utils/cache/read_request_cache_mem.hpp | 57 ++++++++++-------- src/server/client-manager/handlers/read.hpp | 31 ++++++---- .../CapioFile/CapioMemoryFile.hpp | 59 +++---------------- .../storage-service/capio_storage_service.hpp | 16 ++--- 4 files changed, 67 insertions(+), 96 deletions(-) diff --git a/src/posix/utils/cache/read_request_cache_mem.hpp b/src/posix/utils/cache/read_request_cache_mem.hpp index 21efbb6af..3ff6aa12c 100644 --- a/src/posix/utils/cache/read_request_cache_mem.hpp +++ b/src/posix/utils/cache/read_request_cache_mem.hpp @@ -24,10 +24,11 @@ class ReadRequestCacheMEM { } } - protected: +protected: [[nodiscard]] capio_off64_t read_request(const int fd, const capio_off64_t count, - const long tid) { - START_LOG(capio_syscall(SYS_gettid), "call(fd=%ld, count=%llu, tid=%ld)", fd, count, tid); + const long tid, bool use_cache = true) { + START_LOG(capio_syscall(SYS_gettid), "call(fd=%ld, count=%llu, tid=%ld, load_data=%s)", fd, + count, tid, use_cache ? "true" : "false"); char req[CAPIO_REQ_MAX_SIZE]; // send as the last parameter to the server the maximum amount of data that can be read into @@ -35,8 +36,8 @@ class ReadRequestCacheMEM { auto read_begin_offset = get_capio_fd_offset(fd); - sprintf(req, "%04d %ld %llu %llu %llu %s", CAPIO_REQUEST_READ_MEM, tid, read_begin_offset, - count, _max_line_size, get_capio_fd_path(fd).c_str()); + sprintf(req, "%04d %ld %llu %llu %llu %d %s", CAPIO_REQUEST_READ_MEM, tid, + read_begin_offset, count, _max_line_size, use_cache, get_capio_fd_path(fd).c_str()); LOG("Sending read request %s", req); buf_requests->write(req, CAPIO_REQ_MAX_SIZE); capio_off64_t stc_queue_read = bufs_response->at(tid)->read(); @@ -49,26 +50,21 @@ class ReadRequestCacheMEM { LOG("File is commited. Actual offset is: %ld", stc_queue_read); } - // TODO: this code is not needed as the read size is allways at maximum the size of the - // cache line - /*auto read_size = stc_queue_read; - while (read_size > 0) { - const capio_off64_t tmp_read_size = - read_size > _max_line_size ? _max_line_size : read_size; - stc_queue->read(_cache, tmp_read_size); + if (use_cache) { + stc_queue->read(_cache, stc_queue_read); _cache_offset = 0; - read_size -= tmp_read_size; - }*/ - - stc_queue->read(_cache, stc_queue_read); - _cache_offset = 0; - - LOG("Completed fetch of data from server"); + LOG("Completed fetch of data from server"); + } else { + _actual_size = 0; + _cache_offset = 0; + LOG("Data has not been loaded from server, as load_data==false." + " Load will occur indipendently"); + } return stc_queue_read; } - public: +public: explicit ReadRequestCacheMEM(const long line_size = get_posix_read_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) { @@ -85,7 +81,7 @@ class ReadRequestCacheMEM { if (_cache_offset != _actual_size) { _actual_size = _cache_offset = 0; } - committed = false; + committed = false; _real_file_size_commmitted = -1; } @@ -97,7 +93,7 @@ class ReadRequestCacheMEM { if (_fd != fd) { LOG("changed fd from %d to %d: flushing", _fd, fd); flush(); - _fd = fd; + _fd = fd; _last_read_end = get_capio_fd_offset(fd); } @@ -116,11 +112,22 @@ class ReadRequestCacheMEM { return 0; } + /* + * Check: if read size is greater than the capability of the cache line, bypass + * the cache and perform a read directly to the provided buffer + */ + if (count > _max_line_size) { + LOG("count > _max_line_size. Bypassing cache. Performing read() directly to buffer."); + const auto _read_size = read_request(_fd, count, _tid, false); + stc_queue->read(static_cast(buffer), _read_size); + return _read_size; + } + // Check if cache is empty or if all the content of the cache has been already consumed if (_actual_size == 0 || _actual_size == _cache_offset) { LOG("No data is present locally. performing request."); const auto size = count < _max_line_size ? count : _max_line_size; - _actual_size = read_request(_fd, size, _tid); + _actual_size = read_request(_fd, size, _tid); // Update count for current request. If count exceeds _actual_size, resize it to not // exceeds the available size on posix application @@ -132,7 +139,7 @@ class ReadRequestCacheMEM { LOG("The requested amount of data can be served without performing a request"); _read(buffer, count); actual_read_size = count; - _last_read_end = get_capio_fd_offset(_fd) + count; + _last_read_end = get_capio_fd_offset(_fd) + count; set_capio_fd_offset(fd, _last_read_end); } else { @@ -153,7 +160,7 @@ class ReadRequestCacheMEM { LOG("actual_read_size incremented to: %ld", actual_read_size); // Compute the remaining amount of data to send to client - auto remaining_size = count - first_copy_size; + auto remaining_size = count - first_copy_size; capio_off64_t copy_offset = first_copy_size; while (copy_offset < count && !committed) { diff --git a/src/server/client-manager/handlers/read.hpp b/src/server/client-manager/handlers/read.hpp index f80b7b44c..fdd402771 100644 --- a/src/server/client-manager/handlers/read.hpp +++ b/src/server/client-manager/handlers/read.hpp @@ -57,13 +57,15 @@ inline void read_handler(const char *const str) { inline void read_mem_handler(const char *const str) { pid_t tid; capio_off64_t read_size, client_cache_line_size, read_begin_offset; + int use_cache; char path[PATH_MAX]; - sscanf(str, "%ld %llu %llu %llu %s", &tid, &read_begin_offset, &read_size, - &client_cache_line_size, path); + sscanf(str, "%ld %llu %llu %llu %d %s", &tid, &read_begin_offset, &read_size, + &client_cache_line_size, &use_cache, path); START_LOG(gettid(), "call(tid=%d, read_begin_offset=%llu, read_size=%llu, client_cache_line_size=%llu, " - "path=%s)", - tid, read_begin_offset, read_size, client_cache_line_size, path); + "use_cache=%s, path=%s)", + tid, read_begin_offset, read_size, client_cache_line_size, + use_cache ? "true" : "false", path); if (storage_service->sizeOf(path) < read_begin_offset + read_size && !file_manager->isCommitted(path)) { @@ -73,15 +75,15 @@ inline void read_mem_handler(const char *const str) { return; } - LOG("Computing size of data to send: minimum between:"); - LOG("client_cache_line_size: %llu", client_cache_line_size); - LOG("file_size:%llu - read_begin_offset=%llu = %llu", storage_service->sizeOf(path), - read_begin_offset, storage_service->sizeOf(path) - read_begin_offset); - auto size_to_send = - std::min({client_cache_line_size, (storage_service->sizeOf(path) - read_begin_offset)}); - - LOG("Need to sent to client %llu bytes, asking storage service to send data", size_to_send); - storage_service->reply_to_client(tid, path, read_begin_offset, size_to_send); + capio_off64_t size_to_send = storage_service->sizeOf(path); + if (use_cache) { + LOG("Computing size of data to send: minimum between:"); + LOG("client_cache_line_size: %llu", client_cache_line_size); + LOG("file_size:%llu - read_begin_offset=%llu = %llu", size_to_send, + read_begin_offset, size_to_send - read_begin_offset); + size_to_send = + std::min({client_cache_line_size, (size_to_send - read_begin_offset)}); + } LOG("Sending to posix app the offset up to which read."); if (file_manager->isCommitted(path) && @@ -92,6 +94,9 @@ inline void read_mem_handler(const char *const str) { } LOG("Sending offset: %llu", size_to_send); client_manager->reply_to_client(tid, size_to_send); + + LOG("Need to sent to client %llu bytes, asking storage service to send data", size_to_send); + storage_service->reply_to_client(tid, path, read_begin_offset, size_to_send); } #endif // READ_HPP \ No newline at end of file diff --git a/src/server/storage-service/CapioFile/CapioMemoryFile.hpp b/src/server/storage-service/CapioFile/CapioMemoryFile.hpp index c38276052..871d910ce 100644 --- a/src/server/storage-service/CapioFile/CapioMemoryFile.hpp +++ b/src/server/storage-service/CapioFile/CapioMemoryFile.hpp @@ -16,7 +16,7 @@ class CapioMemoryFile : public CapioFile { std::map> memoryBlocks; // Static file sizes of file pages - static constexpr u_int32_t _pageSizeMB = 4; + static constexpr u_int32_t _pageSizeMB = 4; static constexpr u_int64_t _pageSizeBytes = _pageSizeMB * 1024 * 1024; char *cross_page_buffer_view; @@ -59,7 +59,7 @@ class CapioMemoryFile : public CapioFile { return block; } - public: +public: explicit CapioMemoryFile(const std::string &filePath) : CapioFile(filePath) { cross_page_buffer_view = new char[_pageSizeBytes]; } @@ -195,64 +195,23 @@ class CapioMemoryFile : public CapioFile { std::size_t length) const override { std::size_t bytesRead = 0; - const auto offsets = compute_offsets(offset, length); - unsigned long map_offset = std::get<0>(offsets); - unsigned long mem_block_offset_begin = std::get<1>(offsets); - unsigned long buffer_view_size = std::get<2>(offsets); + while (bytesRead < length) { + const auto [map_offset,mem_block_offset_begin , buffer_view_size] = + compute_offsets(offset, length); - if (buffer_view_size != length) { - /* - * In this case, we have requested a view that spansa over different memory blocks and - * cannot be served in a contiguos manner. We allocate a temporary buffer that is used - * to overlap the two memory block region and then write the temporary buffer. - * This requires more memcpy but it is invoked only when the view overlaps and as such - * is not frequent. - */ - - - for (auto it = memoryBlocks.lower_bound(map_offset); - it != memoryBlocks.end() && bytesRead < length; ++it) { + if (const auto it = memoryBlocks.lower_bound(map_offset); it != memoryBlocks.end()) { auto &[blockOffset, block] = *it; if (blockOffset >= offset + length) { - break; // Past the requested range + return bytesRead; // Past the requested range } - // Copy the data to the temporary buffer - memcpy(cross_page_buffer_view + bytesRead, block.data() + mem_block_offset_begin, - buffer_view_size); + // Copy the data to the buffer + queue.write(block.data() + mem_block_offset_begin, buffer_view_size); bytesRead += buffer_view_size; - - const auto updated_offsets = - compute_offsets(offset + bytesRead, length - bytesRead); - map_offset = std::get<0>(updated_offsets); - mem_block_offset_begin = std::get<1>(updated_offsets); - buffer_view_size = std::get<2>(updated_offsets); - } - - // send the temporary buffer to the application - queue.write(cross_page_buffer_view, bytesRead); - - return bytesRead; - } - - /* - * Here we have requested a read that spans over a single memory block. - */ - if (const auto it = memoryBlocks.lower_bound(map_offset); it != memoryBlocks.end()) { - auto &[blockOffset, block] = *it; - - if (blockOffset >= offset + length) { - return bytesRead; // Past the requested range } - - // Copy the data to the buffer - queue.write(block.data() + mem_block_offset_begin, buffer_view_size); - - bytesRead += buffer_view_size; } - return bytesRead; } }; diff --git a/src/server/storage-service/capio_storage_service.hpp b/src/server/storage-service/capio_storage_service.hpp index 724bf91d7..7f3f0aa61 100644 --- a/src/server/storage-service/capio_storage_service.hpp +++ b/src/server/storage-service/capio_storage_service.hpp @@ -10,7 +10,7 @@ class CapioStorageService { // TODO: put all of this conde on a different thread std::unordered_map *_client_to_server_queue; - std::unordered_map *_server_to_clien_queue; + std::unordered_map *_server_to_client_queue; std::unordered_map *_stored_files; std::unordered_map>> @@ -33,7 +33,7 @@ class CapioStorageService { START_LOG(gettid(), "call()"); _stored_files = new std::unordered_map; _client_to_server_queue = new std::unordered_map; - _server_to_clien_queue = new std::unordered_map; + _server_to_client_queue = new std::unordered_map; _threads_waiting_for_memory_data = new std::unordered_map>>; @@ -45,7 +45,7 @@ class CapioStorageService { // TODO: dump files to FS delete _stored_files; delete _client_to_server_queue; - delete _server_to_clien_queue; + delete _server_to_client_queue; delete _threads_waiting_for_memory_data; } @@ -116,7 +116,7 @@ class CapioStorageService { _client_to_server_queue->emplace( pid, new SPSCQueue("queue-" + std::to_string(pid) + +".cts", get_cache_lines(), get_cache_line_size(), workflow_name, false)); - _server_to_clien_queue->emplace( + _server_to_client_queue->emplace( pid, new SPSCQueue("queue-" + std::to_string(pid) + +".stc", get_cache_lines(), get_cache_line_size(), workflow_name, false)); LOG("Created communication queues"); @@ -134,7 +134,7 @@ class CapioStorageService { START_LOG(gettid(), "call(pid=%llu, file=%s, offset=%llu, size=%llu)", pid, file.c_str(), offset, size); - getFile(file)->writeToQueue(*_server_to_clien_queue->at(pid), offset, size); + getFile(file)->writeToQueue(*_server_to_client_queue->at(pid), offset, size); } /** @@ -155,7 +155,7 @@ class CapioStorageService { void remove_client(const pid_t pid) const { _client_to_server_queue->erase(pid); - _server_to_clien_queue->erase(pid); + _server_to_client_queue->erase(pid); } /** @@ -173,7 +173,7 @@ class CapioStorageService { auto c_dir = get_capio_dir().string(); memcpy(f, c_dir.c_str(), c_dir.length()); memcpy(f + c_dir.size(), "/*", 2); - _server_to_clien_queue->at(pid)->write(f, PATH_MAX); + _server_to_client_queue->at(pid)->write(f, PATH_MAX); LOG("Return value=%llu", 1); return 1; } @@ -183,7 +183,7 @@ class CapioStorageService { LOG("Sending file %s", file.c_str()); char f[PATH_MAX + 1]{0}; memcpy(f, file.c_str(), file.size()); - _server_to_clien_queue->at(pid)->write(f, PATH_MAX); + _server_to_client_queue->at(pid)->write(f, PATH_MAX); } LOG("Return value=%llu", files_to_store_in_mem.size()); From a095f7d99bbcf9e2cabbbb19e52c2f2ba2fad42a Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Tue, 6 May 2025 09:39:37 +0200 Subject: [PATCH 22/33] Fixes --- src/server/client-manager/handlers/read.hpp | 8 +++++--- src/server/storage-service/CapioFile/CapioMemoryFile.hpp | 4 +++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/server/client-manager/handlers/read.hpp b/src/server/client-manager/handlers/read.hpp index fdd402771..69e21ed2a 100644 --- a/src/server/client-manager/handlers/read.hpp +++ b/src/server/client-manager/handlers/read.hpp @@ -90,10 +90,12 @@ inline void read_mem_handler(const char *const str) { read_begin_offset + size_to_send >= storage_service->sizeOf(path)) { LOG("File is committed, and end of read >= than file size." " signaling it to posix application by setting offset MSB to 1"); - size_to_send = 0x8000000000000000 | size_to_send; + LOG("Sending offset: %llu", 0x8000000000000000 |size_to_send); + client_manager->reply_to_client(tid, 0x8000000000000000 | size_to_send); + } else { + LOG("File is not committed. Sending offset: %llu", size_to_send); + client_manager->reply_to_client(tid, size_to_send); } - LOG("Sending offset: %llu", size_to_send); - client_manager->reply_to_client(tid, size_to_send); LOG("Need to sent to client %llu bytes, asking storage service to send data", size_to_send); storage_service->reply_to_client(tid, path, read_begin_offset, size_to_send); diff --git a/src/server/storage-service/CapioFile/CapioMemoryFile.hpp b/src/server/storage-service/CapioFile/CapioMemoryFile.hpp index 871d910ce..f1c012684 100644 --- a/src/server/storage-service/CapioFile/CapioMemoryFile.hpp +++ b/src/server/storage-service/CapioFile/CapioMemoryFile.hpp @@ -193,11 +193,12 @@ class CapioMemoryFile : public CapioFile { */ std::size_t writeToQueue(SPSCQueue &queue, std::size_t offset, std::size_t length) const override { + START_LOG(gettid(), "call(offset=%llu, length=%llu)", offset, length); std::size_t bytesRead = 0; while (bytesRead < length) { const auto [map_offset,mem_block_offset_begin , buffer_view_size] = - compute_offsets(offset, length); + compute_offsets(offset, length - bytesRead); if (const auto it = memoryBlocks.lower_bound(map_offset); it != memoryBlocks.end()) { auto &[blockOffset, block] = *it; @@ -210,6 +211,7 @@ class CapioMemoryFile : public CapioFile { queue.write(block.data() + mem_block_offset_begin, buffer_view_size); bytesRead += buffer_view_size; + offset += buffer_view_size; } } return bytesRead; From f7bc6bfb3fdb4cf42f92d1a02c6dff7af4da7216 Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Tue, 6 May 2025 10:00:48 +0200 Subject: [PATCH 23/33] code cleanup --- src/common/capio/queue.hpp | 25 ++-- .../capio-cl-engine/capio_cl_engine.hpp | 116 +++++++++--------- src/server/capio-cl-engine/json_parser.hpp | 116 +++++++++--------- 3 files changed, 130 insertions(+), 127 deletions(-) diff --git a/src/common/capio/queue.hpp b/src/common/capio/queue.hpp index 1854657d8..d1282aa27 100644 --- a/src/common/capio/queue.hpp +++ b/src/common/capio/queue.hpp @@ -18,10 +18,10 @@ * @tparam Mutex Type of semaphore */ template class Queue { - private: +private: void *_shm; const long int _max_num_elems, _elem_size; // elements size in bytes - long int _buff_size; // buffer size in bytes + long int _buff_size; // buffer size in bytes long int *_first_elem = nullptr, *_last_elem = nullptr; const std::string _shm_name, _first_elem_name, _last_elem_name; bool require_cleanup; @@ -50,7 +50,7 @@ template class Queue { _sem_num_elems.unlock(); } - public: +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) : _max_num_elems(max_num_elems), _elem_size(elem_size), @@ -69,20 +69,21 @@ template class Queue { syscall_no_intercept_flag = true; #endif _first_elem = (long int *) create_shm(_first_elem_name, sizeof(long int)); - _last_elem = (long int *) create_shm(_last_elem_name, sizeof(long int)); - _shm = get_shm_if_exist(_shm_name); + _last_elem = (long int *) create_shm(_last_elem_name, sizeof(long int)); + _shm = get_shm_if_exist(_shm_name); if (_shm == nullptr) { *_first_elem = 0; - *_last_elem = 0; - _shm = create_shm(_shm_name, _buff_size); + *_last_elem = 0; + _shm = create_shm(_shm_name, _buff_size); } #ifdef __CAPIO_POSIX syscall_no_intercept_flag = false; #endif } - Queue(const Queue &) = delete; + Queue(const Queue &) = delete; Queue &operator=(const Queue &) = delete; + ~Queue() { START_LOG(capio_syscall(SYS_gettid), "call(_shm_name=%s, _first_elem_name=%s, _last_elem_name=%s)", _shm_name.c_str(), @@ -107,7 +108,7 @@ template class Queue { _sem_num_elems.lock(); std::lock_guard lg(_mutex); - T *segment = reinterpret_cast(_shm) + *_first_elem; + T *segment = reinterpret_cast(_shm) + *_first_elem; *_first_elem = (*_first_elem + _elem_size) % _buff_size; _sem_num_empty.unlock(); @@ -122,7 +123,7 @@ template class Queue { num_bytes); off64_t n_reads = num_bytes / _elem_size; - size_t r = num_bytes % _elem_size; + size_t r = num_bytes % _elem_size; for (int i = 0; i < n_reads; i++) { _read(buff_rcv + i * _elem_size, _elem_size); @@ -143,7 +144,7 @@ template class Queue { _sem_num_empty.lock(); std::lock_guard lg(_mutex); - T *segment = reinterpret_cast(_shm) + *_last_elem; + T *segment = reinterpret_cast(_shm) + *_last_elem; *_last_elem = (*_last_elem + _elem_size) % _buff_size; _sem_num_elems.unlock(); @@ -155,7 +156,7 @@ template class Queue { START_LOG(capio_syscall(SYS_gettid), "call(data=0x%08x, num_bytes=%llu)", data, num_bytes); off64_t n_writes = num_bytes / _elem_size; - size_t r = num_bytes % _elem_size; + size_t r = num_bytes % _elem_size; for (int i = 0; i < n_writes; i++) { _write(data + i * _elem_size, _elem_size); diff --git a/src/server/capio-cl-engine/capio_cl_engine.hpp b/src/server/capio-cl-engine/capio_cl_engine.hpp index 9aaac8517..5ce15c2b3 100644 --- a/src/server/capio-cl-engine/capio_cl_engine.hpp +++ b/src/server/capio-cl-engine/capio_cl_engine.hpp @@ -10,64 +10,64 @@ * */ class CapioCLEngine { - private: - std::unordered_map, // Vector for producers [0] std::vector, // Vector for consumers [1] - std::string, // commit rule [2] - std::string, // fire_rule [3] - bool, // permanent [4] - bool, // exclude [5] + std::string, // commit rule [2] + std::string, // fire_rule [3] + bool, // permanent [4] + bool, // exclude [5] bool, // is_file (if true yes otherwise it is a directory) [6] - int, // commit on close number [7] + int, // commit on close number [7] long, // directory file count [8] std::vector, // File dependencies [9] std::regex, // Regex from name to match globs [10] bool>> // Store File in memory or on FS. true = memory [11] - _locations; + _locations; static std::string truncateLastN(const std::string &str, const int n) { return str.length() > n ? "[..] " + str.substr(str.length() - n) : str; } - public: +public: void print() const { std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name << " ] " - << "Composition of expected CAPIO FS: " << std::endl - << std::endl - << "|============================================================================" - "===============================================|" - << std::endl - << "|" << std::setw(124) << "|" << std::endl - << "| Parsed configuration file for workflow: \e[1;36m" << workflow_name - << std::setw(83 - workflow_name.length()) << "\e[0m |" << std::endl - << "|" << std::setw(124) << "|" << std::endl - << "| File color legend: \e[48;5;034m \e[0m File stored in memory" - << std::setw(72) << "|" << std::endl - << "| " - << "\e[48;5;172m \e[0m File stored on file system" << std::setw(67) << "|" - << std::endl - << "|============================================================================" - "===============================================|" - << std::endl - << "|======|===================|===================|====================|========" - "============|============|===========|=========|" - << std::endl - << "| Kind | Filename | Producer step | Consumer step | " - "Commit Rule | Fire Rule | Permanent | Exclude |" - << std::endl - << "|======|===================|===================|====================|========" - "============|============|===========|=========|" - << std::endl; + << "Composition of expected CAPIO FS: " << std::endl + << std::endl + << "|============================================================================" + "===============================================|" + << std::endl + << "|" << std::setw(124) << "|" << std::endl + << "| Parsed configuration file for workflow: \e[1;36m" << workflow_name + << std::setw(83 - workflow_name.length()) << "\e[0m |" << std::endl + << "|" << std::setw(124) << "|" << std::endl + << "| File color legend: \e[48;5;034m \e[0m File stored in memory" + << std::setw(72) << "|" << std::endl + << "| " + << "\e[48;5;172m \e[0m File stored on file system" << std::setw(67) << "|" + << std::endl + << "|============================================================================" + "===============================================|" + << std::endl + << "|======|===================|===================|====================|========" + "============|============|===========|=========|" + << std::endl + << "| Kind | Filename | Producer step | Consumer step | " + "Commit Rule | Fire Rule | Permanent | Exclude |" + << std::endl + << "|======|===================|===================|====================|========" + "============|============|===========|=========|" + << std::endl; for (auto itm : _locations) { std::string color_preamble = std::get<11>(itm.second) ? "\e[38;5;034m" : "\e[38;5;172m"; - std::string color_post = "\e[0m"; + std::string color_post = "\e[0m"; std::string name_trunc = truncateLastN(itm.first, 12); - auto kind = std::get<6>(itm.second) ? "F" : "D"; + auto kind = std::get<6>(itm.second) ? "F" : "D"; std::cout << "| " << color_preamble << kind << color_post << " | " << color_preamble - << name_trunc << color_post << std::setfill(' ') - << std::setw(20 - name_trunc.length()) << "| "; + << name_trunc << color_post << std::setfill(' ') + << std::setw(20 - name_trunc.length()) << "| "; auto producers = std::get<0>(itm.second); auto consumers = std::get<1>(itm.second); @@ -83,7 +83,7 @@ class CapioCLEngine { if (i < producers.size()) { auto prod1 = truncateLastN(producers.at(i), 12); std::cout << prod1 << std::setfill(' ') << std::setw(20 - prod1.length()) - << " | "; + << " | "; } else { std::cout << std::setfill(' ') << std::setw(20) << " | "; } @@ -91,31 +91,31 @@ class CapioCLEngine { if (i < consumers.size()) { auto cons1 = truncateLastN(consumers.at(i), 12); std::cout << " " << cons1 << std::setfill(' ') << std::setw(20 - cons1.length()) - << " | "; + << " | "; } else { std::cout << std::setfill(' ') << std::setw(21) << " | "; } if (i == 0) { std::string commit_rule = std::get<2>(itm.second), - fire_rule = std::get<3>(itm.second); + fire_rule = std::get<3>(itm.second); bool exclude = std::get<4>(itm.second), permanent = std::get<5>(itm.second); std::cout << " " << commit_rule << std::setfill(' ') - << std::setw(20 - commit_rule.length()) << " | " << fire_rule - << std::setfill(' ') << std::setw(13 - fire_rule.length()) << " | " - << " " << (permanent ? "YES" : "NO ") << " | " - << (exclude ? "YES" : "NO ") << " |" << std::endl; + << std::setw(20 - commit_rule.length()) << " | " << fire_rule + << std::setfill(' ') << std::setw(13 - fire_rule.length()) << " | " + << " " << (permanent ? "YES" : "NO ") << " | " + << (exclude ? "YES" : "NO ") << " |" << std::endl; } else { std::cout << std::setfill(' ') << std::setw(20) << "|" << std::setfill(' ') - << std::setw(13) << "|" << std::setfill(' ') << std::setw(12) << "|" - << std::setfill(' ') << std::setw(10) << "|" << std::endl; + << std::setw(13) << "|" << std::setfill(' ') << std::setw(12) << "|" + << std::setfill(' ') << std::setw(10) << "|" << std::endl; } } std::cout << "*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" - "~~~~~~~" - "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*" - << std::endl; + "~~~~~~~" + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*" + << std::endl; } std::cout << std::endl; }; @@ -163,7 +163,7 @@ class CapioCLEngine { START_LOG(gettid(), "call(path=%s)", path.c_str()); if (_locations.find(path) == _locations.end()) { std::string commit = CAPIO_FILE_COMMITTED_ON_TERMINATION; - std::string fire = CAPIO_FILE_MODE_UPDATE; + std::string fire = CAPIO_FILE_MODE_UPDATE; /* * Inherit commit and fire rules from LPM directory @@ -174,8 +174,8 @@ class CapioCLEngine { if (std::regex_match(path, std::get<10>(data)) && filename.length() > matchSize) { LOG("Found match with %s", filename.c_str()); matchSize = filename.length(); - commit = std::get<2>(data); - fire = std::get<3>(data); + commit = std::get<2>(data); + fire = std::get<3>(data); } } LOG("Adding file %s to _locations with commit=%s, and fire=%s", path.c_str(), @@ -351,9 +351,9 @@ class CapioCLEngine { std::vector producers = std::get<0>(itm->second); DBG(gettid(), [&](const std::vector &arr) { for (auto elem : arr) { - LOG("producer: %s", elem.c_str()); + LOG("producer: %s", elem.c_str()); } - }(producers)); + }(producers)); return std::find(producers.begin(), producers.end(), app_name) != producers.end(); } LOG("No exact match found in locations. checking for globs"); @@ -364,9 +364,9 @@ class CapioCLEngine { std::vector producers = std::get<0>(entry); DBG(gettid(), [&](const std::vector &arr) { for (auto itm : arr) { - LOG("producer: %s", itm.c_str()); + LOG("producer: %s", itm.c_str()); } - }(producers)); + }(producers)); return std::find(producers.begin(), producers.end(), app_name) != producers.end(); } } diff --git a/src/server/capio-cl-engine/json_parser.hpp b/src/server/capio-cl-engine/json_parser.hpp index 0e64b2818..6d9dce0ce 100644 --- a/src/server/capio-cl-engine/json_parser.hpp +++ b/src/server/capio-cl-engine/json_parser.hpp @@ -41,7 +41,7 @@ class JsonParser { return mismatch_pair.second == base.end(); } - public: +public: /** * @brief Perform the parsing of the capio_server configuration file * @@ -49,7 +49,7 @@ class JsonParser { * @return CapioCLEngine instance with the information provided by the config file */ static CapioCLEngine *parse(const std::filesystem::path &source) { - auto locations = new CapioCLEngine(); + auto locations = new CapioCLEngine(); const auto &capio_dir = get_capio_dir(); START_LOG(gettid(), "call(config_file='%s', capio_dir='%s')", source.c_str(), @@ -69,7 +69,7 @@ class JsonParser { simdjson::padded_string json; simdjson::ondemand::document entries; simdjson::ondemand::array input_stream, output_stream, streaming, permanent_files, - exclude_files, storage_memory, storage_fs; + exclude_files, storage_memory, storage_fs; simdjson::ondemand::object storage_section; simdjson::error_code error; @@ -77,7 +77,7 @@ class JsonParser { json = simdjson::padded_string::load(source.c_str()); } catch (const simdjson::simdjson_error &e) { std::cerr << CAPIO_LOG_SERVER_CLI_LEVEL_ERROR << " [ " << node_name << " ] " - << "Exception thrown while opening config file: " << e.what() << std::endl; + << "Exception thrown while opening config file: " << e.what() << std::endl; LOG("Exception thrown while opening config file: %s", e.what()); ERR_EXIT("Exception thrown while opening config file: %s", e.what()); } @@ -90,7 +90,7 @@ class JsonParser { } workflow_name = std::string(wf_name); std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name << " ] " - << "Parsing configuration for workflow: " << workflow_name << std::endl; + << "Parsing configuration for workflow: " << workflow_name << std::endl; LOG("Parsing configuration for workflow: %s", std::string(workflow_name).c_str()); std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name << " ] " << std::endl; @@ -105,23 +105,23 @@ class JsonParser { } std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name << " ] " - << "Parsing config for app " << app_name << std::endl; + << "Parsing config for app " << app_name << std::endl; LOG("Parsing config for app %s", std::string(app_name).c_str()); if (app["input_stream"].get_array().get(input_stream)) { std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_ERROR << " [ " << node_name << " ] " - << "No input_stream section found for app " << app_name << std::endl; + << "No input_stream section found for app " << app_name << std::endl; ERR_EXIT("No input_stream section found for app %s", std::string(app_name).c_str()); } else { for (auto itm : input_stream) { std::filesystem::path file(itm.get_string().take_value()); std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name << " ] " - << "Found file : " << file << std::endl; + << "Found file : " << file << std::endl; if (file.is_relative() || first_is_subpath_of_second(file, get_capio_dir())) { std::string appname(app_name); std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name << " ] " - << "File : " << file << " added to app: " << app_name - << std::endl; + << "File : " << file << " added to app: " << app_name + << std::endl; if (file.is_relative()) { file = capio_dir / file; } @@ -129,20 +129,20 @@ class JsonParser { locations->addConsumer(file, appname); } else { std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_WARNING << " [ " << node_name - << " ] " - << "File : " << file - << " is not relative to CAPIO_DIR. Ignoring..." << std::endl; + << " ] " + << "File : " << file + << " is not relative to CAPIO_DIR. Ignoring..." << std::endl; } } std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name << " ] " - << "Completed input_stream parsing for app: " << app_name << std::endl; + << "Completed input_stream parsing for app: " << app_name << std::endl; LOG("Completed input_stream parsing for app: %s", std::string(app_name).c_str()); } if (app["output_stream"].get_array().get(output_stream)) { std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_ERROR << " [ " << node_name << " ] " - << "No output_stream section found for app " << app_name << std::endl; + << "No output_stream section found for app " << app_name << std::endl; ERR_EXIT("No output_stream section found for app %s", std::string(app_name).c_str()); } else { @@ -151,8 +151,8 @@ class JsonParser { if (file.is_relative() || first_is_subpath_of_second(file, get_capio_dir())) { std::string appname(app_name); std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name << " ] " - << "Adding file: " << file << " to app: " << app_name - << std::endl; + << "Adding file: " << file << " to app: " << app_name + << std::endl; if (file.is_relative()) { file = capio_dir / file; } @@ -161,14 +161,14 @@ class JsonParser { } } std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name << " ] " - << "Completed output_stream parsing for app: " << app_name << std::endl; + << "Completed output_stream parsing for app: " << app_name << std::endl; LOG("Completed output_stream parsing for app: %s", std::string(app_name).c_str()); } // PARSING STREAMING FILES if (app["streaming"].get_array().get(streaming)) { std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_WARNING << " [ " << node_name << " ] " - << "No streaming section found for app: " << app_name << std::endl; + << "No streaming section found for app: " << app_name << std::endl; LOG("No streaming section found for app: %s", std::string(app_name).c_str()); } else { LOG("Began parsing streaming section for app %s", std::string(app_name).c_str()); @@ -210,7 +210,7 @@ class JsonParser { error = file["committed"].get_string().get(committed); if (error) { std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_ERROR << " [ " << node_name << " ] " - << "commit rule is mandatory in streaming section" << std::endl; + << "commit rule is mandatory in streaming section" << std::endl; ERR_EXIT("error commit rule is mandatory in streaming section"); } else { auto pos = committed.find(':'); @@ -218,8 +218,8 @@ class JsonParser { commit_rule = committed.substr(0, pos); if (commit_rule != CAPIO_FILE_COMMITTED_ON_CLOSE) { std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_ERROR << " [ " << node_name - << " ] " - << "commit rule " << commit_rule << std::endl; + << " ] " + << "commit rule " << commit_rule << std::endl; ERR_EXIT("error commit rule: %s", std::string(commit_rule).c_str()); } @@ -227,8 +227,8 @@ class JsonParser { if (!is_int(n_close_str)) { std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_ERROR << " [ " << node_name - << " ] " - << "commit rule on_close invalid number" << std::endl; + << " ] " + << "commit rule on_close invalid number" << std::endl; ERR_EXIT("error commit rule on_close invalid number: !is_int()"); } n_close = std::stol(n_close_str); @@ -244,9 +244,9 @@ class JsonParser { if (error) { std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_ERROR << " [ " << node_name - << " ] " - << "commit rule is on_file but no file_deps section found" - << std::endl; + << " ] " + << "commit rule is on_file but no file_deps section found" + << std::endl; ERR_EXIT("commit rule is on_file but no file_deps section found"); } @@ -258,9 +258,9 @@ class JsonParser { ? (get_capio_dir() / computed_path) : computed_path; std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name - << " ] " - << "Adding file: " << computed_path - << " to file dependencies: " << std::endl; + << " ] " + << "Adding file: " << computed_path + << " to file dependencies: " << std::endl; file_deps.emplace_back(computed_path); } } @@ -287,8 +287,8 @@ class JsonParser { LOG("batch_size: %d", batch_size); for (auto path : streaming_names) { std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name << " ] " - << " [ " << node_name << " ] " - << "Updating metadata for path: " << path << std::endl; + << " [ " << node_name << " ] " + << "Updating metadata for path: " << path << std::endl; if (path.is_relative()) { path = (capio_dir / path).lexically_normal(); } @@ -298,9 +298,9 @@ class JsonParser { std::string commit(commit_rule), firerule(mode); if (n_files != -1) { std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name - << " ] " - << "Setting path: " << path << " n_files to " << n_files - << std::endl; + << " ] " + << "Setting path: " << path << " n_files to " << n_files + << std::endl; locations->setDirectoryFileCount(path, n_files); } @@ -313,22 +313,23 @@ class JsonParser { } std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name << " ] " - << "completed parsing of streaming section for app: " << app_name - << std::endl; + << "completed parsing of streaming section for app: " << app_name + << std::endl; LOG("completed parsing of streaming section for app: %s", std::string(app_name).c_str()); } // END PARSING STREAMING FILES std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name << " ] " - << std::endl; + << std::endl; } // END OF APP MAIN LOOPS LOG("Completed parsing of io_graph app main loops"); std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name << " ] " - << "Completed parsing of io_graph" << std::endl; + << "Completed parsing of io_graph" << std::endl; LOG("Completed parsing of io_graph"); - if (entries["permanent"].get_array().get(permanent_files)) { // PARSING PERMANENT FILES + if (entries["permanent"].get_array().get(permanent_files)) { + // PARSING PERMANENT FILES std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_WARNING << " [ " << node_name << " ] " - << "No permanent section found for workflow: " << workflow_name << std::endl; + << "No permanent section found for workflow: " << workflow_name << std::endl; LOG("No permanent section found for workflow: %s", std::string(workflow_name).c_str()); } else { for (auto file : permanent_files) { @@ -350,15 +351,16 @@ class JsonParser { } } std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name << " ] " - << "Completed parsing of permanent files" << std::endl; + << "Completed parsing of permanent files" << std::endl; LOG("Completed parsing of permanent files"); } // END PARSING PERMANENT FILES std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name << " ] " << std::endl; - if (entries["exclude"].get_array().get(exclude_files)) { // PARSING PERMANENT FILES + if (entries["exclude"].get_array().get(exclude_files)) { + // PARSING PERMANENT FILES std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_WARNING << " [ " << node_name << " ] " - << "No exclude section found for workflow: " << workflow_name << std::endl; + << "No exclude section found for workflow: " << workflow_name << std::endl; LOG("No exclude section found for workflow: %s", std::string(workflow_name).c_str()); } else { for (auto file : exclude_files) { @@ -380,7 +382,7 @@ class JsonParser { } } std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name << " ] " - << "Completed parsing of exclude files" << std::endl; + << "Completed parsing of exclude files" << std::endl; LOG("Completed parsing of exclude files"); } // END PARSING PERMANENT FILES @@ -389,19 +391,19 @@ class JsonParser { auto home_node_policies = entries["home_node_policy"].error(); if (!home_node_policies) { std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_WARNING << " [ " << node_name << " ] " - << "Warning: capio does not support home node policies yet! skipping section " - << std::endl; + << "Warning: capio does not support home node policies yet! skipping section " + << std::endl; } if (entries["storage"].get_object().get(storage_section)) { std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_WARNING << " [ " << node_name << " ] " - << "No storage section found for workflow: " << workflow_name << std::endl; + << "No storage section found for workflow: " << workflow_name << std::endl; LOG("No storage section found for workflow: %s", std::string(workflow_name).c_str()); } else { if (storage_section["memory"].get_array().get(storage_memory)) { std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_WARNING << " [ " << node_name << " ] " - << "No files listed in memory storage section for workflow: " - << workflow_name << std::endl; + << "No files listed in memory storage section for workflow: " + << workflow_name << std::endl; LOG("No files listed in memory storage section for workflow: %s", std::string(workflow_name).c_str()); } else { @@ -409,16 +411,16 @@ class JsonParser { std::string_view file_str; file.get_string().get(file_str); std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name << " ] " - << "Setting file " << file_str << " to be stored in memory" - << std::endl; + << "Setting file " << file_str << " to be stored in memory" + << std::endl; locations->setStoreFileInMemory(file_str); } } if (storage_section["fs"].get_array().get(storage_fs)) { std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_WARNING << " [ " << node_name << " ] " - << "No files listed in fs storage section for workflow: " << workflow_name - << std::endl; + << "No files listed in fs storage section for workflow: " << workflow_name + << std::endl; LOG("No files listed in fs storage section for workflow: %s", std::string(workflow_name).c_str()); } else { @@ -426,13 +428,13 @@ class JsonParser { std::string_view file_str; file.get_string().get(file_str); std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name << " ] " - << "Setting file " << file_str << " to be stored on file system" - << std::endl; + << "Setting file " << file_str << " to be stored on file system" + << std::endl; locations->setStoreFileInFileSystem(file_str); } } std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name << " ] " - << "Completed parsing of memory storage directives" << std::endl; + << "Completed parsing of memory storage directives" << std::endl; } std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << std::endl; From c9ab329cea0e0c579ebb48195a8931752ac889c1 Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Tue, 6 May 2025 11:40:40 +0200 Subject: [PATCH 24/33] Added tests --- .github/workflows/ci-tests.yaml | 6 + tests/CMakeLists.txt | 1 + tests/unit/MemoryFiles/CMakeLists.txt | 63 ++++++++++ tests/unit/MemoryFiles/src/main.cpp | 143 +++++++++++++++++++++++ tests/unit/server/src/CapioFileTests.hpp | 30 ----- 5 files changed, 213 insertions(+), 30 deletions(-) create mode 100644 tests/unit/MemoryFiles/CMakeLists.txt create mode 100644 tests/unit/MemoryFiles/src/main.cpp diff --git a/.github/workflows/ci-tests.yaml b/.github/workflows/ci-tests.yaml index 940d9ba10..c1197c8e6 100644 --- a/.github/workflows/ci-tests.yaml +++ b/.github/workflows/ci-tests.yaml @@ -170,6 +170,12 @@ jobs: capio_posix_unit_tests \ --gtest_break_on_failure \ --gtest_print_time=1 + + echo "Run CAPIO memory file integration tests" + LD_PRELOAD=libcapio_posix.so \ + capio_memory_file_unit_tests \ + --gtest_break_on_failure \ + --gtest_print_time=1 - name: "Show client logs on failure" if: ${{ always() && steps.run-tests.outcome == 'failure' && matrix.build_type == 'Debug' }} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 69f8a41bd..f3fd7597e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -25,5 +25,6 @@ include(GoogleTest) add_subdirectory(unit/posix) add_subdirectory(unit/server) add_subdirectory(unit/syscall) +add_subdirectory(unit/MemoryFiles) add_subdirectory(multinode/integration) add_subdirectory(multinode/backend) diff --git a/tests/unit/MemoryFiles/CMakeLists.txt b/tests/unit/MemoryFiles/CMakeLists.txt new file mode 100644 index 000000000..349f168c4 --- /dev/null +++ b/tests/unit/MemoryFiles/CMakeLists.txt @@ -0,0 +1,63 @@ +##################################### +# Target information +##################################### +set(TARGET_NAME capio_memory_file_unit_tests) +set(TARGET_INCLUDE_FOLDER "${PROJECT_SOURCE_DIR}/src/posix") +set(TARGET_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp +) + +##################################### +# Target definition +##################################### +add_executable(${TARGET_NAME} ${TARGET_SOURCES}) + +##################################### +# External projects +##################################### +set(SYSCALL_INTERCEPT_BINARY_DIR "${PROJECT_BINARY_DIR}/src/posix/syscall_intercept") +set(SYSCALL_INTERCEPT_INCLUDE_FOLDER + "${SYSCALL_INTERCEPT_BINARY_DIR}/${CMAKE_INSTALL_INCLUDEDIR}") +set(SYSCALL_INTERCEPT_LIB_FOLDER + "${SYSCALL_INTERCEPT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}") + +##################################### +# Definitions +##################################### +target_compile_definitions(${TARGET_NAME} PRIVATE __CAPIO_POSIX) + +##################################### +# Include files and directories +##################################### +file(GLOB_RECURSE CAPIO_POSIX_HEADERS "${TARGET_INCLUDE_FOLDER}/*.hpp") +file(GLOB_RECURSE SYSCALL_INTERCEPT_HEADERS "${SYSCALL_INTERCEPT_INCLUDE_FOLDER}/*.h") +target_sources(${TARGET_NAME} PRIVATE + "${CAPIO_COMMON_HEADERS}" + "${CAPIO_POSIX_HEADERS}" + "${GTEST_CONFIG_HEADERS}" + "${SYSCALL_INTERCEPT_HEADERS}" +) +target_include_directories(${TARGET_NAME} PRIVATE + "${TARGET_INCLUDE_FOLDER}" + "${SYSCALL_INTERCEPT_INCLUDE_FOLDER}" +) + +##################################### +# Link libraries +##################################### +target_link_directories(${TARGET_NAME} PRIVATE ${SYSCALL_INTERCEPT_LIB_FOLDER}) +target_link_libraries(${TARGET_NAME} PRIVATE rt syscall_intercept GTest::gtest_main) + +##################################### +# Configure tests +##################################### +gtest_discover_tests(${TARGET_NAME} + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} +) + +##################################### +# Install rules +##################################### +install(TARGETS ${TARGET_NAME} + LIBRARY DESTINATION ${CMAKE_INSTALL_BINDIR} +) \ No newline at end of file diff --git a/tests/unit/MemoryFiles/src/main.cpp b/tests/unit/MemoryFiles/src/main.cpp new file mode 100644 index 000000000..c03231be4 --- /dev/null +++ b/tests/unit/MemoryFiles/src/main.cpp @@ -0,0 +1,143 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +char **build_args() { + char **args = (char **) malloc(4 * sizeof(uintptr_t)); + + char const *command = std::getenv("CAPIO_SERVER_PATH"); + if (command == nullptr) { + command = "capio_server"; + } + + args[0] = strdup(command); + args[1] = strdup("--no-config"); + args[2] = strdup("--mem-only"); + args[3] = (char *) nullptr; + + return args; +} + +char **build_env(char **envp) { + std::vector vars; + for (int i = 0; envp[i] != nullptr; i++) { + const std::string_view var(envp[i]); + const std::string_view key = var.substr(0, var.find('=')); + if (key != "LD_PRELOAD") { + vars.emplace_back(i); + } + } + + char **cleaned_env = (char **) malloc((vars.size() + 2) * sizeof(uintptr_t)); + for (int i = 0; i < vars.size(); i++) { + cleaned_env[i] = strdup(envp[i]); + } + cleaned_env[vars.size()] = strdup("LD_PRELOAD="); + cleaned_env[vars.size() + 1] = (char *) nullptr; + + return cleaned_env; +} + +class CapioServerEnvironment : public testing::Environment { +private: + char **args; + char **envp; + int server_pid; + +public: + explicit CapioServerEnvironment(char **envp) + : args(build_args()), envp(build_env(envp)), server_pid(-1) { + }; + + ~CapioServerEnvironment() override { + for (int i = 0; args[i] != nullptr; i++) { + free(args[i]); + } + free(args); + for (int i = 0; envp[i] != nullptr; i++) { + free(envp[i]); + } + free(envp); + }; + + void SetUp() override { + if (server_pid < 0) { + ASSERT_NE(std::getenv("CAPIO_DIR"), nullptr); + ASSERT_GE(server_pid = fork(), 0); + if (server_pid == 0) { + execvpe(args[0], args, envp); + std::cout << "Error: unable to start server" << std::endl; + _exit(127); + } else { + sleep(5); + } + } + } + + void TearDown() override { + if (server_pid > 0) { + kill(server_pid, SIGTERM); + waitpid(server_pid, nullptr, 0); + server_pid = -1; + } + } +}; + + +const std::string filename = "hello.txt"; +constexpr size_t textSize = 32 * 1024 * 1024; // 32 MBB + + +inline std::string generateLongText() { + std::string pattern = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n"; + std::string longText; + while (longText.size() + pattern.size() <= textSize) { + longText += pattern; + } + // Pad the remaining bytes + if (longText.size() < textSize) { + longText.append(textSize - longText.size(), 'X'); + } + return longText; +} + + +TEST(CapioMemoryFileTest, TestReadAndWrite32MBFile) { + std::string longText = generateLongText(); + + std::ofstream outFile(filename, std::ios::out | std::ios::binary); + EXPECT_TRUE(outFile.is_open()); + outFile.write(longText.c_str(), longText.size()); + outFile.close(); + + std::string fileContent(textSize, ' '); + + std::ifstream inFile(filename, std::ios::in | std::ios::binary); + EXPECT_TRUE(inFile.is_open()); + EXPECT_TRUE(inFile.read(fileContent.data(), fileContent.size())); + inFile.close(); + + EXPECT_EQ(fileContent.size(), longText.size()); + + for (size_t i = 0; i < longText.size(); ++i) { + EXPECT_EQ(fileContent[i], longText[i]); + } + +} + + +int main(int argc, char **argv, char **envp) { + testing::InitGoogleTest(&argc, argv); + testing::AddGlobalTestEnvironment(new CapioServerEnvironment(envp)); + + return RUN_ALL_TESTS(); +} \ No newline at end of file diff --git a/tests/unit/server/src/CapioFileTests.hpp b/tests/unit/server/src/CapioFileTests.hpp index 9b37c367d..9929e8a0a 100644 --- a/tests/unit/server/src/CapioFileTests.hpp +++ b/tests/unit/server/src/CapioFileTests.hpp @@ -53,36 +53,6 @@ TEST(CapioMemoryFileTest, TestHugeFileOnMultiplePages) { delete[] input_buffer4; } -/* - * WARNING: This test uses files that are too big to be handled by the CI/CD on github, - * and as such it has been disabled. Nevertheless this test can be executed locally - * -TEST(CapioMemoryFileTest, TestHugeFileOnMultiplePagesThatStartOnDifferentOffset) { - CapioMemoryFile file1("test.txt"); - capio_off64_t LONG_TEXT_SIZE = 1024 * 1024 * 16; - auto LONG_TEXT = new char[LONG_TEXT_SIZE]{}; // 16 MB string - for (capio_off64_t i = 0; i < LONG_TEXT_SIZE; i++) { - LONG_TEXT[i] = 'A' + (random() % 26); - } - - auto input_buffer4 = new char[LONG_TEXT_SIZE + 1]{}; - bool write_count_match = file1.writeData(LONG_TEXT, 2048, LONG_TEXT_SIZE) == LONG_TEXT_SIZE; - EXPECT_TRUE(write_count_match); - - file1.readData(input_buffer4, 2048, LONG_TEXT_SIZE); - - bool ok = true; - for (capio_off64_t i = 0; i < LONG_TEXT_SIZE && ok; i++) { - ok &= (LONG_TEXT[i] == input_buffer4[i]); - if (!ok) { - std::cout << "Check failed at byte " << i << " out of " << LONG_TEXT_SIZE << std::endl; - } - } - EXPECT_TRUE(ok); - - delete LONG_TEXT; -} -*/ TEST(CapioMemoryFileTest, TestWriteAndRead) { CapioMemoryFile file("test.txt"); From 2718483de22905822e53d517585a78eba11811eb Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Tue, 6 May 2025 13:36:15 +0200 Subject: [PATCH 25/33] fix --- read_write_test.cpp | 149 ------------------ .../utils/cache/read_request_cache_mem.hpp | 4 +- src/posix/utils/clone.hpp | 5 - src/posix/utils/storage.hpp | 5 +- 4 files changed, 6 insertions(+), 157 deletions(-) delete mode 100644 read_write_test.cpp diff --git a/read_write_test.cpp b/read_write_test.cpp deleted file mode 100644 index e508b5bd8..000000000 --- a/read_write_test.cpp +++ /dev/null @@ -1,149 +0,0 @@ -#include -#include -#include -#include -#include - -const std::string filename = "hello.txt"; -const size_t textSize = 32 * 1024 * 1024; // 32 MBB - -// Generate a large text (e.g., repeating a pattern) -std::string generateLongText() { - std::string pattern = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n"; - std::string longText; - while (longText.size() + pattern.size() <= textSize) { - longText += pattern; - } - // If needed, pad the remaining bytes - if (longText.size() < textSize) { - longText.append(textSize - longText.size(), 'X'); - } - return longText; -} - - -void print_surrounding_lines(const std::string &content, std::size_t offset) { - if (offset >= content.size()) { - std::cerr << "Offset is out of range.\n"; - return; - } - - // Find start of current line - std::size_t line_start = content.rfind('\n', offset); - line_start = (line_start == std::string::npos) ? 0 : line_start + 1; - - // Find end of current line - std::size_t line_end = content.find('\n', offset); - line_end = (line_end == std::string::npos) ? content.size() : line_end; - - // Extract current line - std::string current_line = content.substr(line_start, line_end - line_start); - - // Find previous line - if (line_start > 0) { - const std::size_t prev_end = line_start - 1; - std::size_t prev_start = content.rfind('\n', prev_end); - prev_start = (prev_start == std::string::npos) ? 0 : prev_start + 1; - const std::string prev_line = content.substr(prev_start, prev_end - prev_start + 1); - if (!prev_line.empty()) { - std::cout << "Previous line : [" << prev_start << "]" << prev_line << "\n"; - } - } else { - std::cout << "Previous line: [None]\n"; - } - - std::cout << "Offending line: [" << line_start << "] " << current_line << "\n"; - - // Find next line - if (line_end < content.size()) { - std::size_t next_start = line_end + 1; - std::size_t next_end = content.find('\n', next_start); - if (next_end == std::string::npos) - next_end = content.size(); - std::string next_line = content.substr(next_start, next_end - next_start); - - if (!next_line.empty()) { - std::cout << "Next line : [" << next_start << "]" << next_line << "\n"; - } - } else { - std::cout << "Next line: [None]\n"; - } - -} - - -void readFromFile(const std::string &expectedContent) { - - std::string fileContent(textSize, ' '); - - auto write_start = std::chrono::high_resolution_clock::now(); - - std::ifstream inFile(filename, std::ios::in | std::ios::binary); - if (!inFile) { - std::cout << "Error opening file for reading!\n"; - return; - } - if (!inFile.read(fileContent.data(), fileContent.size())) { - std::cerr << "Failed to read file content.\n"; - exit(-1); - } - inFile.close(); - - auto write_end = std::chrono::high_resolution_clock::now(); - std::chrono::duration elapsed = write_end - write_start; - double bandwidthMBps = (textSize / (1024.0 * 1024.0)) / elapsed.count(); - std::cout << "READ(): " << bandwidthMBps << " MB/s (in " << elapsed.count() << ")" << std::endl; - - bool match = true; - size_t minLength = std::min(fileContent.size(), expectedContent.size()); - - if (fileContent.size() != expectedContent.size()) { - std::cout << "Mismatch in size!\n"; - std::cout << "Expected size: " << expectedContent.size() << ", Found size: " << - fileContent.size() << "\n"; - exit(-1); - } - - for (size_t i = 0; i < minLength; ++i) { - if (fileContent[i] != expectedContent[i]) { - std::cout << "Mismatch at position " << i << ":\n"; - std::cout << "Expected: '" << expectedContent[i] << "' (ASCII " << static_cast( - expectedContent[i]) << ")\n"; - std::cout << "Found: '" << fileContent[i] << "' (ASCII " << static_cast( - fileContent[i]) << ")\n"; - print_surrounding_lines(fileContent, i); - exit(-1); - } - } - std::cout << "Content matches expected text.\n"; - -} - -int main(int argc, char *argv[]) { - std::string longText = generateLongText(); - auto write_start = std::chrono::high_resolution_clock::now(); - std::ofstream outFile(filename, std::ios::out | std::ios::binary); - if (!outFile) { - std::cout << "Error opening file for writing!\n"; - exit(-1); - } - outFile.write(longText.c_str(), longText.size()); - outFile.close(); - std::cout << "Successfully wrote " << longText.size() << " bytes to " << filename << std::endl; - - /*Read a single byte to wait for caches to empty*/ - std::ifstream file(filename, std::ios::binary); - char byte; - file.read(&byte, 1); // Read a single byte - file.close(); - auto write_end = std::chrono::high_resolution_clock::now(); - - std::chrono::duration elapsed = write_end - write_start; - double bandwidthMBps = (textSize / (1024.0 * 1024.0)) / elapsed.count(); - - std::cout << "WRITE(): " << bandwidthMBps << " MB/s" << std::endl; - - readFromFile(longText); - - return 0; -} \ No newline at end of file diff --git a/src/posix/utils/cache/read_request_cache_mem.hpp b/src/posix/utils/cache/read_request_cache_mem.hpp index 3ff6aa12c..8b79b6a16 100644 --- a/src/posix/utils/cache/read_request_cache_mem.hpp +++ b/src/posix/utils/cache/read_request_cache_mem.hpp @@ -47,7 +47,7 @@ class ReadRequestCacheMEM { committed = true; stc_queue_read -= 0x8000000000000000; _real_file_size_commmitted = stc_queue_read; - LOG("File is commited. Actual offset is: %ld", stc_queue_read); + LOG("File is committed. Actual offset is: %ld", stc_queue_read); } if (use_cache) { @@ -58,7 +58,7 @@ class ReadRequestCacheMEM { _actual_size = 0; _cache_offset = 0; LOG("Data has not been loaded from server, as load_data==false." - " Load will occur indipendently"); + " Load will occur independently"); } return stc_queue_read; diff --git a/src/posix/utils/clone.hpp b/src/posix/utils/clone.hpp index c4ba9554b..0795c8c0d 100644 --- a/src/posix/utils/clone.hpp +++ b/src/posix/utils/clone.hpp @@ -54,11 +54,6 @@ inline void init_process(pid_t tid) { */ handshake_request(tid, pid, capio_app_name); - /* - * Request which files need to be handled in memory instead of file system - */ - paths_to_store_in_memory = file_in_memory_request(tid); - syscall_no_intercept_flag = false; } diff --git a/src/posix/utils/storage.hpp b/src/posix/utils/storage.hpp index 8f5843848..53c0346ff 100644 --- a/src/posix/utils/storage.hpp +++ b/src/posix/utils/storage.hpp @@ -8,6 +8,9 @@ inline bool store_file_in_memory(const std::filesystem::path &file_name, const long pid) { START_LOG(capio_syscall(SYS_gettid), "call(path=%s, pid=%ld)", file_name.c_str(), pid); if (paths_to_store_in_memory == nullptr) { + /* + * Request which files need to be handled in memory instead of file system + */ LOG("Vector is empty and not allocated. performing request"); paths_to_store_in_memory = file_in_memory_request(pid); } @@ -17,4 +20,4 @@ inline bool store_file_in_memory(const std::filesystem::path &file_name, const l [file_name](const std::regex &rx) { return std::regex_match(file_name.string(), rx); }); } -#endif // STORAGE_HPP +#endif // STORAGE_HPP \ No newline at end of file From 4dbaff158653a40543be6d1c5b82c31e8fae310c Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Tue, 6 May 2025 13:47:35 +0200 Subject: [PATCH 26/33] fix --- tests/unit/MemoryFiles/src/main.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/unit/MemoryFiles/src/main.cpp b/tests/unit/MemoryFiles/src/main.cpp index c03231be4..b35792f7f 100644 --- a/tests/unit/MemoryFiles/src/main.cpp +++ b/tests/unit/MemoryFiles/src/main.cpp @@ -3,7 +3,6 @@ #include #include #include -#include #include #include #include From 94811b1551df19d82d74b53434af5c0006b5cef2 Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Tue, 6 May 2025 13:50:23 +0200 Subject: [PATCH 27/33] test --- tests/unit/MemoryFiles/src/main.cpp | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/tests/unit/MemoryFiles/src/main.cpp b/tests/unit/MemoryFiles/src/main.cpp index b35792f7f..632ab29cd 100644 --- a/tests/unit/MemoryFiles/src/main.cpp +++ b/tests/unit/MemoryFiles/src/main.cpp @@ -1,14 +1,13 @@ +#include + #include #include -#include -#include -#include -#include +#include #include +#include #include - -#include - +#include +#include char **build_args() { char **args = (char **) malloc(4 * sizeof(uintptr_t)); @@ -91,13 +90,12 @@ class CapioServerEnvironment : public testing::Environment { } }; - const std::string filename = "hello.txt"; constexpr size_t textSize = 32 * 1024 * 1024; // 32 MBB - inline std::string generateLongText() { - std::string pattern = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n"; + std::string pattern = + "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n"; std::string longText; while (longText.size() + pattern.size() <= textSize) { longText += pattern; @@ -109,7 +107,6 @@ inline std::string generateLongText() { return longText; } - TEST(CapioMemoryFileTest, TestReadAndWrite32MBFile) { std::string longText = generateLongText(); @@ -130,10 +127,8 @@ TEST(CapioMemoryFileTest, TestReadAndWrite32MBFile) { for (size_t i = 0; i < longText.size(); ++i) { EXPECT_EQ(fileContent[i], longText[i]); } - } - int main(int argc, char **argv, char **envp) { testing::InitGoogleTest(&argc, argv); testing::AddGlobalTestEnvironment(new CapioServerEnvironment(envp)); From 1025ad01ce34ccb303fe2138db9fd309246b3ae8 Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Tue, 6 May 2025 13:53:18 +0200 Subject: [PATCH 28/33] test --- tests/unit/MemoryFiles/src/main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/unit/MemoryFiles/src/main.cpp b/tests/unit/MemoryFiles/src/main.cpp index 632ab29cd..a2cd32781 100644 --- a/tests/unit/MemoryFiles/src/main.cpp +++ b/tests/unit/MemoryFiles/src/main.cpp @@ -39,7 +39,8 @@ char **build_env(char **envp) { for (int i = 0; i < vars.size(); i++) { cleaned_env[i] = strdup(envp[i]); } - cleaned_env[vars.size()] = strdup("LD_PRELOAD="); + + cleaned_env[vars.size()] = strdup("LD_PRELOAD="); cleaned_env[vars.size() + 1] = (char *) nullptr; return cleaned_env; From 1f88af1a1c144a9e9a7f2a66fd11e19b8734d994 Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Wed, 7 May 2025 15:52:12 +0200 Subject: [PATCH 29/33] Investigating test failure --- .github/workflows/ci-tests.yaml | 7 +- src/common/capio/queue.hpp | 6 +- src/common/capio/semaphore.hpp | 23 +++--- src/posix/handlers/exit.hpp | 15 ++-- src/posix/handlers/open.hpp | 20 ++++-- src/posix/handlers/read.hpp | 15 ++-- src/posix/handlers/write.hpp | 10 ++- src/posix/utils/cache.hpp | 15 ++-- .../utils/cache/write_request_cache_mem.hpp | 12 ++-- tests/unit/MemoryFiles/src/main.cpp | 15 ++-- .../server/src/CapioCacheSPSCQueueTests.hpp | 72 ++++++++++++++----- 11 files changed, 136 insertions(+), 74 deletions(-) diff --git a/.github/workflows/ci-tests.yaml b/.github/workflows/ci-tests.yaml index c1197c8e6..1a67a994c 100644 --- a/.github/workflows/ci-tests.yaml +++ b/.github/workflows/ci-tests.yaml @@ -9,11 +9,11 @@ on: - capio-v2 concurrency: group: build-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true jobs: codespell-check: name: "Check codespell conformance" runs-on: ubuntu-22.04 + continue-on-error: true steps: - uses: actions/checkout@v4 - name: "Run codespell" @@ -75,13 +75,14 @@ jobs: steps: - uses: actions/checkout@v4 - name: "Run clang-format style check" - uses: jidicula/clang-format-action@v4.13.0 + uses: jidicula/clang-format-action@v4.15.0 with: - clang-format-version: "16" + clang-format-version: "20" check-path: "${{ matrix.path }}" unit-tests: name: "Build ${{ matrix.build_type }} with ${{ matrix.cxx }}" runs-on: ubuntu-22.04 + continue-on-error: true strategy: matrix: build_type: diff --git a/src/common/capio/queue.hpp b/src/common/capio/queue.hpp index d1282aa27..455d7a2b6 100644 --- a/src/common/capio/queue.hpp +++ b/src/common/capio/queue.hpp @@ -18,7 +18,6 @@ * @tparam Mutex Type of semaphore */ template class Queue { -private: void *_shm; const long int _max_num_elems, _elem_size; // elements size in bytes long int _buff_size; // buffer size in bytes @@ -94,8 +93,11 @@ template class Queue { syscall_no_intercept_flag = true; #endif SHM_DESTROY_CHECK(_shm_name.c_str()); + LOG("Removed %s", _shm_name.c_str()); SHM_DESTROY_CHECK(_first_elem_name.c_str()); + LOG("Removed %s", _first_elem_name.c_str()); SHM_DESTROY_CHECK(_last_elem_name.c_str()); + LOG("Removed %s", _last_elem_name.c_str()); #ifdef __CAPIO_POSIX syscall_no_intercept_flag = false; #endif @@ -177,4 +179,4 @@ template using CircularBuffer = Queue; // Single Producer Single Consumer queue using SPSCQueue = Queue; -#endif // CAPIO_QUEUE_HPP +#endif // CAPIO_QUEUE_HPP \ No newline at end of file diff --git a/src/common/capio/semaphore.hpp b/src/common/capio/semaphore.hpp index fb5bb85ba..4aabdae86 100644 --- a/src/common/capio/semaphore.hpp +++ b/src/common/capio/semaphore.hpp @@ -12,15 +12,18 @@ * */ class NoLock { - public: +public: NoLock(const std::string &name, unsigned int init_value, bool cleanup) { START_LOG(capio_syscall(SYS_gettid), "call(name=%s, initial_value=%d)", name.c_str(), init_value); } - NoLock(const NoLock &) = delete; + NoLock(const NoLock &) = delete; NoLock &operator=(const NoLock &) = delete; - ~NoLock() = default; + + ~NoLock() { + START_LOG(capio_syscall(SYS_gettid), "call()"); + }; static inline void lock() { START_LOG(capio_syscall(SYS_gettid), "call()"); }; @@ -33,12 +36,12 @@ class NoLock { * */ class NamedSemaphore { - private: +private: const std::string _name; sem_t *_sem; bool _require_cleanup; - public: +public: NamedSemaphore(std::string name, unsigned int init_value, bool cleanup = true) : _name(std::move(name)), _require_cleanup(cleanup) { START_LOG(capio_syscall(SYS_gettid), " call(name=%s, init_value=%d, cleanup=%s)", @@ -56,8 +59,9 @@ class NamedSemaphore { } } - NamedSemaphore(const NamedSemaphore &) = delete; + NamedSemaphore(const NamedSemaphore &) = delete; NamedSemaphore &operator=(const NamedSemaphore &) = delete; + ~NamedSemaphore() { START_LOG(capio_syscall(SYS_gettid), "call()"); if (_require_cleanup) { @@ -110,11 +114,11 @@ class NamedSemaphore { * */ class Semaphore { - private: +private: sem_t _sem{}; bool _require_cleanup; - public: +public: explicit Semaphore(unsigned int init_value, bool cleanup = true) { START_LOG(capio_syscall(SYS_gettid), "call(init_value=%d)", init_value); @@ -123,8 +127,9 @@ class Semaphore { } } - Semaphore(const Semaphore &) = delete; + Semaphore(const Semaphore &) = delete; Semaphore &operator=(const Semaphore &) = delete; + ~Semaphore() { START_LOG(capio_syscall(SYS_gettid), "call()"); if (_require_cleanup) { diff --git a/src/posix/handlers/exit.hpp b/src/posix/handlers/exit.hpp index 4a8e49541..c966035fc 100644 --- a/src/posix/handlers/exit.hpp +++ b/src/posix/handlers/exit.hpp @@ -19,9 +19,7 @@ int exit_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long arg START_LOG(tid, "call()"); syscall_no_intercept_flag = true; - - delete_caches(); - LOG("Removed caches"); + LOG("syscall_no_intercept_flag = true"); if (is_capio_tid(tid)) { LOG("Thread %d is a CAPIO thread: clean up", tid); @@ -29,20 +27,19 @@ int exit_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long arg remove_capio_tid(tid); } + delete_caches(); + LOG("Removed caches"); + if (const auto itm = bufs_response->find(tid); itm != bufs_response->end()) { delete itm->second; bufs_response->erase(tid); LOG("Removed response buffer"); } - - delete stc_queue; - delete cts_queue; - LOG("Removed data queues"); - syscall_no_intercept_flag = false; + LOG("syscall_no_intercept_flag = false"); return CAPIO_POSIX_SYSCALL_SKIP; } #endif // SYS_exit || SYS_exit_group -#endif // CAPIO_POSIX_HANDLERS_EXIT_GROUP_HPP +#endif // CAPIO_POSIX_HANDLERS_EXIT_GROUP_HPP \ No newline at end of file diff --git a/src/posix/handlers/open.hpp b/src/posix/handlers/open.hpp index 148a341b5..6740d453d 100644 --- a/src/posix/handlers/open.hpp +++ b/src/posix/handlers/open.hpp @@ -35,8 +35,8 @@ std::string compute_abs_path(char *pathname, int dirfd) { #if defined(SYS_creat) int creat_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, long *result) { std::string pathname(reinterpret_cast(arg0)); - auto tid = static_cast(syscall_no_intercept(SYS_gettid)); - int flags = O_CREAT | O_WRONLY | O_TRUNC; + auto tid = static_cast(syscall_no_intercept(SYS_gettid)); + int flags = O_CREAT | O_WRONLY | O_TRUNC; mode_t mode = static_cast(arg2); START_LOG(tid, "call(path=%s, flags=%d, mode=%d)", pathname.data(), flags, mode); @@ -64,9 +64,9 @@ int creat_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long ar #if defined(SYS_open) int open_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, long *result) { std::string pathname(reinterpret_cast(arg0)); - int flags = static_cast(arg1); + int flags = static_cast(arg1); mode_t mode = static_cast(arg2); - auto tid = static_cast(syscall_no_intercept(SYS_gettid)); + auto tid = static_cast(syscall_no_intercept(SYS_gettid)); START_LOG(tid, "call(path=%s, flags=%d, mode=%d)", pathname.data(), flags, mode); std::string path = compute_abs_path(pathname.data(), -1); @@ -79,6 +79,9 @@ int open_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long arg LOG("not O_CREAT"); open_request(-1, path.data(), tid); } + } else { + LOG("Not a CAPIO path. skipping..."); + return CAPIO_POSIX_SYSCALL_REQUEST_SKIP; } int fd = static_cast(syscall_no_intercept(SYS_open, arg0, arg1, arg2, arg3, arg4, arg5)); @@ -97,9 +100,9 @@ int open_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long arg int openat_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, long *result) { int dirfd = static_cast(arg0); std::string pathname(reinterpret_cast(arg1)); - int flags = static_cast(arg2); + int flags = static_cast(arg2); mode_t mode = static_cast(arg3); - auto tid = static_cast(syscall_no_intercept(SYS_gettid)); + auto tid = static_cast(syscall_no_intercept(SYS_gettid)); START_LOG(tid, "call(path=%s, flags=%d, mode=%d)", pathname.data(), flags, mode); std::string path = compute_abs_path(pathname.data(), dirfd); @@ -112,6 +115,9 @@ int openat_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long a LOG("not O_CREAT"); open_request(-1, path.data(), tid); } + } else { + LOG("Not a CAPIO path. skipping..."); + return CAPIO_POSIX_SYSCALL_REQUEST_SKIP; } int fd = static_cast(syscall_no_intercept(SYS_openat, arg0, arg1, arg2, arg3, arg4, arg5)); @@ -127,4 +133,4 @@ int openat_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long a } #endif // SYS_openat -#endif // CAPIO_POSIX_HANDLERS_OPENAT_HPP +#endif // CAPIO_POSIX_HANDLERS_OPENAT_HPP \ No newline at end of file diff --git a/src/posix/handlers/read.hpp b/src/posix/handlers/read.hpp index d5bf3a65a..5850dba91 100644 --- a/src/posix/handlers/read.hpp +++ b/src/posix/handlers/read.hpp @@ -39,13 +39,16 @@ int read_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long arg auto tid = static_cast(syscall_no_intercept(SYS_gettid)); START_LOG(capio_syscall(SYS_gettid), "call(fd=%d, tid=%d, count=%ld)", fd, tid, count); + if (exists_capio_fd(fd)) { + auto read_result = store_file_in_memory(get_capio_fd_path(fd), tid) + ? capio_read_mem(fd, count, buffer, result) + : capio_read_fs(fd, count, tid); - auto read_result = store_file_in_memory(get_capio_fd_path(fd), tid) - ? capio_read_mem(fd, count, buffer, result) - : capio_read_fs(fd, count, tid); - - LOG("read result: %ld", read_result); - return read_result; + LOG("read result: %ld", read_result); + return read_result; + } + LOG("Not a CAPIO fd... skipping..."); + return CAPIO_POSIX_SYSCALL_REQUEST_SKIP; } #endif // SYS_read diff --git a/src/posix/handlers/write.hpp b/src/posix/handlers/write.hpp index 8ace13927..539f7190b 100644 --- a/src/posix/handlers/write.hpp +++ b/src/posix/handlers/write.hpp @@ -13,6 +13,14 @@ inline off64_t capio_write_fs(int fd, capio_off64_t count, pid_t tid) { return CAPIO_POSIX_SYSCALL_REQUEST_SKIP; } +inline off64_t capio_writev_fs(int fd, char *buffer, off64_t count, pid_t tid) { + START_LOG(tid, "Handling FS write within writev"); + capio_write_fs(fd, count, tid); + const off64_t write_count = syscall_no_intercept(SYS_write, fd, buffer, count); + LOG("Wrote %ld bytes", write_count); + return write_count; +} + inline off64_t capio_write_mem(int fd, char *buffer, capio_off64_t count, pid_t tid) { START_LOG(tid, "call(fd=%d, count=%ld)", fd, count); write_request_cache_mem->write(fd, buffer, count); @@ -65,7 +73,7 @@ int writev_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long a LOG("Handling IOVEC elements %d of size %ld", i, iov_len); write_result += store_file_in_memory(get_capio_fd_path(fd), tid) ? capio_write_mem(fd, static_cast(iov_base), iov_len, tid) - : capio_write_fs(fd, iovcnt, tid); + : capio_writev_fs(fd, static_cast(iov_base), iov_len, tid); } return posix_return_value(write_result, result); diff --git a/src/posix/utils/cache.hpp b/src/posix/utils/cache.hpp index 7c2d6c083..900002a18 100644 --- a/src/posix/utils/cache.hpp +++ b/src/posix/utils/cache.hpp @@ -17,11 +17,11 @@ inline thread_local ReadRequestCacheMEM *read_request_cache_mem; inline void init_caches() { START_LOG(capio_syscall(SYS_gettid), "call()"); - write_request_cache_fs = new WriteRequestCacheFS(); - read_request_cache_fs = new ReadRequestCacheFS(); + write_request_cache_fs = new WriteRequestCacheFS(); + read_request_cache_fs = new ReadRequestCacheFS(); consent_request_cache_fs = new ConsentRequestCache(); - write_request_cache_mem = new WriteRequestCacheMEM(); - read_request_cache_mem = new ReadRequestCacheMEM(); + write_request_cache_mem = new WriteRequestCacheMEM(); + read_request_cache_mem = new ReadRequestCacheMEM(); } inline void delete_caches() { @@ -31,6 +31,11 @@ inline void delete_caches() { delete consent_request_cache_fs; delete write_request_cache_mem; delete read_request_cache_mem; + + delete cts_queue; + LOG("Removed cts_queue"); + delete stc_queue; + LOG("Removed stc_queue"); } -#endif // CAPIO_CACHE_HPP +#endif // CAPIO_CACHE_HPP \ No newline at end of file diff --git a/src/posix/utils/cache/write_request_cache_mem.hpp b/src/posix/utils/cache/write_request_cache_mem.hpp index ffa1f3647..91264a1ca 100644 --- a/src/posix/utils/cache/write_request_cache_mem.hpp +++ b/src/posix/utils/cache/write_request_cache_mem.hpp @@ -1,5 +1,6 @@ #ifndef WRITE_REQUEST_CACHE_MEM_HPP #define WRITE_REQUEST_CACHE_MEM_HPP + class WriteRequestCacheMEM { char *_cache; long _tid; @@ -22,7 +23,7 @@ class WriteRequestCacheMEM { } } - protected: +protected: void write_request(const off64_t count, const long tid, const char *path, const capio_off64_t offset) const { START_LOG(capio_syscall(SYS_gettid), "call(path=%s, count=%ld, offset=%llu)", path, count, @@ -33,10 +34,11 @@ class WriteRequestCacheMEM { buf_requests->write(req, CAPIO_REQ_MAX_SIZE); } - public: +public: explicit WriteRequestCacheMEM(off64_t line_size = get_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) {} + _actual_size(0), _last_write_end(-1), _last_write_begin(0) { + } ~WriteRequestCacheMEM() { START_LOG(capio_syscall(SYS_gettid), "call()"); @@ -48,7 +50,7 @@ class WriteRequestCacheMEM { if (_actual_size != 0) { LOG("Actual size: %ld", _actual_size); write_request(_actual_size, _tid, get_capio_fd_path(_fd).c_str(), _last_write_begin); - _cache = nullptr; + _cache = nullptr; _actual_size = 0; } LOG("Flush completed"); @@ -61,7 +63,7 @@ class WriteRequestCacheMEM { if (_fd != fd) { LOG("changed fd from %d to %d: flushing", _fd, fd); flush(); - _fd = fd; + _fd = fd; _last_write_end = -1; } diff --git a/tests/unit/MemoryFiles/src/main.cpp b/tests/unit/MemoryFiles/src/main.cpp index a2cd32781..4c51b8cff 100644 --- a/tests/unit/MemoryFiles/src/main.cpp +++ b/tests/unit/MemoryFiles/src/main.cpp @@ -47,15 +47,14 @@ char **build_env(char **envp) { } class CapioServerEnvironment : public testing::Environment { -private: + private: char **args; char **envp; int server_pid; -public: + 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++) { @@ -92,11 +91,10 @@ class CapioServerEnvironment : public testing::Environment { }; const std::string filename = "hello.txt"; -constexpr size_t textSize = 32 * 1024 * 1024; // 32 MBB +constexpr size_t textSize = 32 * 1024 * 1024; // 32 MBB inline std::string generateLongText() { - std::string pattern = - "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n"; + std::string pattern = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n"; std::string longText; while (longText.size() + pattern.size() <= textSize) { longText += pattern; @@ -117,10 +115,11 @@ TEST(CapioMemoryFileTest, TestReadAndWrite32MBFile) { outFile.close(); std::string fileContent(textSize, ' '); - std::ifstream inFile(filename, std::ios::in | std::ios::binary); + EXPECT_TRUE(inFile.is_open()); EXPECT_TRUE(inFile.read(fileContent.data(), fileContent.size())); + inFile.close(); EXPECT_EQ(fileContent.size(), longText.size()); diff --git a/tests/unit/server/src/CapioCacheSPSCQueueTests.hpp b/tests/unit/server/src/CapioCacheSPSCQueueTests.hpp index 6912875c9..331aecdd2 100644 --- a/tests/unit/server/src/CapioCacheSPSCQueueTests.hpp +++ b/tests/unit/server/src/CapioCacheSPSCQueueTests.hpp @@ -15,10 +15,23 @@ inline CircularBuffer *buf_requests; #include "../posix/utils/cache.hpp" #include "SourceText.hpp" +auto checkStringEquality = [](const std::string &a, const std::string &b) { + size_t minLen = std::min(a.size(), b.size()); + for (size_t i = 0; i < minLen; ++i) { + if (a[i] != b[i]) { + std::cout << "Difference at offset " << i << ": '" << a[i] << "' vs '" << b[i] << "'\n"; + } + } + if (a.size() != b.size()) { + std::cout << "Strings have different lengths. input: " << a.size() + << ". check: " << b.size() << std::endl; + } +}; + WriteRequestCacheMEM *writeCache; ReadRequestCacheMEM *readCache; -int test_fd = 0; +int test_fd = -1; std::string test_file_name = "test.dat"; void init_server_data_structures() { @@ -69,16 +82,27 @@ TEST(CapioCacheSPSCQueue, TestWriteCacheWithSpscQueueWrite) { capio_files_descriptors->emplace(test_fd, test_file_name); files->insert({test_fd, {std::make_shared(0), 0, 0, false}}); + writeCache->write(test_fd, SOURCE_TEST_TEXT, long_test_length); + writeCache->flush(); + std::thread t1([long_test_length, tmp_buf] { cts_queue->read(tmp_buf->get(), long_test_length); - EXPECT_TRUE(strncmp(tmp_buf->get(), SOURCE_TEST_TEXT, long_test_length) == 0); - }); - writeCache->write(test_fd, SOURCE_TEST_TEXT, long_test_length); - writeCache->flush(); + // In the event a flush is triggered with a write of size 0, read again + if (strlen(tmp_buf->get()) == 0) { + cts_queue->read(tmp_buf->get(), long_test_length); + } + + if (strncmp(tmp_buf->get(), SOURCE_TEST_TEXT, long_test_length) != 0) { + checkStringEquality(std::string(tmp_buf->get()), std::string(SOURCE_TEST_TEXT)); + } + + EXPECT_EQ(strncmp(tmp_buf->get(), SOURCE_TEST_TEXT, long_test_length), 0); + }); t1.join(); + delete tmp_buf; delete_server_data_structures(); } @@ -91,6 +115,9 @@ TEST(CapioCacheSPSCQueue, TestWriteCacheSPSCQueueAndCapioFile) { capio_files_descriptors->emplace(test_fd, test_file_name); files->insert({test_fd, {std::make_shared(0), 0, 0, false}}); + writeCache->write(test_fd, SOURCE_TEST_TEXT, long_test_length); + writeCache->flush(); + std::thread t2([long_test_length, readBufSize] { CapioMemoryFile *testFile = new CapioMemoryFile(test_file_name); testFile->readFromQueue(*cts_queue, 0, long_test_length); @@ -104,9 +131,6 @@ TEST(CapioCacheSPSCQueue, TestWriteCacheSPSCQueueAndCapioFile) { delete testFile; }); - writeCache->write(test_fd, SOURCE_TEST_TEXT, long_test_length); - writeCache->flush(); - t2.join(); delete_server_data_structures(); @@ -222,6 +246,9 @@ TEST(CapioCacheSPSCQueue, TestWriteCacheSPSCQueueAndCapioFileWithRequestAndSeek) // perform to write ad a different offset writeCache->write(test_fd, SOURCE_TEST_TEXT, long_test_length); + // simulate Close on file + writeCache->flush(); + t3.join(); delete_server_data_structures(); @@ -338,31 +365,37 @@ TEST(CapioCacheSPSCQueue, TestReadCacheWithSpscQueueReadWithCapioFileAndSeek) { files->insert({test_fd, {std::make_shared(0), 0, 0, false}}); std::thread server_thread([long_test_length, response_tid] { + START_LOG(gettid(), "call(server_instance)"); int iteration = 0; CapioMemoryFile testFile(test_file_name); testFile.writeData(SOURCE_TEST_TEXT, 0, long_test_length); + LOG("Wrote data to server test file"); capio_off64_t total_data_sent = 0; while (total_data_sent < 2000) { - char req[CAPIO_REQ_MAX_SIZE]; + char req[CAPIO_REQ_MAX_SIZE]{0}; char file[1024]; - int code; + int code, use_cache; pid_t tid; capio_off64_t read_size, client_cache_line_size, read_begin_offset; - buf_requests->read(req, CAPIO_REQ_MAX_SIZE); - auto [ptr, ec] = std::from_chars(req, req + 4, code); - EXPECT_EQ(ec, std::errc()); - strcpy(req, ptr + 1); + buf_requests->read(req, CAPIO_REQ_MAX_SIZE); + LOG("Received request: %s", req); + sscanf(req, "%d %ld %llu %llu %llu %d %s", &code, &tid, &read_begin_offset, &read_size, + &client_cache_line_size, &use_cache, file); EXPECT_EQ(code, CAPIO_REQUEST_READ_MEM); - sscanf(req, "%ld %llu %llu %llu %s", &tid, &read_begin_offset, &read_size, - &client_cache_line_size, file); - + LOG("code: %d", code); + LOG("tid: %ld", tid); + LOG("read_begin_offset: %lld", read_begin_offset); + LOG("read_size: %lld", read_size); + LOG("client_cache_line_size: %lld", client_cache_line_size); + LOG("use_cache: %lld", use_cache); + LOG("file: %s", file); auto size_to_send = read_size < client_cache_line_size ? read_size : client_cache_line_size; - + LOG("Sending %ld data", size_to_send); bufs_response->at(response_tid)->write(size_to_send); testFile.writeToQueue(*stc_queue, read_begin_offset, size_to_send); total_data_sent += size_to_send; @@ -381,10 +414,11 @@ TEST(CapioCacheSPSCQueue, TestReadCacheWithSpscQueueReadWithCapioFileAndSeek) { tmp_buf_ptr += new_offset; readCache->read(test_fd, tmp_buf_ptr, 1000); + // checkStringEquality(SOURCE_TEST_TEXT + new_offset, tmp_buf->get() + new_offset); EXPECT_EQ(strncmp(SOURCE_TEST_TEXT + new_offset, tmp_buf->get() + new_offset, 1000), 0); server_thread.join(); delete_server_data_structures(); } -#endif // CAPIOCACHESPSCQUEUETESTS_HPP +#endif // CAPIOCACHESPSCQUEUETESTS_HPP \ No newline at end of file From d695ea2a3f726b8e5866072bfbd035c0bb3224e3 Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Mon, 12 May 2025 14:23:14 +0200 Subject: [PATCH 30/33] code cleanup --- tests/unit/server/src/CapioFileTests.hpp | 1 - tests/unit/syscall/src/main.cpp | 2 +- tests/unit/syscall/src/stat.cpp | 36 ++++++++++++------------ tests/unit/syscall/src/statx.cpp | 26 ++++++++--------- 4 files changed, 32 insertions(+), 33 deletions(-) diff --git a/tests/unit/server/src/CapioFileTests.hpp b/tests/unit/server/src/CapioFileTests.hpp index 9929e8a0a..d5a7ae40e 100644 --- a/tests/unit/server/src/CapioFileTests.hpp +++ b/tests/unit/server/src/CapioFileTests.hpp @@ -53,7 +53,6 @@ TEST(CapioMemoryFileTest, TestHugeFileOnMultiplePages) { delete[] input_buffer4; } - TEST(CapioMemoryFileTest, TestWriteAndRead) { CapioMemoryFile file("test.txt"); diff --git a/tests/unit/syscall/src/main.cpp b/tests/unit/syscall/src/main.cpp index 954fb51aa..bc5961c3a 100644 --- a/tests/unit/syscall/src/main.cpp +++ b/tests/unit/syscall/src/main.cpp @@ -43,7 +43,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++) { diff --git a/tests/unit/syscall/src/stat.cpp b/tests/unit/syscall/src/stat.cpp index de2198f2d..e643ee53d 100644 --- a/tests/unit/syscall/src/stat.cpp +++ b/tests/unit/syscall/src/stat.cpp @@ -23,7 +23,7 @@ TEST(SystemCallTest, TestStatOnFile) { EXPECT_EQ(access(PATHNAME, F_OK), 0); EXPECT_EQ(write(fd, BUFFER, strlen(BUFFER)), strlen(BUFFER)); EXPECT_NE(close(fd), -1); - struct stat statbuf {}; + struct stat statbuf{}; EXPECT_EQ(stat(PATHNAME, &statbuf), 0); check_statbuf(statbuf, strlen(BUFFER) * sizeof(char)); EXPECT_NE(unlink(PATHNAME), -1); @@ -34,7 +34,7 @@ TEST(SystemCallTest, TestStatOnDirectory) { constexpr const char *PATHNAME = "test"; EXPECT_NE(mkdir(PATHNAME, S_IRWXU), -1); EXPECT_EQ(access(PATHNAME, F_OK), 0); - struct stat statbuf {}; + struct stat statbuf{}; EXPECT_EQ(stat(PATHNAME, &statbuf), 0); check_statbuf(statbuf, 4096); EXPECT_NE(rmdir(PATHNAME), -1); @@ -42,7 +42,7 @@ TEST(SystemCallTest, TestStatOnDirectory) { } TEST(SystemCallTest, TestStatOnNonexistentFile) { - struct stat statbuf {}; + struct stat statbuf{}; EXPECT_EQ(stat("test", &statbuf), -1); EXPECT_EQ(errno, ENOENT); } @@ -55,7 +55,7 @@ TEST(SystemCallTest, TestFstatOnFile) { EXPECT_NE(fd, -1); EXPECT_EQ(access(PATHNAME, F_OK), 0); EXPECT_EQ(write(fd, BUFFER, strlen(BUFFER)), strlen(BUFFER)); - struct stat statbuf {}; + struct stat statbuf{}; EXPECT_EQ(fstat(fd, &statbuf), 0); check_statbuf(statbuf, strlen(BUFFER) * sizeof(char)); EXPECT_NE(close(fd), -1); @@ -70,7 +70,7 @@ TEST(SystemCallTest, TestFstatOnDirectory) { int flags = O_RDONLY | O_DIRECTORY; int fd = open(PATHNAME, flags, S_IRUSR | S_IWUSR); EXPECT_NE(fd, -1); - struct stat statbuf {}; + struct stat statbuf{}; EXPECT_EQ(fstat(fd, &statbuf), 0); check_statbuf(statbuf, 4096); EXPECT_NE(close(fd), -1); @@ -79,7 +79,7 @@ TEST(SystemCallTest, TestFstatOnDirectory) { } TEST(SystemCallTest, TestFstatOnInvalidFd) { - struct stat statbuf {}; + struct stat statbuf{}; EXPECT_EQ(fstat(-1, &statbuf), -1); EXPECT_EQ(errno, EBADF); } @@ -93,7 +93,7 @@ TEST(SystemCallTest, TestFstatatOnFileWithAtFdcwd) { EXPECT_EQ(faccessat(AT_FDCWD, PATHNAME, F_OK, 0), 0); EXPECT_EQ(write(fd, BUFFER, strlen(BUFFER)), strlen(BUFFER)); EXPECT_NE(close(fd), -1); - struct stat statbuf {}; + struct stat statbuf{}; EXPECT_EQ(fstatat(AT_FDCWD, PATHNAME, &statbuf, 0), 0); check_statbuf(statbuf, strlen(BUFFER) * sizeof(char)); EXPECT_NE(unlinkat(AT_FDCWD, PATHNAME, 0), -1); @@ -104,7 +104,7 @@ TEST(SystemCallTest, TestFstatatOnDirectoryWithAtFdcwd) { constexpr const char *PATHNAME = "test"; EXPECT_NE(mkdirat(AT_FDCWD, PATHNAME, S_IRWXU), -1); EXPECT_EQ(faccessat(AT_FDCWD, PATHNAME, F_OK, 0), 0); - struct stat statbuf {}; + struct stat statbuf{}; EXPECT_EQ(fstatat(AT_FDCWD, PATHNAME, &statbuf, 0), 0); check_statbuf(statbuf, 4096); EXPECT_NE(unlinkat(AT_FDCWD, PATHNAME, AT_REMOVEDIR), -1); @@ -122,7 +122,7 @@ TEST(SystemCallTest, TestFstatatOnFileInDifferentDirectoryWithAbsolutePath) { EXPECT_EQ(faccessat(0, PATHNAME, F_OK, 0), 0); EXPECT_EQ(write(fd, BUFFER, strlen(BUFFER)), strlen(BUFFER)); EXPECT_NE(close(fd), -1); - struct stat statbuf {}; + struct stat statbuf{}; EXPECT_EQ(fstatat(0, PATHNAME, &statbuf, 0), 0); check_statbuf(statbuf, strlen(BUFFER) * sizeof(char)); EXPECT_NE(unlinkat(0, PATHNAME, 0), -1); @@ -134,7 +134,7 @@ TEST(SystemCallTest, TestFstatatOnDirectoryInDifferentDirectoryWithAbsolutePath) const char *PATHNAME = path_fs.c_str(); EXPECT_NE(mkdirat(0, PATHNAME, S_IRWXU), -1); EXPECT_EQ(faccessat(0, PATHNAME, F_OK, 0), 0); - struct stat statbuf {}; + struct stat statbuf{}; EXPECT_EQ(fstatat(0, PATHNAME, &statbuf, 0), 0); check_statbuf(statbuf, 4096); EXPECT_NE(unlinkat(0, PATHNAME, AT_REMOVEDIR), -1); @@ -152,7 +152,7 @@ TEST(SystemCallTest, TestFstatatOnFileInDifferentDirectoryWithDirfd) { EXPECT_EQ(faccessat(dirfd, PATHNAME, F_OK, 0), 0); EXPECT_EQ(write(fd, BUFFER, strlen(BUFFER)), strlen(BUFFER)); EXPECT_NE(close(fd), -1); - struct stat statbuf {}; + struct stat statbuf{}; EXPECT_EQ(fstatat(dirfd, PATHNAME, &statbuf, 0), 0); check_statbuf(statbuf, strlen(BUFFER) * sizeof(char)); EXPECT_NE(unlinkat(dirfd, PATHNAME, 0), -1); @@ -167,7 +167,7 @@ TEST(SystemCallTest, TestFstatatOnDirectoryInDifferentDirectoryWithDirfd) { EXPECT_NE(dirfd, -1); EXPECT_NE(mkdirat(dirfd, PATHNAME, S_IRWXU), -1); EXPECT_EQ(faccessat(dirfd, PATHNAME, F_OK, 0), 0); - struct stat statbuf {}; + struct stat statbuf{}; EXPECT_EQ(fstatat(dirfd, PATHNAME, &statbuf, 0), 0); check_statbuf(statbuf, 4096); EXPECT_NE(unlinkat(dirfd, PATHNAME, AT_REMOVEDIR), -1); @@ -176,7 +176,7 @@ TEST(SystemCallTest, TestFstatatOnDirectoryInDifferentDirectoryWithDirfd) { } TEST(SystemCallTest, TwstFstatatWithAtEmptyPathAndAtFdcwd) { - struct stat statbuf {}; + struct stat statbuf{}; EXPECT_EQ(fstatat(AT_FDCWD, "", &statbuf, AT_EMPTY_PATH), 0); check_statbuf(statbuf, 4096); } @@ -188,7 +188,7 @@ TEST(SystemCallTest, TestFstatatOnFileWithAtEmptyPathAndDirfd) { int dirfd = openat(AT_FDCWD, PATHNAME, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR); EXPECT_EQ(faccessat(AT_FDCWD, PATHNAME, F_OK, 0), 0); EXPECT_EQ(write(dirfd, BUFFER, strlen(BUFFER)), strlen(BUFFER)); - struct stat statbuf {}; + struct stat statbuf{}; EXPECT_EQ(fstatat(dirfd, "", &statbuf, AT_EMPTY_PATH), 0); check_statbuf(statbuf, strlen(BUFFER) * sizeof(char)); EXPECT_NE(close(dirfd), -1); @@ -202,7 +202,7 @@ TEST(SystemCallTest, TestFstatatOnDirectoryWIthAtEmptyPathAndDirfd) { EXPECT_EQ(faccessat(AT_FDCWD, PATHNAME, F_OK, 0), 0); int dirfd = openat(AT_FDCWD, PATHNAME, O_RDONLY | O_DIRECTORY); EXPECT_NE(dirfd, -1); - struct stat statbuf {}; + struct stat statbuf{}; EXPECT_EQ(fstatat(dirfd, "", &statbuf, AT_EMPTY_PATH), 0); check_statbuf(statbuf, 4096); EXPECT_NE(close(dirfd), -1); @@ -211,20 +211,20 @@ TEST(SystemCallTest, TestFstatatOnDirectoryWIthAtEmptyPathAndDirfd) { } TEST(SystemCallTest, TestFstatatOnNonexistentFile) { - struct stat statbuf {}; + struct stat statbuf{}; EXPECT_EQ(fstatat(AT_FDCWD, "test", &statbuf, 0), -1); EXPECT_EQ(errno, ENOENT); } TEST(SystemCallTest, TestFstatatOnRelativePathWithInvalidDirfd) { constexpr const char *PATHNAME = "test"; - struct stat statbuf {}; + struct stat statbuf{}; EXPECT_EQ(fstatat(-1, PATHNAME, &statbuf, 0), -1); EXPECT_EQ(errno, EBADF); } TEST(SystemCallTest, TestFstatatWithEmptyPathAndNoAtEmptyPath) { - struct stat statbuf {}; + struct stat statbuf{}; EXPECT_EQ(fstatat(AT_FDCWD, "", &statbuf, 0), -1); EXPECT_EQ(errno, ENOENT); } diff --git a/tests/unit/syscall/src/statx.cpp b/tests/unit/syscall/src/statx.cpp index 9191c73d5..adff1ef38 100644 --- a/tests/unit/syscall/src/statx.cpp +++ b/tests/unit/syscall/src/statx.cpp @@ -22,7 +22,7 @@ TEST(SystemCallTest, TestStatxOnFileWithAtFdcwd) { EXPECT_EQ(faccessat(AT_FDCWD, PATHNAME, F_OK, 0), 0); EXPECT_EQ(write(fd, BUFFER, strlen(BUFFER)), strlen(BUFFER)); EXPECT_NE(close(fd), -1); - struct statx statxbuf {}; + struct statx statxbuf{}; EXPECT_EQ(statx(AT_FDCWD, PATHNAME, 0, STATX_BASIC_STATS | STATX_BTIME, &statxbuf), 0); check_statxbuf(statxbuf, strlen(BUFFER) * sizeof(char)); EXPECT_NE(unlinkat(AT_FDCWD, PATHNAME, 0), -1); @@ -33,7 +33,7 @@ TEST(SystemCallTest, TestStatxOnDirectoryWithAtFdcwd) { constexpr const char *PATHNAME = "test"; EXPECT_NE(mkdirat(AT_FDCWD, PATHNAME, S_IRWXU), -1); EXPECT_EQ(faccessat(AT_FDCWD, PATHNAME, F_OK, 0), 0); - struct statx statxbuf {}; + struct statx statxbuf{}; EXPECT_EQ(statx(AT_FDCWD, PATHNAME, 0, STATX_BASIC_STATS | STATX_BTIME, &statxbuf), 0); check_statxbuf(statxbuf, 4096); EXPECT_NE(unlinkat(AT_FDCWD, PATHNAME, AT_REMOVEDIR), -1); @@ -51,7 +51,7 @@ TEST(SystemCallTest, TestStatxOnFileInDifferentDirectoryWithAbsolutePath) { EXPECT_EQ(faccessat(0, PATHNAME, F_OK, 0), 0); EXPECT_EQ(write(fd, BUFFER, strlen(BUFFER)), strlen(BUFFER)); EXPECT_NE(close(fd), -1); - struct statx statxbuf {}; + struct statx statxbuf{}; EXPECT_EQ(statx(AT_FDCWD, PATHNAME, 0, STATX_BASIC_STATS | STATX_BTIME, &statxbuf), 0); check_statxbuf(statxbuf, strlen(BUFFER) * sizeof(char)); EXPECT_NE(unlinkat(0, PATHNAME, 0), -1); @@ -63,7 +63,7 @@ TEST(SystemCallTest, TestStatxOnDirectoryInDifferentDirectoryWithAbsoluePath) { const char *PATHNAME = path_fs.c_str(); EXPECT_NE(mkdirat(0, PATHNAME, S_IRWXU), -1); EXPECT_EQ(faccessat(0, PATHNAME, F_OK, 0), 0); - struct statx statxbuf {}; + struct statx statxbuf{}; EXPECT_EQ(statx(AT_FDCWD, PATHNAME, 0, STATX_BASIC_STATS | STATX_BTIME, &statxbuf), 0); check_statxbuf(statxbuf, 4096); EXPECT_NE(unlinkat(0, PATHNAME, AT_REMOVEDIR), -1); @@ -81,7 +81,7 @@ TEST(SystemCallTest, TestStatxOnFileInDifferentDirectoryWithDirfd) { EXPECT_EQ(faccessat(dirfd, PATHNAME, F_OK, 0), 0); EXPECT_EQ(write(fd, BUFFER, strlen(BUFFER)), strlen(BUFFER)); EXPECT_NE(close(fd), -1); - struct statx statxbuf {}; + struct statx statxbuf{}; EXPECT_EQ(statx(dirfd, PATHNAME, 0, STATX_BASIC_STATS | STATX_BTIME, &statxbuf), 0); check_statxbuf(statxbuf, strlen(BUFFER) * sizeof(char)); EXPECT_NE(unlinkat(dirfd, PATHNAME, 0), -1); @@ -96,7 +96,7 @@ TEST(SystemCallTest, TestStatxOnDirectoryInDifferentDirectoryWithDirfd) { EXPECT_NE(dirfd, -1); EXPECT_NE(mkdirat(dirfd, PATHNAME, S_IRWXU), -1); EXPECT_EQ(faccessat(dirfd, PATHNAME, F_OK, 0), 0); - struct statx statxbuf {}; + struct statx statxbuf{}; EXPECT_EQ(statx(dirfd, PATHNAME, 0, STATX_BASIC_STATS | STATX_BTIME, &statxbuf), 0); check_statxbuf(statxbuf, 4096); EXPECT_NE(unlinkat(dirfd, PATHNAME, AT_REMOVEDIR), -1); @@ -105,7 +105,7 @@ TEST(SystemCallTest, TestStatxOnDirectoryInDifferentDirectoryWithDirfd) { } TEST(SystemCallTest, TestStatxWithAtEmptyPathAndAtFdcwd) { - struct statx statxbuf {}; + struct statx statxbuf{}; EXPECT_EQ(statx(AT_FDCWD, "", AT_EMPTY_PATH, STATX_BASIC_STATS | STATX_BTIME, &statxbuf), 0); check_statxbuf(statxbuf, 4096); } @@ -117,7 +117,7 @@ TEST(SystemCallTest, TestStatxOnFileWithAtEmptyPathAndDirfd) { int dirfd = openat(AT_FDCWD, PATHNAME, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR); EXPECT_EQ(faccessat(AT_FDCWD, PATHNAME, F_OK, 0), 0); EXPECT_EQ(write(dirfd, BUFFER, strlen(BUFFER)), strlen(BUFFER)); - struct statx statxbuf {}; + struct statx statxbuf{}; EXPECT_EQ(statx(dirfd, "", AT_EMPTY_PATH, STATX_BASIC_STATS | STATX_BTIME, &statxbuf), 0); check_statxbuf(statxbuf, strlen(BUFFER) * sizeof(char)); EXPECT_NE(close(dirfd), -1); @@ -131,7 +131,7 @@ TEST(SystemCallTest, TestStatxOnDirectoryWithAtEmptyPathAndDirfd) { EXPECT_EQ(faccessat(AT_FDCWD, PATHNAME, F_OK, 0), 0); int dirfd = openat(AT_FDCWD, PATHNAME, O_RDONLY | O_DIRECTORY); EXPECT_NE(dirfd, -1); - struct statx statxbuf {}; + struct statx statxbuf{}; EXPECT_EQ(statx(dirfd, "", AT_EMPTY_PATH, STATX_BASIC_STATS | STATX_BTIME, &statxbuf), 0); check_statxbuf(statxbuf, 4096); EXPECT_NE(close(dirfd), -1); @@ -140,27 +140,27 @@ TEST(SystemCallTest, TestStatxOnDirectoryWithAtEmptyPathAndDirfd) { } TEST(SystemCallTest, TestStatxOnNonexistentFile) { - struct statx statxbuf {}; + struct statx statxbuf{}; EXPECT_EQ(statx(AT_FDCWD, "test", 0, STATX_BASIC_STATS | STATX_BTIME, &statxbuf), -1); EXPECT_EQ(errno, ENOENT); } TEST(SystemCallTest, TestStatxOnRelativePathWithInvalidDirfd) { constexpr const char *PATHNAME = "test"; - struct statx statxbuf {}; + struct statx statxbuf{}; EXPECT_EQ(statx(-1, PATHNAME, 0, STATX_BASIC_STATS | STATX_BTIME, &statxbuf), -1); EXPECT_EQ(errno, EBADF); } TEST(SystemCallTest, TestStatxWithStatxReservedSet) { constexpr const char *PATHNAME = "test"; - struct statx statxbuf {}; + struct statx statxbuf{}; EXPECT_EQ(statx(-1, PATHNAME, 0, STATX__RESERVED, &statxbuf), -1); EXPECT_EQ(errno, EINVAL); } TEST(SystemCallTest, TestStatxWithEmptyPathAndNoEmptyPath) { - struct statx statxbuf {}; + struct statx statxbuf{}; EXPECT_EQ(statx(AT_FDCWD, "", 0, STATX_BASIC_STATS | STATX_BTIME, &statxbuf), -1); EXPECT_EQ(errno, ENOENT); } \ No newline at end of file From c9cb02df93b2fa29facd6b0c706745c47c89e30e Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Mon, 12 May 2025 14:32:27 +0200 Subject: [PATCH 31/33] code cleanup --- src/common/capio/queue.hpp | 22 ++-- .../utils/cache/read_request_cache_mem.hpp | 16 +-- .../utils/cache/write_request_cache_mem.hpp | 11 +- src/posix/utils/storage.hpp | 4 +- .../capio-cl-engine/capio_cl_engine.hpp | 116 +++++++++--------- src/server/capio-cl-engine/json_parser.hpp | 110 ++++++++--------- src/server/client-manager/handlers/read.hpp | 9 +- src/server/file-manager/file_manager_impl.hpp | 6 +- .../storage-service/CapioFile/CapioFile.hpp | 9 +- .../CapioFile/CapioMemoryFile.hpp | 10 +- .../storage-service/capio_storage_service.hpp | 10 +- 11 files changed, 159 insertions(+), 164 deletions(-) diff --git a/src/common/capio/queue.hpp b/src/common/capio/queue.hpp index 455d7a2b6..fcdb3ed15 100644 --- a/src/common/capio/queue.hpp +++ b/src/common/capio/queue.hpp @@ -20,7 +20,7 @@ template class Queue { void *_shm; const long int _max_num_elems, _elem_size; // elements size in bytes - long int _buff_size; // buffer size in bytes + long int _buff_size; // buffer size in bytes long int *_first_elem = nullptr, *_last_elem = nullptr; const std::string _shm_name, _first_elem_name, _last_elem_name; bool require_cleanup; @@ -49,7 +49,7 @@ template class Queue { _sem_num_elems.unlock(); } -public: + 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) : _max_num_elems(max_num_elems), _elem_size(elem_size), @@ -68,19 +68,19 @@ template class Queue { syscall_no_intercept_flag = true; #endif _first_elem = (long int *) create_shm(_first_elem_name, sizeof(long int)); - _last_elem = (long int *) create_shm(_last_elem_name, sizeof(long int)); - _shm = get_shm_if_exist(_shm_name); + _last_elem = (long int *) create_shm(_last_elem_name, sizeof(long int)); + _shm = get_shm_if_exist(_shm_name); if (_shm == nullptr) { *_first_elem = 0; - *_last_elem = 0; - _shm = create_shm(_shm_name, _buff_size); + *_last_elem = 0; + _shm = create_shm(_shm_name, _buff_size); } #ifdef __CAPIO_POSIX syscall_no_intercept_flag = false; #endif } - Queue(const Queue &) = delete; + Queue(const Queue &) = delete; Queue &operator=(const Queue &) = delete; ~Queue() { @@ -110,7 +110,7 @@ template class Queue { _sem_num_elems.lock(); std::lock_guard lg(_mutex); - T *segment = reinterpret_cast(_shm) + *_first_elem; + T *segment = reinterpret_cast(_shm) + *_first_elem; *_first_elem = (*_first_elem + _elem_size) % _buff_size; _sem_num_empty.unlock(); @@ -125,7 +125,7 @@ template class Queue { num_bytes); off64_t n_reads = num_bytes / _elem_size; - size_t r = num_bytes % _elem_size; + size_t r = num_bytes % _elem_size; for (int i = 0; i < n_reads; i++) { _read(buff_rcv + i * _elem_size, _elem_size); @@ -146,7 +146,7 @@ template class Queue { _sem_num_empty.lock(); std::lock_guard lg(_mutex); - T *segment = reinterpret_cast(_shm) + *_last_elem; + T *segment = reinterpret_cast(_shm) + *_last_elem; *_last_elem = (*_last_elem + _elem_size) % _buff_size; _sem_num_elems.unlock(); @@ -158,7 +158,7 @@ template class Queue { START_LOG(capio_syscall(SYS_gettid), "call(data=0x%08x, num_bytes=%llu)", data, num_bytes); off64_t n_writes = num_bytes / _elem_size; - size_t r = num_bytes % _elem_size; + size_t r = num_bytes % _elem_size; for (int i = 0; i < n_writes; i++) { _write(data + i * _elem_size, _elem_size); diff --git a/src/posix/utils/cache/read_request_cache_mem.hpp b/src/posix/utils/cache/read_request_cache_mem.hpp index 8b79b6a16..16661c02a 100644 --- a/src/posix/utils/cache/read_request_cache_mem.hpp +++ b/src/posix/utils/cache/read_request_cache_mem.hpp @@ -24,7 +24,7 @@ class ReadRequestCacheMEM { } } -protected: + protected: [[nodiscard]] capio_off64_t read_request(const int fd, const capio_off64_t count, const long tid, bool use_cache = true) { START_LOG(capio_syscall(SYS_gettid), "call(fd=%ld, count=%llu, tid=%ld, load_data=%s)", fd, @@ -55,7 +55,7 @@ class ReadRequestCacheMEM { _cache_offset = 0; LOG("Completed fetch of data from server"); } else { - _actual_size = 0; + _actual_size = 0; _cache_offset = 0; LOG("Data has not been loaded from server, as load_data==false." " Load will occur independently"); @@ -64,7 +64,7 @@ class ReadRequestCacheMEM { return stc_queue_read; } -public: + public: explicit ReadRequestCacheMEM(const long line_size = get_posix_read_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) { @@ -81,7 +81,7 @@ class ReadRequestCacheMEM { if (_cache_offset != _actual_size) { _actual_size = _cache_offset = 0; } - committed = false; + committed = false; _real_file_size_commmitted = -1; } @@ -93,7 +93,7 @@ class ReadRequestCacheMEM { if (_fd != fd) { LOG("changed fd from %d to %d: flushing", _fd, fd); flush(); - _fd = fd; + _fd = fd; _last_read_end = get_capio_fd_offset(fd); } @@ -127,7 +127,7 @@ class ReadRequestCacheMEM { if (_actual_size == 0 || _actual_size == _cache_offset) { LOG("No data is present locally. performing request."); const auto size = count < _max_line_size ? count : _max_line_size; - _actual_size = read_request(_fd, size, _tid); + _actual_size = read_request(_fd, size, _tid); // Update count for current request. If count exceeds _actual_size, resize it to not // exceeds the available size on posix application @@ -139,7 +139,7 @@ class ReadRequestCacheMEM { LOG("The requested amount of data can be served without performing a request"); _read(buffer, count); actual_read_size = count; - _last_read_end = get_capio_fd_offset(_fd) + count; + _last_read_end = get_capio_fd_offset(_fd) + count; set_capio_fd_offset(fd, _last_read_end); } else { @@ -160,7 +160,7 @@ class ReadRequestCacheMEM { LOG("actual_read_size incremented to: %ld", actual_read_size); // Compute the remaining amount of data to send to client - auto remaining_size = count - first_copy_size; + auto remaining_size = count - first_copy_size; capio_off64_t copy_offset = first_copy_size; while (copy_offset < count && !committed) { diff --git a/src/posix/utils/cache/write_request_cache_mem.hpp b/src/posix/utils/cache/write_request_cache_mem.hpp index 91264a1ca..34c570460 100644 --- a/src/posix/utils/cache/write_request_cache_mem.hpp +++ b/src/posix/utils/cache/write_request_cache_mem.hpp @@ -23,7 +23,7 @@ class WriteRequestCacheMEM { } } -protected: + protected: void write_request(const off64_t count, const long tid, const char *path, const capio_off64_t offset) const { START_LOG(capio_syscall(SYS_gettid), "call(path=%s, count=%ld, offset=%llu)", path, count, @@ -34,11 +34,10 @@ class WriteRequestCacheMEM { buf_requests->write(req, CAPIO_REQ_MAX_SIZE); } -public: + public: explicit WriteRequestCacheMEM(off64_t line_size = get_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) { - } + _actual_size(0), _last_write_end(-1), _last_write_begin(0) {} ~WriteRequestCacheMEM() { START_LOG(capio_syscall(SYS_gettid), "call()"); @@ -50,7 +49,7 @@ class WriteRequestCacheMEM { if (_actual_size != 0) { LOG("Actual size: %ld", _actual_size); write_request(_actual_size, _tid, get_capio_fd_path(_fd).c_str(), _last_write_begin); - _cache = nullptr; + _cache = nullptr; _actual_size = 0; } LOG("Flush completed"); @@ -63,7 +62,7 @@ class WriteRequestCacheMEM { if (_fd != fd) { LOG("changed fd from %d to %d: flushing", _fd, fd); flush(); - _fd = fd; + _fd = fd; _last_write_end = -1; } diff --git a/src/posix/utils/storage.hpp b/src/posix/utils/storage.hpp index 53c0346ff..6370af8f8 100644 --- a/src/posix/utils/storage.hpp +++ b/src/posix/utils/storage.hpp @@ -9,8 +9,8 @@ inline bool store_file_in_memory(const std::filesystem::path &file_name, const l START_LOG(capio_syscall(SYS_gettid), "call(path=%s, pid=%ld)", file_name.c_str(), pid); if (paths_to_store_in_memory == nullptr) { /* - * Request which files need to be handled in memory instead of file system - */ + * Request which files need to be handled in memory instead of file system + */ LOG("Vector is empty and not allocated. performing request"); paths_to_store_in_memory = file_in_memory_request(pid); } diff --git a/src/server/capio-cl-engine/capio_cl_engine.hpp b/src/server/capio-cl-engine/capio_cl_engine.hpp index 5ce15c2b3..9aaac8517 100644 --- a/src/server/capio-cl-engine/capio_cl_engine.hpp +++ b/src/server/capio-cl-engine/capio_cl_engine.hpp @@ -10,64 +10,64 @@ * */ class CapioCLEngine { -private: - std::unordered_map, // Vector for producers [0] std::vector, // Vector for consumers [1] - std::string, // commit rule [2] - std::string, // fire_rule [3] - bool, // permanent [4] - bool, // exclude [5] + std::string, // commit rule [2] + std::string, // fire_rule [3] + bool, // permanent [4] + bool, // exclude [5] bool, // is_file (if true yes otherwise it is a directory) [6] - int, // commit on close number [7] + int, // commit on close number [7] long, // directory file count [8] std::vector, // File dependencies [9] std::regex, // Regex from name to match globs [10] bool>> // Store File in memory or on FS. true = memory [11] - _locations; + _locations; static std::string truncateLastN(const std::string &str, const int n) { return str.length() > n ? "[..] " + str.substr(str.length() - n) : str; } -public: + public: void print() const { std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name << " ] " - << "Composition of expected CAPIO FS: " << std::endl - << std::endl - << "|============================================================================" - "===============================================|" - << std::endl - << "|" << std::setw(124) << "|" << std::endl - << "| Parsed configuration file for workflow: \e[1;36m" << workflow_name - << std::setw(83 - workflow_name.length()) << "\e[0m |" << std::endl - << "|" << std::setw(124) << "|" << std::endl - << "| File color legend: \e[48;5;034m \e[0m File stored in memory" - << std::setw(72) << "|" << std::endl - << "| " - << "\e[48;5;172m \e[0m File stored on file system" << std::setw(67) << "|" - << std::endl - << "|============================================================================" - "===============================================|" - << std::endl - << "|======|===================|===================|====================|========" - "============|============|===========|=========|" - << std::endl - << "| Kind | Filename | Producer step | Consumer step | " - "Commit Rule | Fire Rule | Permanent | Exclude |" - << std::endl - << "|======|===================|===================|====================|========" - "============|============|===========|=========|" - << std::endl; + << "Composition of expected CAPIO FS: " << std::endl + << std::endl + << "|============================================================================" + "===============================================|" + << std::endl + << "|" << std::setw(124) << "|" << std::endl + << "| Parsed configuration file for workflow: \e[1;36m" << workflow_name + << std::setw(83 - workflow_name.length()) << "\e[0m |" << std::endl + << "|" << std::setw(124) << "|" << std::endl + << "| File color legend: \e[48;5;034m \e[0m File stored in memory" + << std::setw(72) << "|" << std::endl + << "| " + << "\e[48;5;172m \e[0m File stored on file system" << std::setw(67) << "|" + << std::endl + << "|============================================================================" + "===============================================|" + << std::endl + << "|======|===================|===================|====================|========" + "============|============|===========|=========|" + << std::endl + << "| Kind | Filename | Producer step | Consumer step | " + "Commit Rule | Fire Rule | Permanent | Exclude |" + << std::endl + << "|======|===================|===================|====================|========" + "============|============|===========|=========|" + << std::endl; for (auto itm : _locations) { std::string color_preamble = std::get<11>(itm.second) ? "\e[38;5;034m" : "\e[38;5;172m"; - std::string color_post = "\e[0m"; + std::string color_post = "\e[0m"; std::string name_trunc = truncateLastN(itm.first, 12); - auto kind = std::get<6>(itm.second) ? "F" : "D"; + auto kind = std::get<6>(itm.second) ? "F" : "D"; std::cout << "| " << color_preamble << kind << color_post << " | " << color_preamble - << name_trunc << color_post << std::setfill(' ') - << std::setw(20 - name_trunc.length()) << "| "; + << name_trunc << color_post << std::setfill(' ') + << std::setw(20 - name_trunc.length()) << "| "; auto producers = std::get<0>(itm.second); auto consumers = std::get<1>(itm.second); @@ -83,7 +83,7 @@ class CapioCLEngine { if (i < producers.size()) { auto prod1 = truncateLastN(producers.at(i), 12); std::cout << prod1 << std::setfill(' ') << std::setw(20 - prod1.length()) - << " | "; + << " | "; } else { std::cout << std::setfill(' ') << std::setw(20) << " | "; } @@ -91,31 +91,31 @@ class CapioCLEngine { if (i < consumers.size()) { auto cons1 = truncateLastN(consumers.at(i), 12); std::cout << " " << cons1 << std::setfill(' ') << std::setw(20 - cons1.length()) - << " | "; + << " | "; } else { std::cout << std::setfill(' ') << std::setw(21) << " | "; } if (i == 0) { std::string commit_rule = std::get<2>(itm.second), - fire_rule = std::get<3>(itm.second); + fire_rule = std::get<3>(itm.second); bool exclude = std::get<4>(itm.second), permanent = std::get<5>(itm.second); std::cout << " " << commit_rule << std::setfill(' ') - << std::setw(20 - commit_rule.length()) << " | " << fire_rule - << std::setfill(' ') << std::setw(13 - fire_rule.length()) << " | " - << " " << (permanent ? "YES" : "NO ") << " | " - << (exclude ? "YES" : "NO ") << " |" << std::endl; + << std::setw(20 - commit_rule.length()) << " | " << fire_rule + << std::setfill(' ') << std::setw(13 - fire_rule.length()) << " | " + << " " << (permanent ? "YES" : "NO ") << " | " + << (exclude ? "YES" : "NO ") << " |" << std::endl; } else { std::cout << std::setfill(' ') << std::setw(20) << "|" << std::setfill(' ') - << std::setw(13) << "|" << std::setfill(' ') << std::setw(12) << "|" - << std::setfill(' ') << std::setw(10) << "|" << std::endl; + << std::setw(13) << "|" << std::setfill(' ') << std::setw(12) << "|" + << std::setfill(' ') << std::setw(10) << "|" << std::endl; } } std::cout << "*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" - "~~~~~~~" - "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*" - << std::endl; + "~~~~~~~" + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*" + << std::endl; } std::cout << std::endl; }; @@ -163,7 +163,7 @@ class CapioCLEngine { START_LOG(gettid(), "call(path=%s)", path.c_str()); if (_locations.find(path) == _locations.end()) { std::string commit = CAPIO_FILE_COMMITTED_ON_TERMINATION; - std::string fire = CAPIO_FILE_MODE_UPDATE; + std::string fire = CAPIO_FILE_MODE_UPDATE; /* * Inherit commit and fire rules from LPM directory @@ -174,8 +174,8 @@ class CapioCLEngine { if (std::regex_match(path, std::get<10>(data)) && filename.length() > matchSize) { LOG("Found match with %s", filename.c_str()); matchSize = filename.length(); - commit = std::get<2>(data); - fire = std::get<3>(data); + commit = std::get<2>(data); + fire = std::get<3>(data); } } LOG("Adding file %s to _locations with commit=%s, and fire=%s", path.c_str(), @@ -351,9 +351,9 @@ class CapioCLEngine { std::vector producers = std::get<0>(itm->second); DBG(gettid(), [&](const std::vector &arr) { for (auto elem : arr) { - LOG("producer: %s", elem.c_str()); + LOG("producer: %s", elem.c_str()); } - }(producers)); + }(producers)); return std::find(producers.begin(), producers.end(), app_name) != producers.end(); } LOG("No exact match found in locations. checking for globs"); @@ -364,9 +364,9 @@ class CapioCLEngine { std::vector producers = std::get<0>(entry); DBG(gettid(), [&](const std::vector &arr) { for (auto itm : arr) { - LOG("producer: %s", itm.c_str()); + LOG("producer: %s", itm.c_str()); } - }(producers)); + }(producers)); return std::find(producers.begin(), producers.end(), app_name) != producers.end(); } } diff --git a/src/server/capio-cl-engine/json_parser.hpp b/src/server/capio-cl-engine/json_parser.hpp index 6d9dce0ce..a6d5a4891 100644 --- a/src/server/capio-cl-engine/json_parser.hpp +++ b/src/server/capio-cl-engine/json_parser.hpp @@ -41,7 +41,7 @@ class JsonParser { return mismatch_pair.second == base.end(); } -public: + public: /** * @brief Perform the parsing of the capio_server configuration file * @@ -49,7 +49,7 @@ class JsonParser { * @return CapioCLEngine instance with the information provided by the config file */ static CapioCLEngine *parse(const std::filesystem::path &source) { - auto locations = new CapioCLEngine(); + auto locations = new CapioCLEngine(); const auto &capio_dir = get_capio_dir(); START_LOG(gettid(), "call(config_file='%s', capio_dir='%s')", source.c_str(), @@ -69,7 +69,7 @@ class JsonParser { simdjson::padded_string json; simdjson::ondemand::document entries; simdjson::ondemand::array input_stream, output_stream, streaming, permanent_files, - exclude_files, storage_memory, storage_fs; + exclude_files, storage_memory, storage_fs; simdjson::ondemand::object storage_section; simdjson::error_code error; @@ -77,7 +77,7 @@ class JsonParser { json = simdjson::padded_string::load(source.c_str()); } catch (const simdjson::simdjson_error &e) { std::cerr << CAPIO_LOG_SERVER_CLI_LEVEL_ERROR << " [ " << node_name << " ] " - << "Exception thrown while opening config file: " << e.what() << std::endl; + << "Exception thrown while opening config file: " << e.what() << std::endl; LOG("Exception thrown while opening config file: %s", e.what()); ERR_EXIT("Exception thrown while opening config file: %s", e.what()); } @@ -90,7 +90,7 @@ class JsonParser { } workflow_name = std::string(wf_name); std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name << " ] " - << "Parsing configuration for workflow: " << workflow_name << std::endl; + << "Parsing configuration for workflow: " << workflow_name << std::endl; LOG("Parsing configuration for workflow: %s", std::string(workflow_name).c_str()); std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name << " ] " << std::endl; @@ -105,23 +105,23 @@ class JsonParser { } std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name << " ] " - << "Parsing config for app " << app_name << std::endl; + << "Parsing config for app " << app_name << std::endl; LOG("Parsing config for app %s", std::string(app_name).c_str()); if (app["input_stream"].get_array().get(input_stream)) { std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_ERROR << " [ " << node_name << " ] " - << "No input_stream section found for app " << app_name << std::endl; + << "No input_stream section found for app " << app_name << std::endl; ERR_EXIT("No input_stream section found for app %s", std::string(app_name).c_str()); } else { for (auto itm : input_stream) { std::filesystem::path file(itm.get_string().take_value()); std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name << " ] " - << "Found file : " << file << std::endl; + << "Found file : " << file << std::endl; if (file.is_relative() || first_is_subpath_of_second(file, get_capio_dir())) { std::string appname(app_name); std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name << " ] " - << "File : " << file << " added to app: " << app_name - << std::endl; + << "File : " << file << " added to app: " << app_name + << std::endl; if (file.is_relative()) { file = capio_dir / file; } @@ -129,20 +129,20 @@ class JsonParser { locations->addConsumer(file, appname); } else { std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_WARNING << " [ " << node_name - << " ] " - << "File : " << file - << " is not relative to CAPIO_DIR. Ignoring..." << std::endl; + << " ] " + << "File : " << file + << " is not relative to CAPIO_DIR. Ignoring..." << std::endl; } } std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name << " ] " - << "Completed input_stream parsing for app: " << app_name << std::endl; + << "Completed input_stream parsing for app: " << app_name << std::endl; LOG("Completed input_stream parsing for app: %s", std::string(app_name).c_str()); } if (app["output_stream"].get_array().get(output_stream)) { std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_ERROR << " [ " << node_name << " ] " - << "No output_stream section found for app " << app_name << std::endl; + << "No output_stream section found for app " << app_name << std::endl; ERR_EXIT("No output_stream section found for app %s", std::string(app_name).c_str()); } else { @@ -151,8 +151,8 @@ class JsonParser { if (file.is_relative() || first_is_subpath_of_second(file, get_capio_dir())) { std::string appname(app_name); std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name << " ] " - << "Adding file: " << file << " to app: " << app_name - << std::endl; + << "Adding file: " << file << " to app: " << app_name + << std::endl; if (file.is_relative()) { file = capio_dir / file; } @@ -161,14 +161,14 @@ class JsonParser { } } std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name << " ] " - << "Completed output_stream parsing for app: " << app_name << std::endl; + << "Completed output_stream parsing for app: " << app_name << std::endl; LOG("Completed output_stream parsing for app: %s", std::string(app_name).c_str()); } // PARSING STREAMING FILES if (app["streaming"].get_array().get(streaming)) { std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_WARNING << " [ " << node_name << " ] " - << "No streaming section found for app: " << app_name << std::endl; + << "No streaming section found for app: " << app_name << std::endl; LOG("No streaming section found for app: %s", std::string(app_name).c_str()); } else { LOG("Began parsing streaming section for app %s", std::string(app_name).c_str()); @@ -210,7 +210,7 @@ class JsonParser { error = file["committed"].get_string().get(committed); if (error) { std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_ERROR << " [ " << node_name << " ] " - << "commit rule is mandatory in streaming section" << std::endl; + << "commit rule is mandatory in streaming section" << std::endl; ERR_EXIT("error commit rule is mandatory in streaming section"); } else { auto pos = committed.find(':'); @@ -218,8 +218,8 @@ class JsonParser { commit_rule = committed.substr(0, pos); if (commit_rule != CAPIO_FILE_COMMITTED_ON_CLOSE) { std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_ERROR << " [ " << node_name - << " ] " - << "commit rule " << commit_rule << std::endl; + << " ] " + << "commit rule " << commit_rule << std::endl; ERR_EXIT("error commit rule: %s", std::string(commit_rule).c_str()); } @@ -227,8 +227,8 @@ class JsonParser { if (!is_int(n_close_str)) { std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_ERROR << " [ " << node_name - << " ] " - << "commit rule on_close invalid number" << std::endl; + << " ] " + << "commit rule on_close invalid number" << std::endl; ERR_EXIT("error commit rule on_close invalid number: !is_int()"); } n_close = std::stol(n_close_str); @@ -244,9 +244,9 @@ class JsonParser { if (error) { std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_ERROR << " [ " << node_name - << " ] " - << "commit rule is on_file but no file_deps section found" - << std::endl; + << " ] " + << "commit rule is on_file but no file_deps section found" + << std::endl; ERR_EXIT("commit rule is on_file but no file_deps section found"); } @@ -258,9 +258,9 @@ class JsonParser { ? (get_capio_dir() / computed_path) : computed_path; std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name - << " ] " - << "Adding file: " << computed_path - << " to file dependencies: " << std::endl; + << " ] " + << "Adding file: " << computed_path + << " to file dependencies: " << std::endl; file_deps.emplace_back(computed_path); } } @@ -287,8 +287,8 @@ class JsonParser { LOG("batch_size: %d", batch_size); for (auto path : streaming_names) { std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name << " ] " - << " [ " << node_name << " ] " - << "Updating metadata for path: " << path << std::endl; + << " [ " << node_name << " ] " + << "Updating metadata for path: " << path << std::endl; if (path.is_relative()) { path = (capio_dir / path).lexically_normal(); } @@ -298,9 +298,9 @@ class JsonParser { std::string commit(commit_rule), firerule(mode); if (n_files != -1) { std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name - << " ] " - << "Setting path: " << path << " n_files to " << n_files - << std::endl; + << " ] " + << "Setting path: " << path << " n_files to " << n_files + << std::endl; locations->setDirectoryFileCount(path, n_files); } @@ -313,23 +313,23 @@ class JsonParser { } std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name << " ] " - << "completed parsing of streaming section for app: " << app_name - << std::endl; + << "completed parsing of streaming section for app: " << app_name + << std::endl; LOG("completed parsing of streaming section for app: %s", std::string(app_name).c_str()); } // END PARSING STREAMING FILES std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name << " ] " - << std::endl; + << std::endl; } // END OF APP MAIN LOOPS LOG("Completed parsing of io_graph app main loops"); std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name << " ] " - << "Completed parsing of io_graph" << std::endl; + << "Completed parsing of io_graph" << std::endl; LOG("Completed parsing of io_graph"); if (entries["permanent"].get_array().get(permanent_files)) { // PARSING PERMANENT FILES std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_WARNING << " [ " << node_name << " ] " - << "No permanent section found for workflow: " << workflow_name << std::endl; + << "No permanent section found for workflow: " << workflow_name << std::endl; LOG("No permanent section found for workflow: %s", std::string(workflow_name).c_str()); } else { for (auto file : permanent_files) { @@ -351,7 +351,7 @@ class JsonParser { } } std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name << " ] " - << "Completed parsing of permanent files" << std::endl; + << "Completed parsing of permanent files" << std::endl; LOG("Completed parsing of permanent files"); } // END PARSING PERMANENT FILES @@ -360,7 +360,7 @@ class JsonParser { if (entries["exclude"].get_array().get(exclude_files)) { // PARSING PERMANENT FILES std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_WARNING << " [ " << node_name << " ] " - << "No exclude section found for workflow: " << workflow_name << std::endl; + << "No exclude section found for workflow: " << workflow_name << std::endl; LOG("No exclude section found for workflow: %s", std::string(workflow_name).c_str()); } else { for (auto file : exclude_files) { @@ -382,7 +382,7 @@ class JsonParser { } } std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name << " ] " - << "Completed parsing of exclude files" << std::endl; + << "Completed parsing of exclude files" << std::endl; LOG("Completed parsing of exclude files"); } // END PARSING PERMANENT FILES @@ -391,19 +391,19 @@ class JsonParser { auto home_node_policies = entries["home_node_policy"].error(); if (!home_node_policies) { std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_WARNING << " [ " << node_name << " ] " - << "Warning: capio does not support home node policies yet! skipping section " - << std::endl; + << "Warning: capio does not support home node policies yet! skipping section " + << std::endl; } if (entries["storage"].get_object().get(storage_section)) { std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_WARNING << " [ " << node_name << " ] " - << "No storage section found for workflow: " << workflow_name << std::endl; + << "No storage section found for workflow: " << workflow_name << std::endl; LOG("No storage section found for workflow: %s", std::string(workflow_name).c_str()); } else { if (storage_section["memory"].get_array().get(storage_memory)) { std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_WARNING << " [ " << node_name << " ] " - << "No files listed in memory storage section for workflow: " - << workflow_name << std::endl; + << "No files listed in memory storage section for workflow: " + << workflow_name << std::endl; LOG("No files listed in memory storage section for workflow: %s", std::string(workflow_name).c_str()); } else { @@ -411,16 +411,16 @@ class JsonParser { std::string_view file_str; file.get_string().get(file_str); std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name << " ] " - << "Setting file " << file_str << " to be stored in memory" - << std::endl; + << "Setting file " << file_str << " to be stored in memory" + << std::endl; locations->setStoreFileInMemory(file_str); } } if (storage_section["fs"].get_array().get(storage_fs)) { std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_WARNING << " [ " << node_name << " ] " - << "No files listed in fs storage section for workflow: " << workflow_name - << std::endl; + << "No files listed in fs storage section for workflow: " << workflow_name + << std::endl; LOG("No files listed in fs storage section for workflow: %s", std::string(workflow_name).c_str()); } else { @@ -428,13 +428,13 @@ class JsonParser { std::string_view file_str; file.get_string().get(file_str); std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name << " ] " - << "Setting file " << file_str << " to be stored on file system" - << std::endl; + << "Setting file " << file_str << " to be stored on file system" + << std::endl; locations->setStoreFileInFileSystem(file_str); } } std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << " [ " << node_name << " ] " - << "Completed parsing of memory storage directives" << std::endl; + << "Completed parsing of memory storage directives" << std::endl; } std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_JSON << std::endl; diff --git a/src/server/client-manager/handlers/read.hpp b/src/server/client-manager/handlers/read.hpp index 69e21ed2a..befba4f5a 100644 --- a/src/server/client-manager/handlers/read.hpp +++ b/src/server/client-manager/handlers/read.hpp @@ -79,10 +79,9 @@ inline void read_mem_handler(const char *const str) { if (use_cache) { LOG("Computing size of data to send: minimum between:"); LOG("client_cache_line_size: %llu", client_cache_line_size); - LOG("file_size:%llu - read_begin_offset=%llu = %llu", size_to_send, - read_begin_offset, size_to_send - read_begin_offset); - size_to_send = - std::min({client_cache_line_size, (size_to_send - read_begin_offset)}); + LOG("file_size:%llu - read_begin_offset=%llu = %llu", size_to_send, read_begin_offset, + size_to_send - read_begin_offset); + size_to_send = std::min({client_cache_line_size, (size_to_send - read_begin_offset)}); } LOG("Sending to posix app the offset up to which read."); @@ -90,7 +89,7 @@ inline void read_mem_handler(const char *const str) { read_begin_offset + size_to_send >= storage_service->sizeOf(path)) { LOG("File is committed, and end of read >= than file size." " signaling it to posix application by setting offset MSB to 1"); - LOG("Sending offset: %llu", 0x8000000000000000 |size_to_send); + LOG("Sending offset: %llu", 0x8000000000000000 | size_to_send); client_manager->reply_to_client(tid, 0x8000000000000000 | size_to_send); } else { LOG("File is not committed. Sending offset: %llu", size_to_send); diff --git a/src/server/file-manager/file_manager_impl.hpp b/src/server/file-manager/file_manager_impl.hpp index 29c509e47..775b36ca3 100644 --- a/src/server/file-manager/file_manager_impl.hpp +++ b/src/server/file-manager/file_manager_impl.hpp @@ -111,7 +111,7 @@ inline void CapioFileManager::_unlockThreadAwaitingData( * should be triggered only if the file is a directory and the rule specified on it is * Fire No Update */ - const bool is_directory = std::filesystem::is_directory(path); + const bool is_directory = std::filesystem::is_directory(path); const uintmax_t filesize = is_directory ? ULLONG_MAX : get_file_size_if_exists(path); /* * Check for file size only if it is directory, otherwise, @@ -167,8 +167,8 @@ inline void CapioFileManager::_unlockThreadAwaitingData( */ inline void CapioFileManager::increaseCloseCount(const std::filesystem::path &path) { START_LOG(gettid(), "call(path=%s)", path.c_str()); - auto metadata_path = getAndCreateMetadataPath(path); - const auto lock = new DistributedSemaphore(metadata_path + ".lock", 300); + auto metadata_path = getAndCreateMetadataPath(path); + const auto lock = new DistributedSemaphore(metadata_path + ".lock", 300); long long close_count = 0; LOG("Gained mutual exclusive access to token file %s", (metadata_path + ".lock").c_str()); diff --git a/src/server/storage-service/CapioFile/CapioFile.hpp b/src/server/storage-service/CapioFile/CapioFile.hpp index 8829ca16b..af6ac1a51 100644 --- a/src/server/storage-service/CapioFile/CapioFile.hpp +++ b/src/server/storage-service/CapioFile/CapioFile.hpp @@ -2,13 +2,12 @@ #define CAPIOFILE_HPP class CapioFile { -protected: + protected: const std::string fileName; std::size_t totalSize; -public: - explicit CapioFile(const std::string &filePath) : fileName(filePath), totalSize(0) { - }; + public: + explicit CapioFile(const std::string &filePath) : fileName(filePath), totalSize(0) {}; virtual ~CapioFile() = default; [[nodiscard]] std::size_t getSize() const { @@ -34,7 +33,7 @@ class CapioFile { * @return number of bytes read from CapioMemoryFile */ virtual std::size_t readData(char *buffer, std::size_t file_offset, - std::size_t buffer_size) = 0; + std::size_t buffer_size) = 0; /** * Store data inside the CapioMemoryFile by reading it from a SPSCQueue object. Behaves just diff --git a/src/server/storage-service/CapioFile/CapioMemoryFile.hpp b/src/server/storage-service/CapioFile/CapioMemoryFile.hpp index f1c012684..5fd98bd8d 100644 --- a/src/server/storage-service/CapioFile/CapioMemoryFile.hpp +++ b/src/server/storage-service/CapioFile/CapioMemoryFile.hpp @@ -16,7 +16,7 @@ class CapioMemoryFile : public CapioFile { std::map> memoryBlocks; // Static file sizes of file pages - static constexpr u_int32_t _pageSizeMB = 4; + static constexpr u_int32_t _pageSizeMB = 4; static constexpr u_int64_t _pageSizeBytes = _pageSizeMB * 1024 * 1024; char *cross_page_buffer_view; @@ -59,14 +59,12 @@ class CapioMemoryFile : public CapioFile { return block; } -public: + public: explicit CapioMemoryFile(const std::string &filePath) : CapioFile(filePath) { cross_page_buffer_view = new char[_pageSizeBytes]; } - ~CapioMemoryFile() override { - delete[] cross_page_buffer_view; - } + ~CapioMemoryFile() override { delete[] cross_page_buffer_view; } /** * Write data to a file stored inside the memory @@ -197,7 +195,7 @@ class CapioMemoryFile : public CapioFile { std::size_t bytesRead = 0; while (bytesRead < length) { - const auto [map_offset,mem_block_offset_begin , buffer_view_size] = + const auto [map_offset, mem_block_offset_begin, buffer_view_size] = compute_offsets(offset, length - bytesRead); if (const auto it = memoryBlocks.lower_bound(map_offset); it != memoryBlocks.end()) { diff --git a/src/server/storage-service/capio_storage_service.hpp b/src/server/storage-service/capio_storage_service.hpp index 7f3f0aa61..5de1c3d6d 100644 --- a/src/server/storage-service/capio_storage_service.hpp +++ b/src/server/storage-service/capio_storage_service.hpp @@ -14,7 +14,7 @@ class CapioStorageService { std::unordered_map *_stored_files; std::unordered_map>> - *_threads_waiting_for_memory_data; + *_threads_waiting_for_memory_data; /** * Return a file if exists. if not, create it and then return it @@ -28,17 +28,17 @@ class CapioStorageService { return _stored_files->at(file_name); } -public: + public: CapioStorageService() { START_LOG(gettid(), "call()"); - _stored_files = new std::unordered_map; + _stored_files = new std::unordered_map; _client_to_server_queue = new std::unordered_map; _server_to_client_queue = new std::unordered_map; _threads_waiting_for_memory_data = new std::unordered_map>>; std::cout << CAPIO_SERVER_CLI_LOG_SERVER << " [ " << node_name << " ] " - << "CapioStorageService initialization completed." << std::endl; + << "CapioStorageService initialization completed." << std::endl; } ~CapioStorageService() { @@ -148,7 +148,7 @@ class CapioStorageService { off64_t size) const { START_LOG(gettid(), "call(tid=%d, file=%s, offset=%lld, size=%lld)", tid, file.c_str(), offset, size); - const auto f = getFile(file); + const auto f = getFile(file); const auto queue = _client_to_server_queue->at(tid); f->readFromQueue(*queue, offset, size); } From c4a85d258c7cfa4f42f84d942d391e010b61a861 Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Mon, 12 May 2025 14:47:39 +0200 Subject: [PATCH 32/33] code cleanup --- .../capio-cl-engine/capio_cl_engine.hpp | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/server/capio-cl-engine/capio_cl_engine.hpp b/src/server/capio-cl-engine/capio_cl_engine.hpp index 9aaac8517..bbd8ac3cc 100644 --- a/src/server/capio-cl-engine/capio_cl_engine.hpp +++ b/src/server/capio-cl-engine/capio_cl_engine.hpp @@ -12,18 +12,18 @@ class CapioCLEngine { private: std::unordered_map, // Vector for producers [0] - std::vector, // Vector for consumers [1] - std::string, // commit rule [2] - std::string, // fire_rule [3] - bool, // permanent [4] - bool, // exclude [5] - bool, // is_file (if true yes otherwise it is a directory) [6] - int, // commit on close number [7] - long, // directory file count [8] - std::vector, // File dependencies [9] - std::regex, // Regex from name to match globs [10] - bool>> // Store File in memory or on FS. true = memory [11] + std::tuple, // Vector for producers [0] + std::vector, // Vector for consumers [1] + std::string, // commit rule [2] + std::string, // fire_rule [3] + bool, // permanent [4] + bool, // exclude [5] + bool, // is_file (false = directory) [6] + int, // commit on close number [7] + long, // directory file count [8] + std::vector, // File dependencies [9] + std::regex, // Regex to match globs [10] + bool>> // Store File on FS. true = memory [11] _locations; static std::string truncateLastN(const std::string &str, const int n) { From e2b0460a7e15d46e70fed0d95292437056af6790 Mon Sep 17 00:00:00 2001 From: Marco Edoardo Santimaria Date: Mon, 12 May 2025 14:50:20 +0200 Subject: [PATCH 33/33] code cleanup --- src/common/capio/semaphore.hpp | 20 +++++++++----------- src/posix/handlers/open.hpp | 12 ++++++------ src/posix/handlers/read.hpp | 10 +++++----- src/posix/handlers/write.hpp | 11 +++++------ src/posix/utils/cache.hpp | 8 ++++---- src/posix/utils/filesystem.hpp | 10 +++++----- 6 files changed, 34 insertions(+), 37 deletions(-) diff --git a/src/common/capio/semaphore.hpp b/src/common/capio/semaphore.hpp index 4aabdae86..f1f0f560e 100644 --- a/src/common/capio/semaphore.hpp +++ b/src/common/capio/semaphore.hpp @@ -12,18 +12,16 @@ * */ class NoLock { -public: + public: NoLock(const std::string &name, unsigned int init_value, bool cleanup) { START_LOG(capio_syscall(SYS_gettid), "call(name=%s, initial_value=%d)", name.c_str(), init_value); } - NoLock(const NoLock &) = delete; + NoLock(const NoLock &) = delete; NoLock &operator=(const NoLock &) = delete; - ~NoLock() { - START_LOG(capio_syscall(SYS_gettid), "call()"); - }; + ~NoLock() { START_LOG(capio_syscall(SYS_gettid), "call()"); }; static inline void lock() { START_LOG(capio_syscall(SYS_gettid), "call()"); }; @@ -36,12 +34,12 @@ class NoLock { * */ class NamedSemaphore { -private: + private: const std::string _name; sem_t *_sem; bool _require_cleanup; -public: + public: NamedSemaphore(std::string name, unsigned int init_value, bool cleanup = true) : _name(std::move(name)), _require_cleanup(cleanup) { START_LOG(capio_syscall(SYS_gettid), " call(name=%s, init_value=%d, cleanup=%s)", @@ -59,7 +57,7 @@ class NamedSemaphore { } } - NamedSemaphore(const NamedSemaphore &) = delete; + NamedSemaphore(const NamedSemaphore &) = delete; NamedSemaphore &operator=(const NamedSemaphore &) = delete; ~NamedSemaphore() { @@ -114,11 +112,11 @@ class NamedSemaphore { * */ class Semaphore { -private: + private: sem_t _sem{}; bool _require_cleanup; -public: + public: explicit Semaphore(unsigned int init_value, bool cleanup = true) { START_LOG(capio_syscall(SYS_gettid), "call(init_value=%d)", init_value); @@ -127,7 +125,7 @@ class Semaphore { } } - Semaphore(const Semaphore &) = delete; + Semaphore(const Semaphore &) = delete; Semaphore &operator=(const Semaphore &) = delete; ~Semaphore() { diff --git a/src/posix/handlers/open.hpp b/src/posix/handlers/open.hpp index 6740d453d..65340469f 100644 --- a/src/posix/handlers/open.hpp +++ b/src/posix/handlers/open.hpp @@ -35,8 +35,8 @@ std::string compute_abs_path(char *pathname, int dirfd) { #if defined(SYS_creat) int creat_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, long *result) { std::string pathname(reinterpret_cast(arg0)); - auto tid = static_cast(syscall_no_intercept(SYS_gettid)); - int flags = O_CREAT | O_WRONLY | O_TRUNC; + auto tid = static_cast(syscall_no_intercept(SYS_gettid)); + int flags = O_CREAT | O_WRONLY | O_TRUNC; mode_t mode = static_cast(arg2); START_LOG(tid, "call(path=%s, flags=%d, mode=%d)", pathname.data(), flags, mode); @@ -64,9 +64,9 @@ int creat_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long ar #if defined(SYS_open) int open_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, long *result) { std::string pathname(reinterpret_cast(arg0)); - int flags = static_cast(arg1); + int flags = static_cast(arg1); mode_t mode = static_cast(arg2); - auto tid = static_cast(syscall_no_intercept(SYS_gettid)); + auto tid = static_cast(syscall_no_intercept(SYS_gettid)); START_LOG(tid, "call(path=%s, flags=%d, mode=%d)", pathname.data(), flags, mode); std::string path = compute_abs_path(pathname.data(), -1); @@ -100,9 +100,9 @@ int open_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long arg int openat_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, long *result) { int dirfd = static_cast(arg0); std::string pathname(reinterpret_cast(arg1)); - int flags = static_cast(arg2); + int flags = static_cast(arg2); mode_t mode = static_cast(arg3); - auto tid = static_cast(syscall_no_intercept(SYS_gettid)); + auto tid = static_cast(syscall_no_intercept(SYS_gettid)); START_LOG(tid, "call(path=%s, flags=%d, mode=%d)", pathname.data(), flags, mode); std::string path = compute_abs_path(pathname.data(), dirfd); diff --git a/src/posix/handlers/read.hpp b/src/posix/handlers/read.hpp index 5850dba91..65cdb2391 100644 --- a/src/posix/handlers/read.hpp +++ b/src/posix/handlers/read.hpp @@ -33,10 +33,10 @@ inline off64_t capio_read_mem(int fd, size_t count, void *buffer, long *result) #if defined(SYS_read) int read_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, long *result) { - int fd = static_cast(arg0); - auto count = static_cast(arg2); + int fd = static_cast(arg0); + auto count = static_cast(arg2); auto buffer = reinterpret_cast(arg1); - auto tid = static_cast(syscall_no_intercept(SYS_gettid)); + auto tid = static_cast(syscall_no_intercept(SYS_gettid)); START_LOG(capio_syscall(SYS_gettid), "call(fd=%d, tid=%d, count=%ld)", fd, tid, count); if (exists_capio_fd(fd)) { @@ -54,9 +54,9 @@ int read_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long arg #if defined(SYS_readv) int readv_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, long *result) { - auto fd = static_cast(arg0); + auto fd = static_cast(arg0); auto iovcnt = static_cast(arg2); - auto tid = static_cast(syscall_no_intercept(SYS_gettid)); + auto tid = static_cast(syscall_no_intercept(SYS_gettid)); if (exists_capio_fd(fd)) { auto computed_offset = get_capio_fd_offset(fd) + iovcnt * sizeof(iovec); diff --git a/src/posix/handlers/write.hpp b/src/posix/handlers/write.hpp index 539f7190b..6d2aa6702 100644 --- a/src/posix/handlers/write.hpp +++ b/src/posix/handlers/write.hpp @@ -4,7 +4,6 @@ #include "utils/common.hpp" #include "utils/requests.hpp" - inline off64_t capio_write_fs(int fd, capio_off64_t count, pid_t tid) { START_LOG(tid, "call(fd=%d, count=%ld)", fd, count); @@ -29,10 +28,10 @@ inline off64_t capio_write_mem(int fd, char *buffer, capio_off64_t count, pid_t #if defined(SYS_write) int write_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, long *result) { - auto fd = static_cast(arg0); + auto fd = static_cast(arg0); auto buffer = reinterpret_cast(arg1); - auto count = static_cast(arg2); - auto tid = static_cast(syscall_no_intercept(SYS_gettid)); + auto count = static_cast(arg2); + auto tid = static_cast(syscall_no_intercept(SYS_gettid)); START_LOG(tid, "call(fd=%d, buffer=%p, count=%ld, id=%ld)", fd, buffer, count, tid); if (!exists_capio_fd(fd)) { LOG("FD %d is not handled by capio... skipping syscall", fd); @@ -51,10 +50,10 @@ int write_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long ar #if defined(SYS_writev) int writev_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, long *result) { - auto fd = static_cast(arg0); + auto fd = static_cast(arg0); auto io_vec = reinterpret_cast(arg1); auto iovcnt = static_cast(arg2); - long tid = syscall_no_intercept(SYS_gettid); + long tid = syscall_no_intercept(SYS_gettid); START_LOG(tid, "call(fd=%d, buffer=%p, count=%ld, pid=%ld)", fd, io_vec->iov_base, io_vec->iov_len, tid); if (!exists_capio_fd(fd)) { diff --git a/src/posix/utils/cache.hpp b/src/posix/utils/cache.hpp index 900002a18..67e07977f 100644 --- a/src/posix/utils/cache.hpp +++ b/src/posix/utils/cache.hpp @@ -17,11 +17,11 @@ inline thread_local ReadRequestCacheMEM *read_request_cache_mem; inline void init_caches() { START_LOG(capio_syscall(SYS_gettid), "call()"); - write_request_cache_fs = new WriteRequestCacheFS(); - read_request_cache_fs = new ReadRequestCacheFS(); + write_request_cache_fs = new WriteRequestCacheFS(); + read_request_cache_fs = new ReadRequestCacheFS(); consent_request_cache_fs = new ConsentRequestCache(); - write_request_cache_mem = new WriteRequestCacheMEM(); - read_request_cache_mem = new ReadRequestCacheMEM(); + write_request_cache_mem = new WriteRequestCacheMEM(); + read_request_cache_mem = new ReadRequestCacheMEM(); } inline void delete_caches() { diff --git a/src/posix/utils/filesystem.hpp b/src/posix/utils/filesystem.hpp index 58a5917fb..c64d8c4e6 100644 --- a/src/posix/utils/filesystem.hpp +++ b/src/posix/utils/filesystem.hpp @@ -234,7 +234,7 @@ inline std::filesystem::path get_dir_path(int dirfd) { return it->second; } LOG("dirfd %d not found. Computing it through proclnk", dirfd); - char proclnk[128] = {}; + char proclnk[128] = {}; char dir_pathname[PATH_MAX] = {}; sprintf(proclnk, "/proc/self/fd/%d", dirfd); if (capio_syscall(SYS_readlinkat, AT_FDCWD, proclnk, dir_pathname, PATH_MAX) < 0) { @@ -252,10 +252,10 @@ inline std::filesystem::path get_dir_path(int dirfd) { inline void init_filesystem() { std::unique_ptr buf(new char[PATH_MAX]); capio_syscall(SYS_getcwd, buf.get(), PATH_MAX); - current_dir = std::make_unique(buf.get()); + current_dir = std::make_unique(buf.get()); capio_files_descriptors = new CPFileDescriptors_t(); - capio_files_paths = new CPFilesPaths_t(); - files = new CPFiles_t(); + capio_files_paths = new CPFilesPaths_t(); + files = new CPFiles_t(); } /** @@ -268,7 +268,7 @@ inline void rename_capio_path(const std::string &oldpath, const std::string &new START_LOG(capio_syscall(SYS_gettid), "call(oldpath=%s, newpath=%s)", oldpath.c_str(), newpath.c_str()); if (capio_files_paths->find(oldpath) != capio_files_paths->end()) { - auto entry = capio_files_paths->extract(oldpath); + auto entry = capio_files_paths->extract(oldpath); entry.key() = newpath; capio_files_paths->insert(std::move(entry)); for (auto fd : capio_files_paths->at(newpath)) {