Skip to content

Commit 78f62f4

Browse files
committed
rgw/logging: fix race condition when name update returns ECANCELED
* when we get ECANCELED indication from the name set operation we should bail out and not continue with the rollover * this fix revealed a hidden bug where we do not check the existing temp name when we do conf change cleanup (rollover) Fixes: https://tracker.ceph.com/issues/73434 Signed-off-by: Yuval Lifshitz <[email protected]>
1 parent af633b0 commit 78f62f4

File tree

3 files changed

+23
-16
lines changed

3 files changed

+23
-16
lines changed

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7813,9 +7813,8 @@ int main(int argc, const char **argv)
78137813
const auto region = driver->get_zone()->get_zonegroup().get_api_name();
78147814
ret = rgw::bucketlogging::rollover_logging_object(configuration, target_bucket, obj_name, dpp(), region, bucket, null_yield, true, &objv_tracker, &old_obj);
78157815
if (ret < 0) {
7816-
cerr << "ERROR: failed to flush pending logging object '" << obj_name << "' to target bucket '" << configuration.target_bucket << "'. "
7817-
<< " last committed object is '" << old_obj <<
7818-
"'. error: " << cpp_strerror(-ret) << std::endl;
7816+
cerr << "ERROR: failed to flush pending logging object '" << obj_name << "' to target bucket '" << configuration.target_bucket
7817+
<< "'. error: " << cpp_strerror(-ret) << std::endl;
78197818
return -ret;
78207819
}
78217820
cout << "flushed pending logging object '" << old_obj

src/rgw/rgw_bucket_logging.cc

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -373,16 +373,19 @@ int rollover_logging_object(const configuration& conf,
373373
auto old_obj = obj_name.empty() ? std::nullopt : std::optional<std::string>(obj_name);
374374

375375
auto handle_error = [&dpp, &old_obj, &target_bucket, err_message](int ret) {
376-
if (ret == -ECANCELED) {
377-
ldpp_dout(dpp, 20) << "INFO: rollover already performed for logging object '" << old_obj << "' to logging bucket '" <<
378-
target_bucket->get_key() << "'. ret = " << ret << dendl;
379-
return 0;
380-
}
381376
if (ret < 0) {
382-
ldpp_dout(dpp, 1) << "ERROR: failed to rollover logging object '" << old_obj << "' to logging bucket '" <<
383-
target_bucket->get_key() << "'. ret = " << ret << dendl;
384-
if (err_message) {
385-
*err_message = fmt::format("Failed to rollover logging object of logging bucket '{}'", target_bucket->get_name());
377+
if (ret == -ECANCELED) {
378+
ldpp_dout(dpp, 20) << "INFO: rollover already performed for logging object '" << old_obj << "' to logging bucket '" <<
379+
target_bucket->get_key() << "'. ret = " << ret << dendl;
380+
if (err_message) {
381+
*err_message = fmt::format("Rollover already performed on logging bucket '{}'", target_bucket->get_name());
382+
}
383+
} else {
384+
ldpp_dout(dpp, 1) << "ERROR: failed to rollover logging object '" << old_obj << "' to logging bucket '" <<
385+
target_bucket->get_key() << "'. ret = " << ret << dendl;
386+
if (err_message) {
387+
*err_message = fmt::format("Failed to rollover logging object of logging bucket '{}'", target_bucket->get_name());
388+
}
386389
}
387390
}
388391
return ret;
@@ -515,7 +518,7 @@ int log_record(rgw::sal::Driver* driver,
515518
if (ceph::coarse_real_time::clock::now() > time_to_commit) {
516519
ldpp_dout(dpp, 20) << "INFO: logging object '" << obj_name << "' exceeded its time, will be committed to logging bucket '" <<
517520
target_bucket_id << "'" << dendl;
518-
if (ret = rollover_logging_object(conf, target_bucket, obj_name, dpp, region, s->bucket, y, false, &objv_tracker, nullptr, &err_message); ret < 0) {
521+
if (ret = rollover_logging_object(conf, target_bucket, obj_name, dpp, region, s->bucket, y, false, &objv_tracker, nullptr, &err_message); ret < 0 && ret != -ECANCELED) {
519522
set_journal_err(err_message);
520523
return ret;
521524
}
@@ -666,7 +669,7 @@ int log_record(rgw::sal::Driver* driver,
666669
if (ret == -EFBIG) {
667670
ldpp_dout(dpp, 5) << "WARNING: logging object '" << obj_name << "' is full, will be committed to logging bucket '" <<
668671
target_bucket->get_key() << "'" << dendl;
669-
if (ret = rollover_logging_object(conf, target_bucket, obj_name, dpp, region, s->bucket, y, true, &objv_tracker, nullptr, &err_message); ret < 0 ) {
672+
if (ret = rollover_logging_object(conf, target_bucket, obj_name, dpp, region, s->bucket, y, true, &objv_tracker, nullptr, &err_message); ret < 0 && ret != -ECANCELED) {
670673
set_journal_err(err_message);
671674
return ret;
672675
}

src/rgw/rgw_rest_bucket_logging.cc

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,12 @@ class RGWPutBucketLoggingOp : public RGWDefaultResponseOp {
311311
// conf changed - do cleanup
312312
RGWObjVersionTracker objv_tracker;
313313
std::string obj_name;
314+
if (int ret = target_bucket->get_logging_object_name(obj_name, old_conf->target_prefix, y, this, nullptr); ret < 0 && ret != -ENOENT) {
315+
ldpp_dout(this, 1) << "ERROR: failed to get name of logging object of logging bucket '" <<
316+
target_bucket_id << "' and prefix '" << configuration.target_prefix << "', ret = " << ret << dendl;
317+
op_ret = ret;
318+
return;
319+
}
314320
const auto region = driver->get_zone()->get_zonegroup().get_api_name();
315321
if (const auto ret = rollover_logging_object(*old_conf,
316322
target_bucket,
@@ -324,8 +330,7 @@ class RGWPutBucketLoggingOp : public RGWDefaultResponseOp {
324330
&old_obj); ret < 0) {
325331
ldpp_dout(this, 1) << "WARNING: failed to flush pending logging object '" << obj_name << "'"
326332
<< " to target bucket '" << target_bucket_id << "'. "
327-
<< " last committed object is '" << old_obj <<
328-
"' when updating logging configuration of bucket '" << src_bucket->get_key() << ". error: " << ret << dendl;
333+
<< "' when updating logging configuration of bucket '" << src_bucket->get_key() << ". error: " << ret << dendl;
329334
} else {
330335
ldpp_dout(this, 20) << "INFO: flushed pending logging object '" << old_obj
331336
<< "' to target bucket '" << target_bucket_id << "' when updating logging configuration of bucket '"

0 commit comments

Comments
 (0)