]>
git.proxmox.com Git - ceph.git/blob - ceph/src/tools/rbd_mirror/image_map/LoadRequest.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "common/debug.h"
5 #include "common/errno.h"
7 #include "librbd/Utils.h"
8 #include "include/rbd_types.h"
9 #include "cls/rbd/cls_rbd_client.h"
11 #include "UpdateRequest.h"
12 #include "LoadRequest.h"
14 #define dout_context g_ceph_context
15 #define dout_subsys ceph_subsys_rbd_mirror
17 #define dout_prefix *_dout << "rbd::mirror::image_map::LoadRequest: " \
18 << this << " " << __func__
24 static const uint32_t MAX_RETURN
= 1024;
26 using librbd::util::create_rados_callback
;
27 using librbd::util::create_context_callback
;
30 LoadRequest
<I
>::LoadRequest(librados::IoCtx
&ioctx
,
31 std::map
<std::string
, cls::rbd::MirrorImageMap
> *image_mapping
,
34 m_image_mapping(image_mapping
),
35 m_on_finish(on_finish
) {
39 void LoadRequest
<I
>::send() {
46 void LoadRequest
<I
>::image_map_list() {
49 librados::ObjectReadOperation op
;
50 librbd::cls_client::mirror_image_map_list_start(&op
, m_start_after
, MAX_RETURN
);
52 librados::AioCompletion
*aio_comp
= create_rados_callback
<
53 LoadRequest
, &LoadRequest::handle_image_map_list
>(this);
56 int r
= m_ioctx
.aio_operate(RBD_MIRROR_LEADER
, aio_comp
, &op
, &m_out_bl
);
62 void LoadRequest
<I
>::handle_image_map_list(int r
) {
63 dout(20) << ": r=" << r
<< dendl
;
65 std::map
<std::string
, cls::rbd::MirrorImageMap
> image_mapping
;
67 auto it
= m_out_bl
.cbegin();
68 r
= librbd::cls_client::mirror_image_map_list_finish(&it
, &image_mapping
);
72 derr
<< ": failed to get image map: " << cpp_strerror(r
) << dendl
;
77 m_image_mapping
->insert(image_mapping
.begin(), image_mapping
.end());
79 if (image_mapping
.size() == MAX_RETURN
) {
80 m_start_after
= image_mapping
.rbegin()->first
;
89 void LoadRequest
<I
>::mirror_image_list() {
92 librados::ObjectReadOperation op
;
93 librbd::cls_client::mirror_image_list_start(&op
, m_start_after
, MAX_RETURN
);
96 librados::AioCompletion
*aio_comp
= create_rados_callback
<
98 &LoadRequest
<I
>::handle_mirror_image_list
>(this);
99 int r
= m_ioctx
.aio_operate(RBD_MIRRORING
, aio_comp
, &op
, &m_out_bl
);
105 void LoadRequest
<I
>::handle_mirror_image_list(int r
) {
106 dout(20) << ": r=" << r
<< dendl
;
108 std::map
<std::string
, std::string
> ids
;
110 auto it
= m_out_bl
.cbegin();
111 r
= librbd::cls_client::mirror_image_list_finish(&it
, &ids
);
114 if (r
< 0 && r
!= -ENOENT
) {
115 derr
<< "failed to list mirrored images: " << cpp_strerror(r
) << dendl
;
120 for (auto &id
: ids
) {
121 m_global_image_ids
.emplace(id
.second
);
124 if (ids
.size() == MAX_RETURN
) {
125 m_start_after
= ids
.rbegin()->first
;
134 void LoadRequest
<I
>::cleanup_image_map() {
137 std::set
<std::string
> map_removals
;
139 auto it
= m_image_mapping
->begin();
140 while (it
!= m_image_mapping
->end()) {
141 if (m_global_image_ids
.count(it
->first
) > 0) {
145 map_removals
.emplace(it
->first
);
146 it
= m_image_mapping
->erase(it
);
149 if (map_removals
.size() == 0) {
154 auto ctx
= create_context_callback
<
156 &LoadRequest
<I
>::finish
>(this);
157 image_map::UpdateRequest
<I
> *req
= image_map::UpdateRequest
<I
>::create(
158 m_ioctx
, {}, std::move(map_removals
), ctx
);
163 void LoadRequest
<I
>::finish(int r
) {
164 dout(20) << ": r=" << r
<< dendl
;
166 m_on_finish
->complete(r
);
170 } // namespace image_map
171 } // namespace mirror
174 template class rbd::mirror::image_map::LoadRequest
<librbd::ImageCtx
>;