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