Skip to content

Commit 1e117ce

Browse files
committed
rgw/logging: extract tenant from bucket name on admin flush
test instructions: https://gist.github.com/yuvalif/adfa186fdbe9ad4c5b689753a15ec480 bug was introduced in: 790c38e Fixes: https://tracker.ceph.com/issues/71231 Signed-off-by: Yuval Lifshitz <[email protected]>
1 parent f7c998c commit 1e117ce

File tree

4 files changed

+84
-65
lines changed

4 files changed

+84
-65
lines changed

src/rgw/radosgw-admin/radosgw-admin.cc

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7774,27 +7774,19 @@ int main(int argc, const char **argv)
77747774
if (ret < 0) {
77757775
return -ret;
77767776
}
7777-
const auto& bucket_attrs = bucket->get_attrs();
7778-
auto iter = bucket_attrs.find(RGW_ATTR_BUCKET_LOGGING);
7779-
if (iter == bucket_attrs.end()) {
7780-
cerr << "WARNING: no logging configured on bucket" << std::endl;
7781-
return 0;
7782-
}
7777+
77837778
rgw::bucketlogging::configuration configuration;
7784-
try {
7785-
configuration.enabled = true;
7786-
decode(configuration, iter->second);
7787-
} catch (buffer::error& err) {
7788-
cerr << "ERROR: failed to decode logging attribute '" << RGW_ATTR_BUCKET_LOGGING
7789-
<< "'. error: " << err.what() << std::endl;
7790-
return EINVAL;
7791-
}
77927779
std::unique_ptr<rgw::sal::Bucket> target_bucket;
7793-
ret = init_bucket(tenant, configuration.target_bucket, "", &target_bucket);
7794-
if (ret < 0) {
7795-
cerr << "ERROR: failed to get target logging bucket '" << configuration.target_bucket << "'" << std::endl;
7780+
ret = rgw::bucketlogging::get_target_and_conf_from_source(dpp(), driver, bucket.get(), tenant, configuration, target_bucket, null_yield);
7781+
if (ret < 0 && ret != -ENODATA) {
7782+
cerr << "ERROR: failed to get target bucket and logging conf from source bucket '"
7783+
<< bucket_name << "': " << cpp_strerror(-ret) << std::endl;
77967784
return -ret;
7785+
} else if (ret == -ENODATA) {
7786+
cerr << "ERROR: bucket '" << bucket_name << "' does not have logging enabled" << std::endl;
7787+
return 0;
77977788
}
7789+
77987790
std::string obj_name;
77997791
RGWObjVersionTracker objv_tracker;
78007792
ret = target_bucket->get_logging_object_name(obj_name, configuration.target_prefix, null_yield, dpp(), &objv_tracker);

src/rgw/rgw_bucket_logging.cc

Lines changed: 60 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -197,8 +197,9 @@ ceph::coarse_real_time time_from_name(const std::string& obj_name, const DoutPre
197197
// note: +1 is for the dash between the timestamp and the unique string
198198
std::string time_str = obj_name.substr(time_start_pos, time_format_length);
199199

200-
std::tm t = {};
201-
if (const auto ret = strptime(time_str.c_str(), "%Y-%m-%d-%H-%M-%S", &t); ret == nullptr || *ret != '\0') {
200+
std::tm t;
201+
memset(&t, 0, sizeof(tm));
202+
if (const char* ret = strptime(time_str.c_str(), "%Y-%m-%d-%H-%M-%S", &t); ret == nullptr || *ret != '\0') {
202203
ldpp_dout(dpp, 1) << "ERROR: invalid time format: '" << time_str << "' in logging object name: " << obj_name << dendl;
203204
return extracted_time;
204205
}
@@ -250,7 +251,7 @@ int new_logging_object(const configuration& conf,
250251
break;
251252
}
252253
const auto& target_bucket_id = target_bucket->get_key();
253-
auto ret = target_bucket->set_logging_object_name(obj_name, conf.target_prefix, y, dpp, init_obj, objv_tracker);
254+
int ret = target_bucket->set_logging_object_name(obj_name, conf.target_prefix, y, dpp, init_obj, objv_tracker);
254255
if (ret == -EEXIST || ret == -ECANCELED) {
255256
if (ret = target_bucket->get_logging_object_name(obj_name, conf.target_prefix, y, dpp, nullptr); ret < 0) {
256257
ldpp_dout(dpp, 1) << "ERROR: failed to get name of logging object of bucket '" <<
@@ -277,7 +278,7 @@ int commit_logging_object(const configuration& conf,
277278
optional_yield y) {
278279
std::string target_bucket_name;
279280
std::string target_tenant_name;
280-
auto ret = rgw_parse_url_bucket(conf.target_bucket, tenant_name, target_tenant_name, target_bucket_name);
281+
int ret = rgw_parse_url_bucket(conf.target_bucket, tenant_name, target_tenant_name, target_bucket_name);
281282
if (ret < 0) {
282283
ldpp_dout(dpp, 1) << "ERROR: failed to parse target bucket '" << conf.target_bucket << "' when commiting logging object, ret = "
283284
<< ret << dendl;
@@ -300,12 +301,12 @@ int commit_logging_object(const configuration& conf,
300301
const DoutPrefixProvider *dpp,
301302
optional_yield y) {
302303
std::string obj_name;
303-
if (const auto ret = target_bucket->get_logging_object_name(obj_name, conf.target_prefix, y, dpp, nullptr); ret < 0) {
304+
if (const int ret = target_bucket->get_logging_object_name(obj_name, conf.target_prefix, y, dpp, nullptr); ret < 0) {
304305
ldpp_dout(dpp, 1) << "ERROR: failed to get name of logging object of bucket '" <<
305306
target_bucket->get_key() << "'. ret = " << ret << dendl;
306307
return ret;
307308
}
308-
if (const auto ret = target_bucket->commit_logging_object(obj_name, y, dpp); ret <0 ) {
309+
if (const int ret = target_bucket->commit_logging_object(obj_name, y, dpp); ret <0 ) {
309310
ldpp_dout(dpp, 1) << "ERROR: failed to commit logging object '" << obj_name << "' of bucket '" <<
310311
target_bucket->get_key() << "'. ret = " << ret << dendl;
311312
return ret;
@@ -329,7 +330,7 @@ int rollover_logging_object(const configuration& conf,
329330
return -EINVAL;
330331
}
331332
const auto old_obj = obj_name;
332-
const auto ret = new_logging_object(conf, target_bucket, obj_name, dpp, y, false, objv_tracker);
333+
const int ret = new_logging_object(conf, target_bucket, obj_name, dpp, y, false, objv_tracker);
333334
if (ret == -ECANCELED) {
334335
ldpp_dout(dpp, 20) << "INFO: rollover already performed for object '" << old_obj << "' to logging bucket '" <<
335336
target_bucket->get_key() << "'. ret = " << ret << dendl;
@@ -339,7 +340,7 @@ int rollover_logging_object(const configuration& conf,
339340
target_bucket->get_key() << "'. ret = " << ret << dendl;
340341
return ret;
341342
}
342-
if (const auto ret = target_bucket->commit_logging_object(old_obj, y, dpp); ret < 0) {
343+
if (const int ret = target_bucket->commit_logging_object(old_obj, y, dpp); ret < 0) {
343344
if (must_commit) {
344345
return ret;
345346
}
@@ -413,7 +414,7 @@ int log_record(rgw::sal::Driver* driver,
413414
}
414415
std::string target_bucket_name;
415416
std::string target_tenant_name;
416-
auto ret = rgw_parse_url_bucket(conf.target_bucket, s->bucket_tenant, target_tenant_name, target_bucket_name);
417+
int ret = rgw_parse_url_bucket(conf.target_bucket, s->bucket_tenant, target_tenant_name, target_bucket_name);
417418
if (ret < 0) {
418419
ldpp_dout(dpp, 1) << "ERROR: failed to parse target logging bucket '" << conf.target_bucket << "', ret = " << ret << dendl;
419420
return ret;
@@ -651,7 +652,7 @@ int log_record(rgw::sal::Driver* driver,
651652
}
652653
ldpp_dout(dpp, 20) << "INFO: found matching logging configuration of bucket '" << s->bucket->get_key() <<
653654
"' configuration: " << configuration.to_json_str() << dendl;
654-
if (auto ret = log_record(driver, obj, s, op_name, etag, size, configuration, dpp, y, async_completion, log_source_bucket); ret < 0) {
655+
if (const int ret = log_record(driver, obj, s, op_name, etag, size, configuration, dpp, y, async_completion, log_source_bucket); ret < 0) {
655656
ldpp_dout(dpp, 1) << "ERROR: failed to perform logging for bucket '" << s->bucket->get_key() <<
656657
"'. ret=" << ret << dendl;
657658
return ret;
@@ -667,7 +668,7 @@ int log_record(rgw::sal::Driver* driver,
667668
int get_bucket_id(const std::string& bucket_name, const std::string& tenant_name, rgw_bucket& bucket_id) {
668669
std::string parsed_bucket_name;
669670
std::string parsed_tenant_name;
670-
if (const auto ret = rgw_parse_url_bucket(bucket_name, tenant_name, parsed_tenant_name, parsed_bucket_name); ret < 0) {
671+
if (const int ret = rgw_parse_url_bucket(bucket_name, tenant_name, parsed_tenant_name, parsed_bucket_name); ret < 0) {
671672
return ret;
672673
}
673674
bucket_id = rgw_bucket{parsed_tenant_name, parsed_bucket_name};
@@ -676,7 +677,7 @@ int get_bucket_id(const std::string& bucket_name, const std::string& tenant_name
676677

677678
int update_bucket_logging_sources(const DoutPrefixProvider* dpp, rgw::sal::Driver* driver, const rgw_bucket& target_bucket_id, const rgw_bucket& src_bucket_id, bool add, optional_yield y) {
678679
std::unique_ptr<rgw::sal::Bucket> target_bucket;
679-
const auto ret = driver->load_bucket(dpp, target_bucket_id, &target_bucket, y);
680+
const int ret = driver->load_bucket(dpp, target_bucket_id, &target_bucket, y);
680681
if (ret < 0) {
681682
ldpp_dout(dpp, 5) << "WARNING: failed to get target logging bucket '" << target_bucket_id <<
682683
"' in order to update logging sources. ret = " << ret << dendl;
@@ -735,7 +736,7 @@ int bucket_deletion_cleanup(const DoutPrefixProvider* dpp,
735736
ceph::decode(sources, iter->second);
736737
for (const auto& source : sources) {
737738
std::unique_ptr<rgw::sal::Bucket> src_bucket;
738-
if (const auto ret = driver->load_bucket(dpp, source, &src_bucket, y); ret < 0) {
739+
if (const int ret = driver->load_bucket(dpp, source, &src_bucket, y); ret < 0) {
739740
ldpp_dout(dpp, 5) << "WARNING: failed to get logging source bucket '" << source << "' for logging bucket '" <<
740741
bucket->get_key() << "' during cleanup. ret = " << ret << dendl;
741742
continue;
@@ -748,19 +749,19 @@ int bucket_deletion_cleanup(const DoutPrefixProvider* dpp,
748749
decode(conf, bl_iter);
749750
std::string obj_name;
750751
RGWObjVersionTracker objv;
751-
if (const auto ret = bucket->get_logging_object_name(obj_name, conf.target_prefix, y, dpp, &objv); ret < 0) {
752+
if (const int ret = bucket->get_logging_object_name(obj_name, conf.target_prefix, y, dpp, &objv); ret < 0) {
752753
ldpp_dout(dpp, 5) << "WARNING: failed to get logging object name for logging bucket '" << bucket->get_key() <<
753754
"' during cleanup. ret = " << ret << dendl;
754755
continue;
755756
}
756-
if (const auto ret = bucket->remove_logging_object(obj_name, y, dpp); ret < 0) {
757+
if (const int ret = bucket->remove_logging_object(obj_name, y, dpp); ret < 0) {
757758
ldpp_dout(dpp, 5) << "WARNING: failed to delete pending logging object '" << obj_name << "' for logging bucket '" <<
758759
bucket->get_key() << "' during cleanup. ret = " << ret << dendl;
759760
continue;
760761
}
761762
ldpp_dout(dpp, 20) << "INFO: successfully deleted pending logging object '" << obj_name << "' from deleted logging bucket '" <<
762763
bucket->get_key() << "'" << dendl;
763-
if (const auto ret = bucket->remove_logging_object_name(conf.target_prefix, y, dpp, &objv); ret < 0) {
764+
if (const int ret = bucket->remove_logging_object_name(conf.target_prefix, y, dpp, &objv); ret < 0) {
764765
ldpp_dout(dpp, 5) << "WARNING: failed to delete object holding bucket logging object name for logging bucket '" <<
765766
bucket->get_key() << "' during cleanup. ret = " << ret << dendl;
766767
continue;
@@ -789,7 +790,7 @@ int source_bucket_cleanup(const DoutPrefixProvider* dpp,
789790
bool remove_attr,
790791
optional_yield y) {
791792
std::optional<configuration> conf;
792-
if (const auto ret = retry_raced_bucket_write(dpp, bucket, [dpp, bucket, &conf, remove_attr, y] {
793+
if (const int ret = retry_raced_bucket_write(dpp, bucket, [dpp, bucket, &conf, remove_attr, y] {
793794
auto& attrs = bucket->get_attrs();
794795
if (auto iter = attrs.find(RGW_ATTR_BUCKET_LOGGING); iter != attrs.end()) {
795796
try {
@@ -822,19 +823,19 @@ int source_bucket_cleanup(const DoutPrefixProvider* dpp,
822823
return 0;
823824
}
824825
const auto& info = bucket->get_info();
825-
if (const auto ret = commit_logging_object(*conf, dpp, driver, info.bucket.tenant, y); ret < 0) {
826+
if (const int ret = commit_logging_object(*conf, dpp, driver, info.bucket.tenant, y); ret < 0) {
826827
ldpp_dout(dpp, 5) << "WARNING: could not commit pending logging object of bucket '" <<
827828
bucket->get_key() << "' during cleanup. ret = " << ret << dendl;
828829
} else {
829830
ldpp_dout(dpp, 20) << "INFO: successfully committed pending logging object of bucket '" << bucket->get_key() << "'" << dendl;
830831
}
831832
rgw_bucket target_bucket_id;
832-
if (const auto ret = get_bucket_id(conf->target_bucket, info.bucket.tenant, target_bucket_id); ret < 0) {
833+
if (const int ret = get_bucket_id(conf->target_bucket, info.bucket.tenant, target_bucket_id); ret < 0) {
833834
ldpp_dout(dpp, 5) << "WARNING: failed to parse target logging bucket '" <<
834835
conf->target_bucket << "' during cleanup. ret = " << ret << dendl;
835836
return 0;
836837
}
837-
if (const auto ret = update_bucket_logging_sources(dpp, driver, target_bucket_id, bucket->get_key(), false, y); ret < 0) {
838+
if (const int ret = update_bucket_logging_sources(dpp, driver, target_bucket_id, bucket->get_key(), false, y); ret < 0) {
838839
ldpp_dout(dpp, 5) << "WARNING: could not update bucket logging source '" <<
839840
bucket->get_key() << "' during cleanup. ret = " << ret << dendl;
840841
return 0;
@@ -904,5 +905,44 @@ int verify_target_bucket_attributes(const DoutPrefixProvider* dpp, rgw::sal::Buc
904905
return 0;
905906
}
906907

908+
int get_target_and_conf_from_source(
909+
const DoutPrefixProvider* dpp,
910+
rgw::sal::Driver* driver,
911+
rgw::sal::Bucket* src_bucket,
912+
const std::string& tenant,
913+
configuration& configuration,
914+
std::unique_ptr<rgw::sal::Bucket>& target_bucket,
915+
optional_yield y) {
916+
const auto src_bucket_id = src_bucket->get_key();
917+
const auto& bucket_attrs = src_bucket->get_attrs();
918+
auto iter = bucket_attrs.find(RGW_ATTR_BUCKET_LOGGING);
919+
if (iter == bucket_attrs.end()) {
920+
ldpp_dout(dpp, 1) << "WARNING: no logging configured on bucket '" << src_bucket_id << "'" << dendl;
921+
return -ENODATA;
922+
}
923+
try {
924+
configuration.enabled = true;
925+
auto bl_iter = iter->second.cbegin();
926+
decode(configuration, bl_iter);
927+
} catch (buffer::error& err) {
928+
ldpp_dout(dpp, 1) << "WARNING: failed to decode logging attribute '" << RGW_ATTR_BUCKET_LOGGING
929+
<< "' for bucket '" << src_bucket_id << "', error: " << err.what() << dendl;
930+
return -EINVAL;
931+
}
932+
933+
rgw_bucket target_bucket_id;
934+
if (const int ret = get_bucket_id(configuration.target_bucket, tenant, target_bucket_id); ret < 0) {
935+
ldpp_dout(dpp, 1) << "ERROR: failed to parse target bucket '" << configuration.target_bucket << "', ret = " << ret << dendl;
936+
return ret;
937+
}
938+
939+
if (const int ret = driver->load_bucket(dpp, target_bucket_id,
940+
&target_bucket, y); ret < 0) {
941+
ldpp_dout(dpp, 1) << "ERROR: failed to get target bucket '" << target_bucket_id << "', ret = " << ret << dendl;
942+
return ret;
943+
}
944+
return 0;
945+
}
946+
907947
} // namespace rgw::bucketlogging
908948

src/rgw/rgw_bucket_logging.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,5 +262,19 @@ int verify_target_bucket_policy(const DoutPrefixProvider* dpp,
262262
// - encryption
263263
int verify_target_bucket_attributes(const DoutPrefixProvider* dpp, rgw::sal::Bucket* target_bucket);
264264

265+
// given a source bucket this function is parsing the configuration object
266+
// extracting the target bucket and load it
267+
// the log bucket tenant is taken from configuration
268+
// however, if not explicitly set there, it is taken from the tenant parameter
269+
// both configuration and target bucket are returned by reference
270+
int get_target_and_conf_from_source(
271+
const DoutPrefixProvider* dpp,
272+
rgw::sal::Driver* driver,
273+
rgw::sal::Bucket* src_bucket,
274+
const std::string& tenant,
275+
configuration& configuration,
276+
std::unique_ptr<rgw::sal::Bucket>& target_bucket,
277+
optional_yield y);
278+
265279
} // namespace rgw::bucketlogging
266280

src/rgw/rgw_rest_bucket_logging.cc

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -327,34 +327,7 @@ class RGWPostBucketLoggingOp : public RGWDefaultResponseOp {
327327
return ret;
328328
}
329329
}
330-
const auto src_bucket_id = src_bucket->get_key();
331-
const auto& bucket_attrs = src_bucket->get_attrs();
332-
auto iter = bucket_attrs.find(RGW_ATTR_BUCKET_LOGGING);
333-
if (iter == bucket_attrs.end()) {
334-
ldpp_dout(this, 1) << "WARNING: no logging configured on bucket '" << src_bucket_id << "'" << dendl;
335-
return 0;
336-
}
337-
try {
338-
configuration.enabled = true;
339-
decode(configuration, iter->second);
340-
} catch (buffer::error& err) {
341-
ldpp_dout(this, 1) << "WARNING: failed to decode logging attribute '" << RGW_ATTR_BUCKET_LOGGING
342-
<< "' for bucket '" << src_bucket_id << "', error: " << err.what() << dendl;
343-
return -EINVAL;
344-
}
345-
346-
rgw_bucket target_bucket_id;
347-
if (const auto ret = rgw::bucketlogging::get_bucket_id(configuration.target_bucket, s->bucket_tenant, target_bucket_id); ret < 0) {
348-
ldpp_dout(this, 1) << "ERROR: failed to parse target bucket '" << configuration.target_bucket << "', ret = " << ret << dendl;
349-
return ret;
350-
}
351-
352-
if (const auto ret = driver->load_bucket(this, target_bucket_id,
353-
&target_bucket, y); ret < 0) {
354-
ldpp_dout(this, 1) << "ERROR: failed to get target bucket '" << target_bucket_id << "', ret = " << ret << dendl;
355-
return ret;
356-
}
357-
return 0;
330+
return rgw::bucketlogging::get_target_and_conf_from_source(this, driver, src_bucket.get(), s->bucket_tenant, configuration, target_bucket, y);
358331
}
359332

360333
int verify_permission(optional_yield y) override {

0 commit comments

Comments
 (0)