Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / tools / rbd_mirror / PoolWatcher.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_POOL_WATCHER_H
5 #define CEPH_RBD_MIRROR_POOL_WATCHER_H
6
7 #include <map>
8 #include <memory>
9 #include <set>
10 #include <string>
11
12 #include "common/AsyncOpTracker.h"
13 #include "common/ceph_context.h"
14 #include "common/Mutex.h"
15 #include "include/rados/librados.hpp"
16 #include "types.h"
17 #include <boost/functional/hash.hpp>
18 #include <boost/optional.hpp>
19 #include "include/assert.h"
20
21 namespace librbd { struct ImageCtx; }
22
23 namespace rbd {
24 namespace mirror {
25
26 template <typename> struct Threads;
27
28 /**
29  * Keeps track of images that have mirroring enabled within all
30  * pools.
31  */
32 template <typename ImageCtxT = librbd::ImageCtx>
33 class PoolWatcher {
34 public:
35   struct Listener {
36     virtual ~Listener() {
37     }
38
39     virtual void handle_update(const std::string &mirror_uuid,
40                                ImageIds &&added_image_ids,
41                                ImageIds &&removed_image_ids) = 0;
42   };
43
44   PoolWatcher(Threads<ImageCtxT> *threads, librados::IoCtx &remote_io_ctx,
45               Listener &listener);
46   ~PoolWatcher();
47   PoolWatcher(const PoolWatcher&) = delete;
48   PoolWatcher& operator=(const PoolWatcher&) = delete;
49
50   bool is_blacklisted() const;
51
52   void init(Context *on_finish = nullptr);
53   void shut_down(Context *on_finish);
54
55   inline uint64_t get_image_count() const {
56     Mutex::Locker locker(m_lock);
57     return m_image_ids.size();
58   }
59
60 private:
61   /**
62    * @verbatim
63    *
64    * <start>
65    *    |
66    *    v
67    *  INIT
68    *    |
69    *    v
70    * REGISTER_WATCHER
71    *    |
72    *    |/--------------------------------\
73    *    |                                 |
74    *    v                                 |
75    * REFRESH_IMAGES                       |
76    *    |                                 |
77    *    |/----------------------------\   |
78    *    |                             |   |
79    *    v                             |   |
80    * GET_MIRROR_UUID                  |   |
81    *    |                             |   |
82    *    v                             |   |
83    * NOTIFY_LISTENER                  |   |
84    *    |                             |   |
85    *    v                             |   |
86    *  IDLE ---\                       |   |
87    *    |     |                       |   |
88    *    |     |\---> IMAGE_UPDATED    |   |
89    *    |     |         |             |   |
90    *    |     |         v             |   |
91    *    |     |      GET_IMAGE_NAME --/   |
92    *    |     |                           |
93    *    |     \----> WATCH_ERROR ---------/
94    *    v
95    * SHUT_DOWN
96    *    |
97    *    v
98    * UNREGISTER_WATCHER
99    *    |
100    *    v
101    * <finish>
102    *
103    * @endverbatim
104    */
105   class MirroringWatcher;
106
107   Threads<ImageCtxT> *m_threads;
108   librados::IoCtx m_remote_io_ctx;
109   Listener &m_listener;
110
111   ImageIds m_refresh_image_ids;
112   bufferlist m_out_bl;
113
114   mutable Mutex m_lock;
115
116   Context *m_on_init_finish = nullptr;
117
118   ImageIds m_image_ids;
119   std::string m_mirror_uuid;
120
121   bool m_pending_updates = false;
122   bool m_notify_listener_in_progress = false;
123   ImageIds m_pending_image_ids;
124   ImageIds m_pending_added_image_ids;
125   ImageIds m_pending_removed_image_ids;
126
127   std::string m_pending_mirror_uuid;
128
129   MirroringWatcher *m_mirroring_watcher;
130
131   Context *m_timer_ctx = nullptr;
132
133   AsyncOpTracker m_async_op_tracker;
134   bool m_blacklisted = false;
135   bool m_shutting_down = false;
136   bool m_image_ids_invalid = true;
137   bool m_refresh_in_progress = false;
138   bool m_deferred_refresh = false;
139
140   void register_watcher();
141   void handle_register_watcher(int r);
142   void unregister_watcher();
143
144   void refresh_images();
145   void handle_refresh_images(int r);
146
147   void schedule_refresh_images(double interval);
148   void process_refresh_images();
149
150   void get_mirror_uuid();
151   void handle_get_mirror_uuid(int r);
152
153   void handle_rewatch_complete(int r);
154   void handle_image_updated(const std::string &remote_image_id,
155                             const std::string &global_image_id,
156                             bool enabled);
157
158   void schedule_listener();
159   void notify_listener();
160
161 };
162
163 } // namespace mirror
164 } // namespace rbd
165
166 extern template class rbd::mirror::PoolWatcher<librbd::ImageCtx>;
167
168 #endif // CEPH_RBD_MIRROR_POOL_WATCHER_H