From: weixinwei Date: Tue, 4 Apr 2023 09:40:12 +0000 (+0800) Subject: osd: avoid watcher remains after "rados watch" is interrupted X-Git-Tag: v17.2.8~66^2 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=44c271696f69f5c002da797a8a116b227ef52a24;p=ceph.git 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) --- diff --git a/src/osd/PrimaryLogPG.cc b/src/osd/PrimaryLogPG.cc index 5372da3082421..5b0ce9a67ba00 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 c36ecdc541322..573cb905396ea 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(); + } } }