]> git.proxmox.com Git - ceph.git/blob - ceph/src/messages/MMDSBeacon.h
31febe50a353c9633b743dede8e2e1339cccd273
[ceph.git] / ceph / src / messages / MMDSBeacon.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 /*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 *
13 */
14
15 #ifndef CEPH_MMDSBEACON_H
16 #define CEPH_MMDSBEACON_H
17
18 #include "messages/PaxosServiceMessage.h"
19
20 #include "include/types.h"
21
22 #include "mds/MDSMap.h"
23
24
25
26 /**
27 * Unique ID for each type of metric we can send to the mon, so that if the mon
28 * knows about the IDs then it can implement special behaviour for certain
29 * messages.
30 */
31 enum mds_metric_t {
32 MDS_HEALTH_NULL = 0,
33 MDS_HEALTH_TRIM,
34 MDS_HEALTH_CLIENT_RECALL,
35 MDS_HEALTH_CLIENT_LATE_RELEASE,
36 MDS_HEALTH_CLIENT_RECALL_MANY,
37 MDS_HEALTH_CLIENT_LATE_RELEASE_MANY,
38 MDS_HEALTH_CLIENT_OLDEST_TID,
39 MDS_HEALTH_CLIENT_OLDEST_TID_MANY,
40 MDS_HEALTH_DAMAGE,
41 MDS_HEALTH_READ_ONLY,
42 MDS_HEALTH_SLOW_REQUEST,
43 MDS_HEALTH_CACHE_OVERSIZED
44 };
45
46 /**
47 * This structure is designed to allow some flexibility in how we emit health
48 * complaints, such that:
49 * - The mon doesn't have to have foreknowledge of all possible metrics: we can
50 * implement new messages in the MDS and have the mon pass them through to the user
51 * (enables us to do complex checks inside the MDS, and allows mon to be older version
52 * than MDS)
53 * - The mon has enough information to perform reductions on some types of metric, for
54 * example complaints about the same client from multiple MDSs where we might want
55 * to reduce three "client X is stale on MDS y" metrics into one "client X is stale
56 * on 3 MDSs" message.
57 */
58 struct MDSHealthMetric
59 {
60 mds_metric_t type;
61 health_status_t sev;
62 std::string message;
63 std::map<std::string, std::string> metadata;
64
65 void encode(bufferlist& bl) const {
66 ENCODE_START(1, 1, bl);
67 assert(type != MDS_HEALTH_NULL);
68 ::encode((uint16_t)type, bl);
69 ::encode((uint8_t)sev, bl);
70 ::encode(message, bl);
71 ::encode(metadata, bl);
72 ENCODE_FINISH(bl);
73 }
74
75 void decode(bufferlist::iterator& bl) {
76 DECODE_START(1, bl);
77 ::decode((uint16_t&)type, bl);
78 assert(type != MDS_HEALTH_NULL);
79 ::decode((uint8_t&)sev, bl);
80 ::decode(message, bl);
81 ::decode(metadata, bl);
82 DECODE_FINISH(bl);
83 }
84
85 bool operator==(MDSHealthMetric const &other) const
86 {
87 return (type == other.type && sev == other.sev && message == other.message);
88 }
89
90 MDSHealthMetric() : type(MDS_HEALTH_NULL), sev(HEALTH_OK) {}
91 MDSHealthMetric(mds_metric_t type_, health_status_t sev_, std::string const &message_)
92 : type(type_), sev(sev_), message(message_) {}
93 };
94 WRITE_CLASS_ENCODER(MDSHealthMetric)
95
96
97 /**
98 * Health metrics send by the MDS to the mon, so that the mon can generate
99 * user friendly warnings about undesirable states.
100 */
101 struct MDSHealth
102 {
103 std::list<MDSHealthMetric> metrics;
104
105 void encode(bufferlist& bl) const {
106 ENCODE_START(1, 1, bl);
107 ::encode(metrics, bl);
108 ENCODE_FINISH(bl);
109 }
110
111 void decode(bufferlist::iterator& bl) {
112 DECODE_START(1, bl);
113 ::decode(metrics, bl);
114 DECODE_FINISH(bl);
115 }
116
117 bool operator==(MDSHealth const &other) const
118 {
119 return metrics == other.metrics;
120 }
121 };
122 WRITE_CLASS_ENCODER(MDSHealth)
123
124
125 class MMDSBeacon : public PaxosServiceMessage {
126
127 static const int HEAD_VERSION = 7;
128 static const int COMPAT_VERSION = 6;
129
130 uuid_d fsid;
131 mds_gid_t global_id;
132 string name;
133
134 MDSMap::DaemonState state;
135 version_t seq;
136
137 mds_rank_t standby_for_rank;
138 string standby_for_name;
139 fs_cluster_id_t standby_for_fscid;
140 bool standby_replay;
141
142 CompatSet compat;
143
144 MDSHealth health;
145
146 map<string, string> sys_info;
147
148 uint64_t mds_features;
149
150 public:
151 MMDSBeacon()
152 : PaxosServiceMessage(MSG_MDS_BEACON, 0, HEAD_VERSION, COMPAT_VERSION),
153 global_id(0), state(MDSMap::STATE_NULL), standby_for_rank(MDS_RANK_NONE),
154 standby_for_fscid(FS_CLUSTER_ID_NONE), standby_replay(false),
155 mds_features(0)
156 { }
157 MMDSBeacon(const uuid_d &f, mds_gid_t g, string& n, epoch_t les, MDSMap::DaemonState st, version_t se, uint64_t feat) :
158 PaxosServiceMessage(MSG_MDS_BEACON, les, HEAD_VERSION, COMPAT_VERSION),
159 fsid(f), global_id(g), name(n), state(st), seq(se),
160 standby_for_rank(MDS_RANK_NONE), standby_for_fscid(FS_CLUSTER_ID_NONE),
161 standby_replay(false), mds_features(feat) {
162 }
163 private:
164 ~MMDSBeacon() override {}
165
166 public:
167 uuid_d& get_fsid() { return fsid; }
168 mds_gid_t get_global_id() { return global_id; }
169 string& get_name() { return name; }
170 epoch_t get_last_epoch_seen() { return version; }
171 MDSMap::DaemonState get_state() { return state; }
172 version_t get_seq() { return seq; }
173 const char *get_type_name() const override { return "mdsbeacon"; }
174 mds_rank_t get_standby_for_rank() { return standby_for_rank; }
175 const string& get_standby_for_name() { return standby_for_name; }
176 const fs_cluster_id_t& get_standby_for_fscid() { return standby_for_fscid; }
177 bool get_standby_replay() const { return standby_replay; }
178 uint64_t get_mds_features() const { return mds_features; }
179
180 CompatSet const& get_compat() const { return compat; }
181 void set_compat(const CompatSet& c) { compat = c; }
182
183 MDSHealth const& get_health() const { return health; }
184 void set_health(const MDSHealth &h) { health = h; }
185
186 void set_standby_for_rank(mds_rank_t r) { standby_for_rank = r; }
187 void set_standby_for_name(string& n) { standby_for_name = n; }
188 void set_standby_for_name(const char* c) { standby_for_name.assign(c); }
189 void set_standby_for_fscid(fs_cluster_id_t f) { standby_for_fscid = f; }
190 void set_standby_replay(bool r) { standby_replay = r; }
191
192 const map<string, string>& get_sys_info() const { return sys_info; }
193 void set_sys_info(const map<string, string>& i) { sys_info = i; }
194
195 void print(ostream& out) const override {
196 out << "mdsbeacon(" << global_id << "/" << name << " " << ceph_mds_state_name(state)
197 << " seq " << seq << " v" << version << ")";
198 }
199
200 void encode_payload(uint64_t features) override {
201 paxos_encode();
202 ::encode(fsid, payload);
203 ::encode(global_id, payload);
204 ::encode((__u32)state, payload);
205 ::encode(seq, payload);
206 ::encode(name, payload);
207 ::encode(standby_for_rank, payload);
208 ::encode(standby_for_name, payload);
209 ::encode(compat, payload);
210 ::encode(health, payload);
211 if (state == MDSMap::STATE_BOOT) {
212 ::encode(sys_info, payload);
213 }
214 ::encode(mds_features, payload);
215 ::encode(standby_for_fscid, payload);
216 ::encode(standby_replay, payload);
217 }
218 void decode_payload() override {
219 bufferlist::iterator p = payload.begin();
220 paxos_decode(p);
221 ::decode(fsid, p);
222 ::decode(global_id, p);
223 ::decode((__u32&)state, p);
224 ::decode(seq, p);
225 ::decode(name, p);
226 ::decode(standby_for_rank, p);
227 ::decode(standby_for_name, p);
228 ::decode(compat, p);
229 ::decode(health, p);
230 if (state == MDSMap::STATE_BOOT) {
231 ::decode(sys_info, p);
232 }
233 ::decode(mds_features, p);
234 ::decode(standby_for_fscid, p);
235 if (header.version >= 7) {
236 ::decode(standby_replay, p);
237 }
238
239 if (header.version < 7 && state == MDSMap::STATE_STANDBY_REPLAY) {
240 // Old MDS daemons request the state, instead of explicitly
241 // advertising that they are configured as a replay daemon.
242 standby_replay = true;
243 state = MDSMap::STATE_STANDBY;
244 }
245 }
246 };
247
248 #endif