]> git.proxmox.com Git - ceph.git/blame - ceph/src/mds/MDSPinger.cc
import ceph 16.2.6
[ceph.git] / ceph / src / mds / MDSPinger.cc
CommitLineData
f67539c2
TL
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3
4#include "common/dout.h"
5
6#include "mds/MDSRank.h"
7#include "mds/MDSPinger.h"
8
9#define dout_context g_ceph_context
10#define dout_subsys ceph_subsys_mds
11#undef dout_prefix
12#define dout_prefix *_dout << "mds.pinger " << __func__
13
14MDSPinger::MDSPinger(MDSRank *mds)
15 : mds(mds) {
16}
17
18void MDSPinger::send_ping(mds_rank_t rank, const entity_addrvec_t &addr) {
19 dout(10) << ": rank=" << rank << dendl;
20
21 std::scoped_lock locker(lock);
22 auto [it, inserted] = ping_state_by_rank.emplace(rank, PingState());
23 if (inserted) {
24 dout(20) << ": init ping pong state for rank=" << rank << dendl;
25 }
26
27 auto &ping_state = it->second;
28 auto last_seq = ping_state.last_seq++;
29
30 ping_state.seq_time_map.emplace(last_seq, clock::now());
31
32 dout(10) << ": sending ping with sequence=" << last_seq << " to rank="
33 << rank << dendl;
34 mds->send_message_mds(make_message<MMDSPing>(last_seq), addr);
35}
36
37bool MDSPinger::pong_received(mds_rank_t rank, version_t seq) {
38 dout(10) << ": rank=" << rank << ", sequence=" << seq << dendl;
39
40 std::scoped_lock locker(lock);
41 auto it1 = ping_state_by_rank.find(rank);
42 if (it1 == ping_state_by_rank.end()) {
43 // this *might* just happen on mds failover when a non-rank-0 mds
44 // acks backs a ping message from an earlier rank 0 mds to a newly
45 // appointed rank 0 mds (possible?).
46 // or when non rank 0 active MDSs begin sending metric updates before
47 // rank 0 can start pinging it (although, that should resolve out soon).
48 dout(10) << ": received pong from rank=" << rank << " to which ping was never"
49 << " sent (ignoring...)." << dendl;
50 return false;
51 }
52
53 auto &ping_state = it1->second;
54 // find incoming seq timestamp for updation
55 auto it2 = ping_state.seq_time_map.find(seq);
56 if (it2 == ping_state.seq_time_map.end()) {
57 // rank still bootstrapping
58 dout(10) << ": pong received for unknown ping sequence " << seq
59 << ", rank " << rank << " should catch up soon." << dendl;
60 return false;
61 }
62
63 ping_state.last_acked_time = it2->second;
64 ping_state.seq_time_map.erase(ping_state.seq_time_map.begin(), it2);
65
66 return true;
67}
68
69void MDSPinger::reset_ping(mds_rank_t rank) {
70 dout(10) << ": rank=" << rank << dendl;
71
72 std::scoped_lock locker(lock);
73 auto it = ping_state_by_rank.find(rank);
74 if (it == ping_state_by_rank.end()) {
75 dout(10) << ": rank=" << rank << " was never sent ping request." << dendl;
76 return;
77 }
78
79 // remove the rank from ping state, send_ping() will init it
80 // later when invoked.
81 ping_state_by_rank.erase(it);
82}
83
84bool MDSPinger::is_rank_lagging(mds_rank_t rank) {
85 dout(10) << ": rank=" << rank << dendl;
86
87 std::scoped_lock locker(lock);
88 auto it = ping_state_by_rank.find(rank);
89 if (it == ping_state_by_rank.end()) {
90 derr << ": rank=" << rank << " was never sent ping request." << dendl;
91 return false;
92 }
93
94 auto now = clock::now();
95 auto since = std::chrono::duration<double>(now - it->second.last_acked_time).count();
96 if (since > g_conf().get_val<std::chrono::seconds>("mds_ping_grace").count()) {
97 dout(5) << ": rank=" << rank << " is lagging a pong response (last ack time is "
98 << it->second.last_acked_time << ")" << dendl;
99 return true;
100 }
101
102 return false;
103}