]> git.proxmox.com Git - ceph.git/blame - ceph/src/librbd/image_watcher/NotifyLockOwner.cc
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / librbd / image_watcher / NotifyLockOwner.cc
CommitLineData
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
17namespace librbd {
18
19namespace image_watcher {
20
21using namespace watch_notify;
22using util::create_context_callback;
23
24NotifyLockOwner::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
31void NotifyLockOwner::send() {
32 send_notify();
33}
34
35void 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
44void 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
89void NotifyLockOwner::finish(int r) {
90 m_on_finish->complete(r);
91 delete this;
92}
93
94} // namespace image_watcher
95} // namespace librbd