]>
Commit | Line | Data |
---|---|---|
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- | |
2 | // vim: ts=8 sw=2 smarttab | |
3 | ||
4 | #ifndef RBD_MIRROR_INSTANCE_REPLAYER_H | |
5 | #define RBD_MIRROR_INSTANCE_REPLAYER_H | |
6 | ||
7 | #include <map> | |
8 | #include <sstream> | |
9 | ||
10 | #include "common/AsyncOpTracker.h" | |
11 | #include "common/Formatter.h" | |
12 | #include "common/Mutex.h" | |
13 | #include "types.h" | |
14 | ||
15 | namespace librbd { class ImageCtx; } | |
16 | ||
17 | namespace rbd { | |
18 | namespace mirror { | |
19 | ||
20 | class ImageDeleter; | |
21 | ||
22 | template <typename> class ImageReplayer; | |
23 | template <typename> class InstanceWatcher; | |
24 | template <typename> struct Threads; | |
25 | ||
26 | template <typename ImageCtxT = librbd::ImageCtx> | |
27 | class InstanceReplayer { | |
28 | public: | |
29 | static InstanceReplayer* create( | |
30 | Threads<ImageCtxT> *threads, std::shared_ptr<ImageDeleter> image_deleter, | |
31 | RadosRef local_rados, const std::string &local_mirror_uuid, | |
32 | int64_t local_pool_id) { | |
33 | return new InstanceReplayer(threads, image_deleter, local_rados, | |
34 | local_mirror_uuid, local_pool_id); | |
35 | } | |
36 | void destroy() { | |
37 | delete this; | |
38 | } | |
39 | ||
40 | InstanceReplayer(Threads<ImageCtxT> *threads, | |
41 | std::shared_ptr<ImageDeleter> image_deleter, | |
42 | RadosRef local_rados, const std::string &local_mirror_uuid, | |
43 | int64_t local_pool_id); | |
44 | ~InstanceReplayer(); | |
45 | ||
46 | int init(); | |
47 | void shut_down(); | |
48 | ||
49 | void init(Context *on_finish); | |
50 | void shut_down(Context *on_finish); | |
51 | ||
52 | void add_peer(std::string mirror_uuid, librados::IoCtx io_ctx); | |
53 | void remove_peer(std::string mirror_uuid); | |
54 | ||
55 | void acquire_image(InstanceWatcher<ImageCtxT> *instance_watcher, | |
56 | const std::string &global_image_id, | |
57 | const std::string &peer_mirror_uuid, | |
58 | const std::string &peer_image_id, | |
59 | Context *on_finish); | |
60 | void release_image(const std::string &global_image_id, | |
61 | const std::string &peer_mirror_uuid, | |
62 | const std::string &peer_image_id, | |
63 | bool schedule_delete, Context *on_finish); | |
64 | void release_all(Context *on_finish); | |
65 | ||
66 | void print_status(Formatter *f, stringstream *ss); | |
67 | void start(); | |
68 | void stop(); | |
69 | void restart(); | |
70 | void flush(); | |
71 | ||
72 | private: | |
73 | /** | |
74 | * @verbatim | |
75 | * | |
76 | * <uninitialized> <-------------------\ | |
77 | * | (init) | (repeat for each | |
78 | * v STOP_IMAGE_REPLAYER ---\ image replayer) | |
79 | * SCHEDULE_IMAGE_STATE_CHECK_TASK ^ ^ | | |
80 | * | | | | | |
81 | * v (shut_down) | \---------/ | |
82 | * <initialized> -----------------> WAIT_FOR_OPS | |
83 | * | |
84 | * @endverbatim | |
85 | */ | |
86 | ||
87 | struct Peer { | |
88 | std::string mirror_uuid; | |
89 | librados::IoCtx io_ctx; | |
90 | ||
91 | Peer() { | |
92 | } | |
93 | ||
94 | Peer(const std::string &mirror_uuid) : mirror_uuid(mirror_uuid) { | |
95 | } | |
96 | ||
97 | Peer(const std::string &mirror_uuid, librados::IoCtx &io_ctx) | |
98 | : mirror_uuid(mirror_uuid), io_ctx(io_ctx) { | |
99 | } | |
100 | ||
101 | inline bool operator<(const Peer &rhs) const { | |
102 | return mirror_uuid < rhs.mirror_uuid; | |
103 | } | |
104 | inline bool operator==(const Peer &rhs) const { | |
105 | return mirror_uuid == rhs.mirror_uuid; | |
106 | } | |
107 | }; | |
108 | ||
109 | typedef std::set<Peer> Peers; | |
110 | ||
111 | Threads<ImageCtxT> *m_threads; | |
112 | std::shared_ptr<ImageDeleter> m_image_deleter; | |
113 | RadosRef m_local_rados; | |
114 | std::string m_local_mirror_uuid; | |
115 | int64_t m_local_pool_id; | |
116 | ||
117 | Mutex m_lock; | |
118 | AsyncOpTracker m_async_op_tracker; | |
119 | std::map<std::string, ImageReplayer<ImageCtxT> *> m_image_replayers; | |
120 | Peers m_peers; | |
121 | Context *m_image_state_check_task = nullptr; | |
122 | Context *m_on_shut_down = nullptr; | |
123 | bool m_manual_stop = false; | |
124 | ||
125 | void wait_for_ops(); | |
126 | void handle_wait_for_ops(int r); | |
127 | ||
128 | void start_image_replayer(ImageReplayer<ImageCtxT> *image_replayer); | |
129 | void start_image_replayers(); | |
130 | ||
131 | void stop_image_replayer(ImageReplayer<ImageCtxT> *image_replayer, | |
132 | Context *on_finish); | |
133 | ||
134 | void stop_image_replayers(); | |
135 | void handle_stop_image_replayers(int r); | |
136 | ||
137 | void schedule_image_state_check_task(); | |
138 | void cancel_image_state_check_task(); | |
139 | }; | |
140 | ||
141 | } // namespace mirror | |
142 | } // namespace rbd | |
143 | ||
144 | extern template class rbd::mirror::InstanceReplayer<librbd::ImageCtx>; | |
145 | ||
146 | #endif // RBD_MIRROR_INSTANCE_REPLAYER_H |