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] logicalVolumePath - path to the mapped LUKS device. 31 * 32 * @returns 0 on success, nonzero on failure. 33 */ 34 virtual int runMkfs(const std::string& logicalVolumePath) = 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 /** @brief Wrapper around fsck. 90 * @details Used for mocking purposes. 91 * 92 * @param[in] logicalVolumePath - path to device with filesystem 93 * @param[in] options - Other options to pass into fsck 94 * 95 * @returns 0 on success, nonzero on failure. 96 */ 97 virtual int runFsck(const std::string& logicalVolumePath, 98 const std::string& options) = 0; 99 }; 100 101 /** @class Filesystem 102 * @brief Implements FilesystemInterface 103 */ 104 class Filesystem : public FilesystemInterface 105 { 106 public: 107 ~Filesystem() override = default; 108 Filesystem() = default; 109 Filesystem(const Filesystem&) = delete; 110 Filesystem& operator=(const Filesystem&) = delete; 111 112 Filesystem(Filesystem&&) = delete; 113 Filesystem& operator=(Filesystem&&) = delete; 114 runMkfs(const std::string & logicalVolumePath)115 int runMkfs(const std::string& logicalVolumePath) override 116 { 117 std::string mkfsCommand("mkfs.ext4 " + logicalVolumePath); 118 // calling 'system' uses a command processor //NOLINTNEXTLINE 119 return system(mkfsCommand.c_str()); 120 } 121 doMount(const char * source,const char * target,const char * filesystemtype,unsigned long mountflags,const void * data)122 int doMount(const char* source, const char* target, 123 const char* filesystemtype, unsigned long mountflags, 124 const void* data) override 125 { 126 return mount(source, target, filesystemtype, mountflags, data); 127 } 128 doUnmount(const char * target)129 int doUnmount(const char* target) override 130 { 131 return umount(target); 132 } 133 createDirectory(const std::filesystem::path & p)134 bool createDirectory(const std::filesystem::path& p) override 135 { 136 return std::filesystem::create_directory(p); 137 } 138 removeDirectory(const std::filesystem::path & p)139 bool removeDirectory(const std::filesystem::path& p) override 140 { 141 return std::filesystem::remove(p); 142 } 143 directoryExists(const std::filesystem::path & p)144 bool directoryExists(const std::filesystem::path& p) override 145 { 146 return std::filesystem::is_directory(std::filesystem::status(p)); 147 } 148 runFsck(const std::string & logicalVolumePath,const std::string & options)149 int runFsck(const std::string& logicalVolumePath, 150 const std::string& options) override 151 { 152 std::string fsckCommand("fsck " + logicalVolumePath + " " + options); 153 // calling 'system' uses a command processor //NOLINTNEXTLINE 154 return system(fsckCommand.c_str()); 155 } 156 }; 157 } // namespace estoraged 158