From cd18a801584d3b09a40b9e0cb09f47898f1b724d Mon Sep 17 00:00:00 2001 From: Jos Collin Date: Tue, 28 May 2024 20:27:55 +0530 Subject: [PATCH] cephfs_mirror: Add ErrorListener to maintain blocklisted/failed timestamp in FSMirror Have FSMirror register a listener with InstanceWatcher/MirrorWatcher which would get invoked when the mirror daemon is blocklisted or failed. Thus FSMirror can maintain the last blocklisted/failed timestamp and use that for restarting the mirror daemon. Fixes: https://tracker.ceph.com/issues/64927 Fixes: https://tracker.ceph.com/issues/51964 Fixes: https://tracker.ceph.com/issues/63931 Fixes: https://tracker.ceph.com/issues/63089 Signed-off-by: Jos Collin (cherry picked from commit 77ec7bfde7a349b0e06b34ecdf328996c7642d43) --- src/tools/cephfs_mirror/FSMirror.cc | 5 +-- src/tools/cephfs_mirror/FSMirror.h | 41 ++++++++++++++-------- src/tools/cephfs_mirror/InstanceWatcher.cc | 9 ++--- src/tools/cephfs_mirror/InstanceWatcher.h | 20 +++-------- src/tools/cephfs_mirror/MirrorWatcher.cc | 9 ++--- src/tools/cephfs_mirror/MirrorWatcher.h | 20 +++-------- src/tools/cephfs_mirror/Watcher.h | 7 ++++ 7 files changed, 55 insertions(+), 56 deletions(-) diff --git a/src/tools/cephfs_mirror/FSMirror.cc b/src/tools/cephfs_mirror/FSMirror.cc index 3d5bf2d1c7242..ea1857b1eba86 100644 --- a/src/tools/cephfs_mirror/FSMirror.cc +++ b/src/tools/cephfs_mirror/FSMirror.cc @@ -114,6 +114,7 @@ FSMirror::FSMirror(CephContext *cct, const Filesystem &filesystem, uint64_t pool m_args(args), m_work_queue(work_queue), m_snap_listener(this), + m_ts_listener(this), m_asok_hook(new MirrorAdminSocketHook(cct, filesystem, this)) { m_service_daemon->add_or_update_fs_attribute(m_filesystem.fscid, SERVICE_DAEMON_DIR_COUNT_KEY, (uint64_t)0); @@ -270,7 +271,7 @@ void FSMirror::init_instance_watcher(Context *on_finish) { Context *ctx = new C_CallbackAdapter< FSMirror, &FSMirror::handle_init_instance_watcher>(this); - m_instance_watcher = InstanceWatcher::create(m_ioctx, m_snap_listener, m_work_queue); + m_instance_watcher = InstanceWatcher::create(m_ioctx, m_snap_listener, m_ts_listener, m_work_queue); m_instance_watcher->init(ctx); } @@ -299,7 +300,7 @@ void FSMirror::init_mirror_watcher() { std::scoped_lock locker(m_lock); Context *ctx = new C_CallbackAdapter< FSMirror, &FSMirror::handle_init_mirror_watcher>(this); - m_mirror_watcher = MirrorWatcher::create(m_ioctx, this, m_work_queue); + m_mirror_watcher = MirrorWatcher::create(m_ioctx, this, m_ts_listener, m_work_queue); m_mirror_watcher->init(ctx); } diff --git a/src/tools/cephfs_mirror/FSMirror.h b/src/tools/cephfs_mirror/FSMirror.h index b106fdff8b60d..70ebbd0f4b6d7 100644 --- a/src/tools/cephfs_mirror/FSMirror.h +++ b/src/tools/cephfs_mirror/FSMirror.h @@ -59,14 +59,12 @@ public: monotime get_failed_ts() { std::scoped_lock locker(m_lock); - if (m_instance_watcher) { - return m_instance_watcher->get_failed_ts(); - } - if (m_mirror_watcher) { - return m_mirror_watcher->get_failed_ts(); - } + return m_failed_ts; + } - return clock::now(); + void set_failed_ts() { + std::scoped_lock locker(m_lock); + m_failed_ts = clock::now(); } bool is_blocklisted() { @@ -76,14 +74,12 @@ public: monotime get_blocklisted_ts() { std::scoped_lock locker(m_lock); - if (m_instance_watcher) { - return m_instance_watcher->get_blocklisted_ts(); - } - if (m_mirror_watcher) { - return m_mirror_watcher->get_blocklisted_ts(); - } + return m_blocklisted_ts; + } - return clock::now(); + void set_blocklisted_ts() { + std::scoped_lock locker(m_lock); + m_blocklisted_ts = clock::now(); } Peers get_peers() { @@ -128,8 +124,24 @@ private: void release_directory(std::string_view dir_path) override { fs_mirror->handle_release_directory(dir_path); } + + }; + + struct TimestampListener: public Watcher::ErrorListener { + FSMirror *fs_mirror; + TimestampListener(FSMirror *fs_mirror) + : fs_mirror(fs_mirror) { + } + void set_blocklisted_ts() { + fs_mirror->set_blocklisted_ts(); + } + void set_failed_ts() { + fs_mirror->set_failed_ts(); + } }; + monotime m_blocklisted_ts; + monotime m_failed_ts; CephContext *m_cct; Filesystem m_filesystem; uint64_t m_pool_id; @@ -139,6 +151,7 @@ private: ceph::mutex m_lock = ceph::make_mutex("cephfs::mirror::fs_mirror"); SnapListener m_snap_listener; + TimestampListener m_ts_listener; std::set> m_directories; Peers m_all_peers; std::map> m_peer_replayers; diff --git a/src/tools/cephfs_mirror/InstanceWatcher.cc b/src/tools/cephfs_mirror/InstanceWatcher.cc index fece936a94b4f..5b19d017287d9 100644 --- a/src/tools/cephfs_mirror/InstanceWatcher.cc +++ b/src/tools/cephfs_mirror/InstanceWatcher.cc @@ -31,10 +31,11 @@ std::string instance_oid(const std::string &instance_id) { } // anonymous namespace InstanceWatcher::InstanceWatcher(librados::IoCtx &ioctx, - Listener &listener, ContextWQ *work_queue) + Listener &listener, ErrorListener &elistener, ContextWQ *work_queue) : Watcher(ioctx, instance_oid(stringify(ioctx.get_instance_id())), work_queue), m_ioctx(ioctx), m_listener(listener), + m_elistener(elistener), m_work_queue(work_queue), m_lock(ceph::make_mutex("cephfs::mirror::instance_watcher")) { } @@ -116,15 +117,15 @@ void InstanceWatcher::handle_rewatch_complete(int r) { dout(0) << ": client blocklisted" <