From: Seena Fallah Date: Sat, 19 Apr 2025 20:09:48 +0000 (+0200) Subject: rgw: report copy obj progress from the frontend CR X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=8295e3bf1236a15eb9b955bcfcfb78d7032cca40;p=ceph.git rgw: report copy obj progress from the frontend CR To resolve issues with reporting progress during object copy operations, we now report progress from the frontend CR instead of from the curl thread. Reporting progress directly from the curl thread was causing issues where the final send_response() call in RGWCopyObj() would not resuming the yield after writing to client. By running the fetch_remote_obj() in a separate coroutine and reporting the progress back through the frontend coroutine, we avoid this blockage. Fixes: https://tracker.ceph.com/issues/70840 Signed-off-by: Seena Fallah --- diff --git a/src/rgw/driver/rados/rgw_rados.cc b/src/rgw/driver/rados/rgw_rados.cc index e14d465c688..f8616c0e751 100644 --- a/src/rgw/driver/rados/rgw_rados.cc +++ b/src/rgw/driver/rados/rgw_rados.cc @@ -4989,19 +4989,31 @@ int RGWRados::copy_obj(RGWObjectCtx& src_obj_ctx, ldpp_dout(dpp, 5) << "Copy object " << src_obj.bucket << ":" << src_obj.get_oid() << " => " << dest_obj.bucket << ":" << dest_obj.get_oid() << dendl; if (remote_src || !source_zone.empty()) { - // null_yield resolves a crash when calling progress_cb(), because the beast - // frontend tried to use this same yield context to write the progress - // response to the frontend socket. call fetch_remote_obj() synchronously so - // that only one thread tries to suspend that coroutine - const req_context rctx{dpp, null_yield, nullptr}; - const rgw_owner remote_user_owner(remote_user); - return fetch_remote_obj(dest_obj_ctx, &remote_user_owner, &remote_user, info, source_zone, - dest_obj, src_obj, dest_bucket_info, &src_bucket_info, - dest_placement, src_mtime, mtime, mod_ptr, - unmod_ptr, high_precision_time, - if_match, if_nomatch, attrs_mod, copy_if_newer, attrs, category, - olh_epoch, delete_at, ptag, petag, progress_cb, progress_data, rctx, - nullptr /* filter */, stat_follow_olh, stat_dest_obj, std::nullopt); + RGWCopyObj *op = static_cast(progress_data); + auto& progress_tracker = op->get_progress_tracker(); + + int ret = 0; + boost::asio::spawn(driver->get_io_context(), + [&](boost::asio::yield_context yield) { + const req_context rctx{dpp, yield, nullptr}; + const rgw_owner remote_user_owner(remote_user); + ret = fetch_remote_obj(dest_obj_ctx, &remote_user_owner, &remote_user, info, source_zone, + dest_obj, src_obj, dest_bucket_info, &src_bucket_info, + dest_placement, src_mtime, mtime, mod_ptr, + unmod_ptr, high_precision_time, + if_match, if_nomatch, attrs_mod, copy_if_newer, attrs, category, + olh_epoch, delete_at, ptag, petag, progress_cb, progress_data, rctx, + nullptr /* filter */, stat_follow_olh, stat_dest_obj, std::nullopt); + + progress_tracker.done = true; + progress_tracker.cv.notify_one(); + }, [] (std::exception_ptr eptr) { + if (eptr) std::rethrow_exception(eptr); + }); + + op->progress_cb_handler(); + + return ret; } map src_attrs; diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 36fc34961e5..3d566ac68e5 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -5945,11 +5945,31 @@ void RGWCopyObj::progress_cb(off_t ofs) return; } - send_partial_response(ofs); + std::lock_guard l(progress_tracker->mtx); + progress_tracker->ofs_queue.push(ofs); + progress_tracker->cv.notify_one(); last_ofs = ofs; } +void RGWCopyObj::progress_cb_handler() +{ + std::unique_lock l(progress_tracker->mtx); + while(!progress_tracker->done || !progress_tracker->ofs_queue.empty()) { + progress_tracker->cv.wait(l, [&]() { + return progress_tracker->done || !progress_tracker->ofs_queue.empty(); + }); + + while (!progress_tracker->ofs_queue.empty()) { + auto ofs = progress_tracker->ofs_queue.front(); + progress_tracker->ofs_queue.pop(); + l.unlock(); + send_partial_response(ofs); + l.lock(); + } + } +} + void RGWCopyObj::pre_exec() { rgw_bucket_object_pre_exec(s); diff --git a/src/rgw/rgw_op.h b/src/rgw/rgw_op.h index 85f283551ee..b737dbac7b4 100644 --- a/src/rgw/rgw_op.h +++ b/src/rgw/rgw_op.h @@ -1608,6 +1608,17 @@ protected: RGWObjectRetention *obj_retention; RGWObjectLegalHold *obj_legal_hold; + // remote copy progress helper + struct ProgressTracker { + std::mutex mtx; + std::condition_variable cv; + std::queue ofs_queue; + std::atomic done{false}; + + ProgressTracker() {} + }; + std::optional progress_tracker; + int init_common(); public: @@ -1648,6 +1659,13 @@ public: void pre_exec() override; void execute(optional_yield y) override; void progress_cb(off_t ofs); + void progress_cb_handler(); + ProgressTracker& get_progress_tracker() { + if (!progress_tracker) { + progress_tracker.emplace(); + } + return *progress_tracker; + } virtual int check_storage_class(const rgw_placement_rule& src_placement) { return 0;