From cb6d4de4940cdcfa0dc270ffd0c3c21b9f9aea0a Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Tue, 19 Mar 2013 14:52:47 -0700 Subject: [PATCH] rgw: log user operations Signed-off-by: Yehuda Sadeh --- src/Makefile.am | 2 +- src/cls/log/cls_log_client.h | 1 + src/common/config_opts.h | 1 + src/rgw/rgw_metadata.cc | 41 +++++++++++++++++++++++++++++++- src/rgw/rgw_metadata.h | 5 +++- src/rgw/rgw_rados.cc | 45 +++++++++++++++++++++++++++++++++++- src/rgw/rgw_rados.h | 4 ++++ src/rgw/rgw_tools.cc | 1 - 8 files changed, 95 insertions(+), 5 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 4420b18af512a..933afe6df64e7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -400,7 +400,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 cf1a541e495b2..79cfc459c513e 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 1607c33066fe6..5160a61140224 100644 --- a/src/common/config_opts.h +++ b/src/common/config_opts.h @@ -601,6 +601,7 @@ OPTION(rgw_get_obj_window_size, OPT_INT, 16 << 20) // window size in bytes for s 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_list_buckets_max_chunk, OPT_INT, 1000) // max buckets to retrieve in a single op when listing user 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 a1fc151275193..ff4f8697db381 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::iterator iter; @@ -241,6 +266,20 @@ void RGWMetadataManager::get_sections(list& sections) int RGWMetadataManager::put_obj(RGWMetadataHandler *handler, string& key, bufferlist& bl, bool exclusive, RGWObjVersionTracker *objv_tracker, map *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 d432447e43fa6..f50ab84e1ad6e 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 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 d455e5635d98d..5ce8a2606638a 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 47c42b548ab03..28cfd5bd7ca05 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -976,6 +976,10 @@ public: string& read_iter, map& 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 473a8b245c2fb..3f77c52a0c114 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; -- 2.39.5