From a88f69b4ef7c1a5b7f348a14e8ccd52b51003454 Mon Sep 17 00:00:00 2001 From: weixinwei Date: Tue, 4 Apr 2023 17:40:12 +0800 Subject: [PATCH] osd: avoid watcher remains after "rados watch" is interrupted If "rados watch" is interrupted (e.g. killed), rados watcher remains in osd. The reason is that in do_osd_op_effects, session is nullptr (rados client is killed), resulting in WatchTimeout is not registerd. Fixes: https://tracker.ceph.com/issues/58120 Signed-off-by: weixinwei (cherry picked from commit 5bb185cbc9547a1b324c339753b4b3786073a58f) --- src/osd/PrimaryLogPG.cc | 6 ++---- src/osd/Watch.cc | 9 ++++++++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/osd/PrimaryLogPG.cc b/src/osd/PrimaryLogPG.cc index 49178dc406a..6f8566b8e45 100644 --- a/src/osd/PrimaryLogPG.cc +++ b/src/osd/PrimaryLogPG.cc @@ -8770,15 +8770,14 @@ void PrimaryLogPG::do_osd_op_effects(OpContext *ctx, const ConnectionRef& conn) ceph_assert(conn); auto session = conn->get_priv(); - if (!session) - return; for (list >::iterator i = ctx->watch_connects.begin(); i != ctx->watch_connects.end(); ++i) { pair watcher(i->first.cookie, entity); dout(15) << "do_osd_op_effects applying watch connect on session " - << session.get() << " watcher " << watcher << dendl; + << (session ? session.get() : nullptr) << " watcher " << watcher + << dendl; WatchRef watch; if (ctx->obc->watchers.count(watcher)) { dout(15) << "do_osd_op_effects found existing watch watcher " << watcher @@ -8802,7 +8801,6 @@ void PrimaryLogPG::do_osd_op_effects(OpContext *ctx, const ConnectionRef& conn) p != ctx->notifies.end(); ++p) { dout(10) << "do_osd_op_effects, notify " << *p << dendl; - ConnectionRef conn(ctx->op->get_req()->get_connection()); NotifyRef notif( Notify::makeNotifyRef( conn, diff --git a/src/osd/Watch.cc b/src/osd/Watch.cc index c36ecdc5413..573cb905396 100644 --- a/src/osd/Watch.cc +++ b/src/osd/Watch.cc @@ -393,7 +393,14 @@ void Watch::connect(ConnectionRef con, bool _will_ping) last_ping = ceph_clock_now(); register_cb(); } else { - unregister_cb(); + if (!con->get_priv()) { + // if session is already nullptr + // !will_ping should also register WatchTimeout + conn = ConnectionRef(); + register_cb(); + } else { + unregister_cb(); + } } } -- 2.39.5