Skip to content

Commit cef383b

Browse files
committed
rgw/cloud-restore: Handle versioned objects
While restoring non-current object versions, ensure they remain non-current. Read `olh_epoch` from the restored object's metadata into a new attr "RGW_ATTR_RESTORE_VERSIONED_EPOCH". This attr/olh_epoch is used while updating bi entry and also to reset HEAD object post expiry of temporary copies. Signed-off-by: Soumya Koduri <[email protected]>
1 parent d4ce7b6 commit cef383b

16 files changed

+99
-34
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: 35 additions & 2 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;
@@ -5299,6 +5299,19 @@ int RGWRados::restore_obj_from_cloud(RGWLCCloudTierCtx& tier_ctx,
52995299
return 0;
53005300
});
53015301

5302+
// fetch mtime of the object and other attrs of the object
5303+
// to check for restore_status
5304+
RGWRados::Object op_target(this, dest_bucket_info, obj_ctx, dest_obj);
5305+
RGWRados::Object::Read read_op(&op_target);
5306+
read_op.params.lastmod = &mtime;
5307+
read_op.params.attrs = &attrs;
5308+
5309+
ret = read_op.prepare(y, dpp);
5310+
if (ret < 0) {
5311+
ldpp_dout(dpp, 0) << "Restoring object(" << dest_obj << ") , read_op failed ret=" << ret << dendl;
5312+
return ret;
5313+
}
5314+
53025315
uint64_t accounted_size = 0;
53035316
string etag;
53045317
real_time set_mtime;
@@ -5331,6 +5344,24 @@ int RGWRados::restore_obj_from_cloud(RGWLCCloudTierCtx& tier_ctx,
53315344
return ret;
53325345
}
53335346

5347+
{
5348+
if (!olh_epoch) {
5349+
const auto aiter = attrs.find("x-amz-meta-rgwx-versioned-epoch");
5350+
if (aiter != std::end(attrs)) {
5351+
std::optional<uint64_t> olh_ep = ceph::parse<uint64_t>(rgw_bl_str(aiter->second));
5352+
if (olh_ep) {
5353+
olh_epoch = *olh_ep;
5354+
}
5355+
attrs.erase(aiter);
5356+
}
5357+
}
5358+
if (olh_epoch) { // needed for only versioned objects
5359+
bufferlist bl;
5360+
encode(olh_epoch, bl);
5361+
attrs[RGW_ATTR_RESTORE_VERSIONED_EPOCH] = std::move(bl);
5362+
}
5363+
}
5364+
53345365
{
53355366
bufferlist bl;
53365367
encode(rgw::sal::RGWRestoreStatus::CloudRestored, bl);
@@ -5409,6 +5440,9 @@ int RGWRados::restore_obj_from_cloud(RGWLCCloudTierCtx& tier_ctx,
54095440
attrs[RGW_ATTR_STORAGE_CLASS] = std::move(bl);
54105441
}
54115442

5443+
for (auto& iter: attrs) {
5444+
ldpp_dout(dpp, 30) << "Restore attrs set: " << iter.first << dendl;
5445+
}
54125446
// XXX: handle COMPLETE_RETRY like in fetch_remote_obj
54135447
bool canceled = false;
54145448
rgw_zone_set zone_set{};
@@ -5419,7 +5453,6 @@ int RGWRados::restore_obj_from_cloud(RGWLCCloudTierCtx& tier_ctx,
54195453
return ret;
54205454
}
54215455

5422-
// XXX: handle olh_epoch for versioned objects like in fetch_remote_obj
54235456
return ret;
54245457
}
54255458

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: 11 additions & 13 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;
@@ -3140,7 +3129,7 @@ int RadosObject::handle_obj_expiry(const DoutPrefixProvider* dpp, optional_yield
31403129
RGWObjManifest *pmanifest;
31413130
pmanifest = &m;
31423131

3143-
Object* head_obj = (Object*)this;
3132+
Object* head_obj = (Object*)this;
31443133
RGWObjTier tier_config;
31453134
m.get_tier_config(&tier_config);
31463135

@@ -3151,12 +3140,21 @@ int RadosObject::handle_obj_expiry(const DoutPrefixProvider* dpp, optional_yield
31513140
pmanifest->set_obj_size(0);
31523141
obj_op.meta.manifest = pmanifest;
31533142

3143+
auto v_iter = attrs.find(RGW_ATTR_RESTORE_VERSIONED_EPOCH);
3144+
if (v_iter != attrs.end()) {
3145+
uint64_t versioned_epoch;
3146+
using ceph::decode;
3147+
decode(versioned_epoch, v_iter->second);
3148+
obj_op.meta.olh_epoch = versioned_epoch;
3149+
}
3150+
31543151
// erase restore attrs
31553152
attrs.erase(RGW_ATTR_RESTORE_STATUS);
31563153
attrs.erase(RGW_ATTR_RESTORE_TYPE);
31573154
attrs.erase(RGW_ATTR_RESTORE_TIME);
31583155
attrs.erase(RGW_ATTR_RESTORE_EXPIRY_DATE);
31593156
attrs.erase(RGW_ATTR_CLOUDTIER_STORAGE_CLASS);
3157+
attrs.erase(RGW_ATTR_RESTORE_VERSIONED_EPOCH);
31603158

31613159
bufferlist bl;
31623160
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)