1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #ifndef CEPH_RBD_MIRROR_IMAGE_MAP_H
5 #define CEPH_RBD_MIRROR_IMAGE_MAP_H
9 #include "common/Mutex.h"
10 #include "include/Context.h"
11 #include "common/AsyncOpTracker.h"
12 #include "cls/rbd/cls_rbd_types.h"
13 #include "include/rados/librados.hpp"
15 #include "image_map/Policy.h"
16 #include "image_map/Types.h"
18 namespace librbd
{ class ImageCtx
; }
23 template <typename
> struct Threads
;
25 template <typename ImageCtxT
= librbd::ImageCtx
>
28 static ImageMap
*create(librados::IoCtx
&ioctx
, Threads
<ImageCtxT
> *threads
,
29 const std::string
& instance_id
,
30 image_map::Listener
&listener
) {
31 return new ImageMap(ioctx
, threads
, instance_id
, listener
);
36 // init (load) the instance map from disk
37 void init(Context
*on_finish
);
39 // shut down map operations
40 void shut_down(Context
*on_finish
);
42 // update (add/remove) images
43 void update_images(const std::string
&peer_uuid
,
44 std::set
<std::string
> &&added_global_image_ids
,
45 std::set
<std::string
> &&removed_global_image_ids
);
47 // add/remove instances
48 void update_instances_added(const std::vector
<std::string
> &instances
);
49 void update_instances_removed(const std::vector
<std::string
> &instances
);
52 struct C_NotifyInstance
;
54 ImageMap(librados::IoCtx
&ioctx
, Threads
<ImageCtxT
> *threads
,
55 const std::string
& instance_id
, image_map::Listener
&listener
);
58 std::string global_image_id
;
59 std::string instance_id
;
62 Update(const std::string
&global_image_id
, const std::string
&instance_id
,
64 : global_image_id(global_image_id
),
65 instance_id(instance_id
),
66 mapped_time(mapped_time
) {
68 Update(const std::string
&global_image_id
, const std::string
&instance_id
)
69 : Update(global_image_id
, instance_id
, ceph_clock_now()) {
72 friend std::ostream
& operator<<(std::ostream
& os
,
73 const Update
& update
) {
74 os
<< "{global_image_id=" << update
.global_image_id
<< ", "
75 << "instance_id=" << update
.instance_id
<< "}";
80 typedef std::list
<Update
> Updates
;
82 // Lock ordering: m_threads->timer_lock, m_lock
84 librados::IoCtx
&m_ioctx
;
85 Threads
<ImageCtxT
> *m_threads
;
86 std::string m_instance_id
;
87 image_map::Listener
&m_listener
;
89 std::unique_ptr
<image_map::Policy
> m_policy
; // our mapping policy
91 Context
*m_timer_task
= nullptr;
93 bool m_shutting_down
= false;
94 AsyncOpTracker m_async_op_tracker
;
96 // global_image_id -> registered peers ("" == local, remote otherwise)
97 std::map
<std::string
, std::set
<std::string
> > m_peer_map
;
99 std::set
<std::string
> m_global_image_ids
;
101 Context
*m_rebalance_task
= nullptr;
103 struct C_LoadMap
: Context
{
107 std::map
<std::string
, cls::rbd::MirrorImageMap
> image_mapping
;
109 C_LoadMap(ImageMap
*image_map
, Context
*on_finish
)
110 : image_map(image_map
),
111 on_finish(on_finish
) {
114 void finish(int r
) override
{
116 image_map
->handle_load(image_mapping
);
119 image_map
->finish_async_op();
120 on_finish
->complete(r
);
124 // async op-tracker helper routines
125 void start_async_op() {
126 m_async_op_tracker
.start_op();
128 void finish_async_op() {
129 m_async_op_tracker
.finish_op();
131 void wait_for_async_ops(Context
*on_finish
) {
132 m_async_op_tracker
.wait_for_ops(on_finish
);
135 void handle_peer_ack(const std::string
&global_image_id
, int r
);
136 void handle_peer_ack_remove(const std::string
&global_image_id
, int r
);
138 void handle_load(const std::map
<std::string
, cls::rbd::MirrorImageMap
> &image_mapping
);
139 void handle_update_request(const Updates
&updates
,
140 const std::set
<std::string
> &remove_global_image_ids
, int r
);
142 // continue (retry or resume depending on state machine) processing
144 void continue_action(const std::set
<std::string
> &global_image_ids
, int r
);
146 // schedule an image for update
147 void schedule_action(const std::string
&global_image_id
);
149 void schedule_update_task();
150 void schedule_update_task(const Mutex
&timer_lock
);
151 void process_updates();
152 void update_image_mapping(Updates
&& map_updates
,
153 std::set
<std::string
>&& map_removals
);
156 void schedule_rebalance_task();
158 void notify_listener_acquire_release_images(const Updates
&acquire
, const Updates
&release
);
159 void notify_listener_remove_images(const std::string
&peer_uuid
, const Updates
&remove
);
161 void update_images_added(const std::string
&peer_uuid
,
162 const std::set
<std::string
> &global_image_ids
);
163 void update_images_removed(const std::string
&peer_uuid
,
164 const std::set
<std::string
> &global_image_ids
);
166 void filter_instance_ids(const std::vector
<std::string
> &instance_ids
,
167 std::vector
<std::string
> *filtered_instance_ids
,
172 } // namespace mirror
175 #endif // CEPH_RBD_MIRROR_IMAGE_MAP_H