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 "BackendVFS.hpp"
#include "BackendRados.hpp"
#include "exception/Exception.hpp"
TEST_P(BackendAbstractTest, BasicReadWrite) {
std::cout << "Type=" << m_os->typeName() << std::endl;
......@@ -11,7 +12,7 @@ TEST_P(BackendAbstractTest, BasicReadWrite) {
ASSERT_EQ(false, m_os->exists(testObjectName));
// Check that an update attempt fails on a non-existing object
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);
// Check that re-creating an existing object throws exception
ASSERT_THROW(m_os->create(testObjectName, testValue), cta::exception::Exception);
......
#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
#include "Backend.hpp"
#include "exception/Errnum.hpp"
#include <rados/librados.hpp>
#include <sys/syscall.h>
#include <errno.h>
#include "rados/librados.hpp"
namespace cta { namespace objectstore {
/**
......@@ -18,28 +16,8 @@ public:
* @param userId
* @param pool
*/
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;
}
}
virtual ~BackendRados() {
m_radosCtx.close();
m_cluster.shutdown();
}
BackendRados(std::string userId, std::string pool);
virtual ~BackendRados();
virtual std::string user() {
return m_user;
}
......@@ -48,77 +26,24 @@ public:
}
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 create(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 void atomicOverwrite(std::string name, std::string content);
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 std::string read(std::string name);
virtual void remove(std::string name) {
cta::exception::Errnum::throwOnNegative(m_radosCtx.remove(name));
}
virtual void remove(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;
}
}
virtual bool exists(std::string name);
class ScopedLock: public Backend::ScopedLock {
friend class BackendRados;
public:
virtual void 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;
}
virtual ~ScopedLock() { release(); }
virtual void release();
virtual ~ScopedLock();
private:
ScopedLock(librados::IoCtx & ioCtx): m_lockSet(false), m_context(ioCtx) {}
void set(const std::string & oid, const std::string clientId) {
m_oid = oid;
m_clientId = clientId;\
m_lockSet = true;
}
void set(const std::string & oid, const std::string clientId);
bool m_lockSet;
librados::IoCtx & m_context;
std::string m_clientId;
......@@ -126,52 +51,13 @@ public:
};
private:
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();
}
std::string createUniqueClientId();
public:
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 * lockExclusive(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();
}
virtual ScopedLock * lockShared(std::string name);
class Parameters: public Backend::Parameters {
friend class BackendRados;
......@@ -180,22 +66,13 @@ public:
* The standard-issue params to string for logging
* @return a string representation of the parameters for logging
*/
virtual std::string toStr() {
std::stringstream ret;
ret << "userId=" << m_userId << " pool=" << m_pool;
return ret.str();
}
virtual std::string toStr();
private:
std::string m_userId;
std::string m_pool;
};
virtual Parameters * getParams() {
std::auto_ptr<Parameters> ret (new Parameters);
ret->m_pool = m_pool;
ret->m_userId = m_user;
return ret.release();
}
virtual Parameters * getParams();
virtual std::string typeName() {
return "cta::objectstore::BackendRados";
......
......@@ -16,6 +16,7 @@ add_library (CTAObjectStore
# Agent.cpp
# AgentRegister.cpp
BackendVFS.cpp
BackendRados.cpp
exception/Backtrace.cpp
exception/Errnum.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