refactoring: extract common file operations to StorageBackendSerialized 85/246285/3
authorAdrian Szyndela <adrian.s@samsung.com>
Tue, 27 Oct 2020 11:14:10 +0000 (12:14 +0100)
committerAdrian Szyndela <adrian.s@samsung.com>
Fri, 30 Oct 2020 11:17:02 +0000 (12:17 +0100)
Change-Id: I0a3fd26342482d747f44aae08ece46bb2b40a4fc

Makefile.am
src/internal/storage_backend_flatbuffers.cpp
src/internal/storage_backend_flatbuffers.hpp
src/internal/storage_backend_serialized.cpp [new file with mode: 0644]
src/internal/storage_backend_serialized.hpp

index 0c88727..1848ecd 100644 (file)
@@ -66,6 +66,7 @@ COMMON_SRC =\
        src/internal/serializer_flatbuffers.cpp \
        src/internal/print_content.cpp \
        src/internal/storage_backend_flatbuffers.cpp \
+       src/internal/storage_backend_serialized.cpp \
        src/internal/storage_backend_xml.cpp
 
 src_libdbuspolicy1_la_SOURCES =\
index b0c6933..4867185 100644 (file)
 #include "include/fb_generated.h"
 #include "print_content.hpp"
 #include "serialized_convert.hpp"
-#include "serializer.hpp"
 #include "storage_backend_flatbuffers.hpp"
-#include "transaction_guard.hpp"
 #include "tslog.hpp"
 #include <boost/tokenizer.hpp>
-#include <cerrno>
-#include <fcntl.h>
-#include <map>
 #include <string>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
 
 using namespace FB;
 using ldp_xml_parser::MatchItemSend;
 
 namespace ldp_serialized {
 
-// Set max size of serialized file to prevent mmap with unexpected memory size.
-// 1MB. Adjustable
-#define MAX_SFILE_SIZE (1024 * 1024)
-
 typedef boost::tokenizer<boost::char_separator<char>> tokenizer;
 
 template <typename T>
@@ -124,20 +111,10 @@ ldp_xml_parser::DecisionItem getDecisionItemMaybeNull(const T &item, const P *po
 } // anonymous namespace
 
 class StorageBackendFlatbuffers::StorageBackendFlatbuffersImpl {
-       int fd{-1};
-       uint8_t *mem{static_cast<decltype(mem)>(MAP_FAILED)};
-       size_t length{0};
        const FB::File *file{nullptr};
 
-       std::unique_ptr<ldp_serializer::Serializer> serializer;
-
-       void releaseMMap();
-       void releaseFD();
-
 public:
-       bool init(const char *filename, bool verify);
        bool initFromData(const uint8_t *mem, size_t size, bool verify);
-       bool initFromXML(const char *config_name);
        void release();
 
        ldp_xml_parser::DecisionItem getDecisionFromSendIndex(const MatchItemSend &item, const FB::PolicySend *policy);
@@ -217,79 +194,10 @@ ldp_xml_parser::DecisionItem StorageBackendFlatbuffers::StorageBackendFlatbuffer
        return ldp_xml_parser::DecisionItem(ldp_xml_parser::Decision::ANY);
 }
 
-void StorageBackendFlatbuffers::StorageBackendFlatbuffersImpl::releaseMMap() {
-       assert(MAP_FAILED != mem);
-       assert(0 != length);
-
-       if (munmap(mem, length) != 0)
-               tslog::log_error("munmap(): ", tslog::print_errno(errno), "\n");
-
-       mem = static_cast<decltype(mem)>(MAP_FAILED);
-       length = 0;
-}
-
-void StorageBackendFlatbuffers::StorageBackendFlatbuffersImpl::releaseFD() {
-       assert(-1 != fd);
-
-       if (close(fd) != 0)
-               tslog::log_error("close(): ", tslog::print_errno(errno), "\n");
-
-       fd = -1;
-}
-
 void StorageBackendFlatbuffers::StorageBackendFlatbuffersImpl::release() {
-       if (-1 != fd) {         // we need to check it, because we may have initialized the storage directly from File *
-               releaseMMap();
-               releaseFD();
-       }
-
-       if (nullptr != serializer.get()) {
-               serializer.reset(nullptr);
-       }
-
        file = nullptr;
 }
 
-bool StorageBackendFlatbuffers::StorageBackendFlatbuffersImpl::init(const char *filename, bool verify) {
-       assert(nullptr == file);
-
-       auto err = [filename] (const char *what) {
-               tslog::log_error("Can't ", what, " ", filename, ": ", tslog::print_errno(errno), "\n");
-               return false;
-       };
-
-       fd = open(filename, O_RDONLY);
-       if (-1 == fd)
-               return err("open");
-
-       auto openGuard = transaction_guard::makeGuard([&] () { releaseFD(); });
-
-       struct stat buf;
-
-       if (fstat(fd, &buf) == -1)
-               return err("stat");
-
-       length = buf.st_size;
-       if (length > MAX_SFILE_SIZE) {
-               tslog::log_error("Serialized file size(", length, ") is too large. (>", MAX_SFILE_SIZE, ") bytes.\n");
-               return false;
-       }
-
-       mem = reinterpret_cast<uint8_t*>(mmap(NULL, length, PROT_READ, MAP_PRIVATE, fd, 0));
-       if (MAP_FAILED == mem)
-               return err("mmap");
-
-       auto mmapGuard = transaction_guard::makeGuard([&] () { releaseMMap(); });
-
-       if (!initFromData(mem, length, verify))
-               return false;
-
-       openGuard.dismiss();
-       mmapGuard.dismiss();
-
-       return true;
-}
-
 bool StorageBackendFlatbuffers::StorageBackendFlatbuffersImpl::initFromData(const uint8_t *mem, size_t size, bool verify) {
        assert(nullptr == file);
 
@@ -314,20 +222,6 @@ bool StorageBackendFlatbuffers::StorageBackendFlatbuffersImpl::initFromData(cons
        return file != nullptr;
 }
 
-bool StorageBackendFlatbuffers::StorageBackendFlatbuffersImpl::initFromXML(const char *config_name) {
-       assert(nullptr == file);
-       assert(nullptr == serializer.get());
-
-       serializer.reset(new ldp_serializer::Serializer());
-
-       size_t serialized_size;
-       auto data = serializer->serialize(config_name, serialized_size);
-       if (nullptr == data)
-               return false;
-
-       return initFromData(data, serialized_size, false);
-}
-
 void StorageBackendFlatbuffers::StorageBackendFlatbuffersImpl::printContent(const bool xml_format) const {
        print_content::use_xml_format(xml_format);
        std::cerr << *file;
@@ -353,18 +247,10 @@ TYPE_HELPER(Send, send)
 TYPE_HELPER(Receive, receive)
 TYPE_HELPER(Access, access)
 
-bool StorageBackendFlatbuffers::init(const char *filename, bool verify) {
-       return pimpl->init(filename, verify);
-}
-
 bool StorageBackendFlatbuffers::initFromData(const uint8_t *serialized_data, size_t length, bool verify) {
        return pimpl->initFromData(serialized_data, length, verify);
 }
 
-bool StorageBackendFlatbuffers::initFromXML(const char *config_name) {
-       return pimpl->initFromXML(config_name);
-}
-
 void StorageBackendFlatbuffers::release() {
        pimpl->release();
 }
index aaba006..6bdd707 100644 (file)
@@ -28,9 +28,7 @@ public:
        StorageBackendFlatbuffers();
        ~StorageBackendFlatbuffers();
 
-       bool init(const char *filename, bool verify = false);
-       bool initFromData(const uint8_t *serialized_data, size_t length, bool verify = false);
-       bool initFromXML(const char *config_name);
+       bool initFromData(const uint8_t *serialized_data, size_t length, bool verify);
        void release();
 
        void printContent(const bool xml_format = false) const;
diff --git a/src/internal/storage_backend_serialized.cpp b/src/internal/storage_backend_serialized.cpp
new file mode 100644 (file)
index 0000000..f9fb54f
--- /dev/null
@@ -0,0 +1,136 @@
+/*  MIT License
+ *
+ * Copyright (c) 2019-2020 Samsung Electronics Co., Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE. */
+
+#include "storage_backend_serialized.hpp"
+#include "transaction_guard.hpp"
+#include "tslog.hpp"
+#include <cassert>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+using namespace ldp_serialized;
+
+const size_t StorageBackendSerialized::MAX_SFILE_SIZE;
+
+StorageBackendSerialized::StorageBackendSerialized()
+: __mem{static_cast<decltype(__mem)>(MAP_FAILED)}
+{
+}
+
+StorageBackendSerialized::~StorageBackendSerialized() {
+       if (-1 != __fd) {
+               releaseMMap();
+               releaseFD();
+       }
+}
+
+bool StorageBackendSerialized::init(const char *filename, bool verify)
+{
+       auto err = [filename] (const char *what) {
+               tslog::log_error("Can't ", what, " ", filename, ": ", tslog::print_errno(errno), "\n");
+               return false;
+       };
+
+       __fd = open(filename, O_RDONLY);
+       if (-1 == __fd)
+               return err("open");
+
+       auto openGuard = transaction_guard::makeGuard([&] () { releaseFD(); });
+
+       struct stat buf;
+
+       if (fstat(__fd, &buf) == -1)
+               return err("stat");
+
+       __length = buf.st_size;
+       if (__length > MAX_SFILE_SIZE) {
+               tslog::log_error("Serialized file size(", __length, ") is too large. (>", MAX_SFILE_SIZE, ") bytes.\n");
+               return false;
+       }
+
+       __mem = reinterpret_cast<uint8_t*>(mmap(NULL, __length, PROT_READ, MAP_PRIVATE, __fd, 0));
+       if (MAP_FAILED == __mem)
+               return err("mmap");
+
+       auto mmapGuard = transaction_guard::makeGuard([&] () { releaseMMap(); });
+
+       if (!initFromData(__mem, __length, verify))
+               return false;
+
+       openGuard.dismiss();
+       mmapGuard.dismiss();
+
+       return true;
+}
+
+bool StorageBackendSerialized::initFromData(const uint8_t *serialized_data, size_t length, bool verify)
+{
+       return impl.initFromData(serialized_data, length, verify);
+}
+
+void StorageBackendSerialized::releaseMMap() {
+       assert(MAP_FAILED != __mem);
+       assert(0 != __length);
+
+       if (munmap(__mem, __length) != 0)
+               tslog::log_error("munmap(): ", tslog::print_errno(errno), "\n");
+
+       __mem = static_cast<decltype(__mem)>(MAP_FAILED);
+       __length = 0;
+}
+
+bool StorageBackendSerialized::initFromXML(const char *config_name) {
+       assert(nullptr == serializer.get());
+
+       serializer.reset(new ldp_serializer::Serializer());
+
+       size_t serialized_size;
+       auto data = serializer->serialize(config_name, serialized_size);
+       if (nullptr == data)
+               return false;
+
+       return initFromData(data, serialized_size, false);
+}
+
+void StorageBackendSerialized::releaseFD() {
+       assert(-1 != __fd);
+
+       if (close(__fd) != 0)
+               tslog::log_error("close(): ", tslog::print_errno(errno), "\n");
+
+       __fd = -1;
+}
+
+void StorageBackendSerialized::release() {
+       if (-1 != __fd) {
+               releaseMMap();
+               releaseFD();
+       }
+
+       if (nullptr != serializer.get())
+               serializer.reset(nullptr);
+
+       impl.release();
+}
index c3406ac..dc3a861 100644 (file)
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE. */
 
+#include "policy.hpp"
 #include "storage_backend_flatbuffers.hpp"
+#include "serializer.hpp"
+#include <memory>
+#include <sys/types.h>
 
 namespace ldp_serialized {
-using StorageBackendSerialized = StorageBackendFlatbuffers;
+
+class StorageBackendSerialized
+{
+public:
+       StorageBackendSerialized();
+       ~StorageBackendSerialized();
+
+       bool init(const char *filename, bool verify = false);
+       bool initFromData(const uint8_t *serialized_data, size_t length, bool verify = false);
+       bool initFromXML(const char *config_name);
+       void release();
+
+       void printContent(bool xml_format = false) const
+       { impl.printContent(xml_format); }
+
+       // Supported template parameters are:
+       // MatchItemOwn, MatchItemSend, MatchItemReceive
+       // and - only for Contexts - MatchItemAccess
+       template <typename MatchItem>
+       ldp_xml_parser::DecisionItem getDecisionItemContextMandatory(const MatchItem &item) const
+       { return impl.getDecisionItemContextMandatory(item); }
+       template <typename MatchItem>
+       ldp_xml_parser::DecisionItem getDecisionItemContextDefault(const MatchItem &item) const
+       { return impl.getDecisionItemContextDefault(item); }
+       template <typename MatchItem>
+       ldp_xml_parser::DecisionItem getDecisionItemUser(uid_t uid, const MatchItem &item) const
+       { return impl.getDecisionItemUser(uid, item); }
+       template <typename MatchItem>
+       ldp_xml_parser::DecisionItem getDecisionItemGroup(gid_t gid, const MatchItem &item) const
+       { return impl.getDecisionItemGroup(gid, item); }
+
+       // This works with MatchItem set to MatchItemOwn, MatchItemSend or MatchItemReceive
+       // This is needed for filtering mapGroups. Check NaivePolicyChecker.
+       template <typename MatchItem>
+       bool existsPolicyForGroup(gid_t gid) const
+       { return impl.existsPolicyForGroup<MatchItem>(gid); }
+
+private:
+       typedef StorageBackendFlatbuffers Backend;
+       Backend impl;
+
+       // Set max size of serialized file to prevent mmap with unexpected memory size.
+       // 1MB. Adjustable
+       static const size_t MAX_SFILE_SIZE{1024 * 1024};
+
+       int __fd{-1};
+       uint8_t *__mem;
+       size_t __length{0};
+
+       std::unique_ptr<ldp_serializer::Serializer> serializer;
+
+       void releaseMMap();
+       void releaseFD();
+};
+
 }