From: Jason Dillaman Date: Fri, 11 Mar 2016 00:13:07 +0000 (-0500) Subject: librbd: maintenance ops now send asynchronous requests X-Git-Tag: v10.1.0~104^2~13 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=f67bcc05bd266cd06864d2ebb52e9e17cb1256f8;p=ceph.git librbd: maintenance ops now send asynchronous requests The RBD mirror daemon will need to request the creation/removal of snapshots from a remote image. These operations need to be performed asynchronously as opposed to the current synchronous style of the librbd API. Signed-off-by: Jason Dillaman --- diff --git a/src/librbd/ExclusiveLock.cc b/src/librbd/ExclusiveLock.cc index 3779cc1cca1b..bd945e6a2331 100644 --- a/src/librbd/ExclusiveLock.cc +++ b/src/librbd/ExclusiveLock.cc @@ -113,7 +113,7 @@ template void ExclusiveLock::try_lock(Context *on_tried_lock) { { Mutex::Locker locker(m_lock); - assert(m_image_ctx.owner_lock.is_wlocked()); + assert(m_image_ctx.owner_lock.is_locked()); assert(!is_shutdown()); if (m_state != STATE_LOCKED || !m_actions_contexts.empty()) { diff --git a/src/librbd/ImageWatcher.cc b/src/librbd/ImageWatcher.cc index 2bd3c0a61cb7..b65428078984 100644 --- a/src/librbd/ImageWatcher.cc +++ b/src/librbd/ImageWatcher.cc @@ -16,6 +16,7 @@ #include "include/encoding.h" #include "include/stringify.h" #include "common/errno.h" +#include "common/WorkQueue.h" #include #include #include @@ -191,7 +192,9 @@ void ImageWatcher::handle_async_complete(const AsyncRequestId &request, int r, } } -int ImageWatcher::notify_flatten(uint64_t request_id, ProgressContext &prog_ctx) { +void ImageWatcher::notify_flatten(uint64_t request_id, + ProgressContext &prog_ctx, + Context *on_finish) { assert(m_image_ctx.owner_lock.is_locked()); assert(m_image_ctx.exclusive_lock && !m_image_ctx.exclusive_lock->is_lock_owner()); @@ -200,11 +203,12 @@ int ImageWatcher::notify_flatten(uint64_t request_id, ProgressContext &prog_ctx) bufferlist bl; ::encode(NotifyMessage(FlattenPayload(async_request_id)), bl); - return notify_async_request(async_request_id, std::move(bl), prog_ctx); + notify_async_request(async_request_id, std::move(bl), prog_ctx, on_finish); } -int ImageWatcher::notify_resize(uint64_t request_id, uint64_t size, - ProgressContext &prog_ctx) { +void ImageWatcher::notify_resize(uint64_t request_id, uint64_t size, + ProgressContext &prog_ctx, + Context *on_finish) { assert(m_image_ctx.owner_lock.is_locked()); assert(m_image_ctx.exclusive_lock && !m_image_ctx.exclusive_lock->is_lock_owner()); @@ -213,61 +217,68 @@ int ImageWatcher::notify_resize(uint64_t request_id, uint64_t size, bufferlist bl; ::encode(NotifyMessage(ResizePayload(size, async_request_id)), bl); - return notify_async_request(async_request_id, std::move(bl), prog_ctx); + notify_async_request(async_request_id, std::move(bl), prog_ctx, on_finish); } -int ImageWatcher::notify_snap_create(const std::string &snap_name) { +void ImageWatcher::notify_snap_create(const std::string &snap_name, + Context *on_finish) { assert(m_image_ctx.owner_lock.is_locked()); assert(m_image_ctx.exclusive_lock && !m_image_ctx.exclusive_lock->is_lock_owner()); bufferlist bl; ::encode(NotifyMessage(SnapCreatePayload(snap_name)), bl); - return notify_lock_owner(std::move(bl)); + notify_lock_owner(std::move(bl), on_finish); } -int ImageWatcher::notify_snap_rename(const snapid_t &src_snap_id, - const std::string &dst_snap_name) { +void ImageWatcher::notify_snap_rename(const snapid_t &src_snap_id, + const std::string &dst_snap_name, + Context *on_finish) { assert(m_image_ctx.owner_lock.is_locked()); assert(m_image_ctx.exclusive_lock && !m_image_ctx.exclusive_lock->is_lock_owner()); bufferlist bl; ::encode(NotifyMessage(SnapRenamePayload(src_snap_id, dst_snap_name)), bl); - return notify_lock_owner(std::move(bl)); + notify_lock_owner(std::move(bl), on_finish); } -int ImageWatcher::notify_snap_remove(const std::string &snap_name) { + +void ImageWatcher::notify_snap_remove(const std::string &snap_name, + Context *on_finish) { assert(m_image_ctx.owner_lock.is_locked()); assert(m_image_ctx.exclusive_lock && !m_image_ctx.exclusive_lock->is_lock_owner()); bufferlist bl; ::encode(NotifyMessage(SnapRemovePayload(snap_name)), bl); - return notify_lock_owner(std::move(bl)); + notify_lock_owner(std::move(bl), on_finish); } -int ImageWatcher::notify_snap_protect(const std::string &snap_name) { +void ImageWatcher::notify_snap_protect(const std::string &snap_name, + Context *on_finish) { assert(m_image_ctx.owner_lock.is_locked()); assert(m_image_ctx.exclusive_lock && !m_image_ctx.exclusive_lock->is_lock_owner()); bufferlist bl; ::encode(NotifyMessage(SnapProtectPayload(snap_name)), bl); - return notify_lock_owner(std::move(bl)); + notify_lock_owner(std::move(bl), on_finish); } -int ImageWatcher::notify_snap_unprotect(const std::string &snap_name) { +void ImageWatcher::notify_snap_unprotect(const std::string &snap_name, + Context *on_finish) { assert(m_image_ctx.owner_lock.is_locked()); assert(m_image_ctx.exclusive_lock && !m_image_ctx.exclusive_lock->is_lock_owner()); bufferlist bl; ::encode(NotifyMessage(SnapUnprotectPayload(snap_name)), bl); - return notify_lock_owner(std::move(bl)); + notify_lock_owner(std::move(bl), on_finish); } -int ImageWatcher::notify_rebuild_object_map(uint64_t request_id, - ProgressContext &prog_ctx) { +void ImageWatcher::notify_rebuild_object_map(uint64_t request_id, + ProgressContext &prog_ctx, + Context *on_finish) { assert(m_image_ctx.owner_lock.is_locked()); assert(m_image_ctx.exclusive_lock && !m_image_ctx.exclusive_lock->is_lock_owner()); @@ -276,17 +287,18 @@ int ImageWatcher::notify_rebuild_object_map(uint64_t request_id, bufferlist bl; ::encode(NotifyMessage(RebuildObjectMapPayload(async_request_id)), bl); - return notify_async_request(async_request_id, std::move(bl), prog_ctx); + notify_async_request(async_request_id, std::move(bl), prog_ctx, on_finish); } -int ImageWatcher::notify_rename(const std::string &image_name) { +void ImageWatcher::notify_rename(const std::string &image_name, + Context *on_finish) { assert(m_image_ctx.owner_lock.is_locked()); assert(m_image_ctx.exclusive_lock && !m_image_ctx.exclusive_lock->is_lock_owner()); bufferlist bl; ::encode(NotifyMessage(RenamePayload(image_name)), bl); - return notify_lock_owner(std::move(bl)); + notify_lock_owner(std::move(bl), on_finish); } void ImageWatcher::notify_header_update(Context *on_finish) { @@ -420,19 +432,25 @@ void ImageWatcher::handle_request_lock(int r) { } } -int ImageWatcher::notify_lock_owner(bufferlist &&bl) { - C_SaferCond ctx; - notify_lock_owner(std::move(bl), &ctx); - return ctx.wait(); -} - void ImageWatcher::notify_lock_owner(bufferlist &&bl, Context *on_finish) { + assert(on_finish != nullptr); assert(m_image_ctx.owner_lock.is_locked()); NotifyLockOwner *notify_lock_owner = NotifyLockOwner::create( m_image_ctx, m_notifier, std::move(bl), on_finish); notify_lock_owner->send(); } +Context *ImageWatcher::remove_async_request(const AsyncRequestId &id) { + RWLock::WLocker async_request_locker(m_async_request_lock); + auto it = m_async_requests.find(id); + if (it != m_async_requests.end()) { + Context *on_complete = it->second.first; + m_async_requests.erase(it); + return on_complete; + } + return nullptr; +} + void ImageWatcher::schedule_async_request_timed_out(const AsyncRequestId &id) { Context *ctx = new FunctionContext(boost::bind( &ImageWatcher::async_request_timed_out, this, id)); @@ -444,44 +462,45 @@ void ImageWatcher::schedule_async_request_timed_out(const AsyncRequestId &id) { } void ImageWatcher::async_request_timed_out(const AsyncRequestId &id) { - RWLock::RLocker l(m_async_request_lock); - std::map::iterator it = - m_async_requests.find(id); - if (it != m_async_requests.end()) { - ldout(m_image_ctx.cct, 10) << this << " request timed-out: " << id << dendl; - it->second.first->complete(-ERESTART); + Context *on_complete = remove_async_request(id); + if (on_complete != nullptr) { + ldout(m_image_ctx.cct, 5) << "async request timed out: " << id << dendl; + m_image_ctx.op_work_queue->queue(on_complete, -ETIMEDOUT); } } -int ImageWatcher::notify_async_request(const AsyncRequestId &async_request_id, - bufferlist &&in, - ProgressContext& prog_ctx) { +void ImageWatcher::notify_async_request(const AsyncRequestId &async_request_id, + bufferlist &&in, + ProgressContext& prog_ctx, + Context *on_finish) { + assert(on_finish != nullptr); assert(m_image_ctx.owner_lock.is_locked()); ldout(m_image_ctx.cct, 10) << this << " async request: " << async_request_id << dendl; - C_SaferCond ctx; + Context *on_notify = new FunctionContext([this, async_request_id](int r) { + if (r < 0) { + // notification failed -- don't expect updates + Context *on_complete = remove_async_request(async_request_id); + if (on_complete != nullptr) { + on_complete->complete(r); + } + } + }); + Context *on_complete = new FunctionContext( + [this, async_request_id, on_finish](int r) { + m_task_finisher->cancel(Task(TASK_CODE_ASYNC_REQUEST, async_request_id)); + on_finish->complete(r); + }); { - RWLock::WLocker l(m_async_request_lock); - m_async_requests[async_request_id] = AsyncRequest(&ctx, &prog_ctx); + RWLock::WLocker async_request_locker(m_async_request_lock); + m_async_requests[async_request_id] = AsyncRequest(on_complete, &prog_ctx); } - BOOST_SCOPE_EXIT( (&ctx)(async_request_id)(&m_task_finisher) - (&m_async_requests)(&m_async_request_lock) ) { - m_task_finisher->cancel(Task(TASK_CODE_ASYNC_REQUEST, async_request_id)); - - RWLock::WLocker l(m_async_request_lock); - m_async_requests.erase(async_request_id); - } BOOST_SCOPE_EXIT_END - schedule_async_request_timed_out(async_request_id); - int r = notify_lock_owner(std::move(in)); - if (r < 0) { - return r; - } - return ctx.wait(); + notify_lock_owner(std::move(in), on_notify); } int ImageWatcher::prepare_async_request(const AsyncRequestId& async_request_id, @@ -613,14 +632,12 @@ bool ImageWatcher::handle_payload(const AsyncProgressPayload &payload, bool ImageWatcher::handle_payload(const AsyncCompletePayload &payload, C_NotifyAck *ack_ctx) { - RWLock::RLocker l(m_async_request_lock); - std::map::iterator req_it = - m_async_requests.find(payload.async_request_id); - if (req_it != m_async_requests.end()) { + Context *on_complete = remove_async_request(payload.async_request_id); + if (on_complete != nullptr) { ldout(m_image_ctx.cct, 10) << this << " request finished: " << payload.async_request_id << "=" << payload.result << dendl; - req_it->second.first->complete(payload.result); + on_complete->complete(payload.result); } return true; } diff --git a/src/librbd/ImageWatcher.h b/src/librbd/ImageWatcher.h index 89edb35df2c6..da1c11b332b5 100644 --- a/src/librbd/ImageWatcher.h +++ b/src/librbd/ImageWatcher.h @@ -34,18 +34,20 @@ public: void unregister_watch(Context *on_finish); void flush(Context *on_finish); - int notify_flatten(uint64_t request_id, ProgressContext &prog_ctx); - int notify_resize(uint64_t request_id, uint64_t size, - ProgressContext &prog_ctx); - int notify_snap_create(const std::string &snap_name); - int notify_snap_rename(const snapid_t &src_snap_id, - const std::string &dst_snap_name); - int notify_snap_remove(const std::string &snap_name); - int notify_snap_protect(const std::string &snap_name); - int notify_snap_unprotect(const std::string &snap_name); - int notify_rebuild_object_map(uint64_t request_id, - ProgressContext &prog_ctx); - int notify_rename(const std::string &image_name); + void notify_flatten(uint64_t request_id, ProgressContext &prog_ctx, + Context *on_finish); + void notify_resize(uint64_t request_id, uint64_t size, + ProgressContext &prog_ctx, Context *on_finish); + void notify_snap_create(const std::string &snap_name, Context *on_finish); + void notify_snap_rename(const snapid_t &src_snap_id, + const std::string &dst_snap_name, + Context *on_finish); + void notify_snap_remove(const std::string &snap_name, Context *on_finish); + void notify_snap_protect(const std::string &snap_name, Context *on_finish); + void notify_snap_unprotect(const std::string &snap_name, Context *on_finish); + void notify_rebuild_object_map(uint64_t request_id, + ProgressContext &prog_ctx, Context *on_finish); + void notify_rename(const std::string &image_name, Context *on_finish); void notify_acquired_lock(); void notify_released_lock(); @@ -247,13 +249,14 @@ private: void handle_request_lock(int r); void schedule_request_lock(bool use_timer, int timer_delay = -1); - int notify_lock_owner(bufferlist &&bl); void notify_lock_owner(bufferlist &&bl, Context *on_finish); + Context *remove_async_request(const watch_notify::AsyncRequestId &id); void schedule_async_request_timed_out(const watch_notify::AsyncRequestId &id); void async_request_timed_out(const watch_notify::AsyncRequestId &id); - int notify_async_request(const watch_notify::AsyncRequestId &id, - bufferlist &&in, ProgressContext& prog_ctx); + void notify_async_request(const watch_notify::AsyncRequestId &id, + bufferlist &&in, ProgressContext& prog_ctx, + Context *on_finish); void schedule_async_progress(const watch_notify::AsyncRequestId &id, uint64_t offset, uint64_t total); diff --git a/src/librbd/Operations.cc b/src/librbd/Operations.cc index ff698c28203b..e990304cc906 100644 --- a/src/librbd/Operations.cc +++ b/src/librbd/Operations.cc @@ -8,6 +8,7 @@ #include "librbd/ImageCtx.h" #include "librbd/ImageState.h" #include "librbd/ImageWatcher.h" +#include "librbd/Utils.h" #include "librbd/operation/FlattenRequest.h" #include "librbd/operation/RebuildObjectMapRequest.h" #include "librbd/operation/RenameRequest.h" @@ -51,6 +52,159 @@ struct C_NotifyUpdate : public Context { } }; +template +struct C_InvokeAsyncRequest : public Context { + /** + * @verbatim + * + * + * | + * . . . . . . | . . . . . . . . . . . . . . . . . . + * . . | . . + * . v v v . + * . ACQUIRE_LOCK (skip if exclusive lock . + * . | disabled or has lock) . + * . | . + * . /--------/ \--------\ . . . . . . . . . . . . . + * . | | . + * . v v . + * LOCAL_REQUEST REMOTE_REQUEST + * | | + * | | + * \--------\ /--------/ + * | + * v + * + * + * @endverbatim + */ + + I &image_ctx; + std::string request_type; + bool permit_snapshot; + boost::function local; + boost::function remote; + Context *on_finish; + + C_InvokeAsyncRequest(I &image_ctx, const std::string& request_type, + bool permit_snapshot, + const boost::function& local, + const boost::function& remote, + Context *on_finish) + : image_ctx(image_ctx), request_type(request_type), + permit_snapshot(permit_snapshot), local(local), remote(remote), + on_finish(on_finish) { + } + + void send() { + send_acquire_exclusive_lock(); + } + + void send_acquire_exclusive_lock() { + RWLock::RLocker owner_locker(image_ctx.owner_lock); + { + RWLock::RLocker snap_locker(image_ctx.snap_lock); + if (image_ctx.read_only || + (!permit_snapshot && image_ctx.snap_id != CEPH_NOSNAP)) { + complete(-EROFS); + return; + } + } + + if (image_ctx.exclusive_lock == nullptr) { + send_local_request(); + return; + } else if (image_ctx.image_watcher == nullptr) { + complete(-EROFS); + return; + } + + if (image_ctx.exclusive_lock->is_lock_owner() && + image_ctx.exclusive_lock->accept_requests()) { + send_local_request(); + return; + } + + CephContext *cct = image_ctx.cct; + ldout(cct, 20) << __func__ << dendl; + + Context *ctx = util::create_context_callback< + C_InvokeAsyncRequest, + &C_InvokeAsyncRequest::handle_acquire_exclusive_lock>( + this); + image_ctx.exclusive_lock->try_lock(ctx); + } + + void handle_acquire_exclusive_lock(int r) { + CephContext *cct = image_ctx.cct; + ldout(cct, 20) << __func__ << ": r=" << r << dendl; + + RWLock::RLocker owner_locker(image_ctx.owner_lock); + if (r < 0) { + complete(-EROFS); + return; + } else if (image_ctx.exclusive_lock->is_lock_owner()) { + send_local_request(); + return; + } + + send_remote_request(); + } + + void send_remote_request() { + assert(image_ctx.owner_lock.is_locked()); + + CephContext *cct = image_ctx.cct; + ldout(cct, 20) << __func__ << dendl; + + Context *ctx = util::create_context_callback< + C_InvokeAsyncRequest, &C_InvokeAsyncRequest::handle_remote_request>( + this); + remote(ctx); + } + + void handle_remote_request(int r) { + CephContext *cct = image_ctx.cct; + ldout(cct, 20) << __func__ << ": r=" << r << dendl; + + if (r != -ETIMEDOUT && r != -ERESTART) { + complete(r); + return; + } + + ldout(cct, 5) << request_type << " timed out notifying lock owner" + << dendl; + send_acquire_exclusive_lock(); + } + + void send_local_request() { + assert(image_ctx.owner_lock.is_locked()); + + CephContext *cct = image_ctx.cct; + ldout(cct, 20) << __func__ << dendl; + + Context *ctx = util::create_context_callback< + C_InvokeAsyncRequest, &C_InvokeAsyncRequest::handle_local_request>( + this); + local(ctx); + } + + void handle_local_request(int r) { + CephContext *cct = image_ctx.cct; + ldout(cct, 20) << __func__ << ": r=" << r << dendl; + + if (r == -ERESTART) { + send_acquire_exclusive_lock(); + return; + } + complete(r); + } + + virtual void finish(int r) override { + on_finish->complete(r); + } +}; + } // anonymous namespace template @@ -85,7 +239,7 @@ int Operations::flatten(ProgressContext &prog_ctx) { boost::ref(prog_ctx), _1), boost::bind(&ImageWatcher::notify_flatten, m_image_ctx.image_watcher, request_id, - boost::ref(prog_ctx))); + boost::ref(prog_ctx), _1)); if (r < 0 && r != -EINVAL) { return r; @@ -161,7 +315,7 @@ int Operations::rebuild_object_map(ProgressContext &prog_ctx) { boost::ref(prog_ctx), _1), boost::bind(&ImageWatcher::notify_rebuild_object_map, m_image_ctx.image_watcher, request_id, - boost::ref(prog_ctx))); + boost::ref(prog_ctx), _1)); ldout(cct, 10) << "rebuild object map finished" << dendl; if (r < 0) { @@ -217,7 +371,8 @@ int Operations::rename(const char *dstname) { boost::bind(&Operations::rename, this, dstname, _1), boost::bind(&ImageWatcher::notify_rename, - m_image_ctx.image_watcher, dstname)); + m_image_ctx.image_watcher, dstname, + _1)); if (r < 0 && r != -EEXIST) { return r; } @@ -277,7 +432,7 @@ int Operations::resize(uint64_t size, ProgressContext& prog_ctx) { size, boost::ref(prog_ctx), _1, 0), boost::bind(&ImageWatcher::notify_resize, m_image_ctx.image_watcher, request_id, - size, boost::ref(prog_ctx))); + size, boost::ref(prog_ctx), _1)); m_image_ctx.perfcounter->inc(l_librbd_resize); ldout(cct, 2) << "resize finished" << dendl; @@ -337,7 +492,8 @@ int Operations::snap_create(const char *snap_name) { boost::bind(&Operations::snap_create, this, snap_name, _1, 0), boost::bind(&ImageWatcher::notify_snap_create, - m_image_ctx.image_watcher, snap_name)); + m_image_ctx.image_watcher, snap_name, + _1)); if (r < 0 && r != -EEXIST) { return r; } @@ -473,7 +629,8 @@ int Operations::snap_remove(const char *snap_name) { boost::bind(&Operations::snap_remove, this, snap_name, _1), boost::bind(&ImageWatcher::notify_snap_remove, - m_image_ctx.image_watcher, snap_name)); + m_image_ctx.image_watcher, snap_name, + _1)); if (r < 0 && r != -ENOENT) { return r; } @@ -568,7 +725,7 @@ int Operations::snap_rename(const char *srcname, const char *dstname) { snap_id, dstname, _1), boost::bind(&ImageWatcher::notify_snap_rename, m_image_ctx.image_watcher, snap_id, - dstname)); + dstname, _1)); if (r < 0 && r != -EEXIST) { return r; } @@ -642,7 +799,8 @@ int Operations::snap_protect(const char *snap_name) { boost::bind(&Operations::snap_protect, this, snap_name, _1), boost::bind(&ImageWatcher::notify_snap_protect, - m_image_ctx.image_watcher, snap_name)); + m_image_ctx.image_watcher, snap_name, + _1)); if (r < 0 && r != -EBUSY) { return r; } @@ -711,7 +869,8 @@ int Operations::snap_unprotect(const char *snap_name) { boost::bind(&Operations::snap_unprotect, this, snap_name, _1), boost::bind(&ImageWatcher::notify_snap_unprotect, - m_image_ctx.image_watcher, snap_name)); + m_image_ctx.image_watcher, snap_name, + _1)); if (r < 0 && r != -EINVAL) { return r; } @@ -781,46 +940,16 @@ template int Operations::invoke_async_request(const std::string& request_type, bool permit_snapshot, const boost::function& local_request, - const boost::function& remote_request) { - CephContext *cct = m_image_ctx.cct; - int r; - do { - C_SaferCond ctx; - { - RWLock::RLocker owner_locker(m_image_ctx.owner_lock); - { - RWLock::RLocker snap_locker(m_image_ctx.snap_lock); - if (m_image_ctx.read_only || - (!permit_snapshot && m_image_ctx.snap_id != CEPH_NOSNAP)) { - return -EROFS; - } - } - - while (m_image_ctx.exclusive_lock != nullptr) { - r = prepare_image_update(); - if (r < 0) { - return -EROFS; - } else if (m_image_ctx.exclusive_lock->is_lock_owner()) { - break; - } - - r = remote_request(); - if (r != -ETIMEDOUT && r != -ERESTART) { - return r; - } - ldout(cct, 5) << request_type << " timed out notifying lock owner" - << dendl; - } - - local_request(&ctx); - } - - r = ctx.wait(); - if (r == -ERESTART) { - ldout(cct, 5) << request_type << " interrupted: restarting" << dendl; - } - } while (r == -ERESTART); - return r; + const boost::function& remote_request) { + C_SaferCond ctx; + C_InvokeAsyncRequest *req = new C_InvokeAsyncRequest(m_image_ctx, + request_type, + permit_snapshot, + local_request, + remote_request, + &ctx); + req->send(); + return ctx.wait(); } } // namespace librbd diff --git a/src/librbd/Operations.h b/src/librbd/Operations.h index d1f437154003..b4ae3b431bfa 100644 --- a/src/librbd/Operations.h +++ b/src/librbd/Operations.h @@ -63,8 +63,8 @@ private: int invoke_async_request(const std::string& request_type, bool permit_snapshot, - const boost::function& local_request, - const boost::function& remote_request); + const boost::function& local, + const boost::function& remote); }; } // namespace librbd diff --git a/src/test/librbd/test_ImageWatcher.cc b/src/test/librbd/test_ImageWatcher.cc index 7e7f9eced0fd..a698e33b10e5 100644 --- a/src/test/librbd/test_ImageWatcher.cc +++ b/src/test/librbd/test_ImageWatcher.cc @@ -257,7 +257,9 @@ struct FlattenTask { void operator()() { RWLock::RLocker l(ictx->owner_lock); - result = ictx->image_watcher->notify_flatten(0, *progress_context); + C_SaferCond ctx; + ictx->image_watcher->notify_flatten(0, *progress_context, &ctx); + result = ctx.wait(); } }; @@ -271,7 +273,9 @@ struct ResizeTask { void operator()() { RWLock::RLocker l(ictx->owner_lock); - result = ictx->image_watcher->notify_resize(0, 0, *progress_context); + C_SaferCond ctx; + ictx->image_watcher->notify_resize(0, 0, *progress_context, &ctx); + result = ctx.wait(); } }; @@ -285,7 +289,9 @@ struct RebuildObjectMapTask { void operator()() { RWLock::RLocker l(ictx->owner_lock); - result = ictx->image_watcher->notify_rebuild_object_map(0, *progress_context); + C_SaferCond ctx; + ictx->image_watcher->notify_rebuild_object_map(0, *progress_context, &ctx); + result = ctx.wait(); } }; @@ -481,7 +487,9 @@ TEST_F(TestImageWatcher, NotifySnapCreate) { m_notify_acks = {{NOTIFY_OP_SNAP_CREATE, create_response_message(0)}}; RWLock::RLocker l(ictx->owner_lock); - ASSERT_EQ(0, ictx->image_watcher->notify_snap_create("snap")); + C_SaferCond notify_ctx; + ictx->image_watcher->notify_snap_create("snap", ¬ify_ctx); + ASSERT_EQ(0, notify_ctx.wait()); NotifyOps expected_notify_ops; expected_notify_ops += NOTIFY_OP_SNAP_CREATE; @@ -501,7 +509,9 @@ TEST_F(TestImageWatcher, NotifySnapCreateError) { m_notify_acks = {{NOTIFY_OP_SNAP_CREATE, create_response_message(-EEXIST)}}; RWLock::RLocker l(ictx->owner_lock); - ASSERT_EQ(-EEXIST, ictx->image_watcher->notify_snap_create("snap")); + C_SaferCond notify_ctx; + ictx->image_watcher->notify_snap_create("snap", ¬ify_ctx); + ASSERT_EQ(-EEXIST, notify_ctx.wait()); NotifyOps expected_notify_ops; expected_notify_ops += NOTIFY_OP_SNAP_CREATE; @@ -521,7 +531,9 @@ TEST_F(TestImageWatcher, NotifySnapRename) { m_notify_acks = {{NOTIFY_OP_SNAP_RENAME, create_response_message(0)}}; RWLock::RLocker l(ictx->owner_lock); - ASSERT_EQ(0, ictx->image_watcher->notify_snap_rename(1, "snap-rename")); + C_SaferCond notify_ctx; + ictx->image_watcher->notify_snap_rename(1, "snap-rename", ¬ify_ctx); + ASSERT_EQ(0, notify_ctx.wait()); NotifyOps expected_notify_ops; expected_notify_ops += NOTIFY_OP_SNAP_RENAME; @@ -541,7 +553,9 @@ TEST_F(TestImageWatcher, NotifySnapRenameError) { m_notify_acks = {{NOTIFY_OP_SNAP_RENAME, create_response_message(-EEXIST)}}; RWLock::RLocker l(ictx->owner_lock); - ASSERT_EQ(-EEXIST, ictx->image_watcher->notify_snap_rename(1, "snap-rename")); + C_SaferCond notify_ctx; + ictx->image_watcher->notify_snap_rename(1, "snap-rename", ¬ify_ctx); + ASSERT_EQ(-EEXIST, notify_ctx.wait()); NotifyOps expected_notify_ops; expected_notify_ops += NOTIFY_OP_SNAP_RENAME; @@ -561,7 +575,9 @@ TEST_F(TestImageWatcher, NotifySnapRemove) { m_notify_acks = {{NOTIFY_OP_SNAP_REMOVE, create_response_message(0)}}; RWLock::RLocker l(ictx->owner_lock); - ASSERT_EQ(0, ictx->image_watcher->notify_snap_remove("snap")); + C_SaferCond notify_ctx; + ictx->image_watcher->notify_snap_remove("snap", ¬ify_ctx); + ASSERT_EQ(0, notify_ctx.wait()); NotifyOps expected_notify_ops; expected_notify_ops += NOTIFY_OP_SNAP_REMOVE; @@ -581,7 +597,9 @@ TEST_F(TestImageWatcher, NotifySnapProtect) { m_notify_acks = {{NOTIFY_OP_SNAP_PROTECT, create_response_message(0)}}; RWLock::RLocker l(ictx->owner_lock); - ASSERT_EQ(0, ictx->image_watcher->notify_snap_protect("snap")); + C_SaferCond notify_ctx; + ictx->image_watcher->notify_snap_protect("snap", ¬ify_ctx); + ASSERT_EQ(0, notify_ctx.wait()); NotifyOps expected_notify_ops; expected_notify_ops += NOTIFY_OP_SNAP_PROTECT; @@ -601,7 +619,9 @@ TEST_F(TestImageWatcher, NotifySnapUnprotect) { m_notify_acks = {{NOTIFY_OP_SNAP_UNPROTECT, create_response_message(0)}}; RWLock::RLocker l(ictx->owner_lock); - ASSERT_EQ(0, ictx->image_watcher->notify_snap_unprotect("snap")); + C_SaferCond notify_ctx; + ictx->image_watcher->notify_snap_unprotect("snap", ¬ify_ctx); + ASSERT_EQ(0, notify_ctx.wait()); NotifyOps expected_notify_ops; expected_notify_ops += NOTIFY_OP_SNAP_UNPROTECT; @@ -621,7 +641,9 @@ TEST_F(TestImageWatcher, NotifyRename) { m_notify_acks = {{NOTIFY_OP_RENAME, create_response_message(0)}}; RWLock::RLocker l(ictx->owner_lock); - ASSERT_EQ(0, ictx->image_watcher->notify_rename("new_name")); + C_SaferCond notify_ctx; + ictx->image_watcher->notify_rename("new_name", ¬ify_ctx); + ASSERT_EQ(0, notify_ctx.wait()); NotifyOps expected_notify_ops; expected_notify_ops += NOTIFY_OP_RENAME; @@ -720,6 +742,6 @@ TEST_F(TestImageWatcher, NotifyAsyncRequestTimedOut) { ASSERT_TRUE(wait_for_notifies(*ictx)); ASSERT_TRUE(thread.timed_join(boost::posix_time::seconds(10))); - ASSERT_EQ(-ERESTART, flatten_task.result); + ASSERT_EQ(-ETIMEDOUT, flatten_task.result); }