]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
osdc/Objecter: ignore pings from previous registrations
authorSage Weil <sage@redhat.com>
Mon, 17 Nov 2014 16:00:34 +0000 (08:00 -0800)
committerSage Weil <sage@redhat.com>
Thu, 4 Dec 2014 18:34:05 +0000 (10:34 -0800)
If we have a ping in flight and then reregister (due to interval change
or whatever), ignore the result of the previous ping.

Signed-off-by: Sage Weil <sage@redhat.com>
src/include/rados.h
src/osd/osd_types.cc
src/osdc/Objecter.cc
src/osdc/Objecter.h

index f8bba2a1cc67b25bc0d638556f0a5ac456973851..e303c95ae02ef1d2eb63689f1185e5345f5694fc 100644 (file)
@@ -494,6 +494,7 @@ struct ceph_osd_op {
                        __le64 cookie;
                        __le64 ver;     /* no longer used */
                        __u8 op;        /* CEPH_OSD_WATCH_OP_* */
+                       __u32 gen;      /* registration generation */
                } __attribute__ ((packed)) watch;
                struct {
                        __le64 cookie;
index b88ef20066cfd6eb295bf7faf4b5b058883617e4..03f367374a4b520c6a23ecec4072dcdf5a28b6e6 100644 (file)
@@ -4556,6 +4556,8 @@ ostream& operator<<(ostream& out, const OSDOp& op)
     case CEPH_OSD_OP_WATCH:
       out << " " << ceph_osd_watch_op_name(op.op.watch.op)
          << " cookie " << op.op.watch.cookie;
+      if (op.op.watch.gen)
+       out << " gen " << op.op.watch.gen;
       break;
     case CEPH_OSD_OP_COPY_GET:
     case CEPH_OSD_OP_COPY_GET_CLASSIC:
index a60e2b8a680d1de629428cf496cfdfde09f9d0e9..a0826bf4171365aae22e6e9667b2dc5d92cafc45 100644 (file)
@@ -425,6 +425,7 @@ void Objecter::_send_linger(LingerOp *info)
     opv.back().op.op = CEPH_OSD_OP_WATCH;
     opv.back().op.watch.cookie = info->linger_id;
     opv.back().op.watch.op = CEPH_OSD_WATCH_OP_RECONNECT;
+    opv.back().op.watch.gen = ++info->register_gen;
     oncommit = new C_Linger_Reconnect(this, info);
   } else {
     ldout(cct, 15) << "send_linger " << info->linger_id << " register" << dendl;
@@ -537,6 +538,7 @@ void Objecter::_send_linger_ping(LingerOp *info)
   opv[0].op.op = CEPH_OSD_OP_WATCH;
   opv[0].op.watch.cookie = info->linger_id;
   opv[0].op.watch.op = CEPH_OSD_WATCH_OP_PING;
+  opv[0].op.watch.gen = info->register_gen;
   C_Linger_Ping *onack = new C_Linger_Ping(this, info);
   Op *o = new Op(info->target.base_oid, info->target.base_oloc,
                 opv, info->target.flags | CEPH_OSD_FLAG_READ,
@@ -554,20 +556,26 @@ void Objecter::_send_linger_ping(LingerOp *info)
   logger->inc(l_osdc_linger_ping);
 }
 
-void Objecter::_linger_ping(LingerOp *info, int r, utime_t sent)
+void Objecter::_linger_ping(LingerOp *info, int r, utime_t sent,
+                           uint32_t register_gen)
 {
   ldout(cct, 10) << __func__ << " " << info->linger_id
-                << " sent " << sent << " = " << r
-                << " (last_error " << info->last_error << ")" << dendl;
+                << " sent " << sent << " gen " << register_gen << " = " << r
+                << " (last_error " << info->last_error
+                << " register_gen " << info->register_gen << ")" << dendl;
   info->watch_lock.Lock();
-  if (r == 0) {
-    info->watch_valid_thru = sent;
-  } else if (r < 0) {
-    info->last_error = r;
-    if (info->watch_context)
-      finisher->queue(new C_DoWatchError(info, r));
+  if (info->register_gen == register_gen) {
+    if (r == 0) {
+      info->watch_valid_thru = sent;
+    } else if (r < 0) {
+      info->last_error = r;
+      if (info->watch_context)
+       finisher->queue(new C_DoWatchError(info, r));
+    }
+    info->watch_cond.SignalAll();
+  } else {
+    ldout(cct, 20) << " ignoring old gen" << dendl;
   }
-  info->watch_cond.SignalAll();
   info->watch_lock.Unlock();
 }
 
index 3b5c0690a5a739a0316b45bca1d0bd4575223aec..d1b79193a7b6aee929d0fc92fc9680d98fdf852b 100644 (file)
@@ -1480,6 +1480,7 @@ public:
     Mutex watch_lock;
     Cond watch_cond;
 
+    uint32_t register_gen;
     bool registered;
     bool canceled;
     Context *on_reg_ack, *on_reg_commit;
@@ -1503,6 +1504,7 @@ public:
                 is_watch(false),
                 last_error(0),
                 watch_lock("Objecter::LingerOp::watch_lock"),
+                register_gen(0),
                 registered(false),
                 canceled(false),
                 on_reg_ack(NULL), on_reg_commit(NULL),
@@ -1567,14 +1569,16 @@ public:
     Objecter *objecter;
     LingerOp *info;
     utime_t sent;
-    C_Linger_Ping(Objecter *o, LingerOp *l) : objecter(o), info(l) {
+    uint32_t register_gen;
+    C_Linger_Ping(Objecter *o, LingerOp *l)
+      : objecter(o), info(l), register_gen(info->register_gen) {
       info->get();
     }
     ~C_Linger_Ping() {
       info->put();
     }
     void finish(int r) {
-      objecter->_linger_ping(info, r, sent);
+      objecter->_linger_ping(info, r, sent, register_gen);
     }
   };
 
@@ -1688,7 +1692,7 @@ public:
   void _linger_commit(LingerOp *info, int r);
   void _linger_reconnect(LingerOp *info, int r);
   void _send_linger_ping(LingerOp *info);
-  void _linger_ping(LingerOp *info, int r, utime_t sent);
+  void _linger_ping(LingerOp *info, int r, utime_t sent, uint32_t register_gen);
 
   void _check_op_pool_dne(Op *op, bool session_locked);
   void _send_op_map_check(Op *op);