return 0;
}
+int mirror_group_status_remove(librados::IoCtx *ioctx,
+ const std::string &global_group_id) {
+ librados::ObjectWriteOperation op;
+ mirror_group_status_remove(&op, global_group_id);
+ return ioctx->operate(RBD_MIRRORING, &op);
+}
+
+void mirror_group_status_remove(librados::ObjectWriteOperation *op,
+ const std::string &global_group_id) {
+ bufferlist bl;
+ encode(global_group_id, bl);
+ op->exec("rbd", "mirror_group_status_remove", bl);
+}
+
int mirror_group_status_remove_down(librados::IoCtx *ioctx) {
librados::ObjectWriteOperation op;
mirror_group_status_remove_down(&op);
int mirror_group_status_get_summary_finish(
ceph::buffer::list::const_iterator *iter,
std::map<cls::rbd::MirrorGroupStatusState, int32_t> *states);
+int mirror_group_status_remove(librados::IoCtx *ioctx,
+ const std::string &global_group_id);
+void mirror_group_status_remove(librados::ObjectWriteOperation *op,
+ const std::string &global_group_id);
int mirror_group_status_remove_down(librados::IoCtx *ioctx);
void mirror_group_status_remove_down(librados::ObjectWriteOperation *op);
m_image_replayer_index.clear();
m_manual_stop = false;
m_finished = false;
+ m_delete_requested = false;
+ m_status_removed = false;
ceph_assert(m_on_start_finish == nullptr);
std::swap(m_on_start_finish, on_finish);
}
if (r == -ECANCELED) {
dout(10) << "start canceled" << dendl;
} else if (r == -ENOENT) {
+ m_delete_requested = true;
dout(10) << "mirroring group removed" << dendl;
} else if (r == -EREMOTEIO) {
dout(10) << "mirroring group demoted" << dendl;
template <typename I>
void GroupReplayer<I>::handle_shut_down(int r) {
+ dout(10) << "r=" << r << dendl;
+
+ if (r == -ENOENT) { // group removed
+ if (!m_resync_requested) {
+ set_finished(true);
+ }
+ unregister_admin_socket_hook();
+ }
+
+ if (!m_status_removed) {
+ auto ctx = new LambdaContext([this, r](int) {
+ m_status_removed = true;
+ handle_shut_down(r);
+ });
+ remove_group_status(m_delete_requested, ctx);
+ return;
+ }
dout(10) << "stop complete" << dendl;
Context *on_start = nullptr;
m_state = STATE_STOPPED;
}
- if (r == -ENOENT) { // group removed
- if (!m_resync_requested) {
- set_finished(true);
- }
- unregister_admin_socket_hook();
- }
-
if (on_start != nullptr) {
dout(10) << "on start finish complete, r=" << r << dendl;
on_start->complete(r);
}
}
-
template <typename I>
void GroupReplayer<I>::register_admin_socket_hook() {
GroupReplayerAdminSocketHook<I> *asok_hook;
register_admin_socket_hook();
}
+template <typename I>
+void GroupReplayer<I>::remove_group_status(bool force, Context *on_finish)
+{
+ auto ctx = new LambdaContext([this, force, on_finish](int) {
+ remove_group_status_remote(force, on_finish);
+ });
+
+ if (m_local_status_updater->mirror_group_exists(m_global_group_id)) {
+ dout(15) << "removing local mirror group status: "
+ << m_global_group_id << dendl;
+ if (force) {
+ m_local_status_updater->remove_mirror_group_status(
+ m_global_group_id, true, ctx);
+ } else {
+ m_local_status_updater->remove_refresh_mirror_group_status(
+ m_global_group_id, ctx);
+ }
+ return;
+ }
+
+ ctx->complete(0);
+}
+
+template <typename I>
+void GroupReplayer<I>::remove_group_status_remote(bool force, Context *on_finish)
+{
+ if (m_remote_group_peer.mirror_status_updater != nullptr &&
+ m_remote_group_peer.mirror_status_updater->mirror_group_exists(m_global_group_id)) {
+ dout(15) << "removing remote mirror group status: "
+ << m_global_group_id << dendl;
+ if (force) {
+ m_remote_group_peer.mirror_status_updater->remove_mirror_group_status(
+ m_global_group_id, true, on_finish);
+ } else {
+ m_remote_group_peer.mirror_status_updater->remove_refresh_mirror_group_status(
+ m_global_group_id, on_finish);
+ }
+ return;
+ }
+ if (on_finish) {
+ on_finish->complete(0);
+ }
+}
+
template <typename I>
void GroupReplayer<I>::set_mirror_group_status_update(
cls::rbd::MirrorGroupStatusState state, const std::string &desc) {
bool m_manual_stop = false;
bool m_finished = false;
+ bool m_delete_requested = false;
+ bool m_status_removed = false;
AdminSocketHook *m_asok_hook = nullptr;
void unregister_admin_socket_hook();
void reregister_admin_socket_hook();
+ void remove_group_status(bool force, Context *on_finish);
+ void remove_group_status_remote(bool force, Context *on_finish);
+
void set_mirror_group_status_update(cls::rbd::MirrorGroupStatusState state,
const std::string &desc);
void wait_for_ops();
}
}
+template <typename I>
+void MirrorStatusUpdater<I>::remove_refresh_mirror_group_status(
+ const std::string& global_group_id,
+ Context* on_finish) {
+ dout(15) << "global_group_id=" << global_group_id << dendl;
+
+ if (try_remove_mirror_group_status(global_group_id, false, false,
+ on_finish)) {
+ m_threads->work_queue->queue(on_finish, 0);
+ }
+}
+
template <typename I>
void MirrorStatusUpdater<I>::remove_mirror_group_status(
- const std::string& global_group_id, Context* on_finish) {
- if (try_remove_mirror_group_status(global_group_id, on_finish)) {
+ const std::string& global_group_id, bool immediate_update,
+ Context* on_finish) {
+ dout(15) << "global_group_id=" << global_group_id << dendl;
+ if (try_remove_mirror_group_status(global_group_id, true, immediate_update,
+ on_finish)) {
m_threads->work_queue->queue(on_finish, 0);
}
}
template <typename I>
bool MirrorStatusUpdater<I>::try_remove_mirror_group_status(
- const std::string& global_group_id, Context* on_finish) {
- dout(15) << "global_group_id=" << global_group_id << dendl;
+ const std::string& global_group_id, bool queue_update,
+ bool immediate_update, Context* on_finish) {
+ dout(15) << "global_group_id=" << global_group_id << ", "
+ << "queue_update=" << queue_update << ", "
+ << "immediate_update=" << immediate_update << dendl;
std::unique_lock locker(m_lock);
if ((m_update_in_flight &&
m_update_global_group_ids.count(global_group_id) > 0)) {
// if update is scheduled/in-progress, wait for it to complete
on_finish = new LambdaContext(
- [this, global_group_id, on_finish](int r) {
- if (try_remove_mirror_group_status(global_group_id, on_finish)) {
+ [this, global_group_id, queue_update, immediate_update,
+ on_finish](int r) {
+ if (try_remove_mirror_group_status(global_group_id, queue_update,
+ immediate_update, on_finish)) {
on_finish->complete(0);
}
});
}
m_global_group_status.erase(global_group_id);
+ if (queue_update) {
+ m_update_global_group_ids.insert(global_group_id);
+ if (immediate_update) {
+ queue_update_task(std::move(locker));
+ }
+ }
return true;
}
auto status_it = global_group_status.find(global_group_id);
if (status_it == global_group_status.end()) {
+ librbd::cls_client::mirror_group_status_remove(&op, global_group_id);
+ ++op_count;
continue;
}
const cls::rbd::MirrorGroupSiteStatus& mirror_group_site_status,
bool immediate_update);
void remove_mirror_group_status(const std::string& global_group_id,
- Context* on_finish);
+ bool immediate_update, Context* on_finish);
+ void remove_refresh_mirror_group_status(const std::string& global_group_id,
+ Context* on_finish);
bool mirror_group_image_exists(const std::string& global_group_id,
int64_t image_pool_id,
Context* on_finish);
bool try_remove_mirror_group_status(const std::string& global_image_id,
+ bool queue_update, bool immediate_update,
Context* on_finish);
void init_mirror_status_watcher(Context* on_finish);