summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYehuda Sadeh <yehuda@inktank.com>2013-03-19 14:52:47 -0700
committerYehuda Sadeh <yehuda@inktank.com>2013-04-15 14:44:07 -0700
commit0ec229fca1a95bf8bc01ae565ca7ac9ebc330419 (patch)
tree55f5d5a7f794a2a9663bfcefeaf741759ad6ca26
parent45b596463a4cff8bd1d916a0f51f03c453ce5768 (diff)
downloadceph-0ec229fca1a95bf8bc01ae565ca7ac9ebc330419.tar.gz
rgw: log user operations
Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
-rw-r--r--src/Makefile.am2
-rw-r--r--src/cls/log/cls_log_client.h1
-rw-r--r--src/common/config_opts.h1
-rw-r--r--src/rgw/rgw_metadata.cc41
-rw-r--r--src/rgw/rgw_metadata.h5
-rw-r--r--src/rgw/rgw_rados.cc45
-rw-r--r--src/rgw/rgw_rados.h4
-rw-r--r--src/rgw/rgw_tools.cc1
8 files changed, 95 insertions, 5 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 870c88dac38..f339054fe5e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -385,7 +385,7 @@ librgw_a_CXXFLAGS = -Woverloaded-virtual ${AM_CXXFLAGS}
noinst_LIBRARIES += librgw.a
my_radosgw_ldadd = \
- libglobal.la librgw.a librados.la libcls_rgw_client.a \
+ libglobal.la librgw.a librados.la libcls_rgw_client.a libcls_log_client.a \
libcls_lock_client.a libcls_refcount_client.a libcls_version_client.a -lcurl -lexpat \
$(PTHREAD_LIBS) -lm $(CRYPTO_LIBS) $(EXTRALIBS)
diff --git a/src/cls/log/cls_log_client.h b/src/cls/log/cls_log_client.h
index cf1a541e495..79cfc459c51 100644
--- a/src/cls/log/cls_log_client.h
+++ b/src/cls/log/cls_log_client.h
@@ -3,6 +3,7 @@
#include "include/types.h"
#include "include/rados/librados.hpp"
+#include "cls_log_types.h"
/*
* log objclass
diff --git a/src/common/config_opts.h b/src/common/config_opts.h
index 79b1aebce43..d407e829f3b 100644
--- a/src/common/config_opts.h
+++ b/src/common/config_opts.h
@@ -579,6 +579,7 @@ OPTION(rgw_exit_timeout_secs, OPT_INT, 120) // how many seconds to wait for proc
OPTION(rgw_get_obj_window_size, OPT_INT, 16 << 20) // window size in bytes for single get obj request
OPTION(rgw_get_obj_max_req_size, OPT_INT, 4 << 20) // max length of a single get obj rados op
OPTION(rgw_relaxed_s3_bucket_names, OPT_BOOL, false) // enable relaxed bucket name rules for US region buckets
+OPTION(rgw_md_log_max_shards, OPT_INT, 64) // max shards for metadata log
OPTION(mutex_perf_counter, OPT_BOOL, false) // enable/disable mutex perf counter
diff --git a/src/rgw/rgw_metadata.cc b/src/rgw/rgw_metadata.cc
index a1fc1512751..ff4f8697db3 100644
--- a/src/rgw/rgw_metadata.cc
+++ b/src/rgw/rgw_metadata.cc
@@ -6,6 +6,26 @@
#include "rgw_rados.h"
+#define META_LOG_OBJ_PREFIX "meta.log."
+
+class RGWMetadataLog {
+ CephContext *cct;
+ RGWRados *store;
+ string prefix;
+
+public:
+ RGWMetadataLog(CephContext *_cct, RGWRados *_store) : cct(_cct), store(_store) {
+ prefix = META_LOG_OBJ_PREFIX;
+ }
+
+ int add_entry(RGWRados *store, string& section, string& key, bufferlist& bl) {
+ string oid;
+
+ store->shard_name(prefix, cct->_conf->rgw_md_log_max_shards, section, key, oid);
+ utime_t now = ceph_clock_now(cct);
+ return store->time_log_add(oid, now, section, key, bl);
+ }
+};
obj_version& RGWMetadataObject::get_version()
{
@@ -56,6 +76,11 @@ public:
static RGWMetadataTopHandler md_top_handler;
+RGWMetadataManager::RGWMetadataManager(CephContext *_cct, RGWRados *_store) : store(_store)
+{
+ md_log = new RGWMetadataLog(_cct, _store);
+}
+
RGWMetadataManager::~RGWMetadataManager()
{
map<string, RGWMetadataHandler *>::iterator iter;
@@ -241,6 +266,20 @@ void RGWMetadataManager::get_sections(list<string>& sections)
int RGWMetadataManager::put_obj(RGWMetadataHandler *handler, string& key, bufferlist& bl, bool exclusive,
RGWObjVersionTracker *objv_tracker, map<string, bufferlist> *pattrs)
{
- return handler->put_obj(store, key, bl, exclusive, objv_tracker, pattrs);
+ bufferlist logbl;
+ string section = handler->get_type();
+ int ret = md_log->add_entry(store, section, key, logbl);
+ if (ret < 0)
+ return ret;
+
+ ret = handler->put_obj(store, key, bl, exclusive, objv_tracker, pattrs);
+ if (ret < 0)
+ return ret;
+
+ ret = md_log->add_entry(store, section, key, logbl);
+ if (ret < 0)
+ return ret;
+
+ return 0;
}
diff --git a/src/rgw/rgw_metadata.h b/src/rgw/rgw_metadata.h
index d432447e43f..f50ab84e1ad 100644
--- a/src/rgw/rgw_metadata.h
+++ b/src/rgw/rgw_metadata.h
@@ -47,16 +47,19 @@ public:
virtual void list_keys_complete(void *handle) = 0;
};
+class RGWMetadataLog;
+
class RGWMetadataManager {
map<string, RGWMetadataHandler *> handlers;
RGWRados *store;
+ RGWMetadataLog *md_log;
void parse_metadata_key(const string& metadata_key, string& type, string& entry);
int find_handler(const string& metadata_key, RGWMetadataHandler **handler, string& entry);
public:
- RGWMetadataManager(RGWRados *_store) : store(_store) {}
+ RGWMetadataManager(CephContext *_cct, RGWRados *_store);
~RGWMetadataManager();
int register_handler(RGWMetadataHandler *handler);
diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc
index 8b3c49fcbbf..9afea27b7d6 100644
--- a/src/rgw/rgw_rados.cc
+++ b/src/rgw/rgw_rados.cc
@@ -17,6 +17,7 @@
#include "cls/rgw/cls_rgw_client.h"
#include "cls/refcount/cls_refcount_client.h"
#include "cls/version/cls_version_client.h"
+#include "cls/log/cls_log_client.h"
#include "rgw_tools.h"
@@ -524,7 +525,7 @@ int RGWRados::init_rados()
if (ret < 0)
return ret;
- meta_mgr = new RGWMetadataManager(this);
+ meta_mgr = new RGWMetadataManager(cct, this);
return ret;
}
@@ -1058,6 +1059,48 @@ next:
return 0;
}
+void RGWRados::shard_name(const string& prefix, unsigned max_shards, string& key, string& name)
+{
+ uint32_t val = ceph_str_hash_linux(key.c_str(), key.size());
+ char buf[16];
+ snprintf(buf, sizeof(buf), "%u", (unsigned)(val % max_shards));
+ name = prefix + buf;
+}
+
+void RGWRados::shard_name(const string& prefix, unsigned max_shards, string& section, string& key, string& name)
+{
+ uint32_t val = ceph_str_hash_linux(key.c_str(), key.size());
+ val ^= ceph_str_hash_linux(section.c_str(), section.size());
+ char buf[16];
+ snprintf(buf, sizeof(buf), "%u", (unsigned)(val % max_shards));
+ name = prefix + buf;
+}
+
+int RGWRados::time_log_add(const string& oid, const utime_t& ut, string& section, string& key, bufferlist& bl)
+{
+ librados::IoCtx io_ctx;
+
+ const char *log_pool = zone.log_pool.name.c_str();
+ int r = rados->ioctx_create(log_pool, io_ctx);
+ if (r == -ENOENT) {
+ rgw_bucket pool(log_pool);
+ r = create_pool(pool);
+ if (r < 0)
+ return r;
+
+ // retry
+ r = rados->ioctx_create(log_pool, io_ctx);
+ }
+ if (r < 0)
+ return r;
+
+ ObjectWriteOperation op;
+ cls_log_add(op, ut, section, key, bl);
+
+ r = io_ctx.operate(oid, &op);
+ return r;
+}
+
int RGWRados::decode_policy(bufferlist& bl, ACLOwner *owner)
{
bufferlist::iterator i = bl.begin();
diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h
index f54138cb64b..60fa4bd7c5a 100644
--- a/src/rgw/rgw_rados.h
+++ b/src/rgw/rgw_rados.h
@@ -974,6 +974,10 @@ public:
string& read_iter, map<rgw_user_bucket, rgw_usage_log_entry>& usage, bool *is_truncated);
int cls_obj_usage_log_trim(string& oid, string& user, uint64_t start_epoch, uint64_t end_epoch);
+ void shard_name(const string& prefix, unsigned max_shards, string& key, string& name);
+ void shard_name(const string& prefix, unsigned max_shards, string& section, string& key, string& name);
+ int time_log_add(const string& oid, const utime_t& ut, string& section, string& key, bufferlist& bl);
+
/// clean up/process any temporary objects older than given date[/time]
int remove_temp_objects(string date, string time);
diff --git a/src/rgw/rgw_tools.cc b/src/rgw/rgw_tools.cc
index 473a8b245c2..3f77c52a0c1 100644
--- a/src/rgw/rgw_tools.cc
+++ b/src/rgw/rgw_tools.cc
@@ -51,7 +51,6 @@ int rgw_get_system_obj(RGWRados *rgwstore, void *ctx, rgw_bucket& bucket, string
return ret;
ret = rgwstore->get_obj(ctx, objv_tracker, &handle, obj, bl, 0, request_len - 1);
-#warning FIXME objv_tracker
rgwstore->finish_get_obj(&handle);
if (ret < 0)
return ret;