]> git.proxmox.com Git - ceph.git/blob - ceph/src/tools/rbd_mirror/ImageMap.h
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / tools / rbd_mirror / ImageMap.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #ifndef CEPH_RBD_MIRROR_IMAGE_MAP_H
5 #define CEPH_RBD_MIRROR_IMAGE_MAP_H
6
7 #include <vector>
8
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"
14
15 #include "image_map/Policy.h"
16 #include "image_map/Types.h"
17
18 namespace librbd { class ImageCtx; }
19
20 namespace rbd {
21 namespace mirror {
22
23 template <typename> struct Threads;
24
25 template <typename ImageCtxT = librbd::ImageCtx>
26 class ImageMap {
27 public:
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);
32 }
33
34 ~ImageMap();
35
36 // init (load) the instance map from disk
37 void init(Context *on_finish);
38
39 // shut down map operations
40 void shut_down(Context *on_finish);
41
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);
46
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);
50
51 private:
52 struct C_NotifyInstance;
53
54 ImageMap(librados::IoCtx &ioctx, Threads<ImageCtxT> *threads,
55 const std::string& instance_id, image_map::Listener &listener);
56
57 struct Update {
58 std::string global_image_id;
59 std::string instance_id;
60 utime_t mapped_time;
61
62 Update(const std::string &global_image_id, const std::string &instance_id,
63 utime_t mapped_time)
64 : global_image_id(global_image_id),
65 instance_id(instance_id),
66 mapped_time(mapped_time) {
67 }
68 Update(const std::string &global_image_id, const std::string &instance_id)
69 : Update(global_image_id, instance_id, ceph_clock_now()) {
70 }
71
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 << "}";
76 return os;
77 }
78
79 };
80 typedef std::list<Update> Updates;
81
82 // Lock ordering: m_threads->timer_lock, m_lock
83
84 librados::IoCtx &m_ioctx;
85 Threads<ImageCtxT> *m_threads;
86 std::string m_instance_id;
87 image_map::Listener &m_listener;
88
89 std::unique_ptr<image_map::Policy> m_policy; // our mapping policy
90
91 Context *m_timer_task = nullptr;
92 Mutex m_lock;
93 bool m_shutting_down = false;
94 AsyncOpTracker m_async_op_tracker;
95
96 // global_image_id -> registered peers ("" == local, remote otherwise)
97 std::map<std::string, std::set<std::string> > m_peer_map;
98
99 std::set<std::string> m_global_image_ids;
100
101 Context *m_rebalance_task = nullptr;
102
103 struct C_LoadMap : Context {
104 ImageMap *image_map;
105 Context *on_finish;
106
107 std::map<std::string, cls::rbd::MirrorImageMap> image_mapping;
108
109 C_LoadMap(ImageMap *image_map, Context *on_finish)
110 : image_map(image_map),
111 on_finish(on_finish) {
112 }
113
114 void finish(int r) override {
115 if (r == 0) {
116 image_map->handle_load(image_mapping);
117 }
118
119 image_map->finish_async_op();
120 on_finish->complete(r);
121 }
122 };
123
124 // async op-tracker helper routines
125 void start_async_op() {
126 m_async_op_tracker.start_op();
127 }
128 void finish_async_op() {
129 m_async_op_tracker.finish_op();
130 }
131 void wait_for_async_ops(Context *on_finish) {
132 m_async_op_tracker.wait_for_ops(on_finish);
133 }
134
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);
137
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);
141
142 // continue (retry or resume depending on state machine) processing
143 // current action.
144 void continue_action(const std::set<std::string> &global_image_ids, int r);
145
146 // schedule an image for update
147 void schedule_action(const std::string &global_image_id);
148
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);
154
155 void rebalance();
156 void schedule_rebalance_task();
157
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);
160
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);
165
166 void filter_instance_ids(const std::vector<std::string> &instance_ids,
167 std::vector<std::string> *filtered_instance_ids,
168 bool removal) const;
169
170 };
171
172 } // namespace mirror
173 } // namespace rbd
174
175 #endif // CEPH_RBD_MIRROR_IMAGE_MAP_H