#include "LeaderWatcher.h"
#include "PoolWatcher.h"
#include "ImageDeleter.h"
-#include "types.h"
+#include "tools/rbd_mirror/Types.h"
+#include "tools/rbd_mirror/image_map/Types.h"
+#include "tools/rbd_mirror/leader_watcher/Types.h"
+#include "tools/rbd_mirror/pool_watcher/Types.h"
#include "tools/rbd_mirror/service_daemon/Types.h"
#include <set>
#include <memory>
#include <atomic>
#include <string>
+#include <vector>
class AdminSocketHook;
namespace rbd {
namespace mirror {
+template <typename> class ImageMap;
template <typename> class InstanceReplayer;
template <typename> class InstanceWatcher;
template <typename> class ServiceDaemon;
/**
* Controls mirroring for a single remote cluster.
*/
+template <typename ImageCtxT = librbd::ImageCtx>
class PoolReplayer {
public:
- PoolReplayer(Threads<librbd::ImageCtx> *threads,
- ServiceDaemon<librbd::ImageCtx>* service_daemon,
- ImageDeleter<>* image_deleter,
- int64_t local_pool_id, const peer_t &peer,
+ PoolReplayer(Threads<ImageCtxT> *threads,
+ ServiceDaemon<ImageCtxT>* service_daemon,
+ int64_t local_pool_id, const PeerSpec &peer,
const std::vector<const char*> &args);
~PoolReplayer();
PoolReplayer(const PoolReplayer&) = delete;
void release_leader();
private:
- struct PoolWatcherListener : public PoolWatcher<>::Listener {
+ /**
+ * @verbatim
+ *
+ * <start>
+ * |
+ * v
+ * INIT
+ * |
+ * v
+ * <follower> <-------------------------\
+ * . |
+ * . |
+ * v (leader acquired) |
+ * INIT_IMAGE_MAP SHUT_DOWN_IMAGE_MAP
+ * | ^
+ * v |
+ * INIT_LOCAL_POOL_WATCHER WAIT_FOR_NOTIFICATIONS
+ * | ^
+ * v |
+ * INIT_REMOTE_POOL_WATCHER SHUT_DOWN_POOL_WATCHERS
+ * | ^
+ * v |
+ * INIT_IMAGE_DELETER SHUT_DOWN_IMAGE_DELETER
+ * | ^
+ * v .
+ * <leader> <-----------\ .
+ * . | .
+ * . (image update) | .
+ * . . > NOTIFY_INSTANCE_WATCHER .
+ * . .
+ * . (leader lost / shut down) .
+ * . . . . . . . . . . . . . . . . . .
+ *
+ * @endverbatim
+ */
+
+ typedef std::vector<std::string> InstanceIds;
+
+ struct PoolWatcherListener : public pool_watcher::Listener {
PoolReplayer *pool_replayer;
bool local;
}
};
+ struct ImageMapListener : public image_map::Listener {
+ PoolReplayer *pool_replayer;
+
+ ImageMapListener(PoolReplayer *pool_replayer)
+ : pool_replayer(pool_replayer) {
+ }
+
+ void acquire_image(const std::string &global_image_id,
+ const std::string &instance_id,
+ Context* on_finish) override {
+ pool_replayer->handle_acquire_image(global_image_id, instance_id,
+ on_finish);
+ }
+
+ void release_image(const std::string &global_image_id,
+ const std::string &instance_id,
+ Context* on_finish) override {
+ pool_replayer->handle_release_image(global_image_id, instance_id,
+ on_finish);
+ }
+
+ void remove_image(const std::string &mirror_uuid,
+ const std::string &global_image_id,
+ const std::string &instance_id,
+ Context* on_finish) override {
+ pool_replayer->handle_remove_image(mirror_uuid, global_image_id,
+ instance_id, on_finish);
+ }
+ };
+
void handle_update(const std::string &mirror_uuid,
ImageIds &&added_image_ids,
ImageIds &&removed_image_ids);
int init_rados(const std::string &cluster_name,
const std::string &client_name,
+ const std::string &mon_host,
+ const std::string &key,
const std::string &description, RadosRef *rados_ref,
bool strip_cluster_overrides);
void handle_post_acquire_leader(Context *on_finish);
void handle_pre_release_leader(Context *on_finish);
+ void init_image_map(Context *on_finish);
+ void handle_init_image_map(int r, Context *on_finish);
+
void init_local_pool_watcher(Context *on_finish);
void handle_init_local_pool_watcher(int r, Context *on_finish);
void init_remote_pool_watcher(Context *on_finish);
+ void handle_init_remote_pool_watcher(int r, Context *on_finish);
+
+ void init_image_deleter(Context* on_finish);
+ void handle_init_image_deleter(int r, Context* on_finish);
+
+ void shut_down_image_deleter(Context* on_finish);
+ void handle_shut_down_image_deleter(int r, Context* on_finish);
void shut_down_pool_watchers(Context *on_finish);
void handle_shut_down_pool_watchers(int r, Context *on_finish);
void wait_for_update_ops(Context *on_finish);
void handle_wait_for_update_ops(int r, Context *on_finish);
+ void shut_down_image_map(Context *on_finish);
+ void handle_shut_down_image_map(int r, Context *on_finish);
+
void handle_update_leader(const std::string &leader_instance_id);
- Threads<librbd::ImageCtx> *m_threads;
- ServiceDaemon<librbd::ImageCtx>* m_service_daemon;
- ImageDeleter<>* m_image_deleter;
+ void handle_acquire_image(const std::string &global_image_id,
+ const std::string &instance_id,
+ Context* on_finish);
+ void handle_release_image(const std::string &global_image_id,
+ const std::string &instance_id,
+ Context* on_finish);
+ void handle_remove_image(const std::string &mirror_uuid,
+ const std::string &global_image_id,
+ const std::string &instance_id,
+ Context* on_finish);
+
+ void handle_instances_added(const InstanceIds &instance_ids);
+ void handle_instances_removed(const InstanceIds &instance_ids);
+
+ Threads<ImageCtxT> *m_threads;
+ ServiceDaemon<ImageCtxT>* m_service_daemon;
int64_t m_local_pool_id = -1;
- peer_t m_peer;
+ PeerSpec m_peer;
std::vector<const char*> m_args;
mutable Mutex m_lock;
librados::IoCtx m_remote_io_ctx;
PoolWatcherListener m_local_pool_watcher_listener;
- std::unique_ptr<PoolWatcher<> > m_local_pool_watcher;
+ std::unique_ptr<PoolWatcher<ImageCtxT>> m_local_pool_watcher;
PoolWatcherListener m_remote_pool_watcher_listener;
- std::unique_ptr<PoolWatcher<> > m_remote_pool_watcher;
+ std::unique_ptr<PoolWatcher<ImageCtxT>> m_remote_pool_watcher;
+
+ std::unique_ptr<InstanceReplayer<ImageCtxT>> m_instance_replayer;
+ std::unique_ptr<ImageDeleter<ImageCtxT>> m_image_deleter;
- std::unique_ptr<InstanceReplayer<librbd::ImageCtx>> m_instance_replayer;
+ ImageMapListener m_image_map_listener;
+ std::unique_ptr<ImageMap<ImageCtxT>> m_image_map;
std::string m_asok_hook_name;
AdminSocketHook *m_asok_hook = nullptr;
}
} m_pool_replayer_thread;
- class LeaderListener : public LeaderWatcher<>::Listener {
+ class LeaderListener : public leader_watcher::Listener {
public:
LeaderListener(PoolReplayer *pool_replayer)
: m_pool_replayer(pool_replayer) {
m_pool_replayer->handle_update_leader(leader_instance_id);
}
+ void handle_instances_added(const InstanceIds& instance_ids) override {
+ m_pool_replayer->handle_instances_added(instance_ids);
+ }
+
+ void handle_instances_removed(const InstanceIds& instance_ids) override {
+ m_pool_replayer->handle_instances_removed(instance_ids);
+ }
+
private:
PoolReplayer *m_pool_replayer;
} m_leader_listener;
- std::unique_ptr<LeaderWatcher<> > m_leader_watcher;
- std::unique_ptr<InstanceWatcher<librbd::ImageCtx> > m_instance_watcher;
+ std::unique_ptr<LeaderWatcher<ImageCtxT>> m_leader_watcher;
+ std::unique_ptr<InstanceWatcher<ImageCtxT>> m_instance_watcher;
AsyncOpTracker m_update_op_tracker;
};
} // namespace mirror
} // namespace rbd
+extern template class rbd::mirror::PoolReplayer<librbd::ImageCtx>;
+
#endif // CEPH_RBD_MIRROR_POOL_REPLAYER_H