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