From 88233696ff17cfcaa7d5fc017f1da38fc097397d Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 17 Nov 2014 08:00:34 -0800 Subject: [PATCH] osdc/Objecter: ignore pings from previous registrations 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 --- src/include/rados.h | 1 + src/osd/osd_types.cc | 2 ++ src/osdc/Objecter.cc | 28 ++++++++++++++++++---------- src/osdc/Objecter.h | 10 +++++++--- 4 files changed, 28 insertions(+), 13 deletions(-) diff --git a/src/include/rados.h b/src/include/rados.h index f8bba2a1cc67b..e303c95ae02ef 100644 --- a/src/include/rados.h +++ b/src/include/rados.h @@ -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; diff --git a/src/osd/osd_types.cc b/src/osd/osd_types.cc index b88ef20066cfd..03f367374a4b5 100644 --- a/src/osd/osd_types.cc +++ b/src/osd/osd_types.cc @@ -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: diff --git a/src/osdc/Objecter.cc b/src/osdc/Objecter.cc index a60e2b8a680d1..a0826bf417136 100644 --- a/src/osdc/Objecter.cc +++ b/src/osdc/Objecter.cc @@ -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(); } diff --git a/src/osdc/Objecter.h b/src/osdc/Objecter.h index 3b5c0690a5a73..d1b79193a7b6a 100644 --- a/src/osdc/Objecter.h +++ b/src/osdc/Objecter.h @@ -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); -- 2.39.5