Skip to content

Commit efb9170

Browse files
authored
Merge pull request ceph#62738 from clwluvw/copy-obj-remote-zonegroup
rgw: dont store replication attrs on remote copy obj Reviewed-by: Casey Bodley <[email protected]>
2 parents 7e91398 + f97693b commit efb9170

File tree

3 files changed

+72
-28
lines changed

3 files changed

+72
-28
lines changed

src/rgw/driver/rados/rgw_rados.cc

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4317,7 +4317,7 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& dest_obj_ctx,
43174317
RGWFetchObjFilter *filter,
43184318
bool stat_follow_olh,
43194319
const rgw_obj& stat_dest_obj,
4320-
const rgw_zone_set_entry& source_trace_entry,
4320+
std::optional<rgw_zone_set_entry> source_trace_entry,
43214321
rgw_zone_set *zones_trace,
43224322
std::optional<uint64_t>* bytes_transferred)
43234323
{
@@ -4559,32 +4559,39 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& dest_obj_ctx,
45594559
//erase the append attr
45604560
cb.get_attrs().erase(RGW_ATTR_APPEND_PART_NUM);
45614561

4562-
{ // add x-amz-replication-status=REPLICA
4563-
auto& bl = cb.get_attrs()[RGW_ATTR_OBJ_REPLICATION_STATUS];
4564-
bl.clear(); // overwrite source's status
4565-
bl.append("REPLICA");
4566-
}
4567-
{ // update replication trace
4568-
std::vector<rgw_zone_set_entry> trace;
4569-
if (auto i = cb.get_attrs().find(RGW_ATTR_OBJ_REPLICATION_TRACE);
4570-
i != cb.get_attrs().end()) {
4571-
try {
4572-
decode(trace, i->second);
4573-
} catch (const buffer::error&) {}
4562+
if (source_trace_entry) { // replication attrs only if we are replicating
4563+
{ // add x-amz-replication-status=REPLICA
4564+
auto& bl = cb.get_attrs()[RGW_ATTR_OBJ_REPLICATION_STATUS];
4565+
bl.clear(); // overwrite source's status
4566+
bl.append("REPLICA");
45744567
}
4575-
// add the source entry to the end
4576-
trace.push_back(source_trace_entry);
4568+
{ // update replication trace
4569+
std::vector<rgw_zone_set_entry> trace;
4570+
if (auto i = cb.get_attrs().find(RGW_ATTR_OBJ_REPLICATION_TRACE);
4571+
i != cb.get_attrs().end()) {
4572+
try {
4573+
decode(trace, i->second);
4574+
} catch (const buffer::error&) {}
4575+
}
4576+
// add the source entry to the end
4577+
trace.push_back(*source_trace_entry);
45774578

4578-
bufferlist bl;
4579-
encode(trace, bl);
4580-
cb.get_attrs()[RGW_ATTR_OBJ_REPLICATION_TRACE] = std::move(bl);
4581-
}
4582-
{
4583-
// add x-amz-replicated-at
4584-
bufferlist bl;
4585-
ceph::real_time timestamp = real_clock::now();
4586-
encode(timestamp, bl);
4587-
cb.get_attrs()[RGW_ATTR_OBJ_REPLICATION_TIMESTAMP] = std::move(bl);
4579+
bufferlist bl;
4580+
encode(trace, bl);
4581+
cb.get_attrs()[RGW_ATTR_OBJ_REPLICATION_TRACE] = std::move(bl);
4582+
}
4583+
{
4584+
// add x-amz-replicated-at
4585+
bufferlist bl;
4586+
ceph::real_time timestamp = real_clock::now();
4587+
encode(timestamp, bl);
4588+
cb.get_attrs()[RGW_ATTR_OBJ_REPLICATION_TIMESTAMP] = std::move(bl);
4589+
}
4590+
} else {
4591+
// remove replication attrs
4592+
cb.get_attrs().erase(RGW_ATTR_OBJ_REPLICATION_STATUS);
4593+
cb.get_attrs().erase(RGW_ATTR_OBJ_REPLICATION_TRACE);
4594+
cb.get_attrs().erase(RGW_ATTR_OBJ_REPLICATION_TIMESTAMP);
45884595
}
45894596

45904597
if (source_zone.empty()) {
@@ -4814,7 +4821,6 @@ int RGWRados::copy_obj(RGWObjectCtx& src_obj_ctx,
48144821
ldpp_dout(dpp, 5) << "Copy object " << src_obj.bucket << ":" << src_obj.get_oid() << " => " << dest_obj.bucket << ":" << dest_obj.get_oid() << dendl;
48154822

48164823
if (remote_src || !source_zone.empty()) {
4817-
rgw_zone_set_entry source_trace_entry{source_zone.id, std::nullopt};
48184824
// null_yield resolves a crash when calling progress_cb(), because the beast
48194825
// frontend tried to use this same yield context to write the progress
48204826
// response to the frontend socket. call fetch_remote_obj() synchronously so
@@ -4826,7 +4832,7 @@ int RGWRados::copy_obj(RGWObjectCtx& src_obj_ctx,
48264832
unmod_ptr, high_precision_time,
48274833
if_match, if_nomatch, attrs_mod, copy_if_newer, attrs, category,
48284834
olh_epoch, delete_at, ptag, petag, progress_cb, progress_data, rctx,
4829-
nullptr /* filter */, stat_follow_olh, stat_dest_obj, source_trace_entry);
4835+
nullptr /* filter */, stat_follow_olh, stat_dest_obj, std::nullopt);
48304836
}
48314837

48324838
map<string, bufferlist> src_attrs;

src/rgw/driver/rados/rgw_rados.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1177,7 +1177,7 @@ class RGWRados
11771177
RGWFetchObjFilter *filter,
11781178
bool stat_follow_olh,
11791179
const rgw_obj& stat_dest_obj,
1180-
const rgw_zone_set_entry& source_trace_entry,
1180+
std::optional<rgw_zone_set_entry> source_trace_entry,
11811181
rgw_zone_set *zones_trace = nullptr,
11821182
std::optional<uint64_t>* bytes_transferred = 0);
11831183
/**

src/test/rgw/rgw_multi/tests.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3904,6 +3904,13 @@ def test_bucket_create_location_constraint():
39043904
CreateBucketConfiguration={'LocationConstraint': zg.name})
39053905
assert e.response['ResponseMetadata']['HTTPStatusCode'] == 400
39063906

3907+
def run_per_zonegroup(func):
3908+
def wrapper(*args, **kwargs):
3909+
for zonegroup in realm.current_period.zonegroups:
3910+
func(zonegroup, *args, **kwargs)
3911+
3912+
return wrapper
3913+
39073914
def allow_bucket_replication(function):
39083915
def wrapper(*args, **kwargs):
39093916
zonegroup = realm.master_zonegroup()
@@ -4864,3 +4871,34 @@ def test_bucket_delete_with_sync_policy_object_prefix():
48644871
remove_sync_policy_group(c1, "sync-group")
48654872

48664873
return
4874+
4875+
@run_per_zonegroup
4876+
def test_copy_obj_between_zonegroups(zonegroup):
4877+
if len(realm.current_period.zonegroups) < 2:
4878+
raise SkipTest('need at least 2 zonegroups to run this test')
4879+
4880+
source_zone = ZonegroupConns(zonegroup).rw_zones[0]
4881+
source_bucket = source_zone.create_bucket(gen_bucket_name())
4882+
4883+
objname = 'dummy'
4884+
k = new_key(source_zone, source_bucket.name, objname)
4885+
k.set_contents_from_string('foo')
4886+
4887+
for zg in realm.current_period.zonegroups:
4888+
if zg.name == zonegroup.name:
4889+
continue
4890+
4891+
dest_zone = ZonegroupConns(zg).rw_zones[0]
4892+
dest_bucket = dest_zone.create_bucket(gen_bucket_name())
4893+
realm_meta_checkpoint(realm)
4894+
4895+
# copy object
4896+
dest_zone.s3_client.copy_object(
4897+
Bucket=dest_bucket.name,
4898+
CopySource=f'{source_bucket.name}/{objname}',
4899+
Key=objname
4900+
)
4901+
4902+
# check that object exists in destination bucket
4903+
k = get_key(dest_zone, dest_bucket, objname)
4904+
assert_equal(k.get_contents_as_string().decode('utf-8'), 'foo')

0 commit comments

Comments
 (0)