1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "librbd/mirror/DemoteRequest.h"
5 #include "common/dout.h"
6 #include "common/errno.h"
7 #include "cls/rbd/cls_rbd_client.h"
8 #include "librbd/ExclusiveLock.h"
9 #include "librbd/ImageCtx.h"
10 #include "librbd/ImageState.h"
11 #include "librbd/Journal.h"
12 #include "librbd/Utils.h"
13 #include "librbd/mirror/GetInfoRequest.h"
15 #define dout_subsys ceph_subsys_rbd
17 #define dout_prefix *_dout << "librbd::mirror::DemoteRequest: " << this \
18 << " " << __func__ << ": "
23 using librbd::util::create_context_callback
;
26 void DemoteRequest
<I
>::send() {
31 void DemoteRequest
<I
>::get_info() {
32 CephContext
*cct
= m_image_ctx
.cct
;
33 ldout(cct
, 20) << dendl
;
35 auto ctx
= create_context_callback
<
36 DemoteRequest
<I
>, &DemoteRequest
<I
>::handle_get_info
>(this);
37 auto req
= GetInfoRequest
<I
>::create(m_image_ctx
, &m_mirror_image
,
38 &m_promotion_state
, ctx
);
43 void DemoteRequest
<I
>::handle_get_info(int r
) {
44 CephContext
*cct
= m_image_ctx
.cct
;
45 ldout(cct
, 20) << "r=" << r
<< dendl
;
48 lderr(cct
) << "failed to retrieve mirroring state: " << cpp_strerror(r
)
52 } else if (m_mirror_image
.state
!= cls::rbd::MIRROR_IMAGE_STATE_ENABLED
) {
53 lderr(cct
) << "mirroring is not currently enabled" << dendl
;
56 } else if (m_promotion_state
!= PROMOTION_STATE_PRIMARY
) {
57 lderr(cct
) << "image is not primary" << dendl
;
66 void DemoteRequest
<I
>::acquire_lock() {
67 CephContext
*cct
= m_image_ctx
.cct
;
69 m_image_ctx
.owner_lock
.get_read();
70 if (m_image_ctx
.exclusive_lock
== nullptr) {
71 m_image_ctx
.owner_lock
.put_read();
72 lderr(cct
) << "exclusive lock is not active" << dendl
;
77 // avoid accepting new requests from peers while we demote
79 m_image_ctx
.exclusive_lock
->block_requests(0);
80 m_blocked_requests
= true;
82 if (m_image_ctx
.exclusive_lock
->is_lock_owner()) {
83 m_image_ctx
.owner_lock
.put_read();
88 ldout(cct
, 20) << dendl
;
90 auto ctx
= create_context_callback
<
91 DemoteRequest
<I
>, &DemoteRequest
<I
>::handle_acquire_lock
>(this);
92 m_image_ctx
.exclusive_lock
->acquire_lock(ctx
);
93 m_image_ctx
.owner_lock
.put_read();
97 void DemoteRequest
<I
>::handle_acquire_lock(int r
) {
98 CephContext
*cct
= m_image_ctx
.cct
;
99 ldout(cct
, 20) << "r=" << r
<< dendl
;
102 lderr(cct
) << "failed to lock image: " << cpp_strerror(r
) << dendl
;
107 m_image_ctx
.owner_lock
.get_read();
108 if (m_image_ctx
.exclusive_lock
!= nullptr &&
109 !m_image_ctx
.exclusive_lock
->is_lock_owner()) {
110 r
= m_image_ctx
.exclusive_lock
->get_unlocked_op_error();
111 m_image_ctx
.owner_lock
.put_read();
112 lderr(cct
) << "failed to acquire exclusive lock" << dendl
;
116 m_image_ctx
.owner_lock
.put_read();
121 template <typename I
>
122 void DemoteRequest
<I
>::demote() {
123 CephContext
*cct
= m_image_ctx
.cct
;
124 ldout(cct
, 20) << dendl
;
126 auto ctx
= create_context_callback
<
127 DemoteRequest
<I
>, &DemoteRequest
<I
>::handle_demote
>(this);
128 Journal
<I
>::demote(&m_image_ctx
, ctx
);
131 template <typename I
>
132 void DemoteRequest
<I
>::handle_demote(int r
) {
133 CephContext
*cct
= m_image_ctx
.cct
;
134 ldout(cct
, 20) << "r=" << r
<< dendl
;
138 lderr(cct
) << "failed to demote image: " << cpp_strerror(r
) << dendl
;
144 template <typename I
>
145 void DemoteRequest
<I
>::release_lock() {
146 CephContext
*cct
= m_image_ctx
.cct
;
147 ldout(cct
, 20) << dendl
;
149 m_image_ctx
.owner_lock
.get_read();
150 if (m_image_ctx
.exclusive_lock
== nullptr) {
151 m_image_ctx
.owner_lock
.put_read();
156 auto ctx
= create_context_callback
<
157 DemoteRequest
<I
>, &DemoteRequest
<I
>::handle_release_lock
>(this);
158 m_image_ctx
.exclusive_lock
->release_lock(ctx
);
159 m_image_ctx
.owner_lock
.put_read();
162 template <typename I
>
163 void DemoteRequest
<I
>::handle_release_lock(int r
) {
164 CephContext
*cct
= m_image_ctx
.cct
;
165 ldout(cct
, 20) << "r=" << r
<< dendl
;
168 lderr(cct
) << "failed to release exclusive lock: " << cpp_strerror(r
)
175 template <typename I
>
176 void DemoteRequest
<I
>::finish(int r
) {
182 RWLock::RLocker
owner_locker(m_image_ctx
.owner_lock
);
183 if (m_blocked_requests
&& m_image_ctx
.exclusive_lock
!= nullptr) {
184 m_image_ctx
.exclusive_lock
->unblock_requests();
188 CephContext
*cct
= m_image_ctx
.cct
;
189 ldout(cct
, 20) << "r=" << r
<< dendl
;
191 m_on_finish
->complete(r
);
195 } // namespace mirror
196 } // namespace librbd
198 template class librbd::mirror::DemoteRequest
<librbd::ImageCtx
>;