From: shreyanshjain7174 Date: Wed, 28 Aug 2024 12:25:17 +0000 (-0500) Subject: rgw/restore: Fixed status codes and response headers X-Git-Tag: v20.0.0~603^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=b027d43e97f6ed770203fdffc7401c4790866014;p=ceph.git rgw/restore: Fixed status codes and response headers Added x-amz-restore header and fixed status codes for both restore-cli and read_through Signed-off-by: shreyanshjain7174 --- diff --git a/src/rgw/driver/rados/rgw_rados.cc b/src/rgw/driver/rados/rgw_rados.cc index d154082994e4..e31d5e8ebc21 100644 --- a/src/rgw/driver/rados/rgw_rados.cc +++ b/src/rgw/driver/rados/rgw_rados.cc @@ -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); } diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc index a8874195217a..385d0f761f42 100644 --- a/src/rgw/rgw_admin.cc +++ b/src/rgw/rgw_admin.cc @@ -8623,6 +8623,10 @@ next: handled = decode_dump("pg_ver", bl, formatter.get()); } else if (iter->first == RGW_ATTR_SOURCE_ZONE) { handled = decode_dump("source_zone", bl, formatter.get()); + } else if (iter->first == RGW_ATTR_RESTORE_EXPIRY_DATE) { + handled = decode_dump("restore_expiry_date", bl, formatter.get()); + } else if (iter->first == RGW_ATTR_RESTORE_TIME) { + handled = decode_dump("restore_time", bl, formatter.get()); } if (!handled) diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 67829e6320a6..485dc1b1ee96 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -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 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 <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 < expiry_days; + int restore_ret; public: RGWRestoreObj() {} diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index a245fca9945c..ec23749783d8 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -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);