]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: avoid watcher remains after "rados watch" is interrupted 58845/head
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:24:37 +0000 (12:24 +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 5372da30824211e28bdc6bd25deea2b40a9c55b5..5b0ce9a67ba00651600326d51f7b2fd67e47252b 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();
+    }
   }
 }