Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / librbd / mirror / GetStatusRequest.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/GetStatusRequest.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::GetStatusRequest: " << this \
17                            << " " << __func__ << ": "
18
19 namespace librbd {
20 namespace mirror {
21
22 using librbd::util::create_context_callback;
23 using librbd::util::create_rados_callback;
24
25 template <typename I>
26 void GetStatusRequest<I>::send() {
27   *m_mirror_image_status = cls::rbd::MirrorImageStatus(
28     cls::rbd::MIRROR_IMAGE_STATUS_STATE_UNKNOWN, "status not found");
29
30   get_info();
31 }
32
33 template <typename I>
34 void GetStatusRequest<I>::get_info() {
35   CephContext *cct = m_image_ctx.cct;
36   ldout(cct, 20) << dendl;
37
38   auto ctx = create_context_callback<
39     GetStatusRequest<I>, &GetStatusRequest<I>::handle_get_info>(this);
40   auto req = GetInfoRequest<I>::create(m_image_ctx, m_mirror_image,
41                                        m_promotion_state, ctx);
42   req->send();
43 }
44
45 template <typename I>
46 void GetStatusRequest<I>::handle_get_info(int r) {
47   CephContext *cct = m_image_ctx.cct;
48   ldout(cct, 20) << "r=" << r << dendl;
49
50   if (r < 0) {
51     lderr(cct) << "failed to retrieve mirroring state: " << cpp_strerror(r)
52                << dendl;
53     finish(r);
54     return;
55   } else if (m_mirror_image->state != cls::rbd::MIRROR_IMAGE_STATE_ENABLED) {
56     finish(0);
57     return;
58   }
59
60   get_status();
61 }
62
63 template <typename I>
64 void GetStatusRequest<I>::get_status() {
65   CephContext *cct = m_image_ctx.cct;
66   ldout(cct, 20) << dendl;
67
68   librados::ObjectReadOperation op;
69   cls_client::mirror_image_status_get_start(
70     &op, m_mirror_image->global_image_id);
71
72   librados::AioCompletion *comp = create_rados_callback<
73     GetStatusRequest<I>, &GetStatusRequest<I>::handle_get_status>(this);
74   int r = m_image_ctx.md_ctx.aio_operate(RBD_MIRRORING, comp, &op, &m_out_bl);
75   assert(r == 0);
76   comp->release();
77 }
78
79 template <typename I>
80 void GetStatusRequest<I>::handle_get_status(int r) {
81   CephContext *cct = m_image_ctx.cct;
82   ldout(cct, 20) << "r=" << r << dendl;
83
84   if (r == 0) {
85     bufferlist::iterator iter = m_out_bl.begin();
86     r = cls_client::mirror_image_status_get_finish(&iter,
87                                                    m_mirror_image_status);
88   }
89
90   if (r < 0 && r != -ENOENT) {
91     lderr(cct) << "failed to retrieve mirror image status: " << cpp_strerror(r)
92                << dendl;
93     finish(r);
94     return;
95   }
96
97   finish(0);
98 }
99
100 template <typename I>
101 void GetStatusRequest<I>::finish(int r) {
102   CephContext *cct = m_image_ctx.cct;
103   ldout(cct, 20) << "r=" << r << dendl;
104
105   m_on_finish->complete(r);
106   delete this;
107 }
108
109 } // namespace mirror
110 } // namespace librbd
111
112 template class librbd::mirror::GetStatusRequest<librbd::ImageCtx>;