File indexing completed on 2023-03-17 11:26:46
0001 #include "Utilities/LStoreAdaptor/interface/LStoreFile.h"
0002 #include "FWCore/Utilities/interface/Exception.h"
0003 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0004 #include <cassert>
0005 #include <vector>
0006 #include <unistd.h>
0007 #include <fcntl.h>
0008 #include <pthread.h>
0009 #include <dlfcn.h>
0010 #include <iostream>
0011 #include <cstring>
0012
0013 using namespace edm::storage;
0014
0015
0016 pthread_mutex_t LStoreFile::m_dlopen_lock = PTHREAD_MUTEX_INITIALIZER;
0017
0018 LStoreFile::LStoreFile(void)
0019 : m_fd(nullptr),
0020 m_close(false),
0021 m_name(),
0022 m_library_handle(nullptr),
0023 m_is_loaded(false),
0024 redd_init(nullptr),
0025 redd_read(nullptr),
0026 redd_close(nullptr),
0027 redd_lseek(nullptr),
0028 redd_open(nullptr),
0029 redd_write(nullptr),
0030 redd_term(nullptr),
0031 redd_errno(nullptr),
0032 redd_strerror(nullptr) {
0033 loadLibrary();
0034 }
0035
0036 LStoreFile::LStoreFile(void *fd)
0037 : m_fd(fd),
0038 m_close(true),
0039 m_name(),
0040 m_library_handle(nullptr),
0041 m_is_loaded(false),
0042 redd_init(nullptr),
0043 redd_read(nullptr),
0044 redd_close(nullptr),
0045 redd_lseek(nullptr),
0046 redd_open(nullptr),
0047 redd_write(nullptr),
0048 redd_term(nullptr),
0049 redd_errno(nullptr),
0050 redd_strerror(nullptr) {
0051 loadLibrary();
0052 }
0053
0054 LStoreFile::LStoreFile(const char *name, int flags , int perms )
0055 : m_fd(nullptr), m_close(false), m_is_loaded(false) {
0056 loadLibrary();
0057 open(name, flags, perms);
0058 }
0059
0060 LStoreFile::LStoreFile(const std::string &name, int flags , int perms )
0061 : m_fd(nullptr), m_close(false), m_is_loaded(false) {
0062 loadLibrary();
0063 open(name.c_str(), flags, perms);
0064 }
0065
0066 LStoreFile::~LStoreFile(void) {
0067 if (m_close)
0068 edm::LogError("LStoreFileError") << "Destructor called on LStore file '" << m_name
0069 << "' but the file is still open";
0070 closeLibrary();
0071 }
0072
0073
0074
0075
0076 #define REDD_LOAD_SYMBOL(NAME, TYPE) \
0077 dlerror(); \
0078 NAME = reinterpret_cast<TYPE>(reinterpret_cast<size_t>(dlsym(m_library_handle, #NAME))); \
0079 if ((retval = dlerror())) { \
0080 throw cms::Exception("LStoreFile::loadLibrary()") << "Failed to load dlsym LStore library: " << retval; \
0081 } \
0082 if (NAME == NULL) { \
0083 throw cms::Exception("LStoreFile::loadLibrary()") << "Got a null pointer back from dlsym()\n"; \
0084 }
0085
0086 void LStoreFile::loadLibrary() {
0087 edm::LogError("LStoreFile::loadLibrary()") << "Loading library\n";
0088 LStoreFile::MutexWrapper lockObj(&this->m_dlopen_lock);
0089
0090
0091
0092
0093
0094
0095
0096 m_library_handle = dlopen("libreddnet.so", RTLD_LAZY);
0097 if (m_library_handle == nullptr) {
0098 throw cms::Exception("LStoreFile::loadLibrary()") << "Can't dlopen() LStore libraries: " << dlerror();
0099 }
0100
0101 char *retval = nullptr;
0102
0103 REDD_LOAD_SYMBOL(redd_init, int32_t(*)());
0104 REDD_LOAD_SYMBOL(redd_read, int64_t(*)(void *, char *, int64_t));
0105 REDD_LOAD_SYMBOL(redd_lseek, int64_t(*)(void *, int64_t, uint32_t));
0106 REDD_LOAD_SYMBOL(redd_open, void *(*)(const char *, int, int));
0107 REDD_LOAD_SYMBOL(redd_write, int64_t(*)(void *, const char *, int64_t));
0108 REDD_LOAD_SYMBOL(redd_term, int32_t(*)());
0109 REDD_LOAD_SYMBOL(redd_errno, int32_t(*)());
0110 REDD_LOAD_SYMBOL(redd_strerror, const std::string &(*)());
0111
0112 if ((*redd_init)()) {
0113 throw cms::Exception("LStoreFile::loadLibrary()") << "Error in redd_init: " << (*redd_strerror)();
0114 }
0115 m_is_loaded = true;
0116 }
0117
0118 void LStoreFile::closeLibrary() {
0119 try {
0120 LStoreFile::MutexWrapper lockObj(&this->m_dlopen_lock);
0121
0122
0123
0124
0125
0126 if (m_is_loaded) {
0127 if ((*redd_term)()) {
0128 throw cms::Exception("LStoreFile::closeLibrary()") << "Error in redd_term: " << (*redd_strerror)();
0129 }
0130 }
0131 if (m_library_handle != nullptr) {
0132 if (dlclose(m_library_handle)) {
0133 throw cms::Exception("LStoreFile::closeLibrary()") << "Error on dlclose(): " << dlerror();
0134 }
0135 }
0136 } catch (cms::Exception &e) {
0137 edm::LogError("LStoreFileError") << "LStoreFile had an error in its destructor: " << e;
0138 }
0139 m_is_loaded = false;
0140 }
0141
0142
0143 void LStoreFile::create(const char *name, bool exclusive , int perms ) {
0144 open(name,
0145 (IOFlags::OpenCreate | IOFlags::OpenWrite | IOFlags::OpenTruncate | (exclusive ? IOFlags::OpenExclusive : 0)),
0146 perms);
0147 }
0148
0149 void LStoreFile::create(const std::string &name, bool exclusive , int perms ) {
0150 open(name.c_str(),
0151 (IOFlags::OpenCreate | IOFlags::OpenWrite | IOFlags::OpenTruncate | (exclusive ? IOFlags::OpenExclusive : 0)),
0152 perms);
0153 }
0154
0155 void LStoreFile::open(const std::string &name, int flags , int perms ) {
0156 open(name.c_str(), flags, perms);
0157 }
0158
0159 void LStoreFile::open(const char *name, int flags , int perms ) {
0160
0161 if ((name == nullptr) || (*name == 0))
0162 throw cms::Exception("LStoreFile::open()") << "Cannot open a file without a name";
0163
0164 if ((flags & (IOFlags::OpenRead | IOFlags::OpenWrite)) == 0)
0165 throw cms::Exception("LStoreFile::open()") << "Must open file '" << name << "' at least for read or write";
0166
0167
0168 if (m_fd != nullptr && m_close)
0169 close();
0170
0171
0172 int openflags = 0;
0173
0174 if ((flags & IOFlags::OpenRead) && (flags & IOFlags::OpenWrite))
0175 openflags |= O_RDWR;
0176 else if (flags & IOFlags::OpenRead)
0177 openflags |= O_RDONLY;
0178 else if (flags & IOFlags::OpenWrite)
0179 openflags |= O_WRONLY;
0180
0181 if (flags & IOFlags::OpenNonBlock)
0182 openflags |= O_NONBLOCK;
0183
0184 if (flags & IOFlags::OpenAppend)
0185 openflags |= O_APPEND;
0186
0187 if (flags & IOFlags::OpenCreate)
0188 openflags |= O_CREAT;
0189
0190 if (flags & IOFlags::OpenExclusive)
0191 openflags |= O_EXCL;
0192
0193 if (flags & IOFlags::OpenTruncate)
0194 openflags |= O_TRUNC;
0195
0196 void *newfd = nullptr;
0197 if ((newfd = (*redd_open)(name, openflags, perms)) == nullptr)
0198 throw cms::Exception("LStoreFile::open()")
0199 << "redd_open(name='" << name << "', flags=0x" << std::hex << openflags << ", permissions=0" << std::oct
0200 << perms << std::dec << ") => error '" << (*redd_strerror)() << "' (redd_errno=" << (*redd_errno)() << ")";
0201
0202 m_name = name;
0203 m_fd = newfd;
0204
0205 m_close = true;
0206
0207 edm::LogInfo("LStoreFileInfo") << "Opened " << m_name;
0208 }
0209
0210 void LStoreFile::close(void) {
0211 if (m_fd == nullptr) {
0212 edm::LogError("LStoreFileError") << "LStoreFile::close(name='" << m_name << "') called but the file is not open";
0213 m_close = false;
0214 return;
0215 }
0216 edm::LogInfo("LStoreFile::close()") << "closing " << m_name << std::endl;
0217 if ((*redd_close)(m_fd) == -1)
0218 edm::LogWarning("LStoreFileWarning") << "redd_close(name='" << m_name << "') failed with error '"
0219 << (*redd_strerror)() << "' (redd_errno=" << (*redd_errno)() << ")";
0220
0221 m_close = false;
0222 m_fd = nullptr;
0223
0224
0225
0226 }
0227
0228 void LStoreFile::abort(void) {
0229 if (m_fd != nullptr)
0230 (*redd_close)(m_fd);
0231
0232 m_close = false;
0233 m_fd = nullptr;
0234 }
0235
0236 IOSize LStoreFile::read(void *into, IOSize n) {
0237 IOSize done = 0;
0238 while (done < n) {
0239 ssize_t s = (*redd_read)(m_fd, (char *)into + done, n - done);
0240 if (s == -1)
0241 throw cms::Exception("LStoreFile::read()")
0242 << "redd_read(name='" << m_name << "', n=" << (n - done) << ") failed with error '" << (*redd_strerror)()
0243 << "' (redd_errno=" << (*redd_errno)() << ")";
0244 done += s;
0245 }
0246 return done;
0247 }
0248
0249 IOSize LStoreFile::write(const void *from, IOSize n) {
0250 IOSize done = 0;
0251 while (done < n) {
0252 ssize_t s = (*redd_write)(m_fd, (const char *)from + done, n - done);
0253 if (s == -1)
0254 throw cms::Exception("LStoreFile::write()")
0255 << "redd_write(name='" << m_name << "', n=" << (n - done) << ") failed with error '" << (*redd_strerror)()
0256 << "' (redd_errno=" << (*redd_errno)() << ")";
0257 done += s;
0258 }
0259
0260 return done;
0261 }
0262
0263
0264
0265 IOOffset LStoreFile::position(IOOffset offset, Relative whence ) {
0266 if (m_fd == nullptr)
0267 throw cms::Exception("LStoreFile::position()") << "LStoreFile::position() called on a closed file";
0268 if (whence != CURRENT && whence != SET && whence != END)
0269 throw cms::Exception("LStoreFile::position()") << "LStoreFile::position() called with incorrect 'whence' parameter";
0270
0271 IOOffset result;
0272 uint32_t mywhence = (whence == SET ? SEEK_SET : whence == CURRENT ? SEEK_CUR : SEEK_END);
0273 if ((result = (*redd_lseek)(m_fd, (off_t)offset, (uint32_t)mywhence)) == -1)
0274 throw cms::Exception("LStoreFile::position()")
0275 << "redd_lseek64(name='" << m_name << "', offset=" << offset << ", whence=" << mywhence
0276 << ") failed with error '" << (*redd_strerror)() << "' (redd_errno=" << (*redd_errno)() << ")";
0277 return result;
0278 }
0279
0280 void LStoreFile::resize(IOOffset ) {
0281 throw cms::Exception("LStoreFile::resize()") << "LStoreFile::resize(name='" << m_name << "') not implemented";
0282 }
0283
0284
0285
0286 LStoreFile::MutexWrapper::MutexWrapper(pthread_mutex_t *target) {
0287 m_lock = target;
0288 pthread_mutex_lock(m_lock);
0289 }
0290
0291 LStoreFile::MutexWrapper::~MutexWrapper() {
0292 int retval;
0293 if ((retval = pthread_mutex_unlock(m_lock))) {
0294
0295
0296
0297
0298
0299
0300 char buf[1024];
0301 edm::LogError("LStoreFileError") << "LStoreFile couldn't unlock a mutex. Not good."
0302 << strerror_r(retval, buf, 1024);
0303 }
0304 }