When a directory is removed from mirroring, the persisted directory
stats need to be removed. This patch handles the cleanup.
Omap keys must not be removed when mirrored directories are reshuffled
across cephfs-mirror daemons. The mgr release notify now carries a
purging flag (set only during permanent removal, not reshuffle), and
the daemon removes persisted stats only when purging is true. On
reshuffle with an in-progress sync, clear live current_syncing_snap
state and persist idle metrics so the acquiring daemon does not inherit
stale syncing omap entries.
Fixes: https://tracker.ceph.com/issues/76686
Signed-off-by: Kotresh HR <khiremat@redhat.com>
(cherry picked from commit
51a8348dfd681dfd446c347a82e581f2ed52a4c6)
return json.dumps({'dir_path': dir_path,
'mode': 'acquire'
})
- def release_message(dir_path):
- return json.dumps({'dir_path': dir_path,
- 'mode': 'release'
- })
+ def release_message(dir_path, purging=False):
+ msg = {'dir_path': dir_path,
+ 'mode': 'release'}
+ if purging:
+ msg['purging'] = True
+ return json.dumps(msg)
with self.lock:
if not self.dir_paths or self.stopping.is_set():
return
elif action_type == ActionType.ACQUIRE:
notifies[dir_path] = (lookup_info['instance_id'], acquire_message(dir_path))
elif action_type == ActionType.RELEASE:
- notifies[dir_path] = (lookup_info['instance_id'], release_message(dir_path))
+ notifies[dir_path] = (lookup_info['instance_id'],
+ release_message(dir_path,
+ lookup_info['purging']))
if update_map or removals:
self.update_mapping(update_map, removals, callback=self.continue_action)
for dir_path, message in notifies.items():
}
}
-void FSMirror::handle_release_directory(string_view dir_path) {
- dout(5) << ": dir_path=" << dir_path << dendl;
+void FSMirror::handle_release_directory(string_view dir_path, bool purging) {
+ dout(5) << ": dir_path=" << dir_path << ", purging=" << purging << dendl;
{
std::scoped_lock locker(m_lock);
m_directories.size());
for (auto &[peer, peer_replayer] : m_peer_replayers) {
dout(10) << ": peer=" << peer << dendl;
- peer_replayer->remove_directory(dir_path);
+ peer_replayer->remove_directory(dir_path, purging);
}
}
if (m_perf_counters) {
fs_mirror->handle_acquire_directory(dir_path);
}
- void release_directory(std::string_view dir_path) override {
- fs_mirror->handle_release_directory(dir_path);
+ void release_directory(std::string_view dir_path, bool purging) override {
+ fs_mirror->handle_release_directory(dir_path, purging);
}
};
void handle_shutdown_instance_watcher(int r);
void handle_acquire_directory(std::string_view dir_path);
- void handle_release_directory(std::string_view dir_path);
+ void handle_release_directory(std::string_view dir_path, bool purging);
};
} // namespace mirror
std::string dir_path;
std::string mode;
+ bool purging = false;
try {
JSONDecoder jd(bl);
JSONDecoder::decode_json("dir_path", dir_path, &jd.parser, true);
JSONDecoder::decode_json("mode", mode, &jd.parser, true);
+ JSONDecoder::decode_json("purging", purging, &jd.parser, false);
} catch (const JSONDecoder::err &e) {
derr << ": failed to decode notify json: " << e.what() << dendl;
}
dout(20) << ": notifier_id=" << notifier_id << ", dir_path=" << dir_path
- << ", mode=" << mode << dendl;
+ << ", mode=" << mode << ", purging=" << purging << dendl;
if (mode == "acquire") {
m_listener.acquire_directory(dir_path);
} else if (mode == "release") {
- m_listener.release_directory(dir_path);
+ m_listener.release_directory(dir_path, purging);
} else {
derr << ": unknown mode" << dendl;
}
}
virtual void acquire_directory(std::string_view dir_path) = 0;
- virtual void release_directory(std::string_view dir_path) = 0;
+ virtual void release_directory(std::string_view dir_path, bool purging) = 0;
};
static InstanceWatcher *create(librados::IoCtx &ioctx,