]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: create meta handler for bucket instance
authorYehuda Sadeh <yehuda@inktank.com>
Mon, 24 Jun 2013 04:00:00 +0000 (21:00 -0700)
committerYehuda Sadeh <yehuda@inktank.com>
Mon, 24 Jun 2013 04:00:00 +0000 (21:00 -0700)
Create utility functions for reading writing bucket entry
point and bucket instance. Add a separate meta handler for
bucket instance.

Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
src/rgw/rgw_bucket.cc
src/rgw/rgw_common.h
src/rgw/rgw_json_enc.cc
src/rgw/rgw_rados.cc
src/rgw/rgw_rados.h

index fb92aa311d8cac554d063f9623b34ae38aaaa6a4..3bce4cd4c0b9bdb01a7584f00923af5e381053f7 100644 (file)
@@ -24,6 +24,7 @@
 using namespace std;
 
 static RGWMetadataHandler *bucket_meta_handler = NULL;
+static RGWMetadataHandler *bucket_instance_meta_handler = NULL;
 
 // define as static when RGWBucket implementation compete
 void rgw_get_buckets_obj(string& user_id, string& buckets_obj_id)
@@ -1290,10 +1291,23 @@ struct RGWBucketCompleteInfo {
   }
 };
 
-class RGWBucketMetadataObject : public RGWMetadataObject {
+class RGWBucketEntryMetadataObject : public RGWMetadataObject {
+  RGWBucketEntryPoint ep;
+public:
+  RGWBucketEntryMetadataObject(RGWBucketEntryPoint& _ep, obj_version& v, time_t m) : ep(_ep) {
+    objv = v;
+    mtime = m;
+  }
+
+  void dump(Formatter *f) const {
+    ep.dump(f);
+  }
+};
+
+class RGWBucketInstanceMetadataObject : public RGWMetadataObject {
   RGWBucketCompleteInfo info;
 public:
-  RGWBucketMetadataObject(RGWBucketCompleteInfo& i, obj_version& v, time_t m) : info(i) {
+  RGWBucketInstanceMetadataObject(RGWBucketCompleteInfo& i, obj_version& v, time_t m) : info(i) {
     objv = v;
     mtime = m;
   }
@@ -1320,16 +1334,141 @@ class RGWBucketMetadataHandler : public RGWMetadataHandler {
 public:
   string get_type() { return "bucket"; }
 
+  int get(RGWRados *store, string& entry, RGWMetadataObject **obj) {
+    RGWObjVersionTracker ot;
+    RGWBucketEntryPoint be;
+
+    time_t mtime;
+
+    int ret = store->get_bucket_entrypoint_info(NULL, entry, be, &ot, &mtime);
+    if (ret < 0)
+      return ret;
+
+    RGWBucketEntryMetadataObject *mdo = new RGWBucketEntryMetadataObject(be, ot.read_version, mtime);
+
+    *obj = mdo;
+
+    return 0;
+  }
+
+  int put(RGWRados *store, string& entry, RGWObjVersionTracker& objv_tracker, time_t mtime, JSONObj *obj) {
+    RGWBucketEntryPoint be, old_be;
+    decode_json_obj(be, obj);
+
+    time_t orig_mtime;
+
+    int ret = store->get_bucket_entrypoint_info(NULL, entry, be, &objv_tracker, &orig_mtime);
+    if (ret < 0 && ret != -ENOENT)
+      return ret;
+
+    ret = store->put_bucket_entrypoint_info(entry, old_be, false, mtime);
+    if (ret < 0)
+      return ret;
+
+#warning need to link bucket here
+#if 0
+    ret = rgw_add_bucket(store, bci.info.owner, bci.info.bucket, bci.info.creation_time);
+    if (ret < 0)
+      return ret;
+#endif
+
+    return 0;
+  }
+
+  struct list_keys_info {
+    RGWRados *store;
+    RGWListRawObjsCtx ctx;
+  };
+
+  int remove(RGWRados *store, string& entry, RGWObjVersionTracker& objv_tracker) {
+    rgw_bucket bucket;
+    int r = init_bucket(store, entry, bucket, &objv_tracker);
+    if (r < 0) {
+      cerr << "could not init bucket=" << entry << std::endl;
+      return r;
+    }
+
+    return store->delete_bucket(bucket, objv_tracker);
+  }
+
+  void get_pool_and_oid(RGWRados *store, string& key, rgw_bucket& bucket, string& oid) {
+    oid = key;
+    bucket = store->zone.domain_root;
+  }
+
+  int list_keys_init(RGWRados *store, void **phandle)
+  {
+    list_keys_info *info = new list_keys_info;
+
+    info->store = store;
+
+    *phandle = (void *)info;
+
+    return 0;
+  }
+
+  int list_keys_next(void *handle, int max, list<string>& keys, bool *truncated) {
+    list_keys_info *info = (list_keys_info *)handle;
+
+    string no_filter;
+
+    keys.clear();
+
+    RGWRados *store = info->store;
+
+    list<string> unfiltered_keys;
+
+    int ret = store->list_raw_objects(store->zone.domain_root, no_filter,
+                                      max, info->ctx, unfiltered_keys, truncated);
+    if (ret < 0)
+      return ret;
+
+    // now filter out the system entries
+    list<string>::iterator iter;
+    for (iter = unfiltered_keys.begin(); iter != unfiltered_keys.end(); ++iter) {
+      string& k = *iter;
+
+      if (k[0] != '.') {
+        keys.push_back(k);
+      }
+    }
+
+    return 0;
+  }
+
+  void list_keys_complete(void *handle) {
+    list_keys_info *info = (list_keys_info *)handle;
+    delete info;
+  }
+};
+
+class RGWBucketInstanceMetadataHandler : public RGWMetadataHandler {
+
+  int init_bucket(RGWRados *store, string& bucket_name, rgw_bucket& bucket, RGWObjVersionTracker *objv_tracker) {
+    RGWBucketInfo bucket_info;
+    int r = store->get_bucket_info(NULL, bucket_name, bucket_info, NULL);
+    if (r < 0) {
+      cerr << "could not get bucket info for bucket=" << bucket_name << std::endl;
+      return r;
+    }
+    bucket = bucket_info.bucket;
+
+    return 0;
+  }
+
+public:
+  string get_type() { return "bucket.instance"; }
+
   int get(RGWRados *store, string& entry, RGWMetadataObject **obj) {
     RGWBucketCompleteInfo bci;
 
     time_t mtime;
 
-    int ret = store->get_bucket_info(NULL, entry, bci.info, &mtime, &bci.attrs);
+    int ret = store->get_bucket_instance_info(NULL, entry, bci.info, &mtime, &bci.attrs);
     if (ret < 0)
       return ret;
 
-    RGWBucketMetadataObject *mdo = new RGWBucketMetadataObject(bci, bci.info.objv_tracker.read_version, mtime);
+    RGWBucketInstanceMetadataObject *mdo = new RGWBucketInstanceMetadataObject(bci, bci.info.objv_tracker.read_version, mtime);
 
     *obj = mdo;
 
@@ -1344,7 +1483,7 @@ public:
 
     old_bci.info.objv_tracker = objv_tracker;
 
-    int ret = store->get_bucket_info(NULL, entry, old_bci.info, &orig_mtime, &old_bci.attrs);
+    int ret = store->get_bucket_instance_info(NULL, entry, old_bci.info, &orig_mtime, &old_bci.attrs);
     if (ret < 0 && ret != -ENOENT)
       return ret;
 
@@ -1365,8 +1504,7 @@ public:
       bci.info.objv_tracker = old_bci.info.objv_tracker;
     }
 
-#warning need to take care of different routes here
-    ret = store->put_bucket_info(entry, bci.info, false, mtime, &bci.attrs, false);
+    ret = store->put_bucket_instance_info(entry, bci.info, false, mtime, &bci.attrs);
     if (ret < 0)
       return ret;
 
@@ -1376,10 +1514,6 @@ public:
     if (ret < 0)
       return ret;
 
-    ret = rgw_add_bucket(store, bci.info.owner, bci.info.bucket, bci.info.creation_time);
-    if (ret < 0)
-      return ret;
-
     return 0;
   }
 
@@ -1454,4 +1588,6 @@ void rgw_bucket_init(RGWMetadataManager *mm)
 {
   bucket_meta_handler = new RGWBucketMetadataHandler;
   mm->register_handler(bucket_meta_handler);
+  bucket_instance_meta_handler = new RGWBucketInstanceMetadataHandler;
+  mm->register_handler(bucket_instance_meta_handler);
 }
index 42aeecfbe4b7e532849f0c24b91ed53b72823a2e..af70846f87c3c7205e8d459eb212f928924dd26e 100644 (file)
@@ -707,6 +707,9 @@ struct RGWBucketEntryPoint
     ::decode(bucket, bl);
     DECODE_FINISH(bl);
   }
+
+  void dump(Formatter *f) const;
+  void decode_json(JSONObj *obj);
 };
 WRITE_CLASS_ENCODER(RGWBucketEntryPoint)
 
index bfc09bd6bd6ece11d9fcedd30a83208aa973e419..8ab6ff530e65c19be689701089157d010453c4be 100644 (file)
@@ -436,6 +436,23 @@ void rgw_bucket::decode_json(JSONObj *obj) {
   JSONDecoder::decode_json("bucket_id", bucket_id, obj);
 }
 
+void RGWBucketEntryPoint::dump(Formatter *f) const
+{
+  encode_json("bucket", bucket, f);
+  encode_json("has_bucket_info", has_bucket_info, f);
+  if (has_bucket_info) {
+    encode_json("old_bucket_info", old_bucket_info, f);
+  }
+}
+
+void RGWBucketEntryPoint::decode_json(JSONObj *obj) {
+  JSONDecoder::decode_json("bucket", bucket, obj);
+  JSONDecoder::decode_json("has_bucket_info", has_bucket_info, obj);
+  if (has_bucket_info) {
+    JSONDecoder::decode_json("old_bucket_info", old_bucket_info, obj);
+  }
+}
+
 void RGWBucketInfo::dump(Formatter *f) const
 {
   encode_json("bucket", bucket, f);
index bf1e16d32c7a52391e5cbac877a60b830363cf25..2e490dea13ced8b84abd43e28274f2793e3292b8 100644 (file)
@@ -4464,19 +4464,53 @@ void RGWRados::get_bucket_meta_oid(rgw_bucket& bucket, string& oid)
   oid = ".bucket.meta." + bucket.bucket_id;
 }
 
-int RGWRados::get_bucket_info(void *ctx, string& bucket_name, RGWBucketInfo& info,
-                              time_t *pmtime, map<string, bufferlist> *pattrs)
+int RGWRados::get_bucket_instance_info(void *ctx, string& name, RGWBucketInfo& info,
+                                       time_t *pmtime, map<string, bufferlist> *pattrs)
+{
+  /* entry in the format <bucket>/<bucket_id> */
+  int pos = name.find('/');
+  if (pos < 0) {
+    return -EINVAL;
+  }
+  string oid = ".bucket.meta." + name.substr(pos + 1);
+
+  return get_bucket_instance_from_oid(ctx, oid, info, pmtime, pattrs);
+}
+
+int RGWRados::get_bucket_instance_from_oid(void *ctx, string& oid, RGWBucketInfo& info,
+                                           time_t *pmtime, map<string, bufferlist> *pattrs)
+{
+  ldout(cct, 20) << "reading from " << zone.domain_root << ":" << oid << dendl;
+
+  bufferlist epbl;
+
+  int ret = rgw_get_system_obj(this, ctx, zone.domain_root, oid, epbl, &info.objv_tracker, pmtime, pattrs);
+  if (ret < 0) {
+    return ret;
+  }
+
+  bufferlist::iterator iter = epbl.begin();
+  try {
+    ::decode(info, iter);
+  } catch (buffer::error& err) {
+    ldout(cct, 0) << "ERROR: could not decode buffer info, caught buffer::error" << dendl;
+    return -EIO;
+  }
+  return 0;
+}
+
+int RGWRados::get_bucket_entrypoint_info(void *ctx, string& bucket_name,
+                                         RGWBucketEntryPoint& entry_point,
+                                         RGWObjVersionTracker *objv_tracker,
+                                         time_t *pmtime)
 {
   bufferlist bl;
 
-  RGWObjVersionTracker ot;
-  int ret = rgw_get_system_obj(this, ctx, zone.domain_root, bucket_name, bl, &ot, pmtime, pattrs);
+  int ret = rgw_get_system_obj(this, ctx, zone.domain_root, bucket_name, bl, objv_tracker, pmtime, NULL);
   if (ret < 0) {
-    info.bucket.name = bucket_name; /* only init this field */
     return ret;
   }
 
-  RGWBucketEntryPoint entry_point;
   bufferlist::iterator iter = bl.begin();
   try {
     ::decode(entry_point, iter);
@@ -4484,6 +4518,21 @@ int RGWRados::get_bucket_info(void *ctx, string& bucket_name, RGWBucketInfo& inf
     ldout(cct, 0) << "ERROR: could not decode buffer info, caught buffer::error" << dendl;
     return -EIO;
   }
+  return 0;
+}
+
+int RGWRados::get_bucket_info(void *ctx, string& bucket_name, RGWBucketInfo& info,
+                              time_t *pmtime, map<string, bufferlist> *pattrs)
+{
+  bufferlist bl;
+
+  RGWBucketEntryPoint entry_point;
+  time_t ep_mtime;
+  int ret = get_bucket_entrypoint_info(ctx, bucket_name, entry_point, NULL, &ep_mtime);
+  if (ret < 0) {
+    info.bucket.name = bucket_name; /* only init this field */
+    return ret;
+  }
 
   if (entry_point.has_bucket_info) {
     info = entry_point.old_bucket_info;
@@ -4501,40 +4550,44 @@ int RGWRados::get_bucket_info(void *ctx, string& bucket_name, RGWBucketInfo& inf
   string oid;
   get_bucket_meta_oid(entry_point.bucket, oid);
 
-  ldout(cct, 20) << "reading from " << zone.domain_root << ":" << oid << dendl;
-
-  bufferlist epbl;
-
-  ret = rgw_get_system_obj(this, ctx, zone.domain_root, oid, epbl, &info.objv_tracker, pmtime, pattrs);
+  ret = get_bucket_instance_from_oid(ctx, oid, info, pmtime, pattrs);
   if (ret < 0) {
-    info.bucket.name = bucket_name; /* only init this field */
+    info.bucket.name = bucket_name;
     return ret;
   }
-
-  iter = epbl.begin();
-  try {
-    ::decode(info, iter);
-  } catch (buffer::error& err) {
-    ldout(cct, 0) << "ERROR: could not decode buffer info, caught buffer::error" << dendl;
-    return -EIO;
-  }
   return 0;
 }
 
-int RGWRados::put_bucket_info(string& bucket_name, RGWBucketInfo& info, bool exclusive,
-                              time_t mtime, map<string, bufferlist> *pattrs, bool create_entry_point)
+int RGWRados::put_bucket_entrypoint_info(string& bucket_name, RGWBucketEntryPoint& entry_point,
+                                         bool exclusive, time_t mtime)
 {
-  bufferlist bl;
-
-  bool create_head = !info.has_instance_obj || create_entry_point;
+  bufferlist epbl;
+  ::encode(entry_point, epbl);
+  RGWObjVersionTracker ot;
+  return rgw_bucket_store_info(this, bucket_name, epbl, exclusive, NULL, &ot, mtime);
+}
 
+int RGWRados::put_bucket_instance_info(string& bucket_name, RGWBucketInfo& info, bool exclusive,
+                              time_t mtime, map<string, bufferlist> *pattrs)
+{
   info.has_instance_obj = true;
+  bufferlist bl;
 
   ::encode(info, bl);
 
   string oid;
   get_bucket_meta_oid(info.bucket, oid);
-  int ret = rgw_bucket_store_info(this, oid, bl, exclusive, pattrs, &info.objv_tracker, mtime);
+  return rgw_bucket_store_info(this, oid, bl, exclusive, pattrs, &info.objv_tracker, mtime);
+}
+
+int RGWRados::put_bucket_info(string& bucket_name, RGWBucketInfo& info, bool exclusive,
+                              time_t mtime, map<string, bufferlist> *pattrs, bool create_entry_point)
+{
+  bufferlist bl;
+
+  bool create_head = !info.has_instance_obj || create_entry_point;
+
+  int ret = put_bucket_instance_info(bucket_name, info, exclusive, mtime, pattrs);
   if (ret < 0) {
     return ret;
   }
@@ -4544,12 +4597,10 @@ int RGWRados::put_bucket_info(string& bucket_name, RGWBucketInfo& info, bool exc
 
   RGWBucketEntryPoint entry_point;
   entry_point.bucket = info.bucket;
-  bufferlist epbl;
-  ::encode(entry_point, epbl);
-  RGWObjVersionTracker ot;
-  ret = rgw_bucket_store_info(this, info.bucket.name, epbl, exclusive, pattrs, &ot, mtime);
-
+  ret = put_bucket_entrypoint_info(info.bucket.name, entry_point, exclusive, mtime); 
   if (exclusive && ret == -EEXIST) {
+    string oid;
+    get_bucket_meta_oid(info.bucket, oid);
     rgw_obj obj(zone.domain_root, oid);
     int r = delete_obj(NULL, obj);
     if (r < 0) {
index 725830085871085133f319df301d5d787de9f71a..990bb1372ceac2ff951028613ed32a54db97b281 100644 (file)
@@ -1268,6 +1268,13 @@ public:
   int decode_policy(bufferlist& bl, ACLOwner *owner);
   int get_bucket_stats(rgw_bucket& bucket, uint64_t *bucket_ver, uint64_t *master_ver, map<RGWObjCategory, RGWBucketStats>& stats);
   void get_bucket_meta_oid(rgw_bucket& bucket, string& oid);
+
+  int put_bucket_entrypoint_info(string& bucket_name, RGWBucketEntryPoint& entry_point, bool exclusive, time_t mtime);
+  int put_bucket_instance_info(string& bucket_name, RGWBucketInfo& info, bool exclusive, time_t mtime, map<string, bufferlist> *pattrs);
+  int get_bucket_entrypoint_info(void *ctx, string& bucket_name, RGWBucketEntryPoint& entry_point, RGWObjVersionTracker *objv_tracker, time_t *pmtime);
+  int get_bucket_instance_info(void *ctx, string& name, RGWBucketInfo& info, time_t *pmtime, map<string, bufferlist> *pattrs);
+  int get_bucket_instance_from_oid(void *ctx, string& oid, RGWBucketInfo& info, time_t *pmtime, map<string, bufferlist> *pattrs);
+
   virtual int get_bucket_info(void *ctx, string& bucket_name, RGWBucketInfo& info,
                               time_t *pmtime, map<string, bufferlist> *pattrs = NULL);
   virtual int put_bucket_info(string& bucket_name, RGWBucketInfo& info, bool exclusive,