]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw/restore: Fixed status codes and response headers 60151/head
authorshreyanshjain7174 <ssanchet@redhat.com>
Wed, 28 Aug 2024 12:25:17 +0000 (07:25 -0500)
committershreyanshjain7174 <ssanchet@redhat.com>
Sun, 13 Oct 2024 17:08:06 +0000 (13:08 -0400)
Added x-amz-restore header and fixed status codes for both restore-cli
and read_through

Signed-off-by: shreyanshjain7174 <ssanchet@redhat.com>
src/rgw/driver/rados/rgw_rados.cc
src/rgw/rgw_admin.cc
src/rgw/rgw_op.cc
src/rgw/rgw_op.h
src/rgw/rgw_rest_s3.cc

index d154082994e46051537299002550b77bc2e8b6de..e31d5e8ebc21bd3db4a48649edf0a354b5eae810 100644 (file)
@@ -5247,13 +5247,7 @@ int RGWRados::restore_obj_from_cloud(RGWLCCloudTierCtx& tier_ctx,
 
   ceph::real_time restore_time = real_clock::now();
   {
-    char buf[32];
-    utime_t ut(restore_time);
-    snprintf(buf, sizeof(buf), "%lld.%09lld",
-          (long long)ut.sec(),
-          (long long)ut.nsec());
     bufferlist bl;
-    bl.append(buf, 32);
     encode(restore_time, bl);
     attrs[RGW_ATTR_RESTORE_TIME] = std::move(bl);
   }
@@ -5273,13 +5267,7 @@ int RGWRados::restore_obj_from_cloud(RGWLCCloudTierCtx& tier_ctx,
     delete_at = expiration_date;
 
     {
-      char buf[32];
-      utime_t ut(expiration_date);
-      snprintf(buf, sizeof(buf), "%lld.%09lld",
-            (long long)ut.sec(),
-            (long long)ut.nsec());
       bufferlist bl;
-      bl.append(buf, 32);
       encode(expiration_date, bl);
       attrs[RGW_ATTR_RESTORE_EXPIRY_DATE] = std::move(bl);
     }
index a8874195217a2e92d6f903aafcaeea6efe001c28..385d0f761f42af28080e21a2dae17f23d79f83c0 100644 (file)
@@ -8623,6 +8623,10 @@ next:
         handled = decode_dump<uint64_t>("pg_ver", bl, formatter.get());
       } else if (iter->first == RGW_ATTR_SOURCE_ZONE) {
         handled = decode_dump<uint32_t>("source_zone", bl, formatter.get());
+      } else if (iter->first == RGW_ATTR_RESTORE_EXPIRY_DATE) {
+        handled = decode_dump<utime_t>("restore_expiry_date", bl, formatter.get());
+      } else if (iter->first == RGW_ATTR_RESTORE_TIME) {
+        handled = decode_dump<utime_t>("restore_time", bl, formatter.get());
       }
 
       if (!handled)
index 67829e6320a6ea73fd4689ab01c6fba42c41b47d..485dc1b1ee967077941f5dc0ab81dd7957c11751 100644 (file)
@@ -943,6 +943,17 @@ void handle_replication_status_header(
 /*
  * GET on CloudTiered objects either it will synced to other zones.
  * In all other cases, it will try to fetch the object from remote cloud endpoint.
+ *
+ * @return:
+ * Note - return status may differ based on whether it is RESTORE op or
+ *        READTHROUGH/GET op.
+ *        for e.g, ERR_INVALID_OBJECT_STATE is sent for non cloud-transitioned
+ *        incase of restore op and ERR_REQUEST_TIMEOUT is applicable only for
+ *        read-through etc.
+ *  `<0` :  failed to process; s->err.message & op_ret set accrodingly
+ *  `0`  :  restore request initiated
+ *  `1`  :  restore is already in progress
+ *  `2`  :  already restored
  */
 int handle_cloudtier_obj(req_state* s, const DoutPrefixProvider *dpp, rgw::sal::Driver* driver,
                          rgw::sal::Attrs& attrs, bool sync_cloudtiered, std::optional<uint64_t> days,
@@ -1051,12 +1062,17 @@ int handle_cloudtier_obj(req_state* s, const DoutPrefixProvider *dpp, rgw::sal::
         s->err.message = "restore is still in progress";
       }
       return op_ret;
-    } else if ((!restore_op) && (restore_status == rgw::sal::RGWRestoreStatus::RestoreAlreadyInProgress)) {
-      op_ret = -ERR_REQUEST_TIMEOUT;
-      ldpp_dout(dpp, 5) << "restore is still in progress, please check restore status and retry" << dendl;
-      s->err.message = "restore is still in progress";
-    } else { // CloudRestored..return success
-      return 0;
+    } else if (restore_status == rgw::sal::RGWRestoreStatus::RestoreAlreadyInProgress) {
+        if (!restore_op) {
+          op_ret = -ERR_REQUEST_TIMEOUT;
+          ldpp_dout(dpp, 5) << "restore is still in progress, please check restore status and retry" << dendl;
+          s->err.message = "restore is still in progress";
+          return op_ret;
+        } else { 
+          return 1; // for restore-op, corresponds to RESTORE_ALREADY_IN_PROGRESS
+        } 
+    } else {
+      return 2; // corresponds to CLOUD_RESTORED
     }
   } catch (const buffer::end_of_buffer&) {
     //empty manifest; it's not cloud-tiered
@@ -5282,33 +5298,14 @@ void RGWRestoreObj::execute(optional_yield y)
   int op_ret = s->object->get_obj_attrs(y, this);
   if (op_ret < 0) {
     ldpp_dout(this, 1) << "failed to fetch get_obj_attrs op ret = " << op_ret << dendl;
+    restore_ret = op_ret;
     return;
   }
-  rgw::sal::Attrs attrs = s->object->get_attrs();
-  auto attr_iter = attrs.find(RGW_ATTR_MANIFEST);
-  if (attr_iter != attrs.end()) {
-    RGWObjManifest m;
-    decode(m, attr_iter->second);
-    RGWObjTier tier_config;
-    m.get_tier_config(&tier_config);
-    if (m.get_tier_type() == "cloud-s3") {
-      ldpp_dout(this, 20) << "execute: expiry days" << expiry_days <<dendl;
-      op_ret = handle_cloudtier_obj(s, this, driver, attrs, false, expiry_days, true, y);
-      if (op_ret < 0) {
-        ldpp_dout(this, 4) << "Cannot get cloud tiered object: " << *s->object
-        <<". Failing with " << op_ret << dendl;
-        if (op_ret == -ERR_INVALID_OBJECT_STATE) {
-          s->err.message = "This object was transitioned to cloud-s3";
-        }
-      }
-    } else {
-      ldpp_dout(this, 20) << "not cloud tier object erroring" << dendl;
-      op_ret = -ERR_INVALID_OBJECT_STATE;
-    }
-  } else {
-    ldpp_dout(this, 20) << " manifest not found" << dendl;
-  }
-  ldpp_dout(this, 20) << "completed restore" << dendl;
+  rgw::sal::Attrs attrs;
+  attrs = s->object->get_attrs();
+  op_ret = handle_cloudtier_obj(s, this, driver, attrs, false, expiry_days, true, y);
+  restore_ret = op_ret;
+  ldpp_dout(this, 20) << "Restore completed of object: " << *s->object << "with op ret: " << restore_ret <<dendl;
 
   return;
 } 
index df05500a4370c06a2d51b9d7c9fda87f76368902..a4aa53c5d3f10d0cb590656d088acee1a687528c 100644 (file)
@@ -1464,6 +1464,7 @@ public:
 class RGWRestoreObj : public RGWOp {
 protected:
   std::optional<uint64_t> expiry_days;
+  int restore_ret;
 public:
   RGWRestoreObj() {}
 
index a245fca9945ce5b5cf2a5a4eca126be0ad3bd5be..ec23749783d8f9d29327877437b2ae50e6a8156e 100644 (file)
@@ -449,8 +449,7 @@ int RGWGetObj_ObjStore_S3::send_response_data(bufferlist& bl, off_t bl_ofs,
   dump_content_length(s, total_len);
   dump_last_modified(s, lastmod);
   dump_header_if_nonempty(s, "x-amz-version-id", version_id);
-  dump_header_if_nonempty(s, "x-amz-expiration", expires);
-
+  dump_header_if_nonempty(s, "x-amz-expiration", expires);  
   if (attrs.find(RGW_ATTR_APPEND_PART_NUM) != attrs.end()) {
     dump_header(s, "x-rgw-object-type", "Appendable");
     dump_header(s, "x-rgw-next-append-position", s->obj_size);
@@ -526,7 +525,29 @@ int RGWGetObj_ObjStore_S3::send_response_data(bufferlist& bl, off_t bl_ofs,
       auto iter = bl.cbegin();
       decode(rt, iter);
 
+      rgw::sal::RGWRestoreStatus restore_status;
+      attr_iter = attrs.find(RGW_ATTR_RESTORE_STATUS);
+      if (attr_iter != attrs.end()) {
+        bufferlist bl = attr_iter->second;
+        auto iter = bl.cbegin();
+        decode(restore_status, iter);
+      }
+      
+      //restore status
+      if (restore_status == rgw::sal::RGWRestoreStatus::RestoreAlreadyInProgress) {
+          dump_header(s, "x-amz-restore", "ongoing-request=\"true\"");
+      }
       if (rt == rgw::sal::RGWRestoreType::Temporary) {
+        auto expire_iter = attrs.find(RGW_ATTR_RESTORE_EXPIRY_DATE);
+        ceph::real_time expiration_date;
+        
+        if (expire_iter != attrs.end()) {
+          bufferlist bl = expire_iter->second;
+          auto iter = bl.cbegin();
+          decode(expiration_date, iter);
+        }
+        //restore status
+        dump_header_if_nonempty(s, "x-amz-restore", "ongoing-request=\"false\", expiry-date=\""+ dump_time_to_str(expiration_date) +"\"");
         // temporary restore; set storage-class to cloudtier storage class
         auto c_iter = attrs.find(RGW_ATTR_CLOUDTIER_STORAGE_CLASS);
 
@@ -3513,38 +3534,46 @@ int RGWRestoreObj_ObjStore_S3::get_params(optional_yield y)
 
 void RGWRestoreObj_ObjStore_S3::send_response()
 {
-  if (op_ret < 0)
-  {
-    set_req_state_err(s, op_ret);
+  if (restore_ret < 0) {
+    set_req_state_err(s, restore_ret);
     dump_errno(s);
     end_header(s, this);
     dump_start(s);
     return;
   }
 
-  rgw::sal::Attrs attrs = s->object->get_attrs();
-  auto attr_iter = attrs.find(RGW_ATTR_RESTORE_STATUS);
-  rgw::sal::RGWRestoreStatus restore_status;
-  if (attr_iter != attrs.end()) {
-    bufferlist bl = attr_iter->second;
-    auto iter = bl.cbegin();
-    decode(restore_status, iter);
-  }
-  ldpp_dout(this, 10) << "restore_status=" << restore_status << dendl;
-  
-  if (attr_iter == attrs.end() || restore_status != rgw::sal::RGWRestoreStatus::None) {
-    s->err.http_ret = 202; //Accepted
-    dump_header(s, "x-amz-restore", rgw_bl_str(restore_status));
-  } else if (restore_status != rgw::sal::RGWRestoreStatus::RestoreAlreadyInProgress) {
+  if (restore_ret == 0) {
+    s->err.http_ret = 202; // OK
+  } else if (restore_ret == 1) {
     s->err.http_ret = 409; // Conflict
-    dump_header_if_nonempty(s, "x-amz-restore", rgw_bl_str(restore_status));
-  } else if (restore_status != rgw::sal::RGWRestoreStatus::CloudRestored) {
-    s->err.http_ret = 200; // OK
-    dump_header_if_nonempty(s, "x-amz-restore", rgw_bl_str(restore_status));
-  } else {
-    s->err.http_ret = 202; // Accepted
-    dump_header_if_nonempty(s, "x-amz-restore", rgw_bl_str(restore_status));
-  }
+    dump_header(s, "x-amz-restore", "on-going-request=\"true\"");
+  } else if (restore_ret == 2) {
+    rgw::sal::Attrs attrs;
+    ceph::real_time expiration_date;
+    rgw::sal::RGWRestoreType rt;
+    attrs = s->object->get_attrs();
+    auto expire_iter = attrs.find(RGW_ATTR_RESTORE_EXPIRY_DATE);
+    auto type_iter = attrs.find(RGW_ATTR_RESTORE_TYPE);
+
+    if (expire_iter != attrs.end()) {
+      bufferlist bl = expire_iter->second;
+      auto iter = bl.cbegin();
+      decode(expiration_date, iter);
+    }
+    
+    if (type_iter != attrs.end()) {
+      bufferlist bl = type_iter->second;
+      auto iter = bl.cbegin();
+      decode(rt, iter);
+    }
+    if (rt == rgw::sal::RGWRestoreType::Temporary) {
+      s->err.http_ret = 200; // OK
+      dump_header(s, "x-amz-restore", "ongoing-request=\"false\", expiry-date=\""+ dump_time_to_str(expiration_date) +"\"");
+    } else {
+      s->err.http_ret = 200;
+      dump_header(s, "x-amz-restore", "ongoing-request=\"false\"");
+    }
+  } 
 
   dump_errno(s);
   end_header(s, this);