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);
}
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);
}
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)
/*
* 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,
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
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;
}
class RGWRestoreObj : public RGWOp {
protected:
std::optional<uint64_t> expiry_days;
+ int restore_ret;
public:
RGWRestoreObj() {}
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);
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);
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);