From 23b962157acd28fed77a4db6969738bccb12463c Mon Sep 17 00:00:00 2001 From: Soumya Koduri Date: Wed, 29 Jul 2020 01:57:04 +0530 Subject: [PATCH] rgw/CloudTransition: Update object metadata and bi post cloud tranistion After transitioning the object to cloud, following updates are done to the existing object. * In bi entry, change object category to CloudTiered * Update cloud-tier details (like endpoint, keys etc) in Object Manifest * Mark the tail objects expired to be deleted by gc TODO: * Update all the cloud config details including multiparts * Check if any other object metadata needs to be changed * Optimize to avoid using read_op again to read attrs. * Check for mtime to resolve conflicts when multiple zones try to transition obj Signed-off-by: Soumya Koduri --- src/cls/rgw/cls_rgw_types.h | 2 + src/rgw/rgw_common.h | 2 + src/rgw/rgw_json_enc.cc | 11 ++++++ src/rgw/rgw_lc.cc | 78 +++++++++++++++++++++++++++++++++++++ src/rgw/rgw_obj_manifest.h | 69 +++++++++++++++++++++++++++++++- 5 files changed, 161 insertions(+), 1 deletion(-) diff --git a/src/cls/rgw/cls_rgw_types.h b/src/cls/rgw/cls_rgw_types.h index 7314ad8e21c..b19c46266ee 100644 --- a/src/cls/rgw/cls_rgw_types.h +++ b/src/cls/rgw/cls_rgw_types.h @@ -172,6 +172,8 @@ enum class RGWObjCategory : uint8_t { // uploads; not currently used in the codebase MultiMeta = 3, // b-i entries for multipart upload metadata objs + + CloudTiered = 4, // b-i entries which are tiered to external cloud }; diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index c86d3dd793d..17faa463844 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -1983,6 +1983,8 @@ static inline const char *rgw_obj_category_name(RGWObjCategory category) return "rgw.shadow"; case RGWObjCategory::MultiMeta: return "rgw.multimeta"; + case RGWObjCategory::CloudTiered: + return "rgw.cloudtiered"; } return "unknown"; diff --git a/src/rgw/rgw_json_enc.cc b/src/rgw/rgw_json_enc.cc index 879f0f91645..c37f7098e39 100644 --- a/src/rgw/rgw_json_enc.cc +++ b/src/rgw/rgw_json_enc.cc @@ -99,6 +99,12 @@ void RGWObjManifestRule::dump(Formatter *f) const encode_json("override_prefix", override_prefix, f); } +void RGWObjTier::dump(Formatter *f) const +{ + f->dump_string("name", name); + f->dump_object("tier_placement", tier_placement); +} + void rgw_bucket_placement::dump(Formatter *f) const { encode_json("bucket", bucket, f); @@ -144,6 +150,11 @@ void RGWObjManifest::dump(Formatter *f) const ::encode_json("rules", rules, f); ::encode_json("tail_instance", tail_instance, f); ::encode_json("tail_placement", tail_placement, f); + ::encode_json("tier_type", tier_type, f); + + if (tier_type == "cloud") { + ::encode_json("tier_config", tier_config, f); + } // nullptr being passed into iterators since there // is no cct and we aren't doing anything with these diff --git a/src/rgw/rgw_lc.cc b/src/rgw/rgw_lc.cc index 83f1ae4c656..bbeef3c4f25 100644 --- a/src/rgw/rgw_lc.cc +++ b/src/rgw/rgw_lc.cc @@ -1273,6 +1273,78 @@ public: return 0; } + + int update_tier_obj(lc_op_ctx& oc, RGWLCCloudTierCtx& tier_ctx) { + + map attrs; + RGWRados::Object op_target(tier_ctx.store->getRados(), + tier_ctx.bucket_info, + tier_ctx.rctx, tier_ctx.obj); + + RGWRados::Object::Read read_op(&op_target); + + read_op.params.attrs = &attrs; + + int r = read_op.prepare(null_yield); + if (r < 0) { + return r; + } + + tier_ctx.rctx.set_atomic(tier_ctx.obj); + + RGWRados::Object::Write obj_op(&op_target); + RGWObjState *s = tier_ctx.rctx.get_state(tier_ctx.obj); + + obj_op.meta.modify_tail = true; + obj_op.meta.category = RGWObjCategory::CloudTiered; + obj_op.meta.delete_at = real_time(); + obj_op.meta.data = NULL; + obj_op.meta.if_match = NULL; + obj_op.meta.if_nomatch = NULL; + obj_op.meta.user_data = NULL; + obj_op.meta.zones_trace = NULL; + + RGWObjManifest *pmanifest; + + pmanifest = &(*s->manifest); + RGWObjTier tier_config; + tier_config.name = oc.tier.storage_class; + tier_config.tier_placement = oc.tier; + + pmanifest->set_tier_type("cloud"); + pmanifest->set_tier_config(tier_config); + + /* check if its necessary */ + rgw_placement_rule target_placement; + target_placement.inherit_from(tier_ctx.bucket_info.placement_rule); + target_placement.storage_class = oc.tier.storage_class; + pmanifest->set_head(target_placement, tier_ctx.obj, 0); + + pmanifest->set_tail_placement(target_placement, tier_ctx.obj.bucket); + + /* should the obj_size also be set to '0' or is it needed + * to keep track of original size before transition. + * But unless obj_size is set to '0', obj_iters cannot + * be reset I guess + */ + //pmanifest->set_obj_size(0); + + obj_op.meta.manifest = pmanifest; + + /* update storage class */ + bufferlist bl; + bl.append(oc.tier.storage_class); + attrs[RGW_ATTR_STORAGE_CLASS] = bl; + + + obj_op.write_meta(tier_ctx.o.meta.size, 0, attrs, null_yield); + if (r < 0) { + return r; + } + + return 0; + } + int transition_obj_to_cloud(lc_op_ctx& oc) { std::shared_ptr conn; @@ -1315,6 +1387,12 @@ public: return ret; } + ret = update_tier_obj(oc, tier_ctx); + if (ret < 0) { + ldpp_dout(oc.dpp, 0) << "Updating tier object failed ret=" << ret << dendl; + return ret; + } + return 0; } diff --git a/src/rgw/rgw_obj_manifest.h b/src/rgw/rgw_obj_manifest.h index 45f3ac8adf7..9cb7fec8216 100644 --- a/src/rgw/rgw_obj_manifest.h +++ b/src/rgw/rgw_obj_manifest.h @@ -18,6 +18,7 @@ #include "rgw_common.h" #include "rgw_compression_types.h" #include "rgw_sal.h" +#include "rgw_zone.h" class RGWSI_Zone; struct RGWZoneGroup; @@ -147,6 +148,30 @@ struct RGWObjManifestRule { }; WRITE_CLASS_ENCODER(RGWObjManifestRule) +struct RGWObjTier { + string name; + RGWZoneGroupPlacementTier tier_placement; + /* XXX: Add multipart upload details */ + + RGWObjTier(): name("none") {} + + void encode(bufferlist& bl) const { + ENCODE_START(2, 2, bl); + encode(name, bl); + encode(tier_placement, bl); + ENCODE_FINISH(bl); + } + + void decode(bufferlist::const_iterator& bl) { + DECODE_START_LEGACY_COMPAT_LEN(2, 2, 2, bl); + decode(name, bl); + decode(tier_placement, bl); + DECODE_FINISH(bl); + } + void dump(Formatter *f) const; +}; +WRITE_CLASS_ENCODER(RGWObjTier) + class RGWObjManifest { protected: bool explicit_objs{false}; /* really old manifest? */ @@ -166,6 +191,9 @@ protected: std::string tail_instance; /* tail object's instance */ + string tier_type; + RGWObjTier tier_config; + void convert_to_explicit(const DoutPrefixProvider *dpp, const RGWZoneGroup& zonegroup, const RGWZoneParams& zone_params); int append_explicit(const DoutPrefixProvider *dpp, RGWObjManifest& m, const RGWZoneGroup& zonegroup, const RGWZoneParams& zone_params); void append_rules(RGWObjManifest& m, std::map::iterator& iter, std::string *override_prefix); @@ -187,6 +215,8 @@ public: tail_placement = rhs.tail_placement; rules = rhs.rules; tail_instance = rhs.tail_instance; + tier_type = rhs.tier_type; + tier_config = rhs.tier_config; return *this; } @@ -218,7 +248,7 @@ public: } void encode(bufferlist& bl) const { - ENCODE_START(7, 6, bl); + ENCODE_START(8, 6, bl); encode(obj_size, bl); encode(objs, bl); encode(explicit_objs, bl); @@ -239,6 +269,8 @@ public: } encode(head_placement_rule, bl); encode(tail_placement.placement_rule, bl); + encode(tier_type, bl); + encode(tier_config, bl); ENCODE_FINISH(bl); } @@ -311,6 +343,11 @@ public: decode(tail_placement.placement_rule, bl); } + if (struct_v >= 8) { + decode(tier_type, bl); + decode(tier_config, bl); + } + DECODE_FINISH(bl); } @@ -409,6 +446,36 @@ public: return max_head_size; } + string get_tier_type() { + return tier_type; + } + + void set_tier_type(string value) { + /* Only "cloud" tier-type is supported for now */ + if (value == "cloud") { + tier_type = value; + } else { + tier_type = "none"; + } + } + + void set_tier_config(RGWObjTier t) { + /* Set only if tier_type set to "cloud" */ + if (tier_type != "cloud") + return; + + tier_config.name = t.name; + tier_config.tier_placement = t.tier_placement; + } + + void get_tier_config(RGWObjTier* t) { + if (tier_type != "cloud") + return; + + t->name = tier_config.name; + t->tier_placement = tier_config.tier_placement; + } + class obj_iterator { const DoutPrefixProvider *dpp; const RGWObjManifest *manifest = nullptr; -- 2.39.5