Skip to content

Commit e0958b5

Browse files
authored
Merge pull request ceph#53799 from smanjara/wip-shilpa-cleanup-bi
rgw/multisite: bucket instance cleanup after deletion
2 parents 86aba97 + 8fbef97 commit e0958b5

24 files changed

+1589
-141
lines changed

PendingReleaseNotes

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,9 @@
136136
`ceph fs subvolume earmark rm` have been added to set, get and remove earmark from a given subvolume.
137137
* RADOS: Add ``messenger dump`` command to retrieve runtime information
138138
on connections, sockets, and kernel TCP stats from the messenger.
139+
* RGW: deleted buckets are automatically cleaned up as part of trimming process.
140+
DeleteBucket will start returning 409 BucketNotEmpty errors until empty
141+
on all zones when sync policy is enabled.
139142

140143
* RADOS: A performance botteneck in the balancer mgr module has been fixed.
141144
Related Tracker: https://tracker.ceph.com/issues/68657

src/rgw/driver/rados/rgw_bucket.cc

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2697,6 +2697,7 @@ class RGWBucketInstanceMetadataHandler : public RGWMetadataHandler {
26972697
RGWSI_Zone* svc_zone{nullptr};
26982698
RGWSI_Bucket* svc_bucket{nullptr};
26992699
RGWSI_BucketIndex* svc_bi{nullptr};
2700+
RGWDataChangesLog *svc_datalog{nullptr};
27002701

27012702
int put_prepare(const DoutPrefixProvider* dpp, optional_yield y,
27022703
const std::string& entry, RGWBucketCompleteInfo& bci,
@@ -2711,9 +2712,10 @@ class RGWBucketInstanceMetadataHandler : public RGWMetadataHandler {
27112712
RGWBucketInstanceMetadataHandler(rgw::sal::Driver* driver,
27122713
RGWSI_Zone* svc_zone,
27132714
RGWSI_Bucket* svc_bucket,
2714-
RGWSI_BucketIndex* svc_bi)
2715+
RGWSI_BucketIndex* svc_bi,
2716+
RGWDataChangesLog *svc_datalog)
27152717
: driver(driver), svc_zone(svc_zone),
2716-
svc_bucket(svc_bucket), svc_bi(svc_bi) {}
2718+
svc_bucket(svc_bucket), svc_bi(svc_bi), svc_datalog(svc_datalog) {}
27172719

27182720
string get_type() override { return "bucket.instance"; }
27192721

@@ -2874,6 +2876,25 @@ int RGWBucketInstanceMetadataHandler::put_prepare(
28742876
/* existing bucket, keep its placement */
28752877
bci.info.bucket.explicit_placement = old_bci->info.bucket.explicit_placement;
28762878
bci.info.placement_rule = old_bci->info.placement_rule;
2879+
2880+
//if the bucket is being deleted, create and store a special log type for
2881+
//bucket instance cleanup in multisite setup
2882+
const auto& log = bci.info.layout.logs.back();
2883+
if (bci.info.bucket_deleted() && log.layout.type != rgw::BucketLogType::Deleted) {
2884+
const auto index_log = bci.info.layout.logs.back();
2885+
const int shards_num = rgw::num_shards(index_log.layout.in_index);
2886+
bci.info.layout.logs.push_back({log.gen+1, {rgw::BucketLogType::Deleted}});
2887+
ldpp_dout(dpp, 10) << "store log layout type: " << bci.info.layout.logs.back().layout.type << dendl;
2888+
for (int i = 0; i < shards_num; ++i) {
2889+
ldpp_dout(dpp, 10) << "adding to data_log shard_id: " << i << " of gen:" << index_log.gen << dendl;
2890+
int ret = svc_datalog->add_entry(dpp, bci.info, index_log, i, y);
2891+
if (ret < 0) {
2892+
ldpp_dout(dpp, 1) << "WARNING: failed writing data log for bucket="
2893+
<< bci.info.bucket << ", shard_id=" << i << "of generation="
2894+
<< index_log.gen << dendl;
2895+
} // datalog error is not fatal
2896+
}
2897+
}
28772898
}
28782899

28792900
//always keep bucket versioning enabled on archive zone
@@ -2884,7 +2905,7 @@ int RGWBucketInstanceMetadataHandler::put_prepare(
28842905
/* record the read version (if any), store the new version */
28852906
bci.info.objv_tracker.read_version = objv_tracker.read_version;
28862907
bci.info.objv_tracker.write_version = objv_tracker.write_version;
2887-
2908+
28882909
return 0;
28892910
}
28902911

@@ -2963,10 +2984,8 @@ int RGWBucketInstanceMetadataHandler::remove(std::string& entry, RGWObjVersionTr
29632984
return ret;
29642985
}
29652986

2966-
ret = svc_bucket->remove_bucket_instance_info(
2967-
entry, bci.info, &bci.info.objv_tracker, y, dpp);
2968-
if (ret < 0)
2969-
return ret;
2987+
// skip bucket instance removal. each zone will handle it independently during trimming
2988+
29702989
std::ignore = update_bucket_topic_mappings(dpp, &bci, /*current_bci=*/nullptr,
29712990
driver);
29722991
return 0;
@@ -3032,14 +3051,16 @@ RGWBucketCtl::RGWBucketCtl(RGWSI_Zone *zone_svc,
30323051
RGWSI_Bucket *bucket_svc,
30333052
RGWSI_Bucket_Sync *bucket_sync_svc,
30343053
RGWSI_BucketIndex *bi_svc,
3035-
RGWSI_User* user_svc)
3054+
RGWSI_User* user_svc,
3055+
RGWDataChangesLog *datalog_svc)
30363056
: cct(zone_svc->ctx())
30373057
{
30383058
svc.zone = zone_svc;
30393059
svc.bucket = bucket_svc;
30403060
svc.bucket_sync = bucket_sync_svc;
30413061
svc.bi = bi_svc;
30423062
svc.user = user_svc;
3063+
svc.datalog_rados = datalog_svc;
30433064
}
30443065

30453066
void RGWBucketCtl::init(RGWUserCtl *user_ctl,
@@ -3528,11 +3549,13 @@ auto create_bucket_metadata_handler(librados::Rados& rados,
35283549
auto create_bucket_instance_metadata_handler(rgw::sal::Driver* driver,
35293550
RGWSI_Zone* svc_zone,
35303551
RGWSI_Bucket* svc_bucket,
3531-
RGWSI_BucketIndex* svc_bi)
3552+
RGWSI_BucketIndex* svc_bi,
3553+
RGWDataChangesLog *svc_datalog)
35323554
-> std::unique_ptr<RGWMetadataHandler>
35333555
{
35343556
return std::make_unique<RGWBucketInstanceMetadataHandler>(driver, svc_zone,
3535-
svc_bucket, svc_bi);
3557+
svc_bucket, svc_bi,
3558+
svc_datalog);
35363559
}
35373560

35383561
auto create_archive_bucket_metadata_handler(librados::Rados& rados,
@@ -3547,11 +3570,13 @@ auto create_archive_bucket_metadata_handler(librados::Rados& rados,
35473570
auto create_archive_bucket_instance_metadata_handler(rgw::sal::Driver* driver,
35483571
RGWSI_Zone* svc_zone,
35493572
RGWSI_Bucket* svc_bucket,
3550-
RGWSI_BucketIndex* svc_bi)
3573+
RGWSI_BucketIndex* svc_bi,
3574+
RGWDataChangesLog *svc_datalog)
35513575
-> std::unique_ptr<RGWMetadataHandler>
35523576
{
35533577
return std::make_unique<RGWArchiveBucketInstanceMetadataHandler>(driver, svc_zone,
3554-
svc_bucket, svc_bi);
3578+
svc_bucket, svc_bi,
3579+
svc_datalog);
35553580
}
35563581

35573582
void RGWBucketEntryPoint::generate_test_instances(list<RGWBucketEntryPoint*>& o)

src/rgw/driver/rados/rgw_bucket.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,8 @@ auto create_bucket_metadata_handler(librados::Rados& rados,
180180
auto create_bucket_instance_metadata_handler(rgw::sal::Driver* driver,
181181
RGWSI_Zone* svc_zone,
182182
RGWSI_Bucket* svc_bucket,
183-
RGWSI_BucketIndex* svc_bi)
183+
RGWSI_BucketIndex* svc_bi,
184+
RGWDataChangesLog *svc_datalog)
184185
-> std::unique_ptr<RGWMetadataHandler>;
185186

186187
// archive bucket entrypoint metadata handler factory
@@ -193,7 +194,8 @@ auto create_archive_bucket_metadata_handler(librados::Rados& rados,
193194
auto create_archive_bucket_instance_metadata_handler(rgw::sal::Driver* driver,
194195
RGWSI_Zone* svc_zone,
195196
RGWSI_Bucket* svc_bucket,
196-
RGWSI_BucketIndex* svc_bi)
197+
RGWSI_BucketIndex* svc_bi,
198+
RGWDataChangesLog *svc_datalog)
197199
-> std::unique_ptr<RGWMetadataHandler>;
198200

199201

@@ -426,6 +428,7 @@ class RGWBucketCtl {
426428
RGWSI_Bucket_Sync *bucket_sync{nullptr};
427429
RGWSI_BucketIndex *bi{nullptr};
428430
RGWSI_User* user = nullptr;
431+
RGWDataChangesLog *datalog_rados{nullptr};
429432
} svc;
430433

431434
struct Ctl {
@@ -437,7 +440,8 @@ class RGWBucketCtl {
437440
RGWSI_Bucket *bucket_svc,
438441
RGWSI_Bucket_Sync *bucket_sync_svc,
439442
RGWSI_BucketIndex *bi_svc,
440-
RGWSI_User* user_svc);
443+
RGWSI_User* user_svc,
444+
RGWDataChangesLog *datalog_svc);
441445

442446
void init(RGWUserCtl *user_ctl,
443447
RGWDataChangesLog *datalog,

src/rgw/driver/rados/rgw_cr_rados.cc

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,18 @@ int RGWAsyncPutBucketInstanceInfo::_send_request(const DoutPrefixProvider *dpp)
674674
return 0;
675675
}
676676

677+
int RGWAsyncRemoveBucketInstanceInfo::_send_request(const DoutPrefixProvider *dpp)
678+
{
679+
auto r = store->ctl()->bucket->remove_bucket_instance_info(bucket, bucket_info,
680+
null_yield, dpp);
681+
if (r < 0) {
682+
ldpp_dout(dpp, 0) << "ERROR: failed to remove bucket instance info for "
683+
<< bucket_info.bucket << dendl;
684+
return r;
685+
}
686+
return 0;
687+
}
688+
677689
RGWRadosBILogTrimCR::RGWRadosBILogTrimCR(
678690
const DoutPrefixProvider *dpp,
679691
rgw::sal::RadosStore* store,
@@ -1192,3 +1204,56 @@ int RGWDataPostNotifyCR::operate(const DoutPrefixProvider* dpp)
11921204
}
11931205
return 0;
11941206
}
1207+
1208+
RGWStatRemoteBucketCR::RGWStatRemoteBucketCR(const DoutPrefixProvider *dpp,
1209+
rgw::sal::RadosStore* const store,
1210+
const rgw_zone_id source_zone,
1211+
const rgw_bucket& bucket,
1212+
RGWHTTPManager* http,
1213+
std::vector<rgw_zone_id> zids,
1214+
std::vector<bucket_unordered_list_result>& peer_result)
1215+
: RGWCoroutine(store->ctx()), dpp(dpp), store(store),
1216+
source_zone(source_zone), bucket(bucket), http(http),
1217+
zids(std::move(zids)), peer_result(peer_result) {}
1218+
1219+
int RGWStatRemoteBucketCR::operate(const DoutPrefixProvider *dpp) {
1220+
reenter(this) {
1221+
yield {
1222+
auto result = peer_result.begin();
1223+
for (auto& zid : zids) {
1224+
auto& zone_conn_map = store->getRados()->svc.zone->get_zone_conn_map();
1225+
auto ziter = zone_conn_map.find(zid);
1226+
if (ziter == zone_conn_map.end()) {
1227+
ldpp_dout(dpp, 0) << "WARNING: no connection to zone " << ziter->first << dendl;
1228+
continue;
1229+
}
1230+
ldpp_dout(dpp, 20) << "query bucket from: " << ziter->first << dendl;
1231+
RGWRESTConn *conn = ziter->second;
1232+
1233+
rgw_http_param_pair pairs[] = { { "versions" , NULL },
1234+
{ "format" , "json" },
1235+
{ "objs-container" , "true" },
1236+
{ "max-keys", "1" },
1237+
{ "allow-unordered", "true"},
1238+
{ "key-marker" , NULL },
1239+
{ "version-id-marker" , NULL },
1240+
{ NULL, NULL } };
1241+
string p = string("/") + bucket.get_key(':', 0);
1242+
spawn(new RGWReadRESTResourceCR<bucket_unordered_list_result>(store->ctx(), &*conn, &*http, p, pairs, &*result), false);
1243+
++result;
1244+
}
1245+
}
1246+
1247+
while (num_spawned()) {
1248+
yield wait_for_child();
1249+
collect(&child_ret, nullptr);
1250+
if (child_ret < 0) {
1251+
drain_all();
1252+
return set_cr_error(child_ret);
1253+
}
1254+
}
1255+
1256+
return set_cr_done();
1257+
}
1258+
return 0;
1259+
}

0 commit comments

Comments
 (0)