LogCabin
Storage/Layout.cc
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines