]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
osd: avoid watcher remains after "rados watch" is interrupted
authorweixinwei <weixw3@lenovo.com>
Tue, 4 Apr 2023 09:40:12 +0000 (17:40 +0800)
committerIlya Dryomov <idryomov@gmail.com>
Thu, 25 Jul 2024 10:27:21 +0000 (12:27 +0200)
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 <weixw3@lenovo.com>
(cherry picked from commit 5bb185cbc9547a1b324c339753b4b3786073a58f)

src/osd/PrimaryLogPG.cc
src/osd/Watch.cc

index 49178dc406a4dbb6b5d819d25201c95ef44b6084..6f8566b8e45dac3ee8bf2e177a678e28870ab8c4 100644 (file)
@@ -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<pair<watch_info_t,bool> >::iterator i = ctx->watch_connects.begin();
        i != ctx->watch_connects.end();
        ++i) {
     pair<uint64_t, entity_name_t> 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,
index c36ecdc541322767bae1cec59a70ff3f4d1fd3f6..573cb905396eac058005b1b0f101756d35cf97a0 100644 (file)
@@ -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();
+    }
   }
 }