]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw/cloud-transition: Fix issues with MCG endpoint
authorSoumya Koduri <skoduri@redhat.com>
Sat, 5 Nov 2022 16:53:53 +0000 (22:23 +0530)
committerSoumya Koduri <skoduri@redhat.com>
Mon, 12 Dec 2022 17:54:01 +0000 (23:24 +0530)
Few s3 endpoints (like Noobaa MCG or AWS) may return BucketAlreadyOwned
or BucketAlreadyExists error if the target path (configured for
cloud transition) already exists. Do not fail transition in those cases.

Also fixed below issues -
* with racing lc threads, when one lc thread is trying to check and create the
target bucket, others may go ahead with the object transition assuming target path
exists.
* initialize few fields to avoid setting wrong content_len during transition

Signed-off-by: Soumya Koduri <skoduri@redhat.com>
src/rgw/rgw_lc.cc
src/rgw/rgw_lc_tier.cc
src/rgw/rgw_lc_tier.h
src/rgw/rgw_rest_conn.cc

index 31822d862c60577802cccf9576638c165197ae33..6dad16efc8086e4508f682ab895aac58e04895c7 100644 (file)
@@ -1454,25 +1454,16 @@ public:
     tier_ctx.multipart_sync_threshold = oc.tier.t.s3.multipart_sync_threshold;
     tier_ctx.storage_class = oc.tier.storage_class;
 
-    // check if target_path is already created
     std::set<std::string>& cloud_targets = oc.env.worker->get_cloud_targets();
-    std::pair<std::set<std::string>::iterator, bool> it;
-
-    it = cloud_targets.insert(bucket_name);
-    tier_ctx.target_bucket_created = !(it.second);
 
     ldpp_dout(oc.dpp, 0) << "Transitioning object(" << oc.o.key << ") to the cloud endpoint(" << endpoint << ")" << dendl;
 
     /* Transition object to cloud end point */
-    int ret = rgw_cloud_tier_transfer_object(tier_ctx);
+    int ret = rgw_cloud_tier_transfer_object(tier_ctx, cloud_targets);
 
     if (ret < 0) {
       ldpp_dout(oc.dpp, 0) << "ERROR: failed to transfer object(" << oc.o.key << ") to the cloud endpoint(" << endpoint << ") ret=" << ret << dendl;
       return ret;
-
-      if (!tier_ctx.target_bucket_created) {
-        cloud_targets.erase(it.first);
-      }
     }
 
     if (delete_object) {
index 704b7dee2e2714fcc4d5d045c937f3eee2ace011..080b99737acb661cd624cddc41ff3053d36dd56d 100644 (file)
@@ -326,17 +326,17 @@ class RGWLCStreamRead
   rgw::sal::Object *obj;
   const real_time &mtime;
 
-  bool multipart;
-  uint64_t m_part_size;
-  off_t m_part_off;
-  off_t m_part_end;
+  bool multipart{false};
+  uint64_t m_part_size{0};
+  off_t m_part_off{0};
+  off_t m_part_end{0};
 
   std::unique_ptr<rgw::sal::Object::ReadOp> read_op;
-  off_t ofs;
-  off_t end;
+  off_t ofs{0};
+  off_t end{0};
   rgw_rest_obj rest_obj;
 
-  int retcode;
+  int retcode{0};
 
   public:
   RGWLCStreamRead(CephContext *_cct, const DoutPrefixProvider *_dpp,
@@ -1246,8 +1246,7 @@ static int cloud_tier_create_bucket(RGWLCCloudTierCtx& tier_ctx) {
                                     out_bl, &bl, nullptr, null_yield);
 
   if (ret < 0 ) {
-    ldpp_dout(tier_ctx.dpp, 0) << "ERROR: failed to create target bucket: " << tier_ctx.target_bucket_name << ", ret:" << ret << dendl;
-    return ret;
+    ldpp_dout(tier_ctx.dpp, 0) << "create target bucket : " << tier_ctx.target_bucket_name << " returned ret:" << ret << dendl;
   }
   if (out_bl.length() > 0) {
     RGWXMLDecoder::XMLParser parser;
@@ -1270,7 +1269,7 @@ static int cloud_tier_create_bucket(RGWLCCloudTierCtx& tier_ctx) {
       return -EIO;
     }
 
-    if (result.code != "BucketAlreadyOwnedByYou") {
+    if (result.code != "BucketAlreadyOwnedByYou" && result.code != "BucketAlreadyExists") {
       ldpp_dout(tier_ctx.dpp, 0) << "ERROR: Creating target bucket failed with error: " << result.code << dendl;
       return -EIO;
     }
@@ -1279,9 +1278,15 @@ static int cloud_tier_create_bucket(RGWLCCloudTierCtx& tier_ctx) {
   return 0;
 }
 
-int rgw_cloud_tier_transfer_object(RGWLCCloudTierCtx& tier_ctx) {
+int rgw_cloud_tier_transfer_object(RGWLCCloudTierCtx& tier_ctx, std::set<std::string>& cloud_targets) {
   int ret = 0;
 
+  // check if target_path is already created
+  std::set<std::string>::iterator it;
+
+  it = cloud_targets.find(tier_ctx.target_bucket_name);
+  tier_ctx.target_bucket_created = (it != cloud_targets.end());
+
   /* If run first time attempt to create the target bucket */
   if (!tier_ctx.target_bucket_created) {
     ret = cloud_tier_create_bucket(tier_ctx);
@@ -1291,6 +1296,7 @@ int rgw_cloud_tier_transfer_object(RGWLCCloudTierCtx& tier_ctx) {
       return ret;
     }
     tier_ctx.target_bucket_created = true;
+    cloud_targets.insert(tier_ctx.target_bucket_name);
   }
 
   /* Since multiple zones may try to transition the same object to the cloud,
index 86df479e8280847c23414253ce19cddd12892312..7f38f1e02b833b97eca87a24757d86eb5ca1c75b 100644 (file)
@@ -50,6 +50,6 @@ struct RGWLCCloudTierCtx {
 };
 
 /* Transition object to cloud endpoint */
-int rgw_cloud_tier_transfer_object(RGWLCCloudTierCtx& tier_ctx);
+int rgw_cloud_tier_transfer_object(RGWLCCloudTierCtx& tier_ctx, std::set<std::string>& cloud_targets);
 
 #endif
index afcc86db11cd8ca71d7cb5148e2104aacf2bcd8f..d15c97757e64a164a69c7ab87dd164054bc432ee 100644 (file)
@@ -409,7 +409,12 @@ int RGWRESTConn::send_resource(const DoutPrefixProvider *dpp, const std::string&
     return ret;
   }
 
-  return req.complete_request(y);
+  ret = req.complete_request(y);
+  if (ret < 0) {
+    ldpp_dout(dpp, 5) << __func__ << ": complete_request() resource=" << resource << " returned ret=" << ret << dendl;
+  }
+
+  return ret;
 }
 
 RGWRESTReadResource::RGWRESTReadResource(RGWRESTConn *_conn,