]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: Pass and check destination zone trace when fetching object 52108/head
authorAlex Wojno <awojno@bloomberg.net>
Mon, 22 May 2023 20:13:06 +0000 (16:13 -0400)
committerMark Kogan <mkogan@redhat.com>
Sun, 18 Jun 2023 11:44:46 +0000 (11:44 +0000)
Fixes: https://tracker.ceph.com/issues/58911
Signed-off-by: Alex Wojno <awojno@bloomberg.net>
(cherry picked from commit e70fcf9b0a5c03d10415fb91e76a62229397ef82)

Conflicts:
src/rgw/rgw_rest_s3.cc

src/cls/rgw/cls_rgw_types.h
src/rgw/driver/rados/rgw_rados.cc
src/rgw/rgw_op.cc
src/rgw/rgw_op.h
src/rgw/rgw_rest_conn.cc
src/rgw/rgw_rest_conn.h
src/rgw/rgw_rest_s3.cc

index 37a06defc31fbc967e63d07f2e7fbc648d67f435..f94bf114fa1e6a93989e749c80a598dd0209f9f6 100644 (file)
@@ -38,6 +38,10 @@ struct rgw_zone_set_entry {
     return (location_key < e.location_key);
   }
 
+  bool operator==(const rgw_zone_set_entry& e) const {
+    return zone == e.zone && location_key == e.location_key;
+  }
+
   rgw_zone_set_entry() {}
   rgw_zone_set_entry(const std::string& _zone,
                      std::optional<std::string> _location_key) : zone(_zone),
index 84ac1e26624dede9a3bfd272f5b11163c18a161b..1506540819737012c662f9dfca6fd9b73f5313b5 100644 (file)
@@ -3783,7 +3783,7 @@ int RGWRados::stat_remote_obj(const DoutPrefixProvider *dpp,
   int ret = conn->get_obj(dpp, user_id, info, src_obj, pmod, unmod_ptr,
                       dest_mtime_weight.zone_short_id, dest_mtime_weight.pg_ver,
                       prepend_meta, get_op, rgwx_stat,
-                      sync_manifest, skip_decrypt, sync_cloudtiered,
+                      sync_manifest, skip_decrypt, nullptr, sync_cloudtiered,
                       true, &cb, &in_stream_req);
   if (ret < 0) {
     return ret;
@@ -3978,6 +3978,7 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx,
   const real_time *pmod = mod_ptr;
 
   obj_time_weight dest_mtime_weight;
+  rgw_zone_set_entry dst_zone_trace(svc.zone->get_zone().id, dest_bucket_info.bucket.get_key());
 
   if (copy_if_newer) {
     /* need to get mtime for destination */
@@ -4000,8 +4001,8 @@ int RGWRados::fetch_remote_obj(RGWObjectCtx& obj_ctx,
   ret = conn->get_obj(dpp, user_id, info, src_obj, pmod, unmod_ptr,
                       dest_mtime_weight.zone_short_id, dest_mtime_weight.pg_ver,
                       prepend_meta, get_op, rgwx_stat,
-                      sync_manifest, skip_decrypt, sync_cloudtiered,
-                      true,
+                      sync_manifest, skip_decrypt, &dst_zone_trace,
+                      sync_cloudtiered, true,
                       &cb, &in_stream_req);
   if (ret < 0) {
     goto set_err_state;
index cb8ef5b4988fe87596718f0b4b492570fee28316..68444bdb0c55d85668c8d8991b900484e0d89c9e 100644 (file)
@@ -2310,6 +2310,23 @@ void RGWGetObj::execute(optional_yield y)
       filter = &*decompress;
   }
 
+  attr_iter = attrs.find(RGW_ATTR_OBJ_REPLICATION_TRACE);
+  if (attr_iter != attrs.end()) {
+    try {
+      std::vector<rgw_zone_set_entry> zones;
+      auto p = attr_iter->second.cbegin();
+      decode(zones, p);
+      for (const auto& zone: zones) {
+        if (zone == dst_zone_trace) {
+          op_ret = -ERR_NOT_MODIFIED;
+          ldpp_dout(this, 4) << "Object already has been copied to this destination. Returning "
+            << op_ret << dendl;
+          goto done_err;
+        }
+      }
+    } catch (const buffer::error&) {}
+  }
+
   if (get_type() == RGW_OP_GET_OBJ && get_data) {
     op_ret = handle_cloudtier_obj(attrs, sync_cloudtiered);
     if (op_ret < 0) {
index b1dc8994bd86595bb55effa3262c004544d74b11..f398b5b15ba0764eb47fcfee254a8a5ee2e62aef 100644 (file)
@@ -361,6 +361,7 @@ protected:
   std::string lo_etag;
   bool rgwx_stat; /* extended rgw stat operation */
   std::string version_id;
+  rgw_zone_set_entry dst_zone_trace;
 
   // compression attrs
   RGWCompressionInfo cs_info;
index 21ddf6b718fd1857ec65a7685c7ce37f4ca09048..ffb536ed97733bf7041dbd643f4ffba31ada6c0d 100644 (file)
@@ -203,7 +203,7 @@ int RGWRESTConn::get_obj(const DoutPrefixProvider *dpp, const rgw_user& uid, req
                          uint32_t mod_zone_id, uint64_t mod_pg_ver,
                          bool prepend_metadata, bool get_op, bool rgwx_stat,
                          bool sync_manifest, bool skip_decrypt,
-                         bool sync_cloudtiered,
+                         rgw_zone_set_entry *dst_zone_trace, bool sync_cloudtiered,
                          bool send, RGWHTTPStreamRWRequest::ReceiveCB *cb, RGWRESTStreamRWRequest **req)
 {
   get_obj_params params;
@@ -217,6 +217,7 @@ int RGWRESTConn::get_obj(const DoutPrefixProvider *dpp, const rgw_user& uid, req
   params.sync_manifest = sync_manifest;
   params.skip_decrypt = skip_decrypt;
   params.sync_cloudtiered = sync_cloudtiered;
+  params.dst_zone_trace = dst_zone_trace;
   params.cb = cb;
   return get_obj(dpp, obj, params, send, req);
 }
@@ -245,6 +246,9 @@ int RGWRESTConn::get_obj(const DoutPrefixProvider *dpp, const rgw_obj& obj, cons
   if (in_params.skip_decrypt) {
     params.push_back(param_pair_t(RGW_SYS_PARAM_PREFIX "skip-decrypt", ""));
   }
+  if (in_params.dst_zone_trace) {
+    params.push_back(param_pair_t(RGW_SYS_PARAM_PREFIX "if-not-replicated-to", in_params.dst_zone_trace->to_str()));
+  }
   if (!obj.key.instance.empty()) {
     params.push_back(param_pair_t("versionId", obj.key.instance));
   }
index bb0d5a8bbf848640653a8b04a8fc58ec4ef3a139..81f839f49a23c09ddfba0d70afc6ae31f7e2ae18 100644 (file)
@@ -162,6 +162,7 @@ public:
     bool range_is_set{false};
     uint64_t range_start{0};
     uint64_t range_end{0};
+    rgw_zone_set_entry *dst_zone_trace{nullptr};
   };
 
   int get_obj(const DoutPrefixProvider *dpp, const rgw_obj& obj, const get_obj_params& params, bool send, RGWRESTStreamRWRequest **req);
@@ -170,7 +171,7 @@ public:
               const ceph::real_time *mod_ptr, const ceph::real_time *unmod_ptr,
               uint32_t mod_zone_id, uint64_t mod_pg_ver,
               bool prepend_metadata, bool get_op, bool rgwx_stat, bool sync_manifest,
-              bool skip_decrypt, bool sync_cloudtiered,
+              bool skip_decrypt, rgw_zone_set_entry *dst_zone_trace, bool sync_cloudtiered,
               bool send, RGWHTTPStreamRWRequest::ReceiveCB *cb, RGWRESTStreamRWRequest **req);
   int complete_request(RGWRESTStreamRWRequest *req,
                        std::string *etag,
index eb68d004af5dd4451d4f33b08764ee94ec4758d7..56d00dae3ca9b449a6af9fda650ed272c0d09c51 100644 (file)
@@ -302,6 +302,8 @@ int RGWGetObj_ObjStore_S3::get_params(optional_yield y)
   // multisite sync requests should fetch cloudtiered objects
   sync_cloudtiered = s->info.args.exists(RGW_SYS_PARAM_PREFIX "sync-cloudtiered");
 
+  dst_zone_trace = s->info.args.get(RGW_SYS_PARAM_PREFIX "if-not-replicated-to");
+
   return RGWGetObj_ObjStore::get_params(y);
 }