Loading include/daemon/backend/data/chunk_storage.hpp +0 −1 Original line number Diff line number Diff line Loading @@ -43,7 +43,6 @@ public: class ChunkStorage { private: static constexpr const char* LOGGER_NAME = "ChunkStorage"; std::shared_ptr<spdlog::logger> log_; Loading include/daemon/backend/data/data_module.hpp 0 → 100644 +53 −0 Original line number Diff line number Diff line /* Copyright 2018-2020, Barcelona Supercomputing Center (BSC), Spain Copyright 2015-2020, Johannes Gutenberg Universitaet Mainz, Germany This software was partially supported by the EC H2020 funded project NEXTGenIO (Project ID: 671951, www.nextgenio.eu). This software was partially supported by the ADA-FS project under the SPPEXA project funded by the DFG. SPDX-License-Identifier: MIT */ #ifndef GEKKOFS_DAEMON_DATA_LOGGING_HPP #define GEKKOFS_DAEMON_DATA_LOGGING_HPP #include <spdlog/spdlog.h> namespace gkfs { namespace data { class DataModule { private: DataModule() {} std::shared_ptr<spdlog::logger> log_; public: static constexpr const char* LOGGER_NAME = "DataModule"; static DataModule* getInstance() { static DataModule instance; return &instance; } DataModule(DataModule const&) = delete; void operator=(DataModule const&) = delete; const std::shared_ptr<spdlog::logger>& log() const; void log(const std::shared_ptr<spdlog::logger>& log); }; #define GKFS_DATA_MOD (static_cast<gkfs::data::DataModule*>(gkfs::data::DataModule::getInstance())) } // namespace data } // namespace gkfs #endif //GEKKOFS_DAEMON_DATA_LOGGING_HPP include/daemon/backend/data/file_handle.hpp 0 → 100644 +99 −0 Original line number Diff line number Diff line /* Copyright 2018-2020, Barcelona Supercomputing Center (BSC), Spain Copyright 2015-2020, Johannes Gutenberg Universitaet Mainz, Germany This software was partially supported by the EC H2020 funded project NEXTGenIO (Project ID: 671951, www.nextgenio.eu). This software was partially supported by the ADA-FS project under the SPPEXA project funded by the DFG. SPDX-License-Identifier: MIT */ #ifndef GEKKOFS_DAEMON_FILE_HANDLE_HPP #define GEKKOFS_DAEMON_FILE_HANDLE_HPP #include <daemon/backend/data/data_module.hpp> extern "C" { #include <unistd.h> } namespace gkfs { namespace data { /** * File handle to encapsulate a file descriptor, allowing RAII closing of the file descriptor */ class FileHandle { private: constexpr static const int init_value{-1}; int fd_{init_value}; std::string path_{}; public: FileHandle() = default; explicit FileHandle(int fd, std::string path) noexcept : fd_(fd) {} FileHandle(FileHandle&& rhs) = default; FileHandle(const FileHandle& other) = delete; FileHandle& operator=(FileHandle&& rhs) = default; FileHandle& operator=(const FileHandle& other) = delete; explicit operator bool() const noexcept { return valid(); } bool operator!() const noexcept { return !valid(); } bool valid() const noexcept { return fd_ != init_value; } int native() const noexcept { return fd_; } /** * Closes file descriptor and resets it to initial value * @return */ bool close() noexcept { if (fd_ != init_value) { if (::close(fd_) < 0) { GKFS_DATA_MOD->log()->warn("{}() Failed to close file descriptor '{}' path '{}' errno '{}'", __func__, fd_, path_, ::strerror(errno)); return false; } } fd_ = init_value; return true; } ~FileHandle() { if (fd_ != init_value) close(); } }; } // namespace data } // namespace gkfs #endif //GEKKOFS_DAEMON_FILE_HANDLE_HPP src/daemon/backend/data/CMakeLists.txt +3 −0 Original line number Diff line number Diff line Loading @@ -6,7 +6,10 @@ target_sources(storage PRIVATE ${INCLUDE_DIR}/global/path_util.hpp ${INCLUDE_DIR}/global/global_defs.hpp ${INCLUDE_DIR}/daemon/backend/data/data_module.hpp ${INCLUDE_DIR}/daemon/backend/data/file_handle.hpp ${CMAKE_CURRENT_LIST_DIR}/chunk_storage.cpp ${CMAKE_CURRENT_LIST_DIR}/data_module.cpp ) target_link_libraries(storage Loading src/daemon/backend/data/chunk_storage.cpp +22 −27 Original line number Diff line number Diff line Loading @@ -11,11 +11,12 @@ SPDX-License-Identifier: MIT */ #include <daemon/backend/data/data_module.hpp> #include <daemon/backend/data/chunk_storage.hpp> #include <daemon/backend/data/file_handle.hpp> #include <global/path_util.hpp> #include <cerrno> #include <utility> #include <boost/filesystem.hpp> #include <spdlog/spdlog.h> Loading Loading @@ -75,8 +76,10 @@ void ChunkStorage::init_chunk_space(const string& file_path) const { ChunkStorage::ChunkStorage(string& path, const size_t chunksize) : root_path_(path), chunksize_(chunksize) { /* Initialize logger */ log_ = spdlog::get(LOGGER_NAME); /* Get logger instance and set it for data module and chunk storage */ GKFS_DATA_MOD->log(spdlog::get(GKFS_DATA_MOD->LOGGER_NAME)); assert(GKFS_DATA_MOD->log()); log_ = spdlog::get(GKFS_DATA_MOD->LOGGER_NAME); assert(log_); assert(gkfs::path::is_absolute(root_path_)); // Verify that we have sufficient access for chunk directories Loading Loading @@ -129,25 +132,21 @@ ChunkStorage::write_chunk(const string& file_path, gkfs::rpc::chnk_id_t chunk_id init_chunk_space(file_path); auto chunk_path = absolute(get_chunk_path(file_path, chunk_id)); int fd = open(chunk_path.c_str(), O_WRONLY | O_CREAT, 0640); if (fd < 0) { auto err_str = fmt::format("Failed to open chunk file for write. File: '{}', Error: '{}'", chunk_path, ::strerror(errno)); FileHandle fh(open(chunk_path.c_str(), O_WRONLY | O_CREAT, 0640), chunk_path); if (!fh.valid()) { auto err_str = fmt::format("{}() Failed to open chunk file for write. File: '{}', Error: '{}'", __func__, chunk_path, ::strerror(errno)); throw ChunkStorageException(errno, err_str); } auto wrote = pwrite(fd, buff, size, offset); auto wrote = pwrite(fh.native(), buff, size, offset); if (wrote < 0) { auto err_str = fmt::format("Failed to write chunk file. File: '{}', size: '{}', offset: '{}', Error: '{}'", chunk_path, size, offset, ::strerror(errno)); auto err_str = fmt::format("{}() Failed to write chunk file. File: '{}', size: '{}', offset: '{}', Error: '{}'", __func__, chunk_path, size, offset, ::strerror(errno)); throw ChunkStorageException(errno, err_str); } // if close fails we just write an entry into the log erroring out if (close(fd) < 0) { log_->warn("Failed to close chunk file after write. File: '{}', Error: '{}'", chunk_path, ::strerror(errno)); } // file is closed via the file handle's destructor. return wrote; } Loading @@ -169,17 +168,18 @@ ChunkStorage::read_chunk(const string& file_path, gkfs::rpc::chnk_id_t chunk_id, off64_t offset) const { assert((offset + size) <= chunksize_); auto chunk_path = absolute(get_chunk_path(file_path, chunk_id)); int fd = open(chunk_path.c_str(), O_RDONLY); if (fd < 0) { auto err_str = fmt::format("Failed to open chunk file for read. File: '{}', Error: '{}'", chunk_path, ::strerror(errno)); FileHandle fh(open(chunk_path.c_str(), O_RDONLY), chunk_path); if (!fh.valid()) { auto err_str = fmt::format("{}() Failed to open chunk file for read. File: '{}', Error: '{}'", __func__, chunk_path, ::strerror(errno)); throw ChunkStorageException(errno, err_str); } size_t tot_read = 0; ssize_t read = 0; do { read = pread64(fd, read = pread64(fh.native(), buf + tot_read, size - tot_read, offset + tot_read); Loading Loading @@ -209,12 +209,7 @@ ChunkStorage::read_chunk(const string& file_path, gkfs::rpc::chnk_id_t chunk_id, tot_read += read; } while (tot_read != size); // if close fails we just write an entry into the log erroring out if (close(fd) < 0) { log_->warn("Failed to close chunk file after read. File: '{}', Error: '{}'", chunk_path, ::strerror(errno)); } // file is closed via the file handle's destructor. return tot_read; } Loading Loading
include/daemon/backend/data/chunk_storage.hpp +0 −1 Original line number Diff line number Diff line Loading @@ -43,7 +43,6 @@ public: class ChunkStorage { private: static constexpr const char* LOGGER_NAME = "ChunkStorage"; std::shared_ptr<spdlog::logger> log_; Loading
include/daemon/backend/data/data_module.hpp 0 → 100644 +53 −0 Original line number Diff line number Diff line /* Copyright 2018-2020, Barcelona Supercomputing Center (BSC), Spain Copyright 2015-2020, Johannes Gutenberg Universitaet Mainz, Germany This software was partially supported by the EC H2020 funded project NEXTGenIO (Project ID: 671951, www.nextgenio.eu). This software was partially supported by the ADA-FS project under the SPPEXA project funded by the DFG. SPDX-License-Identifier: MIT */ #ifndef GEKKOFS_DAEMON_DATA_LOGGING_HPP #define GEKKOFS_DAEMON_DATA_LOGGING_HPP #include <spdlog/spdlog.h> namespace gkfs { namespace data { class DataModule { private: DataModule() {} std::shared_ptr<spdlog::logger> log_; public: static constexpr const char* LOGGER_NAME = "DataModule"; static DataModule* getInstance() { static DataModule instance; return &instance; } DataModule(DataModule const&) = delete; void operator=(DataModule const&) = delete; const std::shared_ptr<spdlog::logger>& log() const; void log(const std::shared_ptr<spdlog::logger>& log); }; #define GKFS_DATA_MOD (static_cast<gkfs::data::DataModule*>(gkfs::data::DataModule::getInstance())) } // namespace data } // namespace gkfs #endif //GEKKOFS_DAEMON_DATA_LOGGING_HPP
include/daemon/backend/data/file_handle.hpp 0 → 100644 +99 −0 Original line number Diff line number Diff line /* Copyright 2018-2020, Barcelona Supercomputing Center (BSC), Spain Copyright 2015-2020, Johannes Gutenberg Universitaet Mainz, Germany This software was partially supported by the EC H2020 funded project NEXTGenIO (Project ID: 671951, www.nextgenio.eu). This software was partially supported by the ADA-FS project under the SPPEXA project funded by the DFG. SPDX-License-Identifier: MIT */ #ifndef GEKKOFS_DAEMON_FILE_HANDLE_HPP #define GEKKOFS_DAEMON_FILE_HANDLE_HPP #include <daemon/backend/data/data_module.hpp> extern "C" { #include <unistd.h> } namespace gkfs { namespace data { /** * File handle to encapsulate a file descriptor, allowing RAII closing of the file descriptor */ class FileHandle { private: constexpr static const int init_value{-1}; int fd_{init_value}; std::string path_{}; public: FileHandle() = default; explicit FileHandle(int fd, std::string path) noexcept : fd_(fd) {} FileHandle(FileHandle&& rhs) = default; FileHandle(const FileHandle& other) = delete; FileHandle& operator=(FileHandle&& rhs) = default; FileHandle& operator=(const FileHandle& other) = delete; explicit operator bool() const noexcept { return valid(); } bool operator!() const noexcept { return !valid(); } bool valid() const noexcept { return fd_ != init_value; } int native() const noexcept { return fd_; } /** * Closes file descriptor and resets it to initial value * @return */ bool close() noexcept { if (fd_ != init_value) { if (::close(fd_) < 0) { GKFS_DATA_MOD->log()->warn("{}() Failed to close file descriptor '{}' path '{}' errno '{}'", __func__, fd_, path_, ::strerror(errno)); return false; } } fd_ = init_value; return true; } ~FileHandle() { if (fd_ != init_value) close(); } }; } // namespace data } // namespace gkfs #endif //GEKKOFS_DAEMON_FILE_HANDLE_HPP
src/daemon/backend/data/CMakeLists.txt +3 −0 Original line number Diff line number Diff line Loading @@ -6,7 +6,10 @@ target_sources(storage PRIVATE ${INCLUDE_DIR}/global/path_util.hpp ${INCLUDE_DIR}/global/global_defs.hpp ${INCLUDE_DIR}/daemon/backend/data/data_module.hpp ${INCLUDE_DIR}/daemon/backend/data/file_handle.hpp ${CMAKE_CURRENT_LIST_DIR}/chunk_storage.cpp ${CMAKE_CURRENT_LIST_DIR}/data_module.cpp ) target_link_libraries(storage Loading
src/daemon/backend/data/chunk_storage.cpp +22 −27 Original line number Diff line number Diff line Loading @@ -11,11 +11,12 @@ SPDX-License-Identifier: MIT */ #include <daemon/backend/data/data_module.hpp> #include <daemon/backend/data/chunk_storage.hpp> #include <daemon/backend/data/file_handle.hpp> #include <global/path_util.hpp> #include <cerrno> #include <utility> #include <boost/filesystem.hpp> #include <spdlog/spdlog.h> Loading Loading @@ -75,8 +76,10 @@ void ChunkStorage::init_chunk_space(const string& file_path) const { ChunkStorage::ChunkStorage(string& path, const size_t chunksize) : root_path_(path), chunksize_(chunksize) { /* Initialize logger */ log_ = spdlog::get(LOGGER_NAME); /* Get logger instance and set it for data module and chunk storage */ GKFS_DATA_MOD->log(spdlog::get(GKFS_DATA_MOD->LOGGER_NAME)); assert(GKFS_DATA_MOD->log()); log_ = spdlog::get(GKFS_DATA_MOD->LOGGER_NAME); assert(log_); assert(gkfs::path::is_absolute(root_path_)); // Verify that we have sufficient access for chunk directories Loading Loading @@ -129,25 +132,21 @@ ChunkStorage::write_chunk(const string& file_path, gkfs::rpc::chnk_id_t chunk_id init_chunk_space(file_path); auto chunk_path = absolute(get_chunk_path(file_path, chunk_id)); int fd = open(chunk_path.c_str(), O_WRONLY | O_CREAT, 0640); if (fd < 0) { auto err_str = fmt::format("Failed to open chunk file for write. File: '{}', Error: '{}'", chunk_path, ::strerror(errno)); FileHandle fh(open(chunk_path.c_str(), O_WRONLY | O_CREAT, 0640), chunk_path); if (!fh.valid()) { auto err_str = fmt::format("{}() Failed to open chunk file for write. File: '{}', Error: '{}'", __func__, chunk_path, ::strerror(errno)); throw ChunkStorageException(errno, err_str); } auto wrote = pwrite(fd, buff, size, offset); auto wrote = pwrite(fh.native(), buff, size, offset); if (wrote < 0) { auto err_str = fmt::format("Failed to write chunk file. File: '{}', size: '{}', offset: '{}', Error: '{}'", chunk_path, size, offset, ::strerror(errno)); auto err_str = fmt::format("{}() Failed to write chunk file. File: '{}', size: '{}', offset: '{}', Error: '{}'", __func__, chunk_path, size, offset, ::strerror(errno)); throw ChunkStorageException(errno, err_str); } // if close fails we just write an entry into the log erroring out if (close(fd) < 0) { log_->warn("Failed to close chunk file after write. File: '{}', Error: '{}'", chunk_path, ::strerror(errno)); } // file is closed via the file handle's destructor. return wrote; } Loading @@ -169,17 +168,18 @@ ChunkStorage::read_chunk(const string& file_path, gkfs::rpc::chnk_id_t chunk_id, off64_t offset) const { assert((offset + size) <= chunksize_); auto chunk_path = absolute(get_chunk_path(file_path, chunk_id)); int fd = open(chunk_path.c_str(), O_RDONLY); if (fd < 0) { auto err_str = fmt::format("Failed to open chunk file for read. File: '{}', Error: '{}'", chunk_path, ::strerror(errno)); FileHandle fh(open(chunk_path.c_str(), O_RDONLY), chunk_path); if (!fh.valid()) { auto err_str = fmt::format("{}() Failed to open chunk file for read. File: '{}', Error: '{}'", __func__, chunk_path, ::strerror(errno)); throw ChunkStorageException(errno, err_str); } size_t tot_read = 0; ssize_t read = 0; do { read = pread64(fd, read = pread64(fh.native(), buf + tot_read, size - tot_read, offset + tot_read); Loading Loading @@ -209,12 +209,7 @@ ChunkStorage::read_chunk(const string& file_path, gkfs::rpc::chnk_id_t chunk_id, tot_read += read; } while (tot_read != size); // if close fails we just write an entry into the log erroring out if (close(fd) < 0) { log_->warn("Failed to close chunk file after read. File: '{}', Error: '{}'", chunk_path, ::strerror(errno)); } // file is closed via the file handle's destructor. return tot_read; } Loading