Commit f50bd2c5 authored by Eric Cano's avatar Eric Cano
Browse files

Moved implementation of Rados backend to a separate cpp file, from the hpp file.

parent 1ce732bd
#include "BackendAbstractTests.hpp" #include "BackendAbstractTests.hpp"
#include "BackendVFS.hpp" #include "BackendVFS.hpp"
#include "BackendRados.hpp" #include "BackendRados.hpp"
#include "exception/Exception.hpp"
TEST_P(BackendAbstractTest, BasicReadWrite) { TEST_P(BackendAbstractTest, BasicReadWrite) {
std::cout << "Type=" << m_os->typeName() << std::endl; std::cout << "Type=" << m_os->typeName() << std::endl;
...@@ -11,7 +12,7 @@ TEST_P(BackendAbstractTest, BasicReadWrite) { ...@@ -11,7 +12,7 @@ TEST_P(BackendAbstractTest, BasicReadWrite) {
ASSERT_EQ(false, m_os->exists(testObjectName)); ASSERT_EQ(false, m_os->exists(testObjectName));
// Check that an update attempt fails on a non-existing object // Check that an update attempt fails on a non-existing object
ASSERT_THROW(m_os->atomicOverwrite(testObjectName, testSecondValue), cta::exception::Exception); ASSERT_THROW(m_os->atomicOverwrite(testObjectName, testSecondValue), cta::exception::Exception);
// Check the creation of the obecjt // Check the creation of the object
m_os->create(testObjectName, testValue); m_os->create(testObjectName, testValue);
// Check that re-creating an existing object throws exception // Check that re-creating an existing object throws exception
ASSERT_THROW(m_os->create(testObjectName, testValue), cta::exception::Exception); ASSERT_THROW(m_os->create(testObjectName, testValue), cta::exception::Exception);
...@@ -32,4 +33,4 @@ TEST_P(BackendAbstractTest, BasicReadWrite) { ...@@ -32,4 +33,4 @@ TEST_P(BackendAbstractTest, BasicReadWrite) {
cta::objectstore::BackendVFS osVFS; cta::objectstore::BackendVFS osVFS;
cta::objectstore::BackendRados osRados("tapetest", "tapetest"); cta::objectstore::BackendRados osRados("tapetest", "tapetest");
INSTANTIATE_TEST_CASE_P(BackendTest, BackendAbstractTest, ::testing::Values(&osVFS, &osRados)); INSTANTIATE_TEST_CASE_P(BackendTest, BackendAbstractTest, ::testing::Values(&osVFS, &osRados));
\ No newline at end of file
#include "BackendRados.hpp"
#include "exception/Errnum.hpp"
#include <rados/librados.hpp>
#include <sys/syscall.h>
#include <errno.h>
namespace cta { namespace objectstore {
BackendRados::BackendRados(std::string userId, std::string pool) :
m_user(userId), m_pool(pool), m_cluster(), m_radosCtx() {
cta::exception::Errnum::throwOnNonZero(m_cluster.init(userId.c_str()),
"In ObjectStoreRados::ObjectStoreRados, failed to m_cluster.init");
try {
cta::exception::Errnum::throwOnNonZero(m_cluster.conf_read_file(NULL),
"In ObjectStoreRados::ObjectStoreRados, failed to m_cluster.conf_read_file");
cta::exception::Errnum::throwOnNonZero(m_cluster.conf_parse_env(NULL),
"In ObjectStoreRados::ObjectStoreRados, failed to m_cluster.conf_read_file");
cta::exception::Errnum::throwOnNonZero(m_cluster.connect(),
"In ObjectStoreRados::ObjectStoreRados, failed to m_cluster.connect");
cta::exception::Errnum::throwOnNonZero(m_cluster.ioctx_create(pool.c_str(), m_radosCtx),
"In ObjectStoreRados::ObjectStoreRados, failed to m_cluster.ioctx_create");
} catch (...) {
m_cluster.shutdown();
throw;
}
}
BackendRados::~BackendRados() {
m_radosCtx.close();
m_cluster.shutdown();
}
void BackendRados::create(std::string name, std::string content) {
librados::ObjectWriteOperation wop;
const bool createExclusive = true;
wop.create(createExclusive);
ceph::bufferlist bl;
bl.append(content.c_str(), content.size());
wop.write_full(bl);
cta::exception::Errnum::throwOnNonZero(m_radosCtx.operate(name, &wop),
std::string("In ObjectStoreRados::create, failed to create exclusively or write ")
+ name);
}
void BackendRados::atomicOverwrite(std::string name, std::string content) {
librados::ObjectWriteOperation wop;
wop.assert_exists();
ceph::bufferlist bl;
bl.append(content.c_str(), content.size());
wop.write_full(bl);
cta::exception::Errnum::throwOnNonZero(m_radosCtx.operate(name, &wop),
std::string("In ObjectStoreRados::atomicOverwrite, failed to assert existence or write ")
+ name);
}
std::string BackendRados::read(std::string name) {
std::string ret;
uint64_t size;
time_t time;
cta::exception::Errnum::throwOnNonZero(m_radosCtx.stat(name, &size, &time),
std::string("In ObjectStoreRados::read, failed to stat ")
+ name);
librados::bufferlist bl;
cta::exception::Errnum::throwOnNegative(m_radosCtx.read(name, bl, size, 0),
std::string("In ObjectStoreRados::read, failed to read ")
+ name);
bl.copy(0, size, ret);
return ret;
}
void BackendRados::remove(std::string name) {
cta::exception::Errnum::throwOnNegative(m_radosCtx.remove(name));
}
bool BackendRados::exists(std::string name) {
uint64_t size;
time_t date;
if (m_radosCtx.stat(name, &size, &date)) {
return false;
} else {
return true;
}
}
void BackendRados::ScopedLock::release() {
if (!m_lockSet) return;
cta::exception::Errnum::throwOnReturnedErrno(
-m_context.unlock(m_oid, "lock", m_clientId),
std::string("In cta::objectstore::ScopedLock::release, failed unlock ") +
m_oid);
m_lockSet = false;
}
void BackendRados::ScopedLock::set(const std::string& oid, const std::string clientId) {
m_oid = oid;
m_clientId = clientId;\
m_lockSet = true;
}
BackendRados::ScopedLock::~ScopedLock() {
release();
}
std::string BackendRados::createUniqueClientId() {
// Build a unique client name: host:thread
char buff[200];
cta::exception::Errnum::throwOnMinusOne(gethostname(buff, sizeof (buff)),
"In ObjectStoreRados::lockExclusive: failed to gethostname");
pid_t tid = syscall(SYS_gettid);
std::stringstream client;
client << buff << ":" << tid;
return client.str();
}
BackendRados::ScopedLock* BackendRados::lockExclusive(std::string name) {
std::string client = createUniqueClientId();
struct timeval tv;
tv.tv_usec = 0;
tv.tv_sec = 10;
int rc;
std::auto_ptr<ScopedLock> ret(new ScopedLock(m_radosCtx));
do {
rc = m_radosCtx.lock_exclusive(name, "lock", client, "", &tv, 0);
} while (-EBUSY == rc);
cta::exception::Errnum::throwOnReturnedErrno(-rc,
std::string("In ObjectStoreRados::lockExclusive, failed to librados::IoCtx::lock_exclusive: ") +
name + "/" + "lock" + "/" + client + "//");
ret->set(name, client);
return ret.release();
}
BackendRados::ScopedLock* BackendRados::lockShared(std::string name) {
std::string client = createUniqueClientId();
struct timeval tv;
tv.tv_usec = 0;
tv.tv_sec = 10;
int rc;
std::auto_ptr<ScopedLock> ret(new ScopedLock(m_radosCtx));
do {
rc = m_radosCtx.lock_shared(name, "lock", client, "", "", &tv, 0);
} while (-EBUSY == rc);
cta::exception::Errnum::throwOnReturnedErrno(-rc,
std::string("In ObjectStoreRados::lockShared, failed to librados::IoCtx::lock_shared: ") +
name + "/" + "lock" + "/" + client + "//");
ret->set(name, client);
return ret.release();
}
std::string BackendRados::Parameters::toStr() {
std::stringstream ret;
ret << "userId=" << m_userId << " pool=" << m_pool;
return ret.str();
}
BackendRados::Parameters* BackendRados::getParams() {
std::auto_ptr<Parameters> ret(new Parameters);
ret->m_pool = m_pool;
ret->m_userId = m_user;
return ret.release();
}
}}
\ No newline at end of file
#pragma once #pragma once
#include "Backend.hpp" #include "Backend.hpp"
#include "exception/Errnum.hpp" #include "rados/librados.hpp"
#include <rados/librados.hpp>
#include <sys/syscall.h>
#include <errno.h>
namespace cta { namespace objectstore { namespace cta { namespace objectstore {
/** /**
...@@ -18,28 +16,8 @@ public: ...@@ -18,28 +16,8 @@ public:
* @param userId * @param userId
* @param pool * @param pool
*/ */
BackendRados(std::string userId, std::string pool): BackendRados(std::string userId, std::string pool);
m_user(userId), m_pool(pool), m_cluster(), m_radosCtx() { virtual ~BackendRados();
cta::exception::Errnum::throwOnNonZero(m_cluster.init(userId.c_str()),
"In ObjectStoreRados::ObjectStoreRados, failed to m_cluster.init");
try {
cta::exception::Errnum::throwOnNonZero(m_cluster.conf_read_file(NULL),
"In ObjectStoreRados::ObjectStoreRados, failed to m_cluster.conf_read_file");
cta::exception::Errnum::throwOnNonZero(m_cluster.conf_parse_env(NULL),
"In ObjectStoreRados::ObjectStoreRados, failed to m_cluster.conf_read_file");
cta::exception::Errnum::throwOnNonZero(m_cluster.connect(),
"In ObjectStoreRados::ObjectStoreRados, failed to m_cluster.connect");
cta::exception::Errnum::throwOnNonZero(m_cluster.ioctx_create(pool.c_str(), m_radosCtx),
"In ObjectStoreRados::ObjectStoreRados, failed to m_cluster.ioctx_create");
} catch (...) {
m_cluster.shutdown();
throw;
}
}
virtual ~BackendRados() {
m_radosCtx.close();
m_cluster.shutdown();
}
virtual std::string user() { virtual std::string user() {
return m_user; return m_user;
} }
...@@ -48,77 +26,24 @@ public: ...@@ -48,77 +26,24 @@ public:
} }
virtual void create(std::string name, std::string content) { virtual void create(std::string name, std::string content);
librados::ObjectWriteOperation wop;
const bool createExclusive = true;
wop.create(createExclusive);
ceph::bufferlist bl;
bl.append(content.c_str(), content.size());
wop.write_full(bl);
cta::exception::Errnum::throwOnNonZero(m_radosCtx.operate(name, &wop),
std::string("In ObjectStoreRados::create, failed to create exclusively or write ")
+ name);
}
virtual void atomicOverwrite(std::string name, std::string content) { virtual void atomicOverwrite(std::string name, std::string content);
librados::ObjectWriteOperation wop;
wop.assert_exists();
ceph::bufferlist bl;
bl.append(content.c_str(), content.size());
wop.write_full(bl);
cta::exception::Errnum::throwOnNonZero(m_radosCtx.operate(name, &wop),
std::string("In ObjectStoreRados::atomicOverwrite, failed to assert existence or write ")
+ name);
}
virtual std::string read(std::string name) { virtual std::string read(std::string name);
std::string ret;
uint64_t size;
time_t time;
cta::exception::Errnum::throwOnNonZero(m_radosCtx.stat(name, &size, &time),
std::string("In ObjectStoreRados::read, failed to stat ")
+ name);
librados::bufferlist bl;
cta::exception::Errnum::throwOnNegative(m_radosCtx.read(name, bl, size, 0),
std::string("In ObjectStoreRados::read, failed to read ")
+ name);
bl.copy(0, size, ret);
return ret;
}
virtual void remove(std::string name) { virtual void remove(std::string name);
cta::exception::Errnum::throwOnNegative(m_radosCtx.remove(name));
}
virtual bool exists(std::string name) { virtual bool exists(std::string name);
uint64_t size;
time_t date;
if (m_radosCtx.stat(name, &size, &date)) {
return false;
} else {
return true;
}
}
class ScopedLock: public Backend::ScopedLock { class ScopedLock: public Backend::ScopedLock {
friend class BackendRados; friend class BackendRados;
public: public:
virtual void release() { virtual void release();
if (!m_lockSet) return; virtual ~ScopedLock();
cta::exception::Errnum::throwOnReturnedErrno(
-m_context.unlock(m_oid, "lock", m_clientId),
std::string("In cta::objectstore::ScopedLock::release, failed unlock ")+
m_oid);
m_lockSet = false;
}
virtual ~ScopedLock() { release(); }
private: private:
ScopedLock(librados::IoCtx & ioCtx): m_lockSet(false), m_context(ioCtx) {} ScopedLock(librados::IoCtx & ioCtx): m_lockSet(false), m_context(ioCtx) {}
void set(const std::string & oid, const std::string clientId) { void set(const std::string & oid, const std::string clientId);
m_oid = oid;
m_clientId = clientId;\
m_lockSet = true;
}
bool m_lockSet; bool m_lockSet;
librados::IoCtx & m_context; librados::IoCtx & m_context;
std::string m_clientId; std::string m_clientId;
...@@ -126,52 +51,13 @@ public: ...@@ -126,52 +51,13 @@ public:
}; };
private: private:
std::string createUniqueClientId() { std::string createUniqueClientId();
// Build a unique client name: host:thread
char buff[200];
cta::exception::Errnum::throwOnMinusOne(gethostname(buff, sizeof(buff)),
"In ObjectStoreRados::lockExclusive: failed to gethostname");
pid_t tid = syscall(SYS_gettid);
std::stringstream client;
client << buff << ":" << tid;
return client.str();
}
public: public:
virtual ScopedLock * lockExclusive(std::string name) { virtual ScopedLock * lockExclusive(std::string name);
std::string client = createUniqueClientId();
struct timeval tv;
tv.tv_usec = 0;
tv.tv_sec = 10;
int rc;
std::auto_ptr<ScopedLock> ret(new ScopedLock(m_radosCtx));
do {
rc=m_radosCtx.lock_exclusive(name, "lock", client, "", &tv, 0);
} while (-EBUSY==rc);
cta::exception::Errnum::throwOnReturnedErrno(-rc,
std::string("In ObjectStoreRados::lockExclusive, failed to librados::IoCtx::lock_exclusive: ")+
name + "/" + "lock" + "/" + client + "//");
ret->set(name, client);
return ret.release();
}
virtual ScopedLock * lockShared(std::string name) { virtual ScopedLock * lockShared(std::string name);
std::string client = createUniqueClientId();
struct timeval tv;
tv.tv_usec = 0;
tv.tv_sec = 10;
int rc;
std::auto_ptr<ScopedLock> ret(new ScopedLock(m_radosCtx));
do {
rc=m_radosCtx.lock_shared(name, "lock", client, "", "", &tv, 0);
} while (-EBUSY==rc);
cta::exception::Errnum::throwOnReturnedErrno(-rc,
std::string("In ObjectStoreRados::lockShared, failed to librados::IoCtx::lock_shared: ")+
name + "/" + "lock" + "/" + client + "//");
ret->set(name, client);
return ret.release();
}
class Parameters: public Backend::Parameters { class Parameters: public Backend::Parameters {
friend class BackendRados; friend class BackendRados;
...@@ -180,22 +66,13 @@ public: ...@@ -180,22 +66,13 @@ public:
* The standard-issue params to string for logging * The standard-issue params to string for logging
* @return a string representation of the parameters for logging * @return a string representation of the parameters for logging
*/ */
virtual std::string toStr() { virtual std::string toStr();
std::stringstream ret;
ret << "userId=" << m_userId << " pool=" << m_pool;
return ret.str();
}
private: private:
std::string m_userId; std::string m_userId;
std::string m_pool; std::string m_pool;
}; };
virtual Parameters * getParams() { virtual Parameters * getParams();
std::auto_ptr<Parameters> ret (new Parameters);
ret->m_pool = m_pool;
ret->m_userId = m_user;
return ret.release();
}
virtual std::string typeName() { virtual std::string typeName() {
return "cta::objectstore::BackendRados"; return "cta::objectstore::BackendRados";
......
...@@ -16,6 +16,7 @@ add_library (CTAObjectStore ...@@ -16,6 +16,7 @@ add_library (CTAObjectStore
# Agent.cpp # Agent.cpp
# AgentRegister.cpp # AgentRegister.cpp
BackendVFS.cpp BackendVFS.cpp
BackendRados.cpp
exception/Backtrace.cpp exception/Backtrace.cpp
exception/Errnum.cpp exception/Errnum.cpp
exception/Exception.cpp exception/Exception.cpp
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment