Skip to content

Commit ad8a617

Browse files
authored
Merge pull request ceph#60491 from soumyakoduri/wip-skoduri-restore-vers
rgw/cloud-restore: Handle versioned objects Reviewed-by: Jiffin Tony Thottan <[email protected]> Reviewed-by: Shreyansh Sancheti <[email protected]>
2 parents 320a4e6 + 8fd7be5 commit ad8a617

16 files changed

+124
-37
lines changed

src/rgw/driver/daos/rgw_sal_daos.cc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1032,7 +1032,6 @@ int DaosObject::restore_obj_from_cloud(Bucket* bucket,
10321032
rgw_bucket_dir_entry& o,
10331033
CephContext* cct,
10341034
RGWObjTier& tier_config,
1035-
real_time& mtime,
10361035
uint64_t olh_epoch,
10371036
std::optional<uint64_t> days,
10381037
const DoutPrefixProvider* dpp,

src/rgw/driver/daos/rgw_sal_daos.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -655,7 +655,6 @@ class DaosObject : public StoreObject {
655655
rgw_bucket_dir_entry& o,
656656
CephContext* cct,
657657
RGWObjTier& tier_config,
658-
real_time& mtime,
659658
uint64_t olh_epoch,
660659
std::optional<uint64_t> days,
661660
const DoutPrefixProvider* dpp,

src/rgw/driver/posix/rgw_sal_posix.cc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3059,7 +3059,6 @@ int POSIXObject::restore_obj_from_cloud(Bucket* bucket,
30593059
rgw_bucket_dir_entry& o,
30603060
CephContext* cct,
30613061
RGWObjTier& tier_config,
3062-
real_time& mtime,
30633062
uint64_t olh_epoch,
30643063
std::optional<uint64_t> days,
30653064
const DoutPrefixProvider* dpp,

src/rgw/driver/posix/rgw_sal_posix.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -697,7 +697,6 @@ class POSIXObject : public StoreObject {
697697
rgw_bucket_dir_entry& o,
698698
CephContext* cct,
699699
RGWObjTier& tier_config,
700-
real_time& mtime,
701700
uint64_t olh_epoch,
702701
std::optional<uint64_t> days,
703702
const DoutPrefixProvider* dpp,

src/rgw/driver/rados/rgw_lc_tier.cc

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -319,8 +319,15 @@ int rgw_cloud_tier_get_object(RGWLCCloudTierCtx& tier_ctx, bool head,
319319

320320
const auto aiter = generic_attrs_map.find(name);
321321
if (aiter != std::end(generic_attrs_map)) {
322-
ldpp_dout(tier_ctx.dpp, 20) << __func__ << " Received attrs aiter->first = " << aiter->first << ", aiter->second = " << aiter->second << ret << dendl;
323-
attrs[aiter->second] = bl;
322+
attrs[aiter->second] = bl;
323+
} else {
324+
std::string s1 = boost::algorithm::to_lower_copy(header.first);
325+
std::replace(s1.begin(), s1.end(), '_', '-');
326+
327+
// copy versioned epoch
328+
if (s1 == "x-amz-meta-rgwx-versioned-epoch") {
329+
attrs[s1] = bl;
330+
}
324331
}
325332

326333
if (header.first == "CONTENT_LENGTH") {

src/rgw/driver/rados/rgw_putobj_processor.cc

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,11 @@ namespace rgw::putobj {
3535
* cloudtier config info read from the attrs.
3636
* Since these attrs are used internally for only replication, do not store them
3737
* in the head object.
38+
*
39+
* Update versioned epoch incase the object is being restored.
3840
*/
39-
void read_cloudtier_info_from_attrs(rgw::sal::Attrs& attrs, RGWObjCategory& category,
40-
RGWObjManifest& manifest) {
41+
int read_cloudtier_info_from_attrs(rgw::sal::Attrs& attrs, RGWObjCategory& category,
42+
std::optional<uint64_t>& olh_epoch, RGWObjManifest& manifest) {
4143
auto attr_iter = attrs.find(RGW_ATTR_CLOUD_TIER_TYPE);
4244
if (attr_iter != attrs.end()) {
4345
auto i = attr_iter->second;
@@ -58,11 +60,37 @@ void read_cloudtier_info_from_attrs(rgw::sal::Attrs& attrs, RGWObjCategory& cate
5860
manifest.set_tier_config(tier_config);
5961
attrs.erase(config_iter);
6062
} catch (buffer::error& err) {
63+
return -EIO;
6164
}
6265
}
6366
}
6467
attrs.erase(attr_iter);
6568
}
69+
attr_iter = attrs.find(RGW_ATTR_RESTORE_VERSIONED_EPOCH);
70+
if (attr_iter != attrs.end()) {
71+
try {
72+
using ceph::decode;
73+
uint64_t v_epoch = 0;
74+
decode(v_epoch, attr_iter->second);
75+
olh_epoch = v_epoch;
76+
/*
77+
* Keep this attr only for Temp restored copies as its needed while
78+
* resetting head object post expiry.
79+
*/
80+
auto r_iter = attrs.find(RGW_ATTR_RESTORE_TYPE);
81+
if (r_iter != attrs.end()) {
82+
rgw::sal::RGWRestoreType restore_type;
83+
using ceph::decode;
84+
decode(restore_type, r_iter->second);
85+
if (restore_type != rgw::sal::RGWRestoreType::Temporary) {
86+
attrs.erase(attr_iter);
87+
}
88+
}
89+
} catch (buffer::error& err) {
90+
return -EIO;
91+
}
92+
}
93+
return 0;
6694
}
6795

6896
int HeadObjectProcessor::process(bufferlist&& data, uint64_t logical_offset)
@@ -390,7 +418,11 @@ int AtomicObjectProcessor::complete(
390418
obj_op.meta.zones_trace = zones_trace;
391419
obj_op.meta.modify_tail = true;
392420

393-
read_cloudtier_info_from_attrs(attrs, obj_op.meta.category, manifest);
421+
r = read_cloudtier_info_from_attrs(attrs, obj_op.meta.category, obj_op.meta.olh_epoch, manifest);
422+
423+
if (r < 0) { // incase of any errors while decoding tier_config/restore attrs
424+
return r;
425+
}
394426

395427
r = obj_op.write_meta(actual_size, accounted_size, attrs, rctx,
396428
writer.get_trace(), flags & rgw::sal::FLAG_LOG_OP);

src/rgw/driver/rados/rgw_rados.cc

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5248,7 +5248,6 @@ int RGWRados::restore_obj_from_cloud(RGWLCCloudTierCtx& tier_ctx,
52485248
const rgw_obj& dest_obj,
52495249
rgw_placement_rule& dest_placement,
52505250
RGWObjTier& tier_config,
5251-
real_time& mtime,
52525251
uint64_t olh_epoch,
52535252
std::optional<uint64_t> days,
52545253
const DoutPrefixProvider *dpp,
@@ -5258,6 +5257,7 @@ int RGWRados::restore_obj_from_cloud(RGWLCCloudTierCtx& tier_ctx,
52585257
//XXX: read below from attrs .. check transition_obj()
52595258
ACLOwner owner;
52605259
rgw::sal::Attrs attrs;
5260+
real_time mtime;
52615261
const req_context rctx{dpp, y, nullptr};
52625262
int ret = 0;
52635263
bufferlist t, t_tier;
@@ -5266,8 +5266,16 @@ int RGWRados::restore_obj_from_cloud(RGWLCCloudTierCtx& tier_ctx,
52665266
auto aio = rgw::make_throttle(cct->_conf->rgw_put_obj_min_window_size, y);
52675267
using namespace rgw::putobj;
52685268
jspan_context no_trace{false, false};
5269+
5270+
// bi expects empty instance for the entries created when
5271+
// bucket versioning is not enabled or suspended.
5272+
rgw_obj dest_obj_bi = dest_obj;
5273+
if (dest_obj_bi.key.instance == "null") {
5274+
dest_obj_bi.key.instance.clear();
5275+
}
5276+
52695277
rgw::putobj::AtomicObjectProcessor processor(aio.get(), this, dest_bucket_info, nullptr,
5270-
owner, obj_ctx, dest_obj, olh_epoch, tag, dpp, y, no_trace);
5278+
owner, obj_ctx, dest_obj_bi, olh_epoch, tag, dpp, y, no_trace);
52715279

52725280
void (*progress_cb)(off_t, void *) = NULL;
52735281
void *progress_data = NULL;
@@ -5299,6 +5307,19 @@ int RGWRados::restore_obj_from_cloud(RGWLCCloudTierCtx& tier_ctx,
52995307
return 0;
53005308
});
53015309

5310+
// fetch mtime of the object and other attrs of the object
5311+
// to check for restore_status
5312+
RGWRados::Object op_target(this, dest_bucket_info, obj_ctx, dest_obj);
5313+
RGWRados::Object::Read read_op(&op_target);
5314+
read_op.params.lastmod = &mtime;
5315+
read_op.params.attrs = &attrs;
5316+
5317+
ret = read_op.prepare(y, dpp);
5318+
if (ret < 0) {
5319+
ldpp_dout(dpp, 0) << "Restoring object(" << dest_obj << ") , read_op failed ret=" << ret << dendl;
5320+
return ret;
5321+
}
5322+
53025323
uint64_t accounted_size = 0;
53035324
string etag;
53045325
real_time set_mtime;
@@ -5331,6 +5352,24 @@ int RGWRados::restore_obj_from_cloud(RGWLCCloudTierCtx& tier_ctx,
53315352
return ret;
53325353
}
53335354

5355+
{
5356+
if (!olh_epoch) {
5357+
const auto aiter = attrs.find("x-amz-meta-rgwx-versioned-epoch");
5358+
if (aiter != std::end(attrs)) {
5359+
std::optional<uint64_t> olh_ep = ceph::parse<uint64_t>(rgw_bl_str(aiter->second));
5360+
if (olh_ep) {
5361+
olh_epoch = *olh_ep;
5362+
}
5363+
attrs.erase(aiter);
5364+
}
5365+
}
5366+
if (olh_epoch) { // needed for only versioned objects
5367+
bufferlist bl;
5368+
encode(olh_epoch, bl);
5369+
attrs[RGW_ATTR_RESTORE_VERSIONED_EPOCH] = std::move(bl);
5370+
}
5371+
}
5372+
53345373
{
53355374
bufferlist bl;
53365375
encode(rgw::sal::RGWRestoreStatus::CloudRestored, bl);
@@ -5409,6 +5448,9 @@ int RGWRados::restore_obj_from_cloud(RGWLCCloudTierCtx& tier_ctx,
54095448
attrs[RGW_ATTR_STORAGE_CLASS] = std::move(bl);
54105449
}
54115450

5451+
for (auto& iter: attrs) {
5452+
ldpp_dout(dpp, 30) << "Restore attrs set: " << iter.first << dendl;
5453+
}
54125454
// XXX: handle COMPLETE_RETRY like in fetch_remote_obj
54135455
bool canceled = false;
54145456
rgw_zone_set zone_set{};
@@ -5419,7 +5461,6 @@ int RGWRados::restore_obj_from_cloud(RGWLCCloudTierCtx& tier_ctx,
54195461
return ret;
54205462
}
54215463

5422-
// XXX: handle olh_epoch for versioned objects like in fetch_remote_obj
54235464
return ret;
54245465
}
54255466

src/rgw/driver/rados/rgw_rados.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1255,7 +1255,6 @@ int restore_obj_from_cloud(RGWLCCloudTierCtx& tier_ctx,
12551255
const rgw_obj& dest_obj,
12561256
rgw_placement_rule& dest_placement,
12571257
RGWObjTier& tier_config,
1258-
real_time& mtime,
12591258
uint64_t olh_epoch,
12601259
std::optional<uint64_t> days,
12611260
const DoutPrefixProvider *dpp,

src/rgw/driver/rados/rgw_sal_rados.cc

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2899,7 +2899,6 @@ int RadosObject::restore_obj_from_cloud(Bucket* bucket,
28992899
rgw_bucket_dir_entry& o,
29002900
CephContext* cct,
29012901
RGWObjTier& tier_config,
2902-
real_time& mtime,
29032902
uint64_t olh_epoch,
29042903
std::optional<uint64_t> days,
29052904
const DoutPrefixProvider* dpp,
@@ -2918,16 +2917,6 @@ int RadosObject::restore_obj_from_cloud(Bucket* bucket,
29182917
int ret = 0;
29192918
string src_storage_class = o.meta.storage_class; // or take src_placement also as input
29202919

2921-
// fetch mtime of the object
2922-
std::unique_ptr<rgw::sal::Object::ReadOp> read_op(get_read_op());
2923-
read_op->params.lastmod = &mtime;
2924-
2925-
ret = read_op->prepare(y, dpp);
2926-
if (ret < 0) {
2927-
ldpp_dout(dpp, 0) << "Restoring object(" << o.key << "): read_op failed ret=" << ret << dendl;
2928-
return ret;
2929-
}
2930-
29312920
if (bucket_name.empty()) {
29322921
bucket_name = "rgwx-" + zonegroup.get_name() + "-" + tier->get_storage_class() +
29332922
"-cloud-bucket";
@@ -2968,7 +2957,7 @@ int RadosObject::restore_obj_from_cloud(Bucket* bucket,
29682957
ret = store->getRados()->restore_obj_from_cloud(tier_ctx, *rados_ctx,
29692958
bucket->get_info(), get_obj(), placement_rule,
29702959
tier_config,
2971-
mtime, olh_epoch, days, dpp, y, flags & FLAG_LOG_OP);
2960+
olh_epoch, days, dpp, y, flags & FLAG_LOG_OP);
29722961

29732962
if (ret < 0) { //failed to restore
29742963
ldpp_dout(dpp, 0) << "Restoring object(" << o.key << ") from the cloud endpoint(" << endpoint << ") failed, ret=" << ret << dendl;
@@ -3092,18 +3081,32 @@ int RadosObject::set_cloud_restore_status(const DoutPrefixProvider* dpp,
30923081
*/
30933082
int RadosObject::handle_obj_expiry(const DoutPrefixProvider* dpp, optional_yield y) {
30943083
int ret = 0;
3084+
3085+
/* once bucket versioning is enabled, the non-current entries with
3086+
* instance empty should have instance set to "null" to be able
3087+
* to correctly read its olh version entry.
3088+
*/
3089+
rgw_obj_key& obj_key = get_key();
3090+
rgw::sal::Bucket* bucket = get_bucket();
3091+
3092+
if (obj_key.instance.empty() && bucket->versioned()) {
3093+
obj_key.instance = "null";
3094+
}
3095+
30953096
real_time read_mtime;
30963097
std::unique_ptr<rgw::sal::Object::ReadOp> read_op(get_read_op());
30973098
read_op->params.lastmod = &read_mtime;
3098-
ldpp_dout(dpp, 20) << "Entering handle_obj_expiry Obj:" << get_key() << dendl;
3099-
31003099
ret = read_op->prepare(y, dpp);
31013100
if (ret < 0) {
31023101
ldpp_dout(dpp, -1) << "handle_obj_expiry Obj:" << get_key() <<
31033102
", read_op failed ret=" << ret << dendl;
31043103
return ret;
31053104
}
31063105

3106+
if (obj_key.instance == "null") {
3107+
obj_key.instance.clear();
3108+
}
3109+
31073110
set_atomic();
31083111
map<string, bufferlist> attrs = get_attrs();
31093112
RGWRados::Object op_target(store->getRados(), bucket->get_info(), *rados_ctx, get_obj());
@@ -3140,7 +3143,7 @@ int RadosObject::handle_obj_expiry(const DoutPrefixProvider* dpp, optional_yield
31403143
RGWObjManifest *pmanifest;
31413144
pmanifest = &m;
31423145

3143-
Object* head_obj = (Object*)this;
3146+
Object* head_obj = (Object*)this;
31443147
RGWObjTier tier_config;
31453148
m.get_tier_config(&tier_config);
31463149

@@ -3151,12 +3154,21 @@ int RadosObject::handle_obj_expiry(const DoutPrefixProvider* dpp, optional_yield
31513154
pmanifest->set_obj_size(0);
31523155
obj_op.meta.manifest = pmanifest;
31533156

3157+
auto v_iter = attrs.find(RGW_ATTR_RESTORE_VERSIONED_EPOCH);
3158+
if (v_iter != attrs.end()) {
3159+
uint64_t versioned_epoch;
3160+
using ceph::decode;
3161+
decode(versioned_epoch, v_iter->second);
3162+
obj_op.meta.olh_epoch = versioned_epoch;
3163+
}
3164+
31543165
// erase restore attrs
31553166
attrs.erase(RGW_ATTR_RESTORE_STATUS);
31563167
attrs.erase(RGW_ATTR_RESTORE_TYPE);
31573168
attrs.erase(RGW_ATTR_RESTORE_TIME);
31583169
attrs.erase(RGW_ATTR_RESTORE_EXPIRY_DATE);
31593170
attrs.erase(RGW_ATTR_CLOUDTIER_STORAGE_CLASS);
3171+
attrs.erase(RGW_ATTR_RESTORE_VERSIONED_EPOCH);
31603172

31613173
bufferlist bl;
31623174
bl.append(tier_config.name);

src/rgw/driver/rados/rgw_sal_rados.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -639,7 +639,6 @@ class RadosObject : public StoreObject {
639639
rgw_bucket_dir_entry& o,
640640
CephContext* cct,
641641
RGWObjTier& tier_config,
642-
real_time& mtime,
643642
uint64_t olh_epoch,
644643
std::optional<uint64_t> days,
645644
const DoutPrefixProvider* dpp,

0 commit comments

Comments
 (0)