summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYehuda Sadeh <yehuda@inktank.com>2013-03-01 13:01:18 -0800
committerYehuda Sadeh <yehuda@inktank.com>2013-03-22 11:28:02 -0700
commit39c213384b438d61884cf452f307c7fa9c4aea85 (patch)
treeba50dc390ab3d3c762f8ef327cb58c835458bc2a
parent590b4d2e8ca12df07969e26dd43cd9dd188367db (diff)
downloadceph-39c213384b438d61884cf452f307c7fa9c4aea85.tar.gz
rgw: metadata set/get infrastructure
Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
-rw-r--r--src/Makefile.am7
-rw-r--r--src/cls/version/cls_version_types.cc11
-rw-r--r--src/cls/version/cls_version_types.h2
-rw-r--r--src/rgw/rgw_admin.cc23
-rw-r--r--src/rgw/rgw_metadata.cc81
-rw-r--r--src/rgw/rgw_metadata.h40
-rw-r--r--src/rgw/rgw_rados.cc4
-rw-r--r--src/rgw/rgw_rados.h5
-rw-r--r--src/rgw/rgw_user.cc45
-rw-r--r--src/rgw/rgw_user.h7
10 files changed, 218 insertions, 7 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index afd933e0ceb..fd86e9a91fd 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -370,7 +370,8 @@ librgw_a_SOURCES = \
rgw/rgw_policy_s3.cc \
rgw/rgw_gc.cc \
rgw/rgw_multi_del.cc \
- rgw/rgw_env.cc
+ rgw/rgw_env.cc \
+ rgw/rgw_metadata.cc
librgw_a_CFLAGS = ${CRYPTO_CFLAGS} ${AM_CFLAGS}
librgw_a_CXXFLAGS = -Woverloaded-virtual ${AM_CXXFLAGS}
noinst_LIBRARIES += librgw.a
@@ -551,7 +552,8 @@ libcls_refcount_client_a_SOURCES = \
noinst_LIBRARIES += libcls_refcount_client.a
libcls_version_client_a_SOURCES = \
- cls/version/cls_version_client.cc
+ cls/version/cls_version_client.cc \
+ cls/version/cls_version_types.cc
noinst_LIBRARIES += libcls_version_client.a
libcls_rgw_client_a_SOURCES = \
@@ -1963,6 +1965,7 @@ noinst_HEADERS = \
rgw/rgw_multi.h\
rgw/rgw_policy_s3.h\
rgw/rgw_gc.h\
+ rgw/rgw_metadata.h\
rgw/rgw_multi_del.h\
rgw/rgw_op.h\
rgw/rgw_http_client.h\
diff --git a/src/cls/version/cls_version_types.cc b/src/cls/version/cls_version_types.cc
new file mode 100644
index 00000000000..2ed69733653
--- /dev/null
+++ b/src/cls/version/cls_version_types.cc
@@ -0,0 +1,11 @@
+
+#include "cls/version/cls_version_types.h"
+#include "common/Formatter.h"
+
+
+void obj_version::dump(Formatter *f) const
+{
+ f->dump_int("ver", ver);
+ f->dump_string("tag", tag);
+}
+
diff --git a/src/cls/version/cls_version_types.h b/src/cls/version/cls_version_types.h
index 759ac25e298..82f37c00081 100644
--- a/src/cls/version/cls_version_types.h
+++ b/src/cls/version/cls_version_types.h
@@ -37,6 +37,8 @@ struct obj_version {
return (ver == v->ver &&
tag.compare(v->tag) == 0);
}
+
+ void dump(Formatter *f) const;
};
WRITE_CLASS_ENCODER(obj_version)
diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc
index 2d2f072582f..89ffe021a9d 100644
--- a/src/rgw/rgw_admin.cc
+++ b/src/rgw/rgw_admin.cc
@@ -83,6 +83,7 @@ void _usage()
cerr << " specified date (and optional time)\n";
cerr << " gc list dump expired garbage collection objects\n";
cerr << " gc process manually process garbage\n";
+ cerr << " metadata get get metadata info\n";
cerr << "options:\n";
cerr << " --uid=<id> user id\n";
cerr << " --subuser=<name> subuser name\n";
@@ -184,6 +185,7 @@ enum {
OPT_ZONE_LIST,
OPT_CAPS_ADD,
OPT_CAPS_RM,
+ OPT_METADATA_GET,
};
static uint32_t str_to_perm(const char *str)
@@ -224,7 +226,8 @@ static int get_cmd(const char *cmd, const char *prev_cmd, bool *need_more)
strcmp(cmd, "zone") == 0 ||
strcmp(cmd, "temp") == 0 ||
strcmp(cmd, "usage") == 0 ||
- strcmp(cmd, "user") == 0) {
+ strcmp(cmd, "user") == 0 ||
+ strcmp(cmd, "metadata") == 0) {
*need_more = true;
return 0;
}
@@ -348,6 +351,9 @@ static int get_cmd(const char *cmd, const char *prev_cmd, bool *need_more)
return OPT_GC_LIST;
if (strcmp(cmd, "process") == 0)
return OPT_GC_PROCESS;
+ } else if (strcmp(prev_cmd, "metadata") == 0) {
+ if (strcmp(cmd, "get") == 0)
+ return OPT_METADATA_GET;
}
return -EINVAL;
@@ -859,6 +865,7 @@ int main(int argc, char **argv)
string caps;
int check_objects = false;
string infile;
+ string metadata_key;
std::string val;
std::ostringstream errs;
@@ -960,6 +967,8 @@ int main(int argc, char **argv)
caps = val;
} else if (ceph_argparse_witharg(args, i, &val, "-i", "--infile", (char*)NULL)) {
infile = val;
+ } else if (ceph_argparse_witharg(args, i, &val, "--metadata-key", (char*)NULL)) {
+ metadata_key = val;
} else {
++i;
}
@@ -1045,6 +1054,8 @@ int main(int argc, char **argv)
return 5; //EIO
}
+ rgw_user_init(store->meta_mgr);
+
StoreDestructor store_destructor(store);
if (raw_storage_op) {
@@ -2128,5 +2139,15 @@ next:
check_bad_user_bucket_mapping(store, user_id, fix);
}
+ if (opt_cmd == OPT_METADATA_GET) {
+ int ret = store->meta_mgr->get(metadata_key, formatter);
+ if (ret < 0) {
+ cerr << "ERROR: can't get key: " << cpp_strerror(-ret) << std::endl;
+ return -ret;
+ }
+
+ formatter->flush(cout);
+ }
+
return 0;
}
diff --git a/src/rgw/rgw_metadata.cc b/src/rgw/rgw_metadata.cc
new file mode 100644
index 00000000000..dbc1f269a13
--- /dev/null
+++ b/src/rgw/rgw_metadata.cc
@@ -0,0 +1,81 @@
+
+
+#include "rgw_metadata.h"
+
+
+
+RGWMetadataManager::~RGWMetadataManager()
+{
+ map<string, RGWMetadataHandler *>::iterator iter;
+
+ for (iter = handlers.begin(); iter != handlers.end(); ++iter) {
+ delete iter->second;
+ }
+
+ handlers.clear();
+}
+
+int RGWMetadataManager::register_handler(RGWMetadataHandler *handler)
+{
+ string type = handler->get_type();
+
+ if (handlers.find(type) != handlers.end())
+ return -EINVAL;
+
+ handlers[type] = handler;
+
+ return 0;
+}
+
+void RGWMetadataManager::parse_metadata_key(const string& metadata_key, string& type, string& entry)
+{
+ int pos = metadata_key.find(':');
+ if (pos < 0) {
+ type = metadata_key;
+ }
+
+ type = metadata_key.substr(0, pos);
+ entry = metadata_key.substr(pos + 1);
+}
+
+int RGWMetadataManager::find_handler(const string& metadata_key, RGWMetadataHandler **handler, string& entry)
+{
+ string type;
+
+ parse_metadata_key(metadata_key, type, entry);
+
+ map<string, RGWMetadataHandler *>::iterator iter = handlers.find(type);
+ if (iter == handlers.end())
+ return -ENOENT;
+
+ *handler = iter->second;
+
+ return 0;
+
+}
+
+int RGWMetadataManager::get(string& metadata_key, Formatter *f)
+{
+ RGWMetadataHandler *handler;
+ string entry;
+
+ int ret = find_handler(metadata_key, &handler, entry);
+ if (ret < 0)
+ return ret;
+
+ return handler->get(store, metadata_key, entry, f);
+}
+
+int RGWMetadataManager::update(string& metadata_key, bufferlist& bl)
+{
+ RGWMetadataHandler *handler;
+ string entry;
+
+ int ret = find_handler(metadata_key, &handler, entry);
+ if (ret < 0)
+ return ret;
+
+ return handler->update(store, entry, bl);
+}
+
+
diff --git a/src/rgw/rgw_metadata.h b/src/rgw/rgw_metadata.h
new file mode 100644
index 00000000000..47518065fff
--- /dev/null
+++ b/src/rgw/rgw_metadata.h
@@ -0,0 +1,40 @@
+#ifndef CEPH_RGW_METADATA_H
+#define CEPH_RGW_METADATA_H
+
+#include <string>
+
+#include "include/types.h"
+#include "rgw_common.h"
+
+class RGWRados;
+
+
+class RGWMetadataHandler {
+public:
+ virtual ~RGWMetadataHandler() {}
+ virtual string get_type() = 0;
+
+ virtual int get(RGWRados *store, string& key, string& entry, Formatter *f) = 0;
+ virtual int update(RGWRados *store, string& entry, bufferlist& bl) = 0;
+};
+
+
+class RGWMetadataManager {
+ map<string, RGWMetadataHandler *> handlers;
+ RGWRados *store;
+
+ 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();
+
+ int register_handler(RGWMetadataHandler *handler);
+
+ int get(string& metadata_key, Formatter *f);
+ int update(string& metadata_key, bufferlist& bl);
+};
+
+#endif
diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc
index 455e37065ff..767558c9440 100644
--- a/src/rgw/rgw_rados.cc
+++ b/src/rgw/rgw_rados.cc
@@ -11,6 +11,7 @@
#include "rgw_rados.h"
#include "rgw_cache.h"
#include "rgw_acl.h"
+#include "rgw_metadata.h"
#include "cls/rgw/cls_rgw_types.h"
#include "cls/rgw/cls_rgw_client.h"
@@ -467,6 +468,7 @@ void RGWRadosCtx::set_prefetch_data(rgw_obj& obj) {
void RGWRados::finalize()
{
+ delete meta_mgr;
if (use_gc_thread) {
gc->stop_processor();
delete gc;
@@ -540,6 +542,8 @@ int RGWRados::initialize()
{
int ret;
+ meta_mgr = new RGWMetadataManager(this);
+
ret = init_rados();
if (ret < 0)
return ret;
diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h
index 203031de27b..2da6294e479 100644
--- a/src/rgw/rgw_rados.h
+++ b/src/rgw/rgw_rados.h
@@ -8,6 +8,7 @@
#include "cls/rgw/cls_rgw_types.h"
#include "cls/version/cls_version_types.h"
#include "rgw_log.h"
+#include "rgw_metadata.h"
class RGWWatcher;
class SafeTimer;
@@ -527,7 +528,7 @@ public:
num_watchers(0), watchers(NULL), watch_handles(NULL),
bucket_id_lock("rados_bucket_id"), max_bucket_id(0),
cct(NULL), rados(NULL),
- pools_initialized(false) {}
+ pools_initialized(false), meta_mgr(NULL) {}
void set_context(CephContext *_cct) {
cct = _cct;
@@ -544,6 +545,8 @@ public:
RGWRegion region;
RGWZoneParams zone;
+ RGWMetadataManager *meta_mgr;
+
virtual ~RGWRados() {
if (rados) {
rados->shutdown();
diff --git a/src/rgw/rgw_user.cc b/src/rgw/rgw_user.cc
index 79adde7dfab..e9da226bd7c 100644
--- a/src/rgw/rgw_user.cc
+++ b/src/rgw/rgw_user.cc
@@ -4,6 +4,8 @@
#include <map>
#include "common/errno.h"
+#include "common/Formatter.h"
+#include "common/ceph_json.h"
#include "rgw_rados.h"
#include "rgw_acl.h"
@@ -142,15 +144,15 @@ int rgw_get_user_info_from_index(RGWRados *store, string& key, rgw_bucket& bucke
}
/**
- * Given an email, finds the user info associated with it.
+ * Given a uid, finds the user info associated with it.
* returns: 0 on success, -ERR# on failure (including nonexistence)
*/
-int rgw_get_user_info_by_uid(RGWRados *store, string& uid, RGWUserInfo& info)
+static int rgw_read_uid_info(RGWRados *store, string& uid, RGWUserInfo& info, obj_version *objv)
{
bufferlist bl;
RGWUID user_id;
- int ret = rgw_get_system_obj(store, NULL, store->zone.user_uid_pool, uid, bl, NULL);
+ int ret = rgw_get_system_obj(store, NULL, store->zone.user_uid_pool, uid, bl, objv);
if (ret < 0)
return ret;
@@ -172,6 +174,11 @@ int rgw_get_user_info_by_uid(RGWRados *store, string& uid, RGWUserInfo& info)
return 0;
}
+int rgw_get_user_info_by_uid(RGWRados *store, string& uid, RGWUserInfo& info)
+{
+ return rgw_read_uid_info(store, uid, info, NULL);
+}
+
/**
* Given an email, finds the user info associated with it.
* returns: 0 on success, -ERR# on failure (including nonexistence)
@@ -469,3 +476,35 @@ int rgw_delete_user(RGWRados *store, RGWUserInfo& info) {
return 0;
}
+
+class RGWUserMetadataHandler : public RGWMetadataHandler {
+public:
+ string get_type() { return "user"; }
+ int get(RGWRados *store, string& key, string& entry, Formatter *f) {
+ RGWUserInfo info;
+
+ obj_version objv;
+
+ int ret = rgw_read_uid_info(store, entry, info, &objv);
+ if (ret < 0)
+ return ret;
+
+ f->open_object_section("metadata_info");
+ encode_json("key", key, f);
+ encode_json("ver", objv, f);
+ encode_json("data", info, f);
+ f->close_section();
+ f->flush(cout);
+ return 0;
+ }
+
+ int update(RGWRados *store, string& metadata_key, bufferlist& bl) {
+ return 0;
+ }
+};
+
+
+void rgw_user_init(RGWMetadataManager *mm)
+{
+ mm->register_handler(new RGWUserMetadataHandler);
+}
diff --git a/src/rgw/rgw_user.h b/src/rgw/rgw_user.h
index d8ae3c3f2ec..e70f9535731 100644
--- a/src/rgw/rgw_user.h
+++ b/src/rgw/rgw_user.h
@@ -144,4 +144,11 @@ extern int rgw_remove_key_index(RGWRados *store, RGWAccessKey& access_key);
extern int rgw_remove_uid_index(RGWRados *store, string& uid);
extern int rgw_remove_email_index(RGWRados *store, string& email);
extern int rgw_remove_swift_name_index(RGWRados *store, string& swift_name);
+
+
+class RGWMetadataManager;
+
+extern void rgw_user_init(RGWMetadataManager *mm);
+
+
#endif