blob: 4bf88e403e1572256d532336f8e6035ade2424e4 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
/*
* Ceph - scalable distributed file system
*
* Copyright (C) 2012 Red Hat
*
* This is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software
* Foundation. See file COPYING.
*
*/
#ifndef BEACON_STATE_H
#define BEACON_STATE_H
#include <mutex>
#include <string_view>
#include <thread>
#include "include/types.h"
#include "include/Context.h"
#include "msg/Dispatcher.h"
#include "messages/MMDSBeacon.h"
class MonClient;
class MDSRank;
/**
* One of these per MDS. Handle beacon logic in this separate class so
* that a busy MDS holding its own lock does not hold up sending beacon
* messages to the mon and cause false lagginess.
*
* So that we can continue to operate while the MDS is holding its own lock,
* we keep copies of the data needed to generate beacon messages. The MDS is
* responsible for calling Beacon::notify_* when things change.
*/
class Beacon : public Dispatcher
{
public:
using clock = ceph::coarse_mono_clock;
using time = ceph::coarse_mono_time;
bool missed_beacon_ack_dump = false;
bool missed_internal_heartbeat_dump = false;
Beacon(CephContext *cct, MonClient *monc, std::string_view name);
~Beacon() override;
void init(const MDSMap &mdsmap);
void shutdown();
bool ms_can_fast_dispatch_any() const override { return true; }
bool ms_can_fast_dispatch2(const cref_t<Message>& m) const override;
void ms_fast_dispatch2(const ref_t<Message>& m) override;
bool ms_dispatch2(const ref_t<Message> &m) override;
void ms_handle_connect(Connection *c) override {}
bool ms_handle_reset(Connection *c) override {return false;}
void ms_handle_remote_reset(Connection *c) override {}
bool ms_handle_refused(Connection *c) override {return false;}
void notify_mdsmap(const MDSMap &mdsmap);
void notify_health(const MDSRank *mds);
void handle_mds_beacon(const cref_t<MMDSBeacon> &m);
void send();
void set_want_state(const MDSMap &mdsmap, MDSMap::DaemonState newstate);
MDSMap::DaemonState get_want_state() const;
/**
* Send a beacon, and block until the ack is received from the mon
* or `duration` seconds pass, whichever happens sooner. Useful
* for emitting a last message on shutdown.
*/
void send_and_wait(const double duration);
bool is_laggy();
double last_cleared_laggy() const {
std::unique_lock lock(mutex);
return std::chrono::duration<double>(clock::now()-last_laggy).count();
}
private:
void _notify_mdsmap(const MDSMap &mdsmap);
bool _send();
mutable std::mutex mutex;
std::thread sender;
std::condition_variable cvar;
time last_send = clock::zero();
double beacon_interval = 5.0;
bool finished = false;
MonClient* monc;
// Items we duplicate from the MDS to have access under our own lock
std::string name;
version_t epoch = 0;
CompatSet compat;
MDSMap::DaemonState want_state = MDSMap::STATE_BOOT;
// Internal beacon state
version_t last_seq = 0; // last seq sent to monitor
std::map<version_t,time> seq_stamp; // seq # -> time sent
time last_acked_stamp = clock::zero(); // last time we sent a beacon that got acked
bool laggy = false;
time last_laggy = clock::zero();
// Health status to be copied into each beacon message
MDSHealth health;
};
#endif // BEACON_STATE_H
|