// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- // vim: ts=8 sw=2 smarttab #ifndef CEPH_RBD_MIRROR_POOL_WATCHER_H #define CEPH_RBD_MIRROR_POOL_WATCHER_H #include #include #include #include #include "common/AsyncOpTracker.h" #include "common/ceph_context.h" #include "common/ceph_mutex.h" #include "include/rados/librados.hpp" #include "tools/rbd_mirror/Types.h" #include #include #include "include/ceph_assert.h" #include "tools/rbd_mirror/pool_watcher/Types.h" namespace librbd { struct ImageCtx; } namespace rbd { namespace mirror { template struct Threads; /** * Keeps track of images that have mirroring enabled within all * pools. */ template class PoolWatcher { public: static PoolWatcher* create(Threads *threads, librados::IoCtx &io_ctx, const std::string& mirror_uuid, pool_watcher::Listener &listener) { return new PoolWatcher(threads, io_ctx, mirror_uuid, listener); } PoolWatcher(Threads *threads, librados::IoCtx &io_ctx, const std::string& mirror_uuid, pool_watcher::Listener &listener); ~PoolWatcher(); PoolWatcher(const PoolWatcher&) = delete; PoolWatcher& operator=(const PoolWatcher&) = delete; bool is_blocklisted() const; void init(Context *on_finish = nullptr); void shut_down(Context *on_finish); inline uint64_t get_image_count() const { std::lock_guard locker{m_lock}; return m_image_ids.size(); } private: /** * @verbatim * * * | * v * INIT * | * v * REGISTER_WATCHER * | * |/--------------------------------\ * | | * v | * REFRESH_IMAGES | * | | * |/----------------------------\ | * | | | * v | | * NOTIFY_LISTENER | | * | | | * v | | * IDLE ---\ | | * | | | | * | |\---> IMAGE_UPDATED | | * | | | | | * | | v | | * | | GET_IMAGE_NAME --/ | * | | | * | \----> WATCH_ERROR ---------/ * v * SHUT_DOWN * | * v * UNREGISTER_WATCHER * | * v * * * @endverbatim */ class MirroringWatcher; Threads *m_threads; librados::IoCtx m_io_ctx; std::string m_mirror_uuid; pool_watcher::Listener &m_listener; ImageIds m_refresh_image_ids; bufferlist m_out_bl; mutable ceph::mutex m_lock; Context *m_on_init_finish = nullptr; ImageIds m_image_ids; bool m_pending_updates = false; bool m_notify_listener_in_progress = false; ImageIds m_pending_image_ids; ImageIds m_pending_added_image_ids; ImageIds m_pending_removed_image_ids; MirroringWatcher *m_mirroring_watcher; Context *m_timer_ctx = nullptr; AsyncOpTracker m_async_op_tracker; bool m_blocklisted = false; bool m_shutting_down = false; bool m_image_ids_invalid = true; bool m_refresh_in_progress = false; bool m_deferred_refresh = false; void register_watcher(); void handle_register_watcher(int r); void unregister_watcher(); void refresh_images(); void handle_refresh_images(int r); void schedule_refresh_images(double interval); void process_refresh_images(); void handle_rewatch_complete(int r); void handle_image_updated(const std::string &image_id, const std::string &global_image_id, bool enabled); void schedule_listener(); void notify_listener(); }; } // namespace mirror } // namespace rbd extern template class rbd::mirror::PoolWatcher; #endif // CEPH_RBD_MIRROR_POOL_WATCHER_H