diff --git a/src/common/capio/env.hpp b/src/common/capio/env.hpp index e0cc2f002..2b66527ae 100644 --- a/src/common/capio/env.hpp +++ b/src/common/capio/env.hpp @@ -36,7 +36,7 @@ inline const std::filesystem::path &get_capio_dir() { capio_dir = std::filesystem::path(buf.get()); for (auto &forbidden_path : CAPIO_DIR_FORBIDDEN_PATHS) { if (capio_dir.native().rfind(forbidden_path, 0) == 0) { - ERR_EXIT("CAPIO_DIR inside %s file system is not supported", forbidden_path); + ERR_EXIT("CAPIO_DIR inside %s file system is not supported", forbidden_path.data()); } } } diff --git a/src/common/capio/logger.hpp b/src/common/capio/logger.hpp index c5ec15d5c..cbe2967b4 100644 --- a/src/common/capio/logger.hpp +++ b/src/common/capio/logger.hpp @@ -55,7 +55,7 @@ inline auto open_server_logfile() { std::to_string(capio_syscall(SYS_gettid)) + ".log"; logfile.open(logfile_name, std::ofstream::out); - capio_delete_vec(&hostname); + delete[] hostname; return logfile_name; } @@ -319,6 +319,12 @@ class Logger { #define ERR_EXIT(message, ...) \ log.log(message, ##__VA_ARGS__); \ if (!continue_on_error) { \ + char tmp_buf[1024]; \ + sprintf(tmp_buf, message, ##__VA_ARGS__); \ + char node_name[HOST_NAME_MAX]{0}; \ + gethostname(node_name, HOST_NAME_MAX); \ + printf("%s [ %s ] %s\n", CAPIO_LOG_SERVER_CLI_LEVEL_ERROR, node_name, tmp_buf); \ + fflush(stdout); \ exit(EXIT_FAILURE); \ } #define LOG(message, ...) log.log(message, ##__VA_ARGS__) @@ -355,9 +361,22 @@ class Logger { #else -#define ERR_EXIT(message, ...) \ - if (!continue_on_error) \ - exit(EXIT_FAILURE) +#ifndef __CAPIO_POSIX +inline bool syscall_no_intercept_flag = false; +#endif + +#define ERR_EXIT(fmt, ...) \ + if (!continue_on_error) { \ + syscall_no_intercept_flag = true; \ + char tmp_buf[1024]; \ + sprintf(tmp_buf, fmt, ##__VA_ARGS__); \ + char node_name[HOST_NAME_MAX]{0}; \ + gethostname(node_name, HOST_NAME_MAX); \ + printf("%s [ %s ] %s\n", CAPIO_LOG_SERVER_CLI_LEVEL_ERROR, node_name, tmp_buf); \ + fflush(stdout); \ + exit(EXIT_FAILURE); \ + } + #define LOG(message, ...) #define START_LOG(tid, message, ...) #define START_SYSCALL_LOGGING() diff --git a/src/common/capio/shm.hpp b/src/common/capio/shm.hpp index 66d6b27c8..cbb76e1bf 100644 --- a/src/common/capio/shm.hpp +++ b/src/common/capio/shm.hpp @@ -66,7 +66,7 @@ class CapioShmCanary { auto message = new char[strlen(CAPIO_SHM_CANARY_ERROR)]; sprintf(message, CAPIO_SHM_CANARY_ERROR, _canary_name.data()); std::cout << CAPIO_SERVER_CLI_LOG_SERVER_ERROR << message << std::endl; - capio_delete_vec(&message); + delete[] message; #endif ERR_EXIT("ERR: shm canary flag already exists"); } @@ -118,25 +118,46 @@ void *create_shm(const std::string &shm_name, const long int size) { return p; } +auto get_shm_size(int shm_fd, const char *shm_name) { + START_LOG(capio_syscall(SYS_gettid), "call(fd=%ld)", shm_fd); + struct stat sb = {0}; + /* Open existing object */ + /* Use shared memory object size as length argument for mmap() + and as number of bytes to write() */ + if (fstat(shm_fd, &sb) == -1) { + ERR_EXIT("fstat %s", shm_name); + } + + if (sb.st_size <= 0) { + LOG("WARN: size of stat is %ld. Retry once.", sb.st_size); + if (fstat(shm_fd, &sb) == -1) { + ERR_EXIT("fstat %s", shm_name); + } + if (sb.st_size <= 0) { + LOG("WARN: retry no. 2 gave a size of %ld", sb.st_size); + ERR_EXIT("FATAL: unable to obtain size of shm object %s after two tries...", shm_name); + } + } + + LOG("Size of shm object %s : %ld", shm_name, sb.st_size); + return sb.st_size; +} + void *get_shm(const std::string &shm_name) { START_LOG(capio_syscall(SYS_gettid), "call(shm_name=%s)", shm_name.c_str()); // if we are not creating a new object, mode is equals to 0 - int fd = shm_open(shm_name.c_str(), O_RDWR, 0); // to be closed - struct stat sb = {0}; + int fd = shm_open(shm_name.c_str(), O_RDWR, 0); // to be closed if (fd == -1) { ERR_EXIT("get_shm shm_open %s", shm_name.c_str()); } - /* Open existing object */ - /* Use shared memory object size as length argument for mmap() - and as number of bytes to write() */ - if (fstat(fd, &sb) == -1) { - ERR_EXIT("fstat %s", shm_name.c_str()); - } - void *p = mmap(nullptr, sb.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + + auto size = get_shm_size(fd, shm_name.c_str()); + + void *p = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (p == MAP_FAILED) { LOG("ERROR MMAP arg dump:"); - LOG("mmap-size: %ld", sb.st_size); + LOG("mmap-size: %ld", size); LOG("mmap-prot: %ld", PROT_READ | PROT_WRITE); LOG("mmap-flags: %ld", MAP_SHARED); LOG("mmap-fd: %ld", fd); @@ -152,24 +173,21 @@ void *get_shm_if_exist(const std::string &shm_name) { START_LOG(capio_syscall(SYS_gettid), "call(shm_name=%s)", shm_name.c_str()); // if we are not creating a new object, mode is equals to 0 - int fd = shm_open(shm_name.c_str(), O_RDWR, 0); // to be closed - struct stat sb = {0}; + int fd = shm_open(shm_name.c_str(), O_RDWR, 0); // to be closed + if (fd == -1) { if (errno == ENOENT) { return nullptr; } ERR_EXIT("ERROR: unable to open shared memory %s: %s", shm_name.c_str(), strerror(errno)); } - /* Open existing object */ - /* Use shared memory object size as length argument for mmap() - and as number of bytes to write() */ - if (fstat(fd, &sb) == -1) { - ERR_EXIT("fstat %s", shm_name.c_str()); - } - void *p = mmap(nullptr, sb.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + + auto size = get_shm_size(fd, shm_name.c_str()); + + void *p = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (p == MAP_FAILED) { LOG("ERROR MMAP arg dump:"); - LOG("mmap-size: %ld", sb.st_size); + LOG("mmap-size: %ld", size); LOG("mmap-prot: %ld", PROT_READ | PROT_WRITE); LOG("mmap-flags: %ld", MAP_SHARED); LOG("mmap-fd: %ld", fd); diff --git a/src/common/capio/utils.h b/src/common/capio/utils.h deleted file mode 100644 index 5b29dbffc..000000000 --- a/src/common/capio/utils.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef UTILS_H -#define UTILS_H -#include -#include -#include - -template void capio_delete(T **ptr) { - if (*ptr != nullptr) { - delete *ptr; - *ptr = nullptr; - } -#ifndef __CAPIO_POSIX - else { - char nodename[HOST_NAME_MAX]{0}; - gethostname(nodename, HOST_NAME_MAX); - std::cout << CAPIO_SERVER_CLI_LOG_SERVER_WARNING << " [ " << nodename << " ] " - << "Double delete detected! avoided segfault..." << std::endl; - } -#endif -} - -template void capio_delete_vec(T **ptr) { - if (*ptr != nullptr) { - delete[] *ptr; - *ptr = nullptr; - } -#ifndef __CAPIO_POSIX - else { - char nodename[HOST_NAME_MAX]{0}; - gethostname(nodename, HOST_NAME_MAX); - std::cout << CAPIO_SERVER_CLI_LOG_SERVER_WARNING << " [ " << nodename << " ] " - << "Double delete[] detected! avoided segfault..." << std::endl; - } -#endif -} - -#define lockguard_guard(expr) \ - try { \ - expr; \ - } catch (const std::system_error &e) { \ - char nodename[HOST_NAME_MAX]{0}; \ - gethostname(nodename, HOST_NAME_MAX); \ - std::cout << CAPIO_SERVER_CLI_LOG_SERVER_WARNING << " [ " << nodename << " ] " \ - << "Danger! caught possible deadlock due to already acquired semaphore" \ - << std::endl; \ - } - -#endif // UTILS_H diff --git a/src/posix/handlers/exit.hpp b/src/posix/handlers/exit.hpp index f8bcbb69a..c966035fc 100644 --- a/src/posix/handlers/exit.hpp +++ b/src/posix/handlers/exit.hpp @@ -31,7 +31,7 @@ int exit_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long arg LOG("Removed caches"); if (const auto itm = bufs_response->find(tid); itm != bufs_response->end()) { - capio_delete(&itm->second); + delete itm->second; bufs_response->erase(tid); LOG("Removed response buffer"); } diff --git a/src/posix/libcapio_posix.cpp b/src/posix/libcapio_posix.cpp index 8a70343f5..df309375d 100644 --- a/src/posix/libcapio_posix.cpp +++ b/src/posix/libcapio_posix.cpp @@ -4,8 +4,6 @@ * logs up to CAPIO_MAX_LOG_LEVEL function calls */ -#include - #include #include @@ -411,7 +409,29 @@ static int hook(long syscall_number, long arg0, long arg1, long arg2, long arg3, } LOG("Handling syscall NO %ld (max num is %ld)", syscall_number, CAPIO_NR_SYSCALLS); - return syscallTable[syscall_number](arg0, arg1, arg2, arg3, arg4, arg5, result); + try { + return syscallTable[syscall_number](arg0, arg1, arg2, arg3, arg4, arg5, result); + } catch (const std::exception &exception) { + syscall_no_intercept_flag = true; + + std::cout + << std::endl + << "~~~~~~~~~~~~~~[\033[31mlibcapio_posix.so: FATAL EXCEPTION\033[0m]~~~~~~~~~~~~~~" + << std::endl + << "| Exception thrown while handling syscall " << syscall_number << std::endl + << "| TID of offending thread: " << syscall_no_intercept(SYS_gettid) << std::endl + << "| PID of offending thread: " << syscall_no_intercept(SYS_getpid) << std::endl + << "| PPID of offending thread: " << syscall_no_intercept(SYS_getppid) << std::endl + << "| " << std::endl + << "| `" << typeid(exception).name() << ": " << exception.what() << std::endl + << "|" << std::endl + << "~~~~~~~~~~~~~~[\033[31mlibcapio_posix.so: FATAL EXCEPTION\033[0m]~~~~~~~~~~~~~~" + << std::endl + << std::endl; + + ERR_EXIT("%s", exception.what()); + } + return 1; } static __attribute__((constructor)) void init() { diff --git a/src/posix/utils/cache.hpp b/src/posix/utils/cache.hpp index 6a2e9060d..67e07977f 100644 --- a/src/posix/utils/cache.hpp +++ b/src/posix/utils/cache.hpp @@ -26,15 +26,15 @@ inline void init_caches() { inline void delete_caches() { START_LOG(capio_syscall(SYS_gettid), "call()"); - capio_delete(&write_request_cache_fs); - capio_delete(&read_request_cache_fs); - capio_delete(&consent_request_cache_fs); - capio_delete(&write_request_cache_mem); - capio_delete(&read_request_cache_mem); + delete write_request_cache_fs; + delete read_request_cache_fs; + delete consent_request_cache_fs; + delete write_request_cache_mem; + delete read_request_cache_mem; - capio_delete(&cts_queue); + delete cts_queue; LOG("Removed cts_queue"); - capio_delete(&stc_queue); + delete stc_queue; LOG("Removed stc_queue"); } diff --git a/src/posix/utils/cache/consent_request_cache.hpp b/src/posix/utils/cache/consent_request_cache.hpp index b060c4e7e..bf5cced10 100644 --- a/src/posix/utils/cache/consent_request_cache.hpp +++ b/src/posix/utils/cache/consent_request_cache.hpp @@ -26,7 +26,7 @@ class ConsentRequestCache { ~ConsentRequestCache() { START_LOG(capio_syscall(SYS_gettid), "call()"); - capio_delete(&available_consent); + delete available_consent; }; void consent_request(const std::filesystem::path &path, long tid, diff --git a/src/posix/utils/cache/read_request_cache_fs.hpp b/src/posix/utils/cache/read_request_cache_fs.hpp index f55c674c2..d8a6f07c2 100644 --- a/src/posix/utils/cache/read_request_cache_fs.hpp +++ b/src/posix/utils/cache/read_request_cache_fs.hpp @@ -28,7 +28,7 @@ class ReadRequestCacheFS { ~ReadRequestCacheFS() { START_LOG(capio_syscall(SYS_gettid), "call()"); - capio_delete(&available_read_cache); + delete available_read_cache; }; void read_request(std::filesystem::path path, const long end_of_read, int tid, const int fd) { diff --git a/src/posix/utils/cache/read_request_cache_mem.hpp b/src/posix/utils/cache/read_request_cache_mem.hpp index 9816dc522..16661c02a 100644 --- a/src/posix/utils/cache/read_request_cache_mem.hpp +++ b/src/posix/utils/cache/read_request_cache_mem.hpp @@ -73,7 +73,7 @@ class ReadRequestCacheMEM { ~ReadRequestCacheMEM() { START_LOG(capio_syscall(SYS_gettid), "call()"); - capio_delete_vec(&_cache); + delete[] _cache; } void flush() { diff --git a/src/posix/utils/clone.hpp b/src/posix/utils/clone.hpp index d137c9cda..a84f5c66c 100644 --- a/src/posix/utils/clone.hpp +++ b/src/posix/utils/clone.hpp @@ -13,19 +13,19 @@ inline std::condition_variable clone_cv; inline std::unordered_set *tids; inline bool is_capio_tid(const pid_t tid) { - lockguard_guard(const std::lock_guard lg(clone_mutex)); + const std::lock_guard lg(clone_mutex); return tids->find(tid) != tids->end(); } inline void register_capio_tid(const pid_t tid) { START_LOG(syscall_no_intercept(SYS_gettid), "call(tid=%ld)", tid); - lockguard_guard(const std::lock_guard lg(clone_mutex)); + const std::lock_guard lg(clone_mutex); tids->insert(tid); } inline void remove_capio_tid(const pid_t tid) { START_LOG(syscall_no_intercept(SYS_gettid), "call(tid=%ld)", tid); - lockguard_guard(std::lock_guard lg(clone_mutex)); + std::lock_guard lg(clone_mutex); if (tids->find(tid) != tids->end()) { tids->erase(tid); } diff --git a/src/posix/utils/filesystem.hpp b/src/posix/utils/filesystem.hpp index 1dbe26da1..c64d8c4e6 100644 --- a/src/posix/utils/filesystem.hpp +++ b/src/posix/utils/filesystem.hpp @@ -156,9 +156,9 @@ inline void delete_capio_path(const std::string &path) { */ inline void destroy_filesystem() { current_dir.reset(); - capio_delete(&capio_files_descriptors); - capio_delete(&capio_files_paths); - capio_delete(&files); + delete capio_files_descriptors; + delete capio_files_paths; + delete files; } /** diff --git a/src/posix/utils/requests.hpp b/src/posix/utils/requests.hpp index 0e6e49aec..4390c7651 100644 --- a/src/posix/utils/requests.hpp +++ b/src/posix/utils/requests.hpp @@ -41,16 +41,17 @@ inline void init_client() { inline void handshake_request(const long tid, const long pid, const std::string &app_name) { START_LOG(capio_syscall(SYS_gettid), "call(tid=%ld, pid=%ld, app_name=%s)", tid, pid, app_name.c_str()); - char req[CAPIO_REQ_MAX_SIZE]; - sprintf(req, "%04d %ld %ld %s", CAPIO_REQUEST_HANDSHAKE, tid, pid, app_name.c_str()); - buf_requests->write(req, CAPIO_REQ_MAX_SIZE); - LOG("Sent handshake request"); cts_queue = new SPSCQueue("queue-" + std::to_string(tid) + ".cts", get_cache_lines(), get_cache_line_size(), get_capio_workflow_name(), true); stc_queue = new SPSCQueue("queue-" + std::to_string(tid) + ".stc", get_cache_lines(), get_cache_line_size(), get_capio_workflow_name(), true); LOG("Initialized data transfer queues"); + + char req[CAPIO_REQ_MAX_SIZE]; + sprintf(req, "%04d %ld %ld %s", CAPIO_REQUEST_HANDSHAKE, tid, pid, app_name.c_str()); + buf_requests->write(req, CAPIO_REQ_MAX_SIZE); + LOG("Sent handshake request"); } inline std::vector *file_in_memory_request(const long pid) { @@ -69,7 +70,7 @@ inline std::vector *file_in_memory_request(const long pid) { stc_queue->read(file, PATH_MAX); LOG("Obtained path %s", file); regex_vector->emplace_back(generateCapioRegex(file)); - capio_delete_vec(&file); + delete[] file; } return regex_vector; } diff --git a/src/server/capio-cl-engine/capio_cl_engine.hpp b/src/server/capio-cl-engine/capio_cl_engine.hpp index caceabba1..6d77511b9 100644 --- a/src/server/capio-cl-engine/capio_cl_engine.hpp +++ b/src/server/capio-cl-engine/capio_cl_engine.hpp @@ -10,6 +10,8 @@ * */ class CapioCLEngine { + friend class CapioFileManager; + private: std::unordered_map, // Vector for producers [0] @@ -438,12 +440,8 @@ class CapioCLEngine { return files; } - std::vector getPathsInConfig() { - std::vector paths; - std::transform(_locations.begin(), _locations.end(), std::back_inserter(paths), - [](auto pair) { return pair.first; }); - return paths; - } + protected: + const auto *getLocations() const { return &_locations; } }; inline CapioCLEngine *capio_cl_engine; diff --git a/src/server/capio_server.cpp b/src/server/capio_server.cpp index 78dbc6db2..af05d4e9a 100644 --- a/src/server/capio_server.cpp +++ b/src/server/capio_server.cpp @@ -25,11 +25,10 @@ * to all classes and subclasses. */ std::string workflow_name; +pid_t CAPIO_SERVER_MAIN_PID; inline bool StoreOnlyInMemory = false; char node_name[HOST_NAME_MAX]; -#include - #include "utils/types.hpp" #include "capio/env.hpp" @@ -85,13 +84,15 @@ std::string parseCLI(int argc, char **argv) { std::cout << CAPIO_SERVER_ARG_PARSER_PRE_COMMAND << parser; exit(EXIT_SUCCESS); } catch (args::ParseError &e) { + START_LOG(gettid(), "call()"); std::cerr << e.what() << std::endl; std::cerr << parser; - exit(EXIT_FAILURE); + ERR_EXIT("%s", e.what()); } catch (args::ValidationError &e) { + START_LOG(gettid(), "call()"); std::cerr << e.what() << std::endl; std::cerr << parser; - exit(EXIT_FAILURE); + ERR_EXIT("%s", e.what()); } if (continueOnErrorFlag) { @@ -158,13 +159,11 @@ std::string parseCLI(int argc, char **argv) { << workflow_name.data() << std::endl; } else { + START_LOG(gettid(), "call()"); std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_ERROR << " [ " << node_name << " ] " << "Error: no config file provided. To skip config file use --no-config option!" << std::endl; -#ifdef CAPIO_LOG - log->log("no config file provided, and --no-config not provided"); -#endif - exit(EXIT_FAILURE); + ERR_EXIT("no config file provided, and --no-config not provided"); } std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_INFO << " [ " << node_name << " ] " @@ -176,7 +175,7 @@ std::string parseCLI(int argc, char **argv) { << "LOG_LEVEL set to: " << CAPIO_LOG_LEVEL << std::endl; std::cout << CAPIO_LOG_SERVER_CLI_LOGGING_ENABLED_WARNING; log->log("LOG_LEVEL set to: %d", CAPIO_LOG_LEVEL); - capio_delete(&log); + delete log; #else if (std::getenv("CAPIO_LOG_LEVEL") != nullptr) { std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_WARNING << " [ " << node_name << " ] " @@ -213,10 +212,11 @@ std::string parseCLI(int argc, char **argv) { << "Selected backend is File System" << std::endl; capio_backend = new NoBackend(); } else { + START_LOG(gettid(), "call()"); std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_ERROR << " [ " << node_name << " ] " << "Provided communication backend " << backend_name << " is invalid" << std::endl; - exit(EXIT_FAILURE); + ERR_EXIT("No valid backend was provided"); } } else { std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_INFO << " [ " << node_name << " ] " @@ -234,6 +234,9 @@ int main(int argc, char **argv) { std::cout << CAPIO_LOG_SERVER_BANNER; gethostname(node_name, HOST_NAME_MAX); + CAPIO_SERVER_MAIN_PID = gettid(); + std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_INFO << " [ " << node_name << " ] " + << "Started server with PID: " << CAPIO_SERVER_MAIN_PID << std::endl; const std::string config_path = parseCLI(argc, argv); START_LOG(gettid(), "call()"); diff --git a/src/server/client-manager/client_manager.hpp b/src/server/client-manager/client_manager.hpp index d39490533..ac42d37bf 100644 --- a/src/server/client-manager/client_manager.hpp +++ b/src/server/client-manager/client_manager.hpp @@ -26,9 +26,9 @@ class ClientManager { ~ClientManager() { START_LOG(gettid(), "call()"); - capio_delete(&bufs_response); - capio_delete(&app_names); - capio_delete(&files_created_by_producer); + delete bufs_response; + delete app_names; + delete files_created_by_producer; std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_WARNING << " [ " << node_name << " ] " << "buf_response cleanup completed" << std::endl; } @@ -57,7 +57,7 @@ class ClientManager { inline void remove_client(pid_t tid) const { START_LOG(gettid(), "call(tid=%ld)", tid); if (const auto it_resp = bufs_response->find(tid); it_resp != bufs_response->end()) { - capio_delete(&it_resp->second); + delete it_resp->second; bufs_response->erase(it_resp); } files_created_by_producer->erase(tid); diff --git a/src/server/client-manager/request_handler_engine.hpp b/src/server/client-manager/request_handler_engine.hpp index 6aaaf1da6..3fa5d5472 100644 --- a/src/server/client-manager/request_handler_engine.hpp +++ b/src/server/client-manager/request_handler_engine.hpp @@ -93,7 +93,7 @@ class RequestHandlerEngine { ~RequestHandlerEngine() { START_LOG(gettid(), "call()"); - capio_delete(&buf_requests); + delete buf_requests; std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_WARNING << " [ " << node_name << " ] " << "buf_requests cleanup completed" << std::endl; @@ -113,7 +113,30 @@ class RequestHandlerEngine { while (true) { LOG(CAPIO_LOG_SERVER_REQUEST_START); int code = read_next_request(str.get()); - request_handlers[code](str.get()); + try { + request_handlers[code](str.get()); + } catch (const std::exception &exception) { + std::cout << std::endl + << "~~~~~~~~~~~~~~[\033[31mRequestHandlerEngine::start(): FATAL " + "EXCEPTION\033[0m]~~~~~~~~~~~~~~" + << std::endl + << "| Exception thrown while handling request number: " << code << " : " + << str.get() << std::endl + << "| TID of offending thread: " << gettid() << std::endl + << "| PID of offending thread: " << getpid() << std::endl + << "| PPID of offending thread: " << getppid() << std::endl + << "| " << std::endl + << "| `" << typeid(exception).name() << ": " << exception.what() + << std::endl + << "|" << std::endl + << "~~~~~~~~~~~~~~[\033[31mRequestHandlerEngine::start(): FATAL " + "EXCEPTION\033[0m]~~~~~~~~~~~~~~" + << std::endl + << std::endl; + + ERR_EXIT("%s", exception.what()); + } + LOG(CAPIO_LOG_SERVER_REQUEST_END); } } diff --git a/src/server/communication-service/MTCL_backend.hpp b/src/server/communication-service/MTCL_backend.hpp index 223309252..b17ab2224 100644 --- a/src/server/communication-service/MTCL_backend.hpp +++ b/src/server/communication-service/MTCL_backend.hpp @@ -25,7 +25,7 @@ class TransportUnit { public: TransportUnit() = default; - ~TransportUnit() { capio_delete_vec(&_bytes); } + ~TransportUnit() { delete[] _bytes; } friend class MTCL_backend; }; @@ -76,7 +76,7 @@ class MTCL_backend : public BackendInterface { HandlerPointer->send(&unit->_start_write_offset, sizeof(capio_off64_t)); LOG("[send] Sent %ld bytes of file %s with offset of %ld", unit->_buffer_size, unit->_filepath.c_str(), unit->_start_write_offset); - capio_delete(&unit); + delete unit; } /** @@ -106,7 +106,7 @@ class MTCL_backend : public BackendInterface { send_unit(&HandlerPointer, unit); LOG("[send] Message sent"); - lockguard_guard(const std::lock_guard lg(*mutex)); + const std::lock_guard lg(*mutex); LOG("[send] Locked guard"); out->pop(); } @@ -118,7 +118,7 @@ class MTCL_backend : public BackendInterface { LOG("[recv] Receiving data"); auto unit = receive_unit(&HandlerPointer); LOG("[recv] Lock guard"); - lockguard_guard(const std::lock_guard lg(*mutex)); + const std::lock_guard lg(*mutex); in->push(unit); LOG("[recv] Pushed %ld bytes to be stored on file %s", unit->_buffer_size, unit->_filepath.c_str()); @@ -130,7 +130,7 @@ class MTCL_backend : public BackendInterface { // terminate phase if (*terminate) { - lockguard_guard(const std::lock_guard lg(*mutex)); + const std::lock_guard lg(*mutex); LOG("[TERM PHASE] Locked access send and receive queues"); while (!out->empty()) { const auto unit = out->front(); @@ -168,7 +168,7 @@ class MTCL_backend : public BackendInterface { LOG("Received connection hostname: %s", connected_hostname); - lockguard_guard(const std::lock_guard lock(*guard)); + const std::lock_guard lock(*guard); open_connections->insert( {connected_hostname, @@ -259,7 +259,7 @@ class MTCL_backend : public BackendInterface { << "Connected to " << remoteToken << std::endl; LOG("Connected to: %s", remoteToken.c_str()); UserManager.send(ownHostname, HOST_NAME_MAX); - lockguard_guard(const std::lock_guard lg(*_guard)); + const std::lock_guard lg(*_guard); auto connection_tuple = std::make_tuple(new std::queue(), @@ -298,9 +298,9 @@ class MTCL_backend : public BackendInterface { pthread_cancel(th->native_handle()); th->join(); - capio_delete(&th); - capio_delete(&continue_execution); - capio_delete(&terminate); + delete th; + delete continue_execution; + delete terminate; LOG("Handler closed."); @@ -330,7 +330,7 @@ class MTCL_backend : public BackendInterface { } } LOG("Found incoming message"); - lockguard_guard(const std::lock_guard lg(*std::get<2>(interface))); + const std::lock_guard lg(*std::get<2>(interface)); auto inputUnit = inQueue->front(); *buf_size = inputUnit->_buffer_size; *start_offset = inputUnit->_start_write_offset; @@ -340,7 +340,7 @@ class MTCL_backend : public BackendInterface { std::string filename(inputUnit->_filepath); - capio_delete(&inputUnit); + delete inputUnit; return filename; } @@ -364,7 +364,7 @@ class MTCL_backend : public BackendInterface { memcpy(outputUnit->_bytes, buf, buf_size); LOG("Copied buffer: %s", outputUnit->_bytes); - lockguard_guard(const std::lock_guard lg(*std::get<2>(interface))); + const std::lock_guard lg(*std::get<2>(interface)); LOG("Pushing Transport unit to out queue"); out->push(outputUnit); } else { diff --git a/src/server/file-manager/file_manager_impl.hpp b/src/server/file-manager/file_manager_impl.hpp index dd918fea2..977a414ad 100644 --- a/src/server/file-manager/file_manager_impl.hpp +++ b/src/server/file-manager/file_manager_impl.hpp @@ -53,7 +53,7 @@ inline uintmax_t CapioFileManager::get_file_size_if_exists(const std::filesystem */ inline void CapioFileManager::addThreadAwaitingCreation(const std::string &path, pid_t tid) { START_LOG(gettid(), "call(path=%s, tid=%ld)", path.c_str(), tid); - lockguard_guard(const std::lock_guard lg(creation_mutex)); + const std::lock_guard lg(creation_mutex); thread_awaiting_file_creation[path].push_back(tid); } @@ -92,7 +92,7 @@ inline void CapioFileManager::addThreadAwaitingData(const std::string &path, int return; } - lockguard_guard(const std::lock_guard lg(data_mutex)); + const std::lock_guard lg(data_mutex); thread_awaiting_data[path].emplace(tid, expected_size); } @@ -189,7 +189,7 @@ inline void CapioFileManager::increaseCloseCount(const std::filesystem::path &pa LOG("Updated close count to %llu", close_count); - capio_delete(&lock); + delete lock; } /** @@ -342,7 +342,7 @@ inline bool CapioFileManager::isCommitted(const std::filesystem::path &path) { */ inline void CapioFileManager::checkFilesAwaitingCreation() { // NOTE: do not put inside here log code as it will generate a lot of useless log - lockguard_guard(const std::lock_guard lg(creation_mutex)); + const std::lock_guard lg(creation_mutex); std::vector path_to_delete; for (auto element : thread_awaiting_file_creation) { @@ -367,7 +367,7 @@ inline void CapioFileManager::checkFilesAwaitingCreation() { */ inline void CapioFileManager::checkFileAwaitingData() { // NOTE: do not put inside here log code as it will generate a lot of useless log - lockguard_guard(const std::lock_guard lg(data_mutex)); + const std::lock_guard lg(data_mutex); for (auto iter = thread_awaiting_data.begin(); iter != thread_awaiting_data.end();) { START_LOG(gettid(), "\n\ncall()"); // no need to check if file exists as this method is called only by read_handler @@ -392,14 +392,24 @@ inline void CapioFileManager::checkFileAwaitingData() { * @brief commit directories that have NFILES inside them if their commit rule is n_files */ inline void CapioFileManager::checkDirectoriesNFiles() const { + /* + * WARN: this function directly access the _location internal structure in read only mode to + * avoid race conditions. Since we do not update locations, get the pointer only at the + * beginning and then use it. + */ + static const auto loc = capio_cl_engine->getLocations(); + + for (const auto &[path_config, config] : *loc) { - for (const auto &path_config : capio_cl_engine->getPathsInConfig()) { - if (capio_cl_engine->isFile(path_config)) { + if (std::get<6>(config)) { + /* + * In this case we are trying to check for a file. + * skip this check and go to the next path. + */ continue; } - auto n_files = capio_cl_engine->getDirectoryFileCount(path_config); - if (n_files > 0) { + if (auto n_files = std::get<8>(config); n_files > 0) { START_LOG(gettid(), "call()"); LOG("Directory %s needs %ld files before being committed", path_config.c_str(), n_files); diff --git a/src/server/file-manager/fs_monitor.hpp b/src/server/file-manager/fs_monitor.hpp index de2ca8f2d..6908cc4a9 100644 --- a/src/server/file-manager/fs_monitor.hpp +++ b/src/server/file-manager/fs_monitor.hpp @@ -11,6 +11,27 @@ class FileSystemMonitor { bool *continue_execution = new bool; + static void print_message_error(const std::string &func, const std::exception &exception) { + START_LOG(gettid(), "call()"); + std::cout << std::endl + << "~~~~~~~~~~~~~~[\033[31mFileSystemMonitor: FATAL " + "EXCEPTION\033[0m]~~~~~~~~~~~~~~" + << std::endl + << "| Exception thrown while handling method: " << func << " : " << std::endl + << "| TID of offending thread: " << gettid() << std::endl + << "| PID of offending thread: " << getpid() << std::endl + << "| PPID of offending thread: " << getppid() << std::endl + << "| " << std::endl + << "| `" << typeid(exception).name() << ": " << exception.what() << std::endl + << "|" << std::endl + << "~~~~~~~~~~~~~~[\033[31mFileSystemMonitor: FATAL " + "EXCEPTION\033[0m]~~~~~~~~~~~~~~" + << std::endl + << std::endl; + + ERR_EXIT("%s", exception.what()); + } + public: /** * @brief Main thread execution loop. Main idea is to check @@ -29,11 +50,23 @@ class FileSystemMonitor { timespec sleep{}; sleep.tv_nsec = 300; // sleep 0.3 seconds while (*continue_execution) { + try { + file_manager->checkFilesAwaitingCreation(); + } catch (const std::exception &exception) { + print_message_error("file_manager->checkFilesAwaitingCreation()", exception); + } - file_manager->checkFilesAwaitingCreation(); - file_manager->checkFileAwaitingData(); - file_manager->checkDirectoriesNFiles(); + try { + file_manager->checkFileAwaitingData(); + } catch (const std::exception &exception) { + print_message_error("file_manager->checkFileAwaitingData()", exception); + } + try { + file_manager->checkDirectoriesNFiles(); + } catch (const std::exception &exception) { + print_message_error("file_manager->checkDirectoriesNFiles()", exception); + } nanosleep(&sleep, nullptr); } } @@ -49,9 +82,14 @@ class FileSystemMonitor { ~FileSystemMonitor() { START_LOG(gettid(), "call()"); *continue_execution = false; - th->join(); - capio_delete(&th); - capio_delete(&continue_execution); + try { + th->join(); + } catch (const std::system_error &exception) { + print_message_error("~FileSystemMonitor()::th->joing()", exception); + } + + delete th; + delete continue_execution; std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_WARNING << " [ " << node_name << " ] " << "fs_monitor cleanup completed" << std::endl; } diff --git a/src/server/storage-service/CapioFile/CapioMemoryFile.hpp b/src/server/storage-service/CapioFile/CapioMemoryFile.hpp index 3de28527f..5fd98bd8d 100644 --- a/src/server/storage-service/CapioFile/CapioMemoryFile.hpp +++ b/src/server/storage-service/CapioFile/CapioMemoryFile.hpp @@ -64,7 +64,7 @@ class CapioMemoryFile : public CapioFile { cross_page_buffer_view = new char[_pageSizeBytes]; } - ~CapioMemoryFile() override { capio_delete_vec(&cross_page_buffer_view); } + ~CapioMemoryFile() override { delete[] cross_page_buffer_view; } /** * Write data to a file stored inside the memory diff --git a/src/server/storage-service/capio_storage_service.hpp b/src/server/storage-service/capio_storage_service.hpp index ff61c5ab3..88d8f1385 100644 --- a/src/server/storage-service/capio_storage_service.hpp +++ b/src/server/storage-service/capio_storage_service.hpp @@ -43,10 +43,10 @@ class CapioStorageService { ~CapioStorageService() { // TODO: dump files to FS - capio_delete(&_stored_files); - capio_delete(&_client_to_server_queue); - capio_delete(&_server_to_client_queue); - capio_delete(&_threads_waiting_for_memory_data); + delete _stored_files; + delete _client_to_server_queue; + delete _server_to_client_queue; + delete _threads_waiting_for_memory_data; } void createFile(const std::string &file_name) const { diff --git a/src/server/utils/signals.hpp b/src/server/utils/signals.hpp index 51f08ae2a..7398c7521 100644 --- a/src/server/utils/signals.hpp +++ b/src/server/utils/signals.hpp @@ -17,6 +17,9 @@ extern "C" void __gcov_dump(void); * @param ptr */ inline void sig_term_handler(int signum, siginfo_t *info, void *ptr) { + if (gettid() != CAPIO_SERVER_MAIN_PID) { + return; + } START_LOG(gettid(), "call(signal=[%d] (%s) from process with pid=%ld)", signum, strsignal(signum), info != nullptr ? info->si_pid : -1); @@ -33,10 +36,10 @@ inline void sig_term_handler(int signum, siginfo_t *info, void *ptr) { __gcov_dump(); #endif - capio_delete(&request_handlers_engine); - capio_delete(&fs_monitor); - capio_delete(&capio_backend); - capio_delete(&shm_canary); + delete request_handlers_engine; + delete fs_monitor; + delete capio_backend; + delete shm_canary; std::cout << CAPIO_LOG_SERVER_CLI_LEVEL_INFO << " [ " << node_name << " ] " << "Bye!" << std::endl; exit(EXIT_SUCCESS); diff --git a/tests/multinode/backend/src/main.cpp b/tests/multinode/backend/src/main.cpp index 274f7800b..83d55f326 100644 --- a/tests/multinode/backend/src/main.cpp +++ b/tests/multinode/backend/src/main.cpp @@ -1,4 +1,4 @@ -#include + #include #include diff --git a/tests/multinode/integration/src/common.hpp b/tests/multinode/integration/src/common.hpp index 868a1e055..f8d2a647b 100644 --- a/tests/multinode/integration/src/common.hpp +++ b/tests/multinode/integration/src/common.hpp @@ -1,6 +1,5 @@ #ifndef COMMON_HPP #define COMMON_HPP -#include #include #include diff --git a/tests/unit/MemoryFiles/src/main.cpp b/tests/unit/MemoryFiles/src/main.cpp index 03485460f..4c51b8cff 100644 --- a/tests/unit/MemoryFiles/src/main.cpp +++ b/tests/unit/MemoryFiles/src/main.cpp @@ -1,4 +1,3 @@ -#include #include #include diff --git a/tests/unit/posix/src/realpath.cpp b/tests/unit/posix/src/realpath.cpp index 8da761fff..e338f2212 100644 --- a/tests/unit/posix/src/realpath.cpp +++ b/tests/unit/posix/src/realpath.cpp @@ -2,8 +2,6 @@ #include #include -#include - #include "utils/filesystem.hpp" class RealpathPosixTest : public testing::Test { diff --git a/tests/unit/server/src/main.cpp b/tests/unit/server/src/main.cpp index dda929955..9efd16c12 100644 --- a/tests/unit/server/src/main.cpp +++ b/tests/unit/server/src/main.cpp @@ -1,5 +1,4 @@ #include -#include #include std::string workflow_name = CAPIO_DEFAULT_WORKFLOW_NAME; diff --git a/tests/unit/syscall/src/main.cpp b/tests/unit/syscall/src/main.cpp index 9098c72ea..c3d8572e1 100644 --- a/tests/unit/syscall/src/main.cpp +++ b/tests/unit/syscall/src/main.cpp @@ -1,5 +1,3 @@ -#include - #include "capio/constants.hpp" #include