Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / librbd / image_watcher / NotifyLockOwner.cc
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 &notifier,
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
39   assert(m_image_ctx.owner_lock.is_locked());
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 {
76     bufferlist::iterator iter = response.begin();
77
78     ResponseMessage response_message;
79     ::decode(response_message, iter);
80
81     r = response_message.result;
82   } catch (const buffer::error &err) {
83     r = -EINVAL;
84   }
85   finish(r);
86 }
87
88 void NotifyLockOwner::finish(int r) {
89   m_on_finish->complete(r);
90   delete this;
91 }
92
93 } // namespace image_watcher
94 } // namespace librbd