template <typename I>
MirrorStatusWatcher<I>::MirrorStatusWatcher(librados::IoCtx &io_ctx,
librbd::asio::ContextWQ *work_queue)
- : Watcher(io_ctx, work_queue, RBD_MIRRORING) {
+ : Watcher(io_ctx, work_queue, RBD_MIRRORING),
+ m_lock(ceph::make_mutex("rbd::mirror::MirrorStatusWatcher " +
+ stringify(io_ctx.get_id()))) {
}
template <typename I>
MirrorStatusWatcher<I>::~MirrorStatusWatcher() {
+ ceph_assert(m_on_start_finish == nullptr);
}
template <typename I>
register_watch(on_finish);
});
- remove_down_image_status(on_finish);
+ {
+ std::lock_guard locker{m_lock};
+ ceph_assert(m_on_start_finish == nullptr);
+ std::swap(m_on_start_finish, on_finish);
+ }
+
+ remove_down_image_status();
}
template <typename I>
-void MirrorStatusWatcher<I>::remove_down_image_status(Context *on_finish) {
+void MirrorStatusWatcher<I>::remove_down_image_status() {
dout(20) << dendl;
librados::ObjectWriteOperation op;
librbd::cls_client::mirror_image_status_remove_down(&op);
auto comp = create_rados_callback(
- new LambdaContext([this, on_finish](int r) {
- handle_remove_down_image_status(r, on_finish);
+ new LambdaContext([this](int r) {
+ handle_remove_down_image_status(r);
}));
int r = m_ioctx.aio_operate(RBD_MIRRORING, comp, &op);
}
template <typename I>
-void MirrorStatusWatcher<I>::handle_remove_down_image_status(int r,
- Context *on_finish) {
+void MirrorStatusWatcher<I>::handle_remove_down_image_status(int r) {
dout(20) << "r=" << r << dendl;
- remove_down_group_status(on_finish);
+ remove_down_group_status();
}
template <typename I>
-void MirrorStatusWatcher<I>::remove_down_group_status(Context *on_finish) {
+void MirrorStatusWatcher<I>::remove_down_group_status() {
dout(20) << dendl;
librados::ObjectWriteOperation op;
librbd::cls_client::mirror_group_status_remove_down(&op);
auto comp = create_rados_callback(
- new LambdaContext([this, on_finish](int r) {
- handle_remove_down_group_status(r, on_finish);
+ new LambdaContext([this](int r) {
+ handle_remove_down_group_status(r);
}));
int r = m_ioctx.aio_operate(RBD_MIRRORING, comp, &op);
}
template <typename I>
-void MirrorStatusWatcher<I>::handle_remove_down_group_status(int r,
- Context *on_finish) {
+void MirrorStatusWatcher<I>::handle_remove_down_group_status(int r) {
dout(20) << "r=" << r << dendl;
- on_finish->complete(r);
+ Context *on_finish = nullptr;
+ {
+ std::lock_guard locker{m_lock};
+ std::swap(m_on_start_finish, on_finish);
+ }
+
+ if (on_finish) {
+ on_finish->complete(0);
+ }
}
template <typename I>
~MirrorStatusWatcher() override;
void init(Context *on_finish);
- void remove_down_image_status(Context *on_finish);
- void handle_remove_down_image_status(int r, Context *on_finish);
- void remove_down_group_status(Context *on_finish);
- void handle_remove_down_group_status(int r, Context *on_finish);
void shut_down(Context *on_finish);
+private:
+ mutable ceph::mutex m_lock;
+ Context* m_on_start_finish = nullptr;
+
+ void remove_down_image_status();
+ void handle_remove_down_image_status(int r);
+ void remove_down_group_status();
+ void handle_remove_down_group_status(int r);
+
protected:
void handle_notify(uint64_t notify_id, uint64_t handle,
uint64_t notifier_id, bufferlist &bl) override;