1 #pragma once 2 3 #include <sys/mount.h> 4 5 #include <filesystem> 6 #include <string> 7 8 namespace estoraged 9 { 10 11 /** @class FilesystemInterface 12 * @brief Interface to the filesystem operations that eStoraged needs. 13 * @details This class is used to mock out the filesystem operations. 14 */ 15 class FilesystemInterface 16 { 17 public: 18 virtual ~FilesystemInterface() = default; 19 20 FilesystemInterface() = default; 21 FilesystemInterface(const FilesystemInterface&) = delete; 22 FilesystemInterface& operator=(const FilesystemInterface&) = delete; 23 24 FilesystemInterface(FilesystemInterface&&) = delete; 25 FilesystemInterface& operator=(FilesystemInterface&&) = delete; 26 27 /** @brief Runs the mkfs command to create the filesystem. 28 * @details Used for mocking purposes. 29 * 30 * @param[in] logicalVolume - name of the mapped LUKS device. 31 * 32 * @returns 0 on success, nonzero on failure. 33 */ 34 virtual int runMkfs(const std::string& logicalVolume) = 0; 35 36 /** @brief Wrapper around mount(). 37 * @details Used for mocking purposes. 38 * 39 * @param[in] source - device where the filesystem is located. 40 * @param[in] target - path to where the filesystem should be mounted. 41 * @param[in] filesystemType - (e.g. "ext4"). 42 * @param[in] mountflags - flags bit mask (see mount() documentation). 43 * @param[in] data - options for specific filesystem type, can be NULL 44 * (see mount() documentation). 45 * 46 * @returns On success, zero is returned. On error, -1 is returned, and 47 * errno is set to indicate the error. 48 */ 49 virtual int doMount(const char* source, const char* target, 50 const char* filesystemtype, unsigned long mountflags, 51 const void* data) = 0; 52 53 /** @brief Wrapper around umount(). 54 * @details Used for mocking purposes. 55 * 56 * @param[in] target - path location where the filesystem is mounted. 57 * 58 * @returns On success, zero is returned. On error, -1 is returned, and 59 * errno is set to indicate the error. 60 */ 61 virtual int doUnmount(const char* target) = 0; 62 63 /** @brief Wrapper around std::filesystem::create_directory. 64 * @details Used for mocking purposes. 65 * 66 * @param[in] p - path to directory that should be created. 67 * 68 * @returns true on success, false otherwise. 69 */ 70 virtual bool createDirectory(const std::filesystem::path& p) = 0; 71 72 /** @brief Wrapper around std::filesystem::remove. 73 * @details Used for mocking purposes. 74 * 75 * @param[in] p - path to directory that should be removed. 76 * 77 * @returns true on success, false otherwise. 78 */ 79 virtual bool removeDirectory(const std::filesystem::path& p) = 0; 80 81 /** @brief Wrapper around std::filesystem::is_directory 82 * 83 * @param[in] p - path to directory that we want to query. 84 * 85 * @returns true if the path exists and represents a directory. 86 */ 87 virtual bool directoryExists(const std::filesystem::path& p) = 0; 88 }; 89 90 /** @class Filesystem 91 * @brief Implements FilesystemInterface 92 */ 93 class Filesystem : public FilesystemInterface 94 { 95 public: 96 ~Filesystem() override = default; 97 Filesystem() = default; 98 Filesystem(const Filesystem&) = delete; 99 Filesystem& operator=(const Filesystem&) = delete; 100 101 Filesystem(Filesystem&&) = delete; 102 Filesystem& operator=(Filesystem&&) = delete; 103 104 int runMkfs(const std::string& logicalVolume) override 105 { 106 std::string mkfsCommand("mkfs.ext4 /dev/mapper/" + logicalVolume); 107 // calling 'system' uses a command processor //NOLINTNEXTLINE 108 return system(mkfsCommand.c_str()); 109 } 110 111 int doMount(const char* source, const char* target, 112 const char* filesystemtype, unsigned long mountflags, 113 const void* data) override 114 { 115 return mount(source, target, filesystemtype, mountflags, data); 116 } 117 118 int doUnmount(const char* target) override 119 { 120 return umount(target); 121 } 122 123 bool createDirectory(const std::filesystem::path& p) override 124 { 125 return std::filesystem::create_directory(p); 126 } 127 128 bool removeDirectory(const std::filesystem::path& p) override 129 { 130 return std::filesystem::remove(p); 131 } 132 133 bool directoryExists(const std::filesystem::path& p) override 134 { 135 return std::filesystem::is_directory(std::filesystem::status(p)); 136 } 137 }; 138 } // namespace estoraged 139