Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / librbd / mirror / PromoteRequest.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/mirror/PromoteRequest.h"
5 #include "common/dout.h"
6 #include "common/errno.h"
7 #include "cls/rbd/cls_rbd_client.h"
8 #include "librbd/ImageCtx.h"
9 #include "librbd/ImageState.h"
10 #include "librbd/Journal.h"
11 #include "librbd/Utils.h"
12 #include "librbd/mirror/GetInfoRequest.h"
13
14 #define dout_subsys ceph_subsys_rbd
15 #undef dout_prefix
16 #define dout_prefix *_dout << "librbd::mirror::PromoteRequest: " << this \
17                            << " " << __func__ << ": "
18
19 namespace librbd {
20 namespace mirror {
21
22 using librbd::util::create_context_callback;
23
24 template <typename I>
25 void PromoteRequest<I>::send() {
26   get_info();
27 }
28
29 template <typename I>
30 void PromoteRequest<I>::get_info() {
31   CephContext *cct = m_image_ctx.cct;
32   ldout(cct, 20) << dendl;
33
34   auto ctx = create_context_callback<
35     PromoteRequest<I>, &PromoteRequest<I>::handle_get_info>(this);
36   auto req = GetInfoRequest<I>::create(m_image_ctx, &m_mirror_image,
37                                        &m_promotion_state, ctx);
38   req->send();
39 }
40
41 template <typename I>
42 void PromoteRequest<I>::handle_get_info(int r) {
43   CephContext *cct = m_image_ctx.cct;
44   ldout(cct, 20) << "r=" << r << dendl;
45
46   if (r < 0) {
47     lderr(cct) << "failed to retrieve mirroring state: " << cpp_strerror(r)
48                << dendl;
49     finish(r);
50     return;
51   } else if (m_mirror_image.state != cls::rbd::MIRROR_IMAGE_STATE_ENABLED) {
52     lderr(cct) << "mirroring is not currently enabled" << dendl;
53     finish(-EINVAL);
54     return;
55   } else if (m_promotion_state == PROMOTION_STATE_PRIMARY) {
56     lderr(cct) << "image is already primary" << dendl;
57     finish(-EINVAL);
58     return;
59   } else if (m_promotion_state == PROMOTION_STATE_NON_PRIMARY && !m_force) {
60     lderr(cct) << "image is still primary within a remote cluster" << dendl;
61     finish(-EBUSY);
62     return;
63   }
64
65   promote();
66 }
67
68 template <typename I>
69 void PromoteRequest<I>::promote() {
70   CephContext *cct = m_image_ctx.cct;
71   ldout(cct, 20) << dendl;
72
73   auto ctx = create_context_callback<
74     PromoteRequest<I>, &PromoteRequest<I>::handle_promote>(this);
75   Journal<I>::promote(&m_image_ctx, ctx);
76 }
77
78 template <typename I>
79 void PromoteRequest<I>::handle_promote(int r) {
80   CephContext *cct = m_image_ctx.cct;
81   ldout(cct, 20) << "r=" << r << dendl;
82
83   if (r < 0) {
84     lderr(cct) << "failed to promote image: " << cpp_strerror(r)
85                << dendl;
86   }
87
88   finish(r);
89 }
90
91 template <typename I>
92 void PromoteRequest<I>::finish(int r) {
93   CephContext *cct = m_image_ctx.cct;
94   ldout(cct, 20) << "r=" << r << dendl;
95
96   m_on_finish->complete(r);
97   delete this;
98 }
99
100 } // namespace mirror
101 } // namespace librbd
102
103 template class librbd::mirror::PromoteRequest<librbd::ImageCtx>;