]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | ||
4 | #include "librbd/image_watcher/NotifyLockOwner.h" | |
5 | #include "common/errno.h" | |
6 | #include "librbd/ImageCtx.h" | |
7 | #include "librbd/Utils.h" | |
8 | #include "librbd/WatchNotifyTypes.h" | |
9 | #include "librbd/watcher/Notifier.h" | |
10 | #include <map> | |
11 | ||
12 | #define dout_subsys ceph_subsys_rbd | |
13 | #undef dout_prefix | |
14 | #define dout_prefix *_dout << "librbd::image_watcher::NotifyLockOwner: " \ | |
15 | << this << " " << __func__ | |
16 | ||
17 | namespace librbd { | |
18 | ||
19 | namespace image_watcher { | |
20 | ||
21 | using namespace watch_notify; | |
22 | using util::create_context_callback; | |
23 | ||
24 | NotifyLockOwner::NotifyLockOwner(ImageCtx &image_ctx, | |
25 | watcher::Notifier ¬ifier, | |
26 | bufferlist &&bl, Context *on_finish) | |
27 | : m_image_ctx(image_ctx), m_notifier(notifier), m_bl(std::move(bl)), | |
28 | m_on_finish(on_finish) { | |
29 | } | |
30 | ||
31 | void NotifyLockOwner::send() { | |
32 | send_notify(); | |
33 | } | |
34 | ||
35 | void NotifyLockOwner::send_notify() { | |
36 | CephContext *cct = m_image_ctx.cct; | |
37 | ldout(cct, 20) << dendl; | |
38 | ||
11fdf7f2 | 39 | ceph_assert(m_image_ctx.owner_lock.is_locked()); |
7c673cae FG |
40 | m_notifier.notify(m_bl, &m_notify_response, create_context_callback< |
41 | NotifyLockOwner, &NotifyLockOwner::handle_notify>(this)); | |
42 | } | |
43 | ||
44 | void NotifyLockOwner::handle_notify(int r) { | |
45 | CephContext *cct = m_image_ctx.cct; | |
46 | ldout(cct, 20) << ": r=" << r << dendl; | |
47 | ||
48 | if (r < 0 && r != -ETIMEDOUT) { | |
49 | lderr(cct) << ": lock owner notification failed: " << cpp_strerror(r) | |
50 | << dendl; | |
51 | finish(r); | |
52 | return; | |
53 | } | |
54 | ||
55 | bufferlist response; | |
56 | bool lock_owner_responded = false; | |
57 | for (auto &it : m_notify_response.acks) { | |
58 | if (it.second.length() > 0) { | |
59 | if (lock_owner_responded) { | |
60 | lderr(cct) << ": duplicate lock owners detected" << dendl; | |
61 | finish(-EINVAL); | |
62 | return; | |
63 | } | |
64 | lock_owner_responded = true; | |
65 | response.claim(it.second); | |
66 | } | |
67 | } | |
68 | ||
69 | if (!lock_owner_responded) { | |
70 | ldout(cct, 1) << ": no lock owners detected" << dendl; | |
71 | finish(-ETIMEDOUT); | |
72 | return; | |
73 | } | |
74 | ||
75 | try { | |
11fdf7f2 | 76 | auto iter = response.cbegin(); |
7c673cae FG |
77 | |
78 | ResponseMessage response_message; | |
11fdf7f2 TL |
79 | using ceph::decode; |
80 | decode(response_message, iter); | |
7c673cae FG |
81 | |
82 | r = response_message.result; | |
83 | } catch (const buffer::error &err) { | |
84 | r = -EINVAL; | |
85 | } | |
86 | finish(r); | |
87 | } | |
88 | ||
89 | void NotifyLockOwner::finish(int r) { | |
90 | m_on_finish->complete(r); | |
91 | delete this; | |
92 | } | |
93 | ||
94 | } // namespace image_watcher | |
95 | } // namespace librbd |