diff --git a/CHANGELOG.md b/CHANGELOG.md index c329f6bbc693c96e295f5d3b17c5e3a2809d964e..891b11b8cd3edc2a8322294137b3b0e4dd7bbb82 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - Support to print newer syscall (although not implemented). Added syscall number to log for easy capture missing ones. - Unify dependency scripts (dl and compile): Unify `-d` and `-p` flags ([!174](https://storage.bsc.es/gitlab/hpc/gekkofs/-/merge_requests/174)). - Increased merge assert for files with size 0, specific for DLIO with GekkoFS in Debug ([!208])(https://storage.bsc.es/gitlab/hpc/gekkofs/-/merge_requests/208)). +- Added code to correct fork issues. `pthread_at_fork` cleans and starts GekkoFS ([!210](https://storage.bsc.es/gitlab/hpc/gekkofs/-/merge_requests/210)). ### Removed ### Fixed diff --git a/include/client/preload.hpp b/include/client/preload.hpp index afad97c684bbb5736bceef4079e67adc7b120b3c..ffc3e942d564f290a50dc3e5e5dc229cb74fe12f 100644 --- a/include/client/preload.hpp +++ b/include/client/preload.hpp @@ -49,4 +49,11 @@ void destroy_preload() __attribute__((destructor)); #endif +void +at_fork_syscall(); +void +at_child_syscall(); +void +at_parent_syscall(); + #endif // IOINTERCEPT_PRELOAD_HPP diff --git a/include/client/preload_context.hpp b/include/client/preload_context.hpp index d818ca21eb287ea89f54be42910937465b48c5d2..7ca56e1a2fef89fb5abee6a28826ca32d0beb764 100644 --- a/include/client/preload_context.hpp +++ b/include/client/preload_context.hpp @@ -153,6 +153,9 @@ public: bool init_metrics(); + void + destroy_metrics(); + void mountdir(const std::string& path); diff --git a/src/client/preload.cpp b/src/client/preload.cpp index 67926fbb329b25e7a1ffe3193e41da9cb0b05c60..ae7b03817c7778b238c7e662ba0578b71fd6bf4c 100644 --- a/src/client/preload.cpp +++ b/src/client/preload.cpp @@ -337,6 +337,9 @@ init_environment() { } // namespace gkfs::preload + +std::atomic init{false}; + /** * Called initially ONCE when preload library is used with the LD_PRELOAD * environment variable @@ -346,7 +349,10 @@ init_preload() { // The original errno value will be restored after initialization to not // leak internal error codes auto oerrno = errno; - + if(!init) { + init = true; + pthread_atfork(&at_fork_syscall, &at_parent_syscall, &at_child_syscall); + } CTX->enable_interception(); gkfs::preload::start_self_interception(); @@ -407,6 +413,7 @@ destroy_preload() { CTX->read_metrics()->flush_msgpack(); LOG(INFO, "Metrics flushed. Total flush operations: {}", CTX->write_metrics()->flush_count()); + CTX->destroy_metrics(); #endif CTX->clear_hosts(); LOG(DEBUG, "Peer information deleted"); @@ -459,3 +466,17 @@ gkfs_end() { return 0; } + +void +at_fork_syscall() { + destroy_preload(); +} +void +at_parent_syscall() { + init_preload(); +} + +void +at_child_syscall() { + init_preload(); +} diff --git a/src/client/preload_context.cpp b/src/client/preload_context.cpp index a15813b2513a66cff49f60e67f41912930865bce..438bf55a6abe22c728f60d6d762b785864712434 100644 --- a/src/client/preload_context.cpp +++ b/src/client/preload_context.cpp @@ -121,6 +121,14 @@ PreloadContext::init_logging() { ); } +void +PreloadContext::destroy_metrics() { +#ifdef GKFS_ENABLE_CLIENT_METRICS + write_metrics_.reset(); + read_metrics_.reset(); +#endif +} + bool PreloadContext::init_metrics() { #ifdef GKFS_ENABLE_CLIENT_METRICS