diff --git a/libs/middletier/CMakeLists.txt b/libs/middletier/CMakeLists.txt index 8173d6ebae276c6420138f103d19ea946e1a47ba..4fae59d9a343842c729e22f7f482b6eb4086853f 100644 --- a/libs/middletier/CMakeLists.txt +++ b/libs/middletier/CMakeLists.txt @@ -43,7 +43,8 @@ set (MIDDLE_TIER_LIB_SRC_FILES Tape.cpp TapePool.cpp UserIdentity.cpp - Utils.cpp) + Utils.cpp + Vfs.cpp) add_library (ctamiddletier SHARED ${MIDDLE_TIER_LIB_SRC_FILES}) diff --git a/libs/middletier/SqliteDatabase.hpp b/libs/middletier/SqliteDatabase.hpp index 765c55238f240577afdcc90b736e1a8b717ca441..3edca48a627f51c6d737d75eecf354ca3806e844 100644 --- a/libs/middletier/SqliteDatabase.hpp +++ b/libs/middletier/SqliteDatabase.hpp @@ -1,17 +1,19 @@ #pragma once +#include <list> + #include <sqlite3.h> +#include "AdminHost.hpp" +#include "AdminUser.hpp" #include "ArchivalJob.hpp" +#include "ArchiveRoute.hpp" +#include "LogicalLibrary.hpp" #include "RetrievalJob.hpp" -#include "FileSystemNode.hpp" -#include "FileSystemStorageClasses.hpp" -#include "MockAdminHostTable.hpp" -#include "MockAdminUserTable.hpp" -#include "MockArchiveRouteTable.hpp" -#include "MockLogicalLibraryTable.hpp" -#include "MockTapeTable.hpp" -#include "MockTapePoolTable.hpp" +#include "SecurityIdentity.hpp" +#include "StorageClass.hpp" +#include "Tape.hpp" +#include "TapePool.hpp" namespace cta { diff --git a/libs/middletier/Vfs.cpp b/libs/middletier/Vfs.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ad95dcc7256078c7c4e651b655a4bf944fbf2b7f --- /dev/null +++ b/libs/middletier/Vfs.cpp @@ -0,0 +1,214 @@ +#include <dirent.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <sstream> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <attr/xattr.h> +#include <fcntl.h> + +#include "Exception.hpp" +#include "Utils.hpp" +#include "Vfs.hpp" + +//------------------------------------------------------------------------------ +// checkDirectoryExists +//------------------------------------------------------------------------------ +void cta::Vfs::checkDirectoryExists(const std::string &dirPath) { + struct stat stat_result; + int rc; + + rc = stat(dirPath.c_str(), &stat_result); + if(rc != 0) { + char buf[256]; + std::ostringstream message; + message << "checkDirectoryExists() - " << dirPath << " stat error. Reason: " << strerror_r(errno, buf, 256); + throw(Exception(message.str())); + } + + if(!S_ISDIR(stat_result.st_mode)) { + std::ostringstream message; + message << "checkDirectoryExists() - " << dirPath << " is not a directory"; + throw(Exception(message.str())); + } +} + +//------------------------------------------------------------------------------ +// checkPathnameDoesNotExist +//------------------------------------------------------------------------------ +void cta::Vfs::checkPathnameDoesNotExist(const std::string &dirPath) { + struct stat stat_result; + int rc; + + rc = stat(dirPath.c_str(), &stat_result); + if(rc == 0) { + std::ostringstream message; + message << "checkPathnameDoesNotExist() - " << dirPath << " exists."; + throw(Exception(message.str())); + } +} + +//------------------------------------------------------------------------------ +// constructor +//------------------------------------------------------------------------------ +cta::Vfs::Vfs() { + m_baseDir = "/tmp"; + m_fsDir = m_baseDir+"/CTATmpFs"; + + checkDirectoryExists(m_baseDir); + checkPathnameDoesNotExist(m_fsDir); + + int rc = mkdir(m_fsDir.c_str(), 0777); + if(rc != 0) { + char buf[256]; + std::ostringstream message; + message << "Vfs() - mkdir " << m_fsDir << " error. Reason: \n" << strerror_r(errno, buf, 256); + throw(Exception(message.str())); + } +} + +//------------------------------------------------------------------------------ +// destructor +//------------------------------------------------------------------------------ +cta::Vfs::~Vfs() throw() { + system("rm -rf /tmp/CTATmpFs"); +} + +//------------------------------------------------------------------------------ +// setDirectoryStorageClass +//------------------------------------------------------------------------------ +void cta::Vfs::setDirectoryStorageClass(const SecurityIdentity &requester, const std::string &path, const std::string &storageClassName) { + cta::Utils::checkAbsolutePathSyntax(path); + checkDirectoryExists(m_fsDir+path); + + int rc = setxattr((m_fsDir+path).c_str(), "CTAStorageClass", (void *)(storageClassName.c_str()), storageClassName.length(), XATTR_REPLACE); + if(rc != 0) { + char buf[256]; + std::ostringstream message; + message << "setDirectoryStorageClass() - " << m_fsDir+path << " setxattr error. Reason: " << strerror_r(errno, buf, 256); + throw(Exception(message.str())); + } +} + +//------------------------------------------------------------------------------ +// clearDirectoryStorageClass +//------------------------------------------------------------------------------ +void cta::Vfs::clearDirectoryStorageClass(const SecurityIdentity &requester, const std::string &path) { + cta::Utils::checkAbsolutePathSyntax(path); + checkDirectoryExists(m_fsDir+path); + + int rc = removexattr((m_fsDir+path).c_str(), "CTAStorageClass"); + if(rc != 0) { + char buf[256]; + std::ostringstream message; + message << "setDirectoryStorageClass() - " << m_fsDir+path << " setxattr error. Reason: " << strerror_r(errno, buf, 256); + throw(Exception(message.str())); + } +} + +//------------------------------------------------------------------------------ +// getDirectoryStorageClass +//------------------------------------------------------------------------------ +std::string cta::Vfs::getDirectoryStorageClass(const SecurityIdentity &requester, const std::string &path) { + cta::Utils::checkAbsolutePathSyntax(path); + checkDirectoryExists(m_fsDir+path); + + char value[1024]; + int rc = getxattr((m_fsDir+path).c_str(), "CTAStorageClass", (void *)value, 1024); + if(rc != 0) { + char buf[256]; + std::ostringstream message; + message << "setDirectoryStorageClass() - " << m_fsDir+path << " setxattr error. Reason: " << strerror_r(errno, buf, 256); + throw(Exception(message.str())); + } + return std::string(value); +} + +//------------------------------------------------------------------------------ +// createFile +//------------------------------------------------------------------------------ +void cta::Vfs::createFile(const SecurityIdentity &requester, const std::string &pathname, const uint16_t mode) { + cta::Utils::checkAbsolutePathSyntax(pathname); + std::string path = cta::Utils::getEnclosingDirPath(pathname); + std::string name = cta::Utils::getEnclosedName(pathname); + checkDirectoryExists(m_fsDir+path); + + int fd = open((m_fsDir+pathname).c_str(), O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK, 0666); + if(fd<0) { + char buf[256]; + std::ostringstream message; + message << "createFile() - " << m_fsDir+pathname << " open error. Reason: " << strerror_r(errno, buf, 256); + throw(Exception(message.str())); + } + int rc = utimensat(AT_FDCWD, (m_fsDir+pathname).c_str(), NULL, 0); + if(rc) { + char buf[256]; + std::ostringstream message; + message << "createFile() - " << m_fsDir+pathname << " utimensat error. Reason: " << strerror_r(errno, buf, 256); + throw(Exception(message.str())); + } +} + +//------------------------------------------------------------------------------ +// createDirectory +//------------------------------------------------------------------------------ +void cta::Vfs::createDirectory(const SecurityIdentity &requester, const std::string &pathname, const uint16_t mode) { + cta::Utils::checkAbsolutePathSyntax(pathname); + std::string path = cta::Utils::getEnclosingDirPath(pathname); + std::string name = cta::Utils::getEnclosedName(pathname); + checkDirectoryExists(m_fsDir+path); + + int rc = mkdir((m_fsDir+pathname).c_str(), 0777); + if(rc != 0) { + char buf[256]; + std::ostringstream message; + message << "createDirectory() - mkdir " << m_fsDir+pathname << " error. Reason: \n" << strerror_r(errno, buf, 256); + throw(Exception(message.str())); + } +} + +//------------------------------------------------------------------------------ +// deleteFile +//------------------------------------------------------------------------------ +void cta::Vfs::deleteFile(const SecurityIdentity &requester, const std::string &pathname) { + cta::Utils::checkAbsolutePathSyntax(pathname); + + int rc = unlink((m_fsDir+pathname).c_str()); + if(rc != 0) { + char buf[256]; + std::ostringstream message; + message << "deleteFile() - unlink " << m_fsDir+pathname << " error. Reason: \n" << strerror_r(errno, buf, 256); + throw(Exception(message.str())); + } +} + +//------------------------------------------------------------------------------ +// deleteDirectory +//------------------------------------------------------------------------------ +void cta::Vfs::deleteDirectory(const SecurityIdentity &requester, const std::string &pathname) { + cta::Utils::checkAbsolutePathSyntax(pathname); + + int rc = rmdir((m_fsDir+pathname).c_str()); + if(rc != 0) { + char buf[256]; + std::ostringstream message; + message << "deleteDirectory() - rmdir " << m_fsDir+pathname << " error. Reason: \n" << strerror_r(errno, buf, 256); + throw(Exception(message.str())); + } +} + +//------------------------------------------------------------------------------ +// stat +//------------------------------------------------------------------------------ +cta::DirectoryEntry cta::Vfs::statDirectoryEntry(const SecurityIdentity &requester, const std::string &pathname) { + throw(Exception("statDirectoryEntry() - Not implemented!")); +} + +//------------------------------------------------------------------------------ +// getDirectoryContents +//------------------------------------------------------------------------------ +cta::DirectoryIterator cta::Vfs::getDirectoryContents(const SecurityIdentity &requester, const std::string &dirPath) { + throw(Exception("statDirectoryEntry() - Not implemented!")); +} \ No newline at end of file diff --git a/libs/middletier/Vfs.hpp b/libs/middletier/Vfs.hpp new file mode 100644 index 0000000000000000000000000000000000000000..6f0eae0ad0a6949bc5e00846aee212b132088866 --- /dev/null +++ b/libs/middletier/Vfs.hpp @@ -0,0 +1,55 @@ +#pragma once + +#include "DirectoryIterator.hpp" +#include "SecurityIdentity.hpp" + +namespace cta { + +/** + * Mock database. + */ +class Vfs { + +public: + + /** + * Constructor. + */ + Vfs(); + + /** + * Destructor. + */ + ~Vfs() throw(); + + void setDirectoryStorageClass(const SecurityIdentity &requester, const std::string &path, const std::string &storageClassName); + + void clearDirectoryStorageClass(const SecurityIdentity &requester, const std::string &path); + + std::string getDirectoryStorageClass(const SecurityIdentity &requester, const std::string &path); + + void createFile(const SecurityIdentity &requester, const std::string &pathname, const uint16_t mode); + + void createDirectory(const SecurityIdentity &requester, const std::string &pathname, const uint16_t mode); + + void deleteFile(const SecurityIdentity &requester, const std::string &pathname); + + void deleteDirectory(const SecurityIdentity &requester, const std::string &pathname); + + cta::DirectoryEntry statDirectoryEntry(const SecurityIdentity &requester, const std::string &pathname); + + cta::DirectoryIterator getDirectoryContents(const SecurityIdentity &requester, const std::string &dirPath); + +private: + + std::string m_baseDir; + + std::string m_fsDir; + + void checkDirectoryExists(const std::string &dirPath); + + void checkPathnameDoesNotExist(const std::string &dirPath); + +}; // struct Vfs + +} // namespace cta