-
Notifications
You must be signed in to change notification settings - Fork 5.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
rbd-mirror: load/update image map state machine
Signed-off-by: Venky Shankar <vshankar@redhat.com>
- Loading branch information
Showing
5 changed files
with
330 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- | ||
// vim: ts=8 sw=2 smarttab | ||
|
||
#include "common/debug.h" | ||
#include "common/errno.h" | ||
|
||
#include "librbd/Utils.h" | ||
#include "include/rbd_types.h" | ||
#include "cls/rbd/cls_rbd_client.h" | ||
|
||
#include "LoadRequest.h" | ||
|
||
#define dout_context g_ceph_context | ||
#define dout_subsys ceph_subsys_rbd_mirror | ||
#undef dout_prefix | ||
#define dout_prefix *_dout << "rbd::mirror::image_map::LoadRequest: " \ | ||
<< this << " " << __func__ | ||
|
||
namespace rbd { | ||
namespace mirror { | ||
namespace image_map { | ||
|
||
static const uint32_t MAX_RETURN = 1024; | ||
|
||
using librbd::util::create_rados_callback; | ||
|
||
template<typename I> | ||
LoadRequest<I>::LoadRequest(librados::IoCtx &ioctx, | ||
std::map<std::string, cls::rbd::MirrorImageMap> *image_mapping, | ||
Context *on_finish) | ||
: m_ioctx(ioctx), | ||
m_image_mapping(image_mapping), | ||
m_on_finish(on_finish) { | ||
} | ||
|
||
template<typename I> | ||
void LoadRequest<I>::send() { | ||
dout(20) << dendl; | ||
|
||
image_map_list(); | ||
} | ||
|
||
template<typename I> | ||
void LoadRequest<I>::image_map_list() { | ||
dout(20) << dendl; | ||
|
||
librados::ObjectReadOperation op; | ||
librbd::cls_client::mirror_image_map_list_start(&op, m_start_after, MAX_RETURN); | ||
|
||
librados::AioCompletion *aio_comp = create_rados_callback< | ||
LoadRequest, &LoadRequest::handle_image_map_list>(this); | ||
|
||
m_out_bl.clear(); | ||
int r = m_ioctx.aio_operate(RBD_MIRROR_LEADER, aio_comp, &op, &m_out_bl); | ||
assert(r == 0); | ||
aio_comp->release(); | ||
} | ||
|
||
template<typename I> | ||
void LoadRequest<I>::handle_image_map_list(int r) { | ||
dout(20) << ": r=" << r << dendl; | ||
|
||
std::map<std::string, cls::rbd::MirrorImageMap> image_mapping; | ||
if (r == 0) { | ||
bufferlist::iterator it = m_out_bl.begin(); | ||
r = librbd::cls_client::mirror_image_map_list_finish(&it, &image_mapping); | ||
} | ||
|
||
if (r < 0) { | ||
derr << ": failed to get image map: " << cpp_strerror(r) << dendl; | ||
finish(r); | ||
return; | ||
} | ||
|
||
m_image_mapping->insert(image_mapping.begin(), image_mapping.end()); | ||
|
||
if (image_mapping.size() == MAX_RETURN) { | ||
m_start_after = image_mapping.rbegin()->first; | ||
image_map_list(); | ||
return; | ||
} | ||
|
||
finish(0); | ||
} | ||
|
||
template<typename I> | ||
void LoadRequest<I>::finish(int r) { | ||
dout(20) << ": r=" << r << dendl; | ||
|
||
m_on_finish->complete(r); | ||
delete this; | ||
} | ||
|
||
} // namespace image_map | ||
} // namespace mirror | ||
} // namespace rbd | ||
|
||
template class rbd::mirror::image_map::LoadRequest<librbd::ImageCtx>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- | ||
// vim: ts=8 sw=2 smarttab | ||
|
||
#ifndef CEPH_RBD_MIRROR_IMAGE_MAP_LOAD_REQUEST_H | ||
#define CEPH_RBD_MIRROR_IMAGE_MAP_LOAD_REQUEST_H | ||
|
||
#include "cls/rbd/cls_rbd_types.h" | ||
#include "include/rados/librados.hpp" | ||
|
||
class Context; | ||
|
||
namespace librbd { class ImageCtx; } | ||
|
||
namespace rbd { | ||
namespace mirror { | ||
namespace image_map { | ||
|
||
template<typename ImageCtxT = librbd::ImageCtx> | ||
class LoadRequest { | ||
public: | ||
static LoadRequest *create(librados::IoCtx &ioctx, | ||
std::map<std::string, cls::rbd::MirrorImageMap> *image_mapping, | ||
Context *on_finish) { | ||
return new LoadRequest(ioctx, image_mapping, on_finish); | ||
} | ||
|
||
void send(); | ||
|
||
private: | ||
/** | ||
* @verbatim | ||
* | ||
* <start> | ||
* | . . . . . . . . | ||
* v v . MAX_RETURN | ||
* IMAGE_MAP_LIST. . . . . . . | ||
* | | ||
* v | ||
* <finish> | ||
* | ||
* @endverbatim | ||
*/ | ||
LoadRequest(librados::IoCtx &ioctx, | ||
std::map<std::string, cls::rbd::MirrorImageMap> *image_mapping, | ||
Context *on_finish); | ||
|
||
librados::IoCtx &m_ioctx; | ||
std::map<std::string, cls::rbd::MirrorImageMap> *m_image_mapping; | ||
Context *m_on_finish; | ||
|
||
bufferlist m_out_bl; | ||
std::string m_start_after; | ||
|
||
void image_map_list(); | ||
void handle_image_map_list(int r); | ||
|
||
void finish(int r); | ||
}; | ||
|
||
} // namespace image_map | ||
} // namespace mirror | ||
} // namespace rbd | ||
|
||
#endif // CEPH_RBD_MIRROR_IMAGE_MAP_LOAD_REQUEST_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- | ||
// vim: ts=8 sw=2 smarttab | ||
|
||
#include "common/debug.h" | ||
#include "common/errno.h" | ||
|
||
#include "librbd/Utils.h" | ||
#include "include/rbd_types.h" | ||
#include "cls/rbd/cls_rbd_client.h" | ||
|
||
#include "UpdateRequest.h" | ||
|
||
#define dout_context g_ceph_context | ||
#define dout_subsys ceph_subsys_rbd_mirror | ||
#undef dout_prefix | ||
#define dout_prefix *_dout << "rbd::mirror::image_map::UpdateRequest: " \ | ||
<< this << " " << __func__ | ||
|
||
namespace rbd { | ||
namespace mirror { | ||
namespace image_map { | ||
|
||
using librbd::util::create_rados_callback; | ||
|
||
static const uint32_t MAX_UPDATE = 256; | ||
|
||
template <typename I> | ||
UpdateRequest<I>::UpdateRequest(librados::IoCtx &ioctx, | ||
std::map<std::string, cls::rbd::MirrorImageMap> &&update_mapping, | ||
std::set<std::string> &&remove_global_image_ids, Context *on_finish) | ||
: m_ioctx(ioctx), | ||
m_update_mapping(update_mapping), | ||
m_remove_global_image_ids(remove_global_image_ids), | ||
m_on_finish(on_finish) { | ||
} | ||
|
||
template <typename I> | ||
void UpdateRequest<I>::send() { | ||
dout(20) << dendl; | ||
|
||
update_image_map(); | ||
} | ||
|
||
template <typename I> | ||
void UpdateRequest<I>::update_image_map() { | ||
dout(20) << dendl; | ||
|
||
if (m_update_mapping.empty() && m_remove_global_image_ids.empty()) { | ||
finish(0); | ||
return; | ||
} | ||
|
||
uint32_t nr_updates = 0; | ||
librados::ObjectWriteOperation op; | ||
|
||
auto it1 = m_update_mapping.begin(); | ||
while (it1 != m_update_mapping.end() && nr_updates++ < MAX_UPDATE) { | ||
librbd::cls_client::mirror_image_map_update(&op, it1->first, it1->second); | ||
it1 = m_update_mapping.erase(it1); | ||
} | ||
|
||
auto it2 = m_remove_global_image_ids.begin(); | ||
while (it2 != m_remove_global_image_ids.end() && nr_updates++ < MAX_UPDATE) { | ||
librbd::cls_client::mirror_image_map_remove(&op, *it2); | ||
it2 = m_remove_global_image_ids.erase(it2); | ||
} | ||
|
||
librados::AioCompletion *aio_comp = create_rados_callback< | ||
UpdateRequest, &UpdateRequest::handle_update_image_map>(this); | ||
int r = m_ioctx.aio_operate(RBD_MIRROR_LEADER, aio_comp, &op); | ||
assert(r == 0); | ||
aio_comp->release(); | ||
} | ||
|
||
template <typename I> | ||
void UpdateRequest<I>::handle_update_image_map(int r) { | ||
dout(20) << ": r=" << r << dendl; | ||
|
||
if (r < 0) { | ||
derr << ": failed to update image map: " << cpp_strerror(r) << dendl; | ||
finish(r); | ||
return; | ||
} | ||
|
||
update_image_map(); | ||
} | ||
|
||
template <typename I> | ||
void UpdateRequest<I>::finish(int r) { | ||
dout(20) << ": r=" << r << dendl; | ||
|
||
m_on_finish->complete(r); | ||
delete this; | ||
} | ||
|
||
} // namespace image_map | ||
} // namespace mirror | ||
} // namespace rbd | ||
|
||
template class rbd::mirror::image_map::UpdateRequest<librbd::ImageCtx>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- | ||
// vim: ts=8 sw=2 smarttab | ||
|
||
#ifndef CEPH_RBD_MIRROR_IMAGE_MAP_UPDATE_REQUEST_H | ||
#define CEPH_RBD_MIRROR_IMAGE_MAP_UPDATE_REQUEST_H | ||
|
||
#include "cls/rbd/cls_rbd_types.h" | ||
#include "include/rados/librados.hpp" | ||
|
||
class Context; | ||
|
||
namespace librbd { class ImageCtx; } | ||
|
||
namespace rbd { | ||
namespace mirror { | ||
namespace image_map { | ||
|
||
template<typename ImageCtxT = librbd::ImageCtx> | ||
class UpdateRequest { | ||
public: | ||
// accepts an image map for updation and a collection of | ||
// global image ids to purge. | ||
static UpdateRequest *create(librados::IoCtx &ioctx, | ||
std::map<std::string, cls::rbd::MirrorImageMap> &&update_mapping, | ||
std::set<std::string> &&remove_global_image_ids, Context *on_finish) { | ||
return new UpdateRequest(ioctx, std::move(update_mapping), std::move(remove_global_image_ids), | ||
on_finish); | ||
} | ||
|
||
void send(); | ||
|
||
private: | ||
/** | ||
* @verbatim | ||
* | ||
* <start> | ||
* | . . . . . . . . | ||
* v v . MAX_UPDATE | ||
* UPDATE_IMAGE_MAP. . . . . . . | ||
* | | ||
* v | ||
* <finish> | ||
* | ||
* @endverbatim | ||
*/ | ||
UpdateRequest(librados::IoCtx &ioctx, | ||
std::map<std::string, cls::rbd::MirrorImageMap> &&update_mapping, | ||
std::set<std::string> &&remove_global_image_ids, Context *on_finish); | ||
|
||
librados::IoCtx &m_ioctx; | ||
std::map<std::string, cls::rbd::MirrorImageMap> m_update_mapping; | ||
std::set<std::string> m_remove_global_image_ids; | ||
Context *m_on_finish; | ||
|
||
void update_image_map(); | ||
void handle_update_image_map(int r); | ||
|
||
void finish(int r); | ||
}; | ||
|
||
} // namespace image_map | ||
} // namespace mirror | ||
} // namespace rbd | ||
|
||
#endif // CEPH_RBD_MIRROR_IMAGE_MAP_UPDATE_REQUEST_H |