LogCabin
|
00001 /* Copyright (c) 2015 Diego Ongaro 00002 * 00003 * Permission to use, copy, modify, and distribute this software for any 00004 * purpose with or without fee is hereby granted, provided that the above 00005 * copyright notice and this permission notice appear in all copies. 00006 * 00007 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES 00008 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 00009 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR 00010 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 00011 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 00012 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 00013 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 00014 */ 00015 00016 #include <sys/types.h> 00017 #include <sys/stat.h> 00018 #include <fcntl.h> 00019 00020 #include "Core/Config.h" 00021 #include "Core/Debug.h" 00022 #include "Core/StringUtil.h" 00023 #include "Storage/Layout.h" 00024 00025 namespace LogCabin { 00026 namespace Storage { 00027 00028 namespace FS = FilesystemUtil; 00029 00030 Layout::Layout() 00031 : topDir() 00032 , serverDir() 00033 , lockFile() 00034 , logDir() 00035 , snapshotDir() 00036 , removeAllFiles(false) 00037 { 00038 } 00039 00040 Layout::Layout(Layout&& other) 00041 : topDir(std::move(other.topDir)) 00042 , serverDir(std::move(other.serverDir)) 00043 , lockFile(std::move(other.lockFile)) 00044 , logDir(std::move(other.logDir)) 00045 , snapshotDir(std::move(other.snapshotDir)) 00046 , removeAllFiles(other.removeAllFiles) 00047 { 00048 other.removeAllFiles = false; 00049 } 00050 00051 Layout::~Layout() 00052 { 00053 if (removeAllFiles) 00054 Storage::FilesystemUtil::remove(topDir.path); 00055 } 00056 00057 Layout& 00058 Layout::operator=(Layout&& other) 00059 { 00060 if (removeAllFiles) { 00061 Storage::FilesystemUtil::remove(topDir.path); 00062 removeAllFiles = false; 00063 } 00064 topDir = std::move(other.topDir); 00065 serverDir = std::move(other.serverDir); 00066 lockFile = std::move(other.lockFile); 00067 logDir = std::move(other.logDir); 00068 snapshotDir = std::move(other.snapshotDir); 00069 removeAllFiles = other.removeAllFiles; 00070 other.removeAllFiles = false; 00071 return *this; 00072 } 00073 00074 void 00075 Layout::init(const Core::Config& config, uint64_t serverId) 00076 { 00077 init(config.read<std::string>("storagePath", "storage"), 00078 serverId); 00079 } 00080 00081 void 00082 Layout::init(const std::string& storagePath, uint64_t serverId) 00083 { 00084 if (removeAllFiles) { 00085 Storage::FilesystemUtil::remove(topDir.path); 00086 removeAllFiles = false; 00087 } 00088 topDir = FS::openDir(storagePath); 00089 serverDir = FS::openDir( 00090 topDir, 00091 Core::StringUtil::format("server%lu", serverId)); 00092 // We used to lock serverDir, but that doesn't work across NFS clients, at 00093 // least on RHEL6. Locking a file within the directory does seem to work. 00094 lockFile = FS::openFile( 00095 serverDir, 00096 "lock", 00097 O_CREAT); 00098 // lock file so that Storage/Tool doesn't use serverDir while the daemon is 00099 // running 00100 std::string error = FS::tryFlock(lockFile, LOCK_EX|LOCK_NB); 00101 if (!error.empty()) { 00102 EXIT("Could not lock storage directory. Is LogCabin already running? " 00103 "Error was: %s", error.c_str()); 00104 } 00105 logDir = FS::openDir(serverDir, "log"); 00106 snapshotDir = FS::openDir(serverDir, "snapshot"); 00107 } 00108 00109 void 00110 Layout::initTemporary(uint64_t serverId) 00111 { 00112 init(Storage::FilesystemUtil::mkdtemp(), serverId); 00113 removeAllFiles = true; 00114 } 00115 00116 } // namespace LogCabin::Storage 00117 } // namespace LogCabin