From bfadb8282c921f977119c9d979d8c9af4ca5edc7 Mon Sep 17 00:00:00 2001 From: Yingxin Cheng Date: Thu, 27 Aug 2020 10:29:11 +0800 Subject: [PATCH] crimson/osd: fix unexpected connection markdown in heartbeat Pass reference when log Heartbeat::Connection instance, or the destructor will be called incorrectly, and the conn be marked down unexpectedly. Also, the replacing conn is actually connected during replacement-reset event. Fixes: https://tracker.ceph.com/issues/47124 Signed-off-by: Yingxin Cheng --- src/crimson/net/ProtocolV2.cc | 6 ++++++ src/crimson/osd/heartbeat.cc | 2 +- src/crimson/osd/heartbeat.h | 8 +++++++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/crimson/net/ProtocolV2.cc b/src/crimson/net/ProtocolV2.cc index 3e348241569b8..fd9567be9949e 100644 --- a/src/crimson/net/ProtocolV2.cc +++ b/src/crimson/net/ProtocolV2.cc @@ -1591,6 +1591,12 @@ void ProtocolV2::execute_establishing( trigger_state(state_t::ESTABLISHING, write_state_t::delay, false); if (existing_conn) { existing_conn->protocol->close(dispatch_reset, std::move(accept_me)); + if (unlikely(state != state_t::ESTABLISHING)) { + logger().warn("{} triggered {} during execute_establishing(), " + "the accept event will not be delivered!", + conn, get_state_name(state)); + abort_protocol(); + } } else { accept_me(); } diff --git a/src/crimson/osd/heartbeat.cc b/src/crimson/osd/heartbeat.cc index bd7f906f322e1..d8dc1e550e168 100644 --- a/src/crimson/osd/heartbeat.cc +++ b/src/crimson/osd/heartbeat.cc @@ -402,7 +402,7 @@ void Heartbeat::Connection::replaced() racing_detected = true; logger().warn("Heartbeat::Connection::replaced(): {} racing", *this); assert(conn != replaced_conn); - assert(!conn->is_connected()); + assert(conn->is_connected()); } void Heartbeat::Connection::reset() diff --git a/src/crimson/osd/heartbeat.h b/src/crimson/osd/heartbeat.h index d71d4e0c87c2c..b8d13ee356712 100644 --- a/src/crimson/osd/heartbeat.h +++ b/src/crimson/osd/heartbeat.h @@ -176,6 +176,11 @@ class Heartbeat::Connection { is_winner_side{is_winner_side} { connect(); } + Connection(const Connection&) = delete; + Connection(Connection&&) = delete; + Connection& operator=(const Connection&) = delete; + Connection& operator=(Connection&&) = delete; + ~Connection(); bool matches(crimson::net::Connection* _conn) const; @@ -235,7 +240,7 @@ class Heartbeat::Connection { crimson::net::ConnectionRef conn; bool is_connected = false; - friend std::ostream& operator<<(std::ostream& os, const Connection c) { + friend std::ostream& operator<<(std::ostream& os, const Connection& c) { if (c.type == type_t::front) { return os << "con_front(osd." << c.peer << ")"; } else { @@ -393,6 +398,7 @@ class Heartbeat::Peer final : private Heartbeat::ConnectionListener { ~Peer(); Peer(Peer&&) = delete; Peer(const Peer&) = delete; + Peer& operator=(Peer&&) = delete; Peer& operator=(const Peer&) = delete; void set_epoch(epoch_t epoch) { session.set_epoch(epoch); } -- 2.39.5