@@ -503,8 +503,8 @@ int log_record(rgw::sal::Driver* driver,
503503
504504 // make sure that the logging source attribute is up-to-date
505505 if (ret = update_bucket_logging_sources (dpp, target_bucket, s->bucket ->get_key (), true , y); ret < 0 ) {
506- ldpp_dout (dpp, 5 ) << " WARNING: failed to update logging sources attribute '" << RGW_ATTR_BUCKET_LOGGING_SOURCES
507- << " ' in logging bucket '" << target_bucket_id << " '. error: " << ret << dendl;
506+ ldpp_dout (dpp, 5 ) << " WARNING: could not update bucket logging source '" <<
507+ s-> bucket -> get_key () << " ' in logging bucket '" << target_bucket_id << " ' attribute, during record logging. ret = " << ret << dendl;
508508 }
509509
510510 const auto region = driver->get_zone ()->get_zonegroup ().get_api_name ();
@@ -793,8 +793,7 @@ int update_bucket_logging_sources(const DoutPrefixProvider* dpp, std::unique_ptr
793793 ldpp_dout (dpp, 5 ) << " WARNING: failed to decode logging sources attribute '" << RGW_ATTR_BUCKET_LOGGING_SOURCES
794794 << " ' for bucket '" << bucket->get_key () << " ' when updating logging sources. error: " << err.what () << dendl;
795795 }
796- ldpp_dout (dpp, 20 ) << " INFO: logging source '" << src_bucket_id << " ' already " <<
797- (add ? " added to" : " removed from" ) << " bucket '" << bucket->get_key () << " '" << dendl;
796+ // no change
798797 return 0 ;
799798 }, y);
800799}
@@ -808,53 +807,59 @@ int bucket_deletion_cleanup(const DoutPrefixProvider* dpp,
808807 // and also delete the object holding the pending object name
809808 auto & attrs = bucket->get_attrs ();
810809 if (const auto iter = attrs.find (RGW_ATTR_BUCKET_LOGGING_SOURCES); iter != attrs.end ()) {
810+ source_buckets sources;
811811 try {
812- source_buckets sources;
813812 ceph::decode (sources, iter->second );
814- for (const auto & source : sources) {
815- std::unique_ptr<rgw::sal::Bucket> src_bucket;
816- if (const int ret = driver->load_bucket (dpp, source, &src_bucket, y); ret < 0 ) {
817- ldpp_dout (dpp, 5 ) << " WARNING: failed to get logging source bucket '" << source << " ' for logging bucket '" <<
813+ } catch (buffer::error& err) {
814+ ldpp_dout (dpp, 5 ) << " WARNING: failed to decode logging sources attribute '" << RGW_ATTR_BUCKET_LOGGING_SOURCES
815+ << " ' for logging bucket '" << bucket->get_key () << " '. error: " << err.what () << dendl;
816+ return -EIO;
817+ }
818+ // since we removed the attribute, we should not return error code from now on
819+ // any retry, would find no attribute and return success
820+ for (const auto & source : sources) {
821+ std::unique_ptr<rgw::sal::Bucket> src_bucket;
822+ if (const int ret = driver->load_bucket (dpp, source, &src_bucket, y); ret < 0 ) {
823+ ldpp_dout (dpp, 5 ) << " WARNING: failed to get logging source bucket '" << source << " ' for logging bucket '" <<
824+ bucket->get_key () << " ' during cleanup. ret = " << ret << dendl;
825+ continue ;
826+ }
827+ auto & src_attrs = src_bucket->get_attrs ();
828+ if (const auto iter = src_attrs.find (RGW_ATTR_BUCKET_LOGGING); iter != src_attrs.end ()) {
829+ configuration conf;
830+ try {
831+ auto bl_iter = iter->second .cbegin ();
832+ decode (conf, bl_iter);
833+ } catch (buffer::error& err) {
834+ ldpp_dout (dpp, 5 ) << " WARNING: failed to decode logging attribute '" << RGW_ATTR_BUCKET_LOGGING
835+ << " ' of bucket '" << src_bucket->get_key () << " ' during cleanup. error: " << err.what () << dendl;
836+ continue ;
837+ }
838+ std::string obj_name;
839+ RGWObjVersionTracker objv;
840+ if (const int ret = bucket->get_logging_object_name (obj_name, conf.target_prefix , y, dpp, &objv); ret < 0 ) {
841+ ldpp_dout (dpp, 5 ) << " WARNING: failed to get logging object name for logging bucket '" << bucket->get_key () <<
842+ " ' during cleanup. ret = " << ret << dendl;
843+ continue ;
844+ }
845+ if (const int ret = bucket->remove_logging_object_name (conf.target_prefix , y, dpp, &objv); ret < 0 ) {
846+ ldpp_dout (dpp, 5 ) << " WARNING: failed to delete object holding bucket logging object name for logging bucket '" <<
818847 bucket->get_key () << " ' during cleanup. ret = " << ret << dendl;
819848 continue ;
820849 }
821- auto & src_attrs = src_bucket->get_attrs ();
822- if (const auto iter = src_attrs.find (RGW_ATTR_BUCKET_LOGGING); iter != src_attrs.end ()) {
823- configuration conf;
824- try {
825- auto bl_iter = iter->second .cbegin ();
826- decode (conf, bl_iter);
827- std::string obj_name;
828- RGWObjVersionTracker objv;
829- if (const int ret = bucket->get_logging_object_name (obj_name, conf.target_prefix , y, dpp, &objv); ret < 0 ) {
830- ldpp_dout (dpp, 5 ) << " WARNING: failed to get logging object name for logging bucket '" << bucket->get_key () <<
831- " ' during cleanup. ret = " << ret << dendl;
832- continue ;
833- }
834- if (const int ret = bucket->remove_logging_object (obj_name, y, dpp); ret < 0 ) {
835- ldpp_dout (dpp, 5 ) << " WARNING: failed to delete pending logging object '" << obj_name << " ' for logging bucket '" <<
836- bucket->get_key () << " ' during cleanup. ret = " << ret << dendl;
837- continue ;
838- }
839- ldpp_dout (dpp, 20 ) << " INFO: successfully deleted pending logging object '" << obj_name << " ' from deleted logging bucket '" <<
840- bucket->get_key () << " '" << dendl;
841- if (const int ret = bucket->remove_logging_object_name (conf.target_prefix , y, dpp, &objv); ret < 0 ) {
842- ldpp_dout (dpp, 5 ) << " WARNING: failed to delete object holding bucket logging object name for logging bucket '" <<
843- bucket->get_key () << " ' during cleanup. ret = " << ret << dendl;
844- continue ;
845- }
846- ldpp_dout (dpp, 20 ) << " INFO: successfully deleted object holding bucket logging object name from deleted logging bucket '" <<
847- bucket->get_key () << " '" << dendl;
848- } catch (buffer::error& err) {
849- ldpp_dout (dpp, 5 ) << " WARNING: failed to decode logging attribute '" << RGW_ATTR_BUCKET_LOGGING
850- << " ' of bucket '" << src_bucket->get_key () << " ' during cleanup. error: " << err.what () << dendl;
851- }
850+ ldpp_dout (dpp, 20 ) << " INFO: successfully deleted object holding bucket logging object name from deleted logging bucket '" <<
851+ bucket->get_key () << " '" << dendl;
852+ if (const int ret = bucket->remove_logging_object (obj_name, y, dpp); ret < 0 ) {
853+ ldpp_dout (dpp, 5 ) << " WARNING: failed to delete pending logging object '" << obj_name << " ' for logging bucket '" <<
854+ bucket->get_key () << " ' during cleanup. ret = " << ret << dendl;
855+ continue ;
852856 }
857+ ldpp_dout (dpp, 20 ) << " INFO: successfully deleted pending logging object '" << obj_name << " ' from deleted logging bucket '" <<
858+ bucket->get_key () << " '" << dendl;
859+ } else {
860+ ldpp_dout (dpp, 5 ) << " WARNING: no logging attribute '" << RGW_ATTR_BUCKET_LOGGING
861+ << " ' found in logging source bucket '" << src_bucket->get_key () << " ' during cleanup" << dendl;
853862 }
854- } catch (buffer::error& err) {
855- ldpp_dout (dpp, 5 ) << " WARNING: failed to decode logging sources attribute '" << RGW_ATTR_BUCKET_LOGGING_SOURCES
856- << " ' for logging bucket '" << bucket->get_key () << " '. error: " << err.what () << dendl;
857- return -EIO;
858863 }
859864 }
860865
@@ -879,7 +884,7 @@ int source_bucket_cleanup(const DoutPrefixProvider* dpp,
879884 conf = std::move (tmp_conf);
880885 } catch (buffer::error& err) {
881886 ldpp_dout (dpp, 5 ) << " WARNING: failed to decode existing logging attribute '" << RGW_ATTR_BUCKET_LOGGING
882- << " ' of bucket '" << bucket->get_key () << " ' during cleanup. error: " << err.what () << dendl;
887+ << " ' of bucket '" << bucket->get_key () << " ' during source cleanup. error: " << err.what () << dendl;
883888 return -EIO;
884889 }
885890 if (remove_attr) {
@@ -892,34 +897,67 @@ int source_bucket_cleanup(const DoutPrefixProvider* dpp,
892897 }, y); ret < 0 ) {
893898 if (remove_attr) {
894899 ldpp_dout (dpp, 5 ) << " WARNING: failed to remove logging attribute '" << RGW_ATTR_BUCKET_LOGGING <<
895- " ' from bucket '" << bucket->get_key () << " ' during cleanup. ret = " << ret << dendl;
900+ " ' from bucket '" << bucket->get_key () << " ' during source cleanup. ret = " << ret << dendl;
896901 }
897902 return ret;
898903 }
904+ if (last_committed) {
905+ last_committed->clear ();
906+ }
899907 if (!conf) {
900908 // no logging attribute found
901909 return 0 ;
902910 }
903- const auto & info = bucket->get_info ();
904- if (const int ret = commit_logging_object (*conf, dpp, driver, info.bucket .tenant , y, last_committed); ret < 0 ) {
905- ldpp_dout (dpp, 5 ) << " WARNING: could not commit pending logging object of bucket '" <<
906- bucket->get_key () << " ' during cleanup. ret = " << ret << dendl;
907- } else {
908- ldpp_dout (dpp, 20 ) << " INFO: successfully committed pending logging object of bucket '" << bucket->get_key () << " '" << dendl;
909- }
911+ // since we removed the attribute, we should not return error code from now on
912+ // any retry, would find no attribute and return success
910913 rgw_bucket target_bucket_id;
914+ const auto & info = bucket->get_info ();
911915 if (const int ret = get_bucket_id (conf->target_bucket , info.bucket .tenant , target_bucket_id); ret < 0 ) {
912916 ldpp_dout (dpp, 5 ) << " WARNING: failed to parse logging bucket '" <<
913- conf->target_bucket << " ' during cleanup. ret = " << ret << dendl;
917+ conf->target_bucket << " ' during source cleanup. ret = " << ret << dendl;
918+ return 0 ;
919+ }
920+ std::unique_ptr<rgw::sal::Bucket> target_bucket;
921+ const int ret = driver->load_bucket (dpp, target_bucket_id, &target_bucket, y);
922+ if (ret < 0 ) {
923+ ldpp_dout (dpp, 5 ) << " WARNING: failed to get logging bucket '" << target_bucket_id <<
924+ " ' when doing source cleanup. ret = " << ret << dendl;
914925 return 0 ;
915926 }
916- if (const int ret = update_bucket_logging_sources (dpp, driver, target_bucket_id , bucket->get_key (), false , y); ret < 0 ) {
927+ if (const int ret = update_bucket_logging_sources (dpp, target_bucket , bucket->get_key (), false , y); ret < 0 ) {
917928 ldpp_dout (dpp, 5 ) << " WARNING: could not update bucket logging source '" <<
918- bucket->get_key () << " ' during cleanup. ret = " << ret << dendl;
929+ bucket->get_key () << " ' in logging bucket '" << target_bucket_id << " ' attribute, during source cleanup. ret = " << ret << dendl;
930+ }
931+ std::string obj_name;
932+ RGWObjVersionTracker objv;
933+ if (const int ret = target_bucket->get_logging_object_name (obj_name, conf->target_prefix , y, dpp, &objv); ret < 0 ) {
934+ ldpp_dout (dpp, 5 ) << " WARNING: failed to get logging object name for logging bucket '" << bucket->get_key () <<
935+ " ' during source cleanup. ret = " << ret << dendl;
936+ // if name cannot be fetched, we should not commit or remove the object holding the name
937+ // it is better to leak an object than to cause a possible data loss
938+ return 0 ;
939+ }
940+ if (const int ret = target_bucket->remove_logging_object_name (conf->target_prefix , y, dpp, &objv); ret < 0 ) {
941+ ldpp_dout (dpp, 5 ) << " WARNING: failed to delete object holding bucket logging object name for bucket '" <<
942+ bucket->get_key () << " ' during source cleanup. ret = " << ret << dendl;
943+ // this could be because of a race someone else trying to commit the object
944+ // (another bucket cleanup with shared prefix, rollover or an explicit commit)
945+ // and since committing the object twice will cause data loss, we should not try to commit it here
919946 return 0 ;
920947 }
921- ldpp_dout (dpp, 20 ) << " INFO: successfully updated bucket logging source '" <<
922- bucket->get_key () << " ' during cleanup" << dendl;
948+ ldpp_dout (dpp, 20 ) << " INFO: successfully deleted object holding bucket logging object name for bucket '" <<
949+ bucket->get_key () << " ' during source cleanup" << dendl;
950+ // since the object holding the name was deleted, we cannot fetch the last commited name from it
951+ if (const int ret = target_bucket->commit_logging_object (obj_name, y, dpp, conf->target_prefix , nullptr ); ret < 0 ) {
952+ ldpp_dout (dpp, 5 ) << " WARNING: could not commit pending logging object of bucket '" <<
953+ bucket->get_key () << " ' during source cleanup. ret = " << ret << dendl;
954+ return 0 ;
955+ }
956+ ldpp_dout (dpp, 20 ) << " INFO: successfully committed pending logging object of bucket '" <<
957+ bucket->get_key () << " ' during source cleanup. ret = " << ret << dendl;
958+ if (last_committed) {
959+ *last_committed = obj_name;
960+ }
923961 return 0 ;
924962}
925963
0 commit comments