]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: metadata set/get infrastructure
authorYehuda Sadeh <yehuda@inktank.com>
Fri, 1 Mar 2013 21:01:18 +0000 (13:01 -0800)
committerYehuda Sadeh <yehuda@inktank.com>
Wed, 8 May 2013 17:55:50 +0000 (10:55 -0700)
Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
src/Makefile.am
src/cls/version/cls_version_types.cc [new file with mode: 0644]
src/cls/version/cls_version_types.h
src/rgw/rgw_admin.cc
src/rgw/rgw_metadata.cc [new file with mode: 0644]
src/rgw/rgw_metadata.h [new file with mode: 0644]
src/rgw/rgw_rados.cc
src/rgw/rgw_rados.h
src/rgw/rgw_user.cc
src/rgw/rgw_user.h

index edf0776a3be70cc397e577040c60ce8e2bbfe4bd..250433fc81f8f7eec364e322290391d760558345 100644 (file)
@@ -393,7 +393,8 @@ librgw_a_SOURCES =  \
        rgw/rgw_multi_del.cc \
        rgw/rgw_env.cc \
        rgw/rgw_cors.cc \
-       rgw/rgw_cors_s3.cc
+       rgw/rgw_cors_s3.cc \
+       rgw/rgw_metadata.cc
 librgw_a_CFLAGS = ${CRYPTO_CFLAGS} ${AM_CFLAGS}
 librgw_a_CXXFLAGS = -Woverloaded-virtual ${AM_CXXFLAGS}
 noinst_LIBRARIES += librgw.a
@@ -577,7 +578,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 =  \
@@ -2029,6 +2031,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 (file)
index 0000000..2ed6973
--- /dev/null
@@ -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);
+}
+
index 759ac25e298a9425acb79100c3c30c3095a0b990..82f37c0008115d1c8d49353d573be3e4b4b47497 100644 (file)
@@ -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)
 
index 9756187e4e794b955fbc48a0715f765d940ad341..76fbe792b3006caeee59c2b441b9c149195a4b6a 100644 (file)
@@ -84,6 +84,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";
@@ -185,6 +186,7 @@ enum {
   OPT_ZONE_LIST,
   OPT_CAPS_ADD,
   OPT_CAPS_RM,
+  OPT_METADATA_GET,
 };
 
 static int get_cmd(const char *cmd, const char *prev_cmd, bool *need_more)
@@ -207,7 +209,11 @@ static int get_cmd(const char *cmd, const char *prev_cmd, bool *need_more)
       strcmp(cmd, "regions") == 0 ||
       strcmp(cmd, "region-map") == 0 ||
       strcmp(cmd, "regionmap") == 0 ||
-      strcmp(cmd, "zone") == 0) {
+      strcmp(cmd, "zone") == 0 ||
+      strcmp(cmd, "temp") == 0 ||
+      strcmp(cmd, "usage") == 0 ||
+      strcmp(cmd, "user") == 0 ||
+      strcmp(cmd, "metadata") == 0) {
     *need_more = true;
     return 0;
   }
@@ -331,6 +337,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;
@@ -529,9 +538,10 @@ int main(int argc, char **argv)
   map<string, bool> categories;
   string caps;
   int check_objects = false;
-  std::string infile;
   RGWUserAdminOpState user_op;
   RGWBucketAdminOpState bucket_op;
+  string infile;
+  string metadata_key;
 
   std::string val;
   std::ostringstream errs;
@@ -633,6 +643,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;
     }
@@ -692,6 +704,8 @@ int main(int argc, char **argv)
     return 5; //EIO
   }
 
+  rgw_user_init(store->meta_mgr);
+
   StoreDestructor store_destructor(store);
 
   if (raw_storage_op) {
@@ -1436,5 +1450,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 (file)
index 0000000..dbc1f26
--- /dev/null
@@ -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 (file)
index 0000000..4751806
--- /dev/null
@@ -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
index e83bc18c82f217efa9a5d70607936ca638ab9edd..5850c7276db1ec8edb57963c0a45edf5a6f37bfd 100644 (file)
@@ -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;
index 7798d97505dfdb0f6b9b5f823deac86700ae459c..a792cb4d788e75fa66b8f3f3443d41eab7560760 100644 (file)
@@ -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;
@@ -528,7 +529,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;
@@ -545,6 +546,8 @@ public:
   RGWRegion region;
   RGWZoneParams zone;
 
+  RGWMetadataManager *meta_mgr;
+
   virtual ~RGWRados() {
     if (rados) {
       rados->shutdown();
index fa19351882a06cd30b8b1ec8a59ab997393fc922..6973586a60d15c583c9b15edb7881eaad5967f19 100644 (file)
@@ -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"
 
@@ -148,15 +150,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;
 
@@ -178,6 +180,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)
@@ -2184,6 +2191,7 @@ int RGWUserAdminOp_Caps::add(RGWRados *store, RGWUserAdminOpState& op_state,
   return 0;
 }
 
+
 int RGWUserAdminOp_Caps::remove(RGWRados *store, RGWUserAdminOpState& op_state,
                   RGWFormatterFlusher& flusher)
 {
@@ -2210,3 +2218,34 @@ int RGWUserAdminOp_Caps::remove(RGWRados *store, RGWUserAdminOpState& op_state,
 
   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);
+}
index 3b277000b57561f98df28be56d6fc31bab79f117..14a7c1d8cbdad629aadfed54f201858ca7619cd2 100644 (file)
@@ -616,4 +616,8 @@ public:
                  RGWUserAdminOpState& op_state, RGWFormatterFlusher& flusher);
 };
 
+class RGWMetadataManager;
+
+extern void rgw_user_init(RGWMetadataManager *mm);
+
 #endif