#include "librbd/ImageCtx.h"
#include "librbd/journal/Types.h"
#include "librbd/journal/TypeTraits.h"
-#include "ImageDeleter.h"
#include "ProgressContext.h"
#include "types.h"
+#include "tools/rbd_mirror/image_replayer/Types.h"
#include <boost/noncopyable.hpp>
#include <boost/optional.hpp>
namespace rbd {
namespace mirror {
+template <typename> struct ImageDeleter;
+template <typename> struct InstanceWatcher;
template <typename> struct Threads;
namespace image_replayer { template <typename> class BootstrapRequest; }
template <typename ImageCtxT = librbd::ImageCtx>
class ImageReplayer {
public:
- typedef typename librbd::journal::TypeTraits<ImageCtxT>::ReplayEntry ReplayEntry;
-
- enum State {
- STATE_UNKNOWN,
- STATE_STARTING,
- STATE_REPLAYING,
- STATE_REPLAY_FLUSHING,
- STATE_STOPPING,
- STATE_STOPPED,
- };
-
static ImageReplayer *create(
- Threads<librbd::ImageCtx> *threads,
- std::shared_ptr<ImageDeleter> image_deleter,
- ImageSyncThrottlerRef<ImageCtxT> image_sync_throttler,
+ Threads<ImageCtxT> *threads, ImageDeleter<ImageCtxT>* image_deleter,
+ InstanceWatcher<ImageCtxT> *instance_watcher,
RadosRef local, const std::string &local_mirror_uuid, int64_t local_pool_id,
const std::string &global_image_id) {
- return new ImageReplayer(threads, image_deleter, image_sync_throttler,
+ return new ImageReplayer(threads, image_deleter, instance_watcher,
local, local_mirror_uuid, local_pool_id,
global_image_id);
}
delete this;
}
- ImageReplayer(Threads<librbd::ImageCtx> *threads,
- std::shared_ptr<ImageDeleter> image_deleter,
- ImageSyncThrottlerRef<ImageCtxT> image_sync_throttler,
+ ImageReplayer(Threads<ImageCtxT> *threads,
+ ImageDeleter<ImageCtxT>* image_deleter,
+ InstanceWatcher<ImageCtxT> *instance_watcher,
RadosRef local, const std::string &local_mirror_uuid,
int64_t local_pool_id, const std::string &global_image_id);
virtual ~ImageReplayer();
ImageReplayer(const ImageReplayer&) = delete;
ImageReplayer& operator=(const ImageReplayer&) = delete;
- State get_state() { Mutex::Locker l(m_lock); return get_state_(); }
bool is_stopped() { Mutex::Locker l(m_lock); return is_stopped_(); }
bool is_running() { Mutex::Locker l(m_lock); return is_running_(); }
bool is_replaying() { Mutex::Locker l(m_lock); return is_replaying_(); }
std::string get_name() { Mutex::Locker l(m_lock); return m_name; };
void set_state_description(int r, const std::string &desc);
+ // TODO temporary until policy handles release of image replayers
+ inline bool is_finished() const {
+ Mutex::Locker locker(m_lock);
+ return m_finished;
+ }
+ inline void set_finished(bool finished) {
+ Mutex::Locker locker(m_lock);
+ m_finished = finished;
+ }
+
inline bool is_blacklisted() const {
Mutex::Locker locker(m_lock);
return (m_last_r == -EBLACKLISTED);
}
- void add_remote_image(const std::string &remote_mirror_uuid,
- const std::string &remote_image_id,
- librados::IoCtx &remote_io_ctx);
- void remove_remote_image(const std::string &remote_mirror_uuid,
- const std::string &remote_image_id,
- bool schedule_delete);
- bool remote_images_empty() const;
+ image_replayer::HealthState get_health_state() const;
+
+ void add_peer(const std::string &peer_uuid, librados::IoCtx &remote_io_ctx);
inline int64_t get_local_pool_id() const {
return m_local_pool_id;
* v *
* <starting> *
* | *
+ * v *
+ * WAIT_FOR_DELETION *
+ * | *
* v (error) *
* PREPARE_LOCAL_IMAGE * * * * * * * * * * * * * * * * * *
* | *
* v (error) *
+ * PREPARE_REMOTE_IMAGE * * * * * * * * * * * * * * * * * *
+ * | *
+ * v (error) *
* BOOTSTRAP_IMAGE * * * * * * * * * * * * * * * * * * * *
* | *
* v (error) *
bool on_replay_interrupted();
private:
+ typedef typename librbd::journal::TypeTraits<ImageCtxT>::ReplayEntry ReplayEntry;
+
+ enum State {
+ STATE_UNKNOWN,
+ STATE_STARTING,
+ STATE_REPLAYING,
+ STATE_REPLAY_FLUSHING,
+ STATE_STOPPING,
+ STATE_STOPPED,
+ };
+
struct RemoteImage {
std::string mirror_uuid;
std::string image_id;
RemoteImage() {
}
- RemoteImage(const std::string &mirror_uuid,
- const std::string &image_id)
- : mirror_uuid(mirror_uuid), image_id(image_id) {
- }
- RemoteImage(const std::string &mirror_uuid,
- const std::string &image_id,
- librados::IoCtx &io_ctx)
- : mirror_uuid(mirror_uuid), image_id(image_id), io_ctx(io_ctx) {
- }
-
- inline bool operator<(const RemoteImage &rhs) const {
- if (mirror_uuid != rhs.mirror_uuid) {
- return mirror_uuid < rhs.mirror_uuid;
- } else {
- return image_id < rhs.image_id;
- }
- }
- inline bool operator==(const RemoteImage &rhs) const {
- return (mirror_uuid == rhs.mirror_uuid && image_id == rhs.image_id);
+ RemoteImage(const Peer& peer) : io_ctx(peer.io_ctx) {
}
};
- typedef std::set<RemoteImage> RemoteImages;
-
typedef typename librbd::journal::TypeTraits<ImageCtxT>::Journaler Journaler;
typedef boost::optional<State> OptionalState;
+ typedef boost::optional<cls::rbd::MirrorImageStatusState>
+ OptionalMirrorImageStatusState;
struct JournalListener : public librbd::journal::Listener {
ImageReplayer *img_replayer;
ImageReplayer<ImageCtxT> *replayer;
};
- Threads<librbd::ImageCtx> *m_threads;
- std::shared_ptr<ImageDeleter> m_image_deleter;
- ImageSyncThrottlerRef<ImageCtxT> m_image_sync_throttler;
+ Threads<ImageCtxT> *m_threads;
+ ImageDeleter<ImageCtxT>* m_image_deleter;
+ InstanceWatcher<ImageCtxT> *m_instance_watcher;
- RemoteImages m_remote_images;
+ Peers m_peers;
RemoteImage m_remote_image;
RadosRef m_local;
std::string m_local_image_id;
std::string m_global_image_id;
std::string m_name;
+
mutable Mutex m_lock;
State m_state = STATE_STOPPED;
- int m_last_r = 0;
std::string m_state_desc;
+
+ OptionalMirrorImageStatusState m_mirror_image_status_state = boost::none;
+ int m_last_r = 0;
+
BootstrapProgressContext m_progress_cxt;
- bool m_do_resync;
+
+ bool m_finished = false;
+ bool m_delete_requested = false;
+ bool m_resync_requested = false;
+
image_replayer::EventPreprocessor<ImageCtxT> *m_event_preprocessor = nullptr;
image_replayer::ReplayStatusFormatter<ImageCtxT> *m_replay_status_formatter =
nullptr;
Journaler* m_remote_journaler = nullptr;
::journal::ReplayHandler *m_replay_handler = nullptr;
librbd::journal::Listener *m_journal_listener;
- bool m_stopping_for_resync = false;
Context *m_on_start_finish = nullptr;
Context *m_on_stop_finish = nullptr;
static std::string to_string(const State state);
- State get_state_() const {
- return m_state;
- }
bool is_stopped_() const {
return m_state == STATE_STOPPED;
}
void handle_shut_down(int r);
void handle_remote_journal_metadata_updated();
+ void wait_for_deletion();
+ void handle_wait_for_deletion(int r);
+
void prepare_local_image();
void handle_prepare_local_image(int r);
+ void prepare_remote_image();
+ void handle_prepare_remote_image(int r);
+
void bootstrap();
void handle_bootstrap(int r);
void handle_process_entry_ready(int r);
void handle_process_entry_safe(const ReplayEntry& replay_entry, int r);
+ void register_admin_socket_hook();
+ void unregister_admin_socket_hook();
+
+ void on_name_changed();
};
} // namespace mirror