// 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
};
return "rgw.shadow";
case RGWObjCategory::MultiMeta:
return "rgw.multimeta";
+ case RGWObjCategory::CloudTiered:
+ return "rgw.cloudtiered";
}
return "unknown";
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);
::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
return 0;
}
+
+ int update_tier_obj(lc_op_ctx& oc, RGWLCCloudTierCtx& tier_ctx) {
+
+ map<string, bufferlist> 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<RGWRESTConn> conn;
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;
}
#include "rgw_common.h"
#include "rgw_compression_types.h"
#include "rgw_sal.h"
+#include "rgw_zone.h"
class RGWSI_Zone;
struct RGWZoneGroup;
};
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? */
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<uint64_t, RGWObjManifestRule>::iterator& iter, std::string *override_prefix);
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;
}
}
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);
}
encode(head_placement_rule, bl);
encode(tail_placement.placement_rule, bl);
+ encode(tier_type, bl);
+ encode(tier_config, bl);
ENCODE_FINISH(bl);
}
decode(tail_placement.placement_rule, bl);
}
+ if (struct_v >= 8) {
+ decode(tier_type, bl);
+ decode(tier_config, bl);
+ }
+
DECODE_FINISH(bl);
}
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;