From 57629b3073f1442babe23de78af472235ff3b355 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Wed, 3 Sep 2014 13:02:26 -0700 Subject: [PATCH] rgw: initial olh implementation Signed-off-by: Yehuda Sadeh --- src/rgw/rgw_admin.cc | 35 +++++++++++++++++++++++++ src/rgw/rgw_common.h | 6 +++++ src/rgw/rgw_json_enc.cc | 5 ++++ src/rgw/rgw_rados.cc | 58 ++++++++++++++++++++++++++++++++++++++++- src/rgw/rgw_rados.h | 22 ++++++++++++++++ 5 files changed, 125 insertions(+), 1 deletion(-) diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc index 038b3e28c61ca..e3d11f6d4a8d8 100644 --- a/src/rgw/rgw_admin.cc +++ b/src/rgw/rgw_admin.cc @@ -222,6 +222,7 @@ enum { OPT_OBJECT_UNLINK, OPT_OBJECT_STAT, OPT_OBJECT_REWRITE, + OPT_OLH_GET, OPT_QUOTA_SET, OPT_QUOTA_ENABLE, OPT_QUOTA_DISABLE, @@ -272,6 +273,7 @@ static int get_cmd(const char *cmd, const char *prev_cmd, bool *need_more) strcmp(cmd, "mdlog") == 0 || strcmp(cmd, "metadata") == 0 || strcmp(cmd, "object") == 0 || + strcmp(cmd, "olh") == 0 || strcmp(cmd, "opstate") == 0 || strcmp(cmd, "pool") == 0 || strcmp(cmd, "pools") == 0 || @@ -382,6 +384,9 @@ static int get_cmd(const char *cmd, const char *prev_cmd, bool *need_more) return OPT_OBJECT_STAT; if (strcmp(cmd, "rewrite") == 0) return OPT_OBJECT_REWRITE; + } else if (strcmp(prev_cmd, "olh") == 0) { + if (strcmp(cmd, "get") == 0) + return OPT_OLH_GET; } else if (strcmp(prev_cmd, "region") == 0) { if (strcmp(cmd, "get") == 0) return OPT_REGION_GET; @@ -1891,6 +1896,36 @@ next: } } + if (opt_cmd == OPT_OLH_GET /* || opt_cmd == OPT_OLH_SET */) { +#warning clean up + if (bucket_name.empty()) { + cerr << "ERROR: bucket not specified" << std::endl; + return EINVAL; + } + if (object.empty()) { + cerr << "ERROR: object not specified" << std::endl; + return EINVAL; + } + RGWBucketInfo bucket_info; + int ret = init_bucket(bucket_name, bucket_info, bucket); + if (ret < 0) { + cerr << "ERROR: could not init bucket: " << cpp_strerror(-ret) << std::endl; + return -ret; + } + } + + if (opt_cmd == OPT_OLH_GET) { + RGWOLHInfo olh; + rgw_obj obj(bucket, object); + int ret = store->get_olh(obj, &olh); + if (ret < 0) { + cerr << "ERROR: failed reading olh: " << cpp_strerror(-ret) << dendl; + return -ret; + } + encode_json("olh", olg, formatter); + formatter->flush(cout); + } + if (opt_cmd == OPT_OBJECT_RM) { RGWBucketInfo bucket_info; int ret = init_bucket(bucket_name, bucket_info, bucket); diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index dde83cb2859a5..1ecffca21a13f 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -70,6 +70,12 @@ using ceph::crypto::MD5; #define RGW_ATTR_MANIFEST RGW_ATTR_PREFIX "manifest" #define RGW_ATTR_USER_MANIFEST RGW_ATTR_PREFIX "user_manifest" +#define RGW_ATTR_OLH_PREFIX RGW_ATTR_PREFIX "olh." + +#define RGW_ATTR_OLH_INFO RGW_ATTR_OLH_PREFIX "info" +#define RGW_ATTR_OLH_VER RGW_ATTR_OLH_PREFIX "ver" +#define RGW_ATTR_OLH_PENDING_PREFIX RGW_ATTR_OLH_PREFIX "pending." + #define RGW_BUCKETS_OBJ_SUFFIX ".buckets" #define RGW_MAX_PENDING_CHUNKS 16 diff --git a/src/rgw/rgw_json_enc.cc b/src/rgw/rgw_json_enc.cc index c86966a99430e..8e6220340d16d 100644 --- a/src/rgw/rgw_json_enc.cc +++ b/src/rgw/rgw_json_enc.cc @@ -33,6 +33,11 @@ void encode_json(const char *name, const RGWUserCaps& val, Formatter *f) } +void RGWOLHInfo::dump(Formatter *f) const +{ + encode_json("target", target, f); +} + void RGWObjManifestPart::dump(Formatter *f) const { f->open_object_section("loc"); diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index f362001a27ac0..e228efe4be36e 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -5206,7 +5206,58 @@ int RGWRados::read(void *ctx, rgw_obj& obj, off_t ofs, size_t size, bufferlist& return ref.ioctx.operate(ref.oid, &op, NULL); } -int RGWRados::obj_stat(void *ctx, rgw_obj& obj, uint64_t *psize, time_t *pmtime, uint64_t *epoch, map *attrs, bufferlist *first_chunk, +int RGWRados::get_olh(rgw_obj& obj, RGWOLHInfo *olh) +{ + rgw_rados_ref ref; + rgw_bucket bucket; + int r = get_obj_ref(obj, &ref, &bucket); + if (r < 0) { + return r; + } + + map unfiltered_attrset; + ObjectReadOperation op; + op.getxattrs(&unfiltered_attrset, NULL); + + bufferlist outbl; + r = ref.ioctx.operate(ref.oid, &op, &outbl); + + if (r < 0) { + return r; + } + map attrset; + map::iterator iter; + string check_prefix = RGW_ATTR_OLH_PREFIX; + for (iter = unfiltered_attrset.lower_bound(check_prefix); + iter != unfiltered_attrset.end(); ++iter) { + if (!str_startswith(iter->first, check_prefix)) + break; + attrset[iter->first] = iter->second; + } + + map::iterator iter = attrset.find(RGW_ATTR_OLH_INFO); + if (iter == attrset.end()) { /* not an olh */ + return -EINVAL; + } + + try { + bufferlist::iterator biter = iter->second.begin(); + ::decode(*olh, biter); + } catch (buffer::error& err) { + ldout(cct, 0) << "ERROR: failed to decode olh info" << dendl; + return -EIO; + } + + return 0; +} + +int RGWRados::set_olh(rgw_obj& obj, RGWOLHInfo& olh) +{ + return 0; +} + +int RGWRados::obj_stat(void *ctx, rgw_obj& obj, uint64_t *psize, time_t *pmtime, uint64_t *epoch, + map *attrs, bufferlist *first_chunk, RGWObjVersionTracker *objv_tracker) { rgw_rados_ref ref; @@ -5248,6 +5299,11 @@ int RGWRados::obj_stat(void *ctx, rgw_obj& obj, uint64_t *psize, time_t *pmtime, attrset[iter->first] = iter->second; } + iter = attrset.find(RGW_ATTR_OLH_INFO); + if (iter != attrset.end()) { +#warning implment me + } + if (psize) *psize = size; if (pmtime) diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index e9d5b05618fa5..d14d616c4ca4d 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -57,6 +57,25 @@ static inline void get_obj_bucket_and_oid_loc(const rgw_obj& obj, rgw_bucket& bu int rgw_policy_from_attrset(CephContext *cct, map& attrset, RGWAccessControlPolicy *policy); +struct RGWOLHInfo { + rgw_obj target; + + void encode(bufferlist& bl) const { + ENCODE_START(1, 1, bl); + ::encode(target, bl); + ENCODE_FINISH(bl); + } + + void decode(bufferlist::iterator& bl) { + DECODE_START(1, bl); + ::decode(target, bl); + DECODE_FINISH(bl); + } + + void dump(Formatter *f) const; +}; +WRITE_CLASS_ENCODER(RGWOLHInfo) + struct RGWUsageBatch { map m; @@ -1722,6 +1741,9 @@ public: uint64_t *epoch, map *attrs, bufferlist *first_chunk, RGWObjVersionTracker *objv_tracker); + int get_olh(rgw_obj& obj, RGWOLHInfo *olh); + int set_olh(rgw_obj& obj, RGWOLHInfo& olh); + virtual bool supports_omap() { return true; } int omap_get_vals(rgw_obj& obj, bufferlist& header, const std::string& marker, uint64_t count, std::map& m); virtual int omap_get_all(rgw_obj& obj, bufferlist& header, std::map& m); -- 2.39.5