Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / mon / MgrMap.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) 2016 John Spray <john.spray@redhat.com>
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 #ifndef MGR_MAP_H_
15 #define MGR_MAP_H_
16
17 #include <sstream>
18
19 #include "msg/msg_types.h"
20 #include "common/Formatter.h"
21 #include "include/encoding.h"
22
23 class StandbyInfo
24 {
25 public:
26   uint64_t gid;
27   std::string name;
28   std::set<std::string> available_modules;
29
30   StandbyInfo(uint64_t gid_, const std::string &name_,
31               std::set<std::string>& am)
32     : gid(gid_), name(name_), available_modules(am)
33   {}
34
35   StandbyInfo()
36     : gid(0)
37   {}
38
39   void encode(bufferlist& bl) const
40   {
41     ENCODE_START(2, 1, bl);
42     ::encode(gid, bl);
43     ::encode(name, bl);
44     ::encode(available_modules, bl);
45     ENCODE_FINISH(bl);
46   }
47
48   void decode(bufferlist::iterator& p)
49   {
50     DECODE_START(2, p);
51     ::decode(gid, p);
52     ::decode(name, p);
53     if (struct_v >= 2) {
54       ::decode(available_modules, p);
55     }
56     DECODE_FINISH(p);
57   }
58 };
59 WRITE_CLASS_ENCODER(StandbyInfo)
60
61 class MgrMap
62 {
63 public:
64   epoch_t epoch = 0;
65
66   /// global_id of the ceph-mgr instance selected as a leader
67   uint64_t active_gid = 0;
68   /// server address reported by the leader once it is active
69   entity_addr_t active_addr;
70   /// whether the nominated leader is active (i.e. has initialized its server)
71   bool available = false;
72   /// the name (foo in mgr.<foo>) of the active daemon
73   std::string active_name;
74
75   std::map<uint64_t, StandbyInfo> standbys;
76
77   std::set<std::string> modules;
78   std::set<std::string> available_modules;
79
80   // Map of module name to URI, indicating services exposed by
81   // running modules on the active mgr daemon.
82   std::map<std::string, std::string> services;
83
84   epoch_t get_epoch() const { return epoch; }
85   entity_addr_t get_active_addr() const { return active_addr; }
86   uint64_t get_active_gid() const { return active_gid; }
87   bool get_available() const { return available; }
88   const std::string &get_active_name() const { return active_name; }
89
90   bool all_support_module(const std::string& module) {
91     if (!available_modules.count(module)) {
92       return false;
93     }
94     for (auto& p : standbys) {
95       if (!p.second.available_modules.count(module)) {
96         return false;
97       }
98     }
99     return true;
100   }
101
102   bool have_name(const string& name) const {
103     if (active_name == name) {
104       return true;
105     }
106     for (auto& p : standbys) {
107       if (p.second.name == name) {
108         return true;
109       }
110     }
111     return false;
112   }
113
114   std::set<std::string> get_all_names() const {
115     std::set<std::string> ls;
116     if (active_name.size()) {
117       ls.insert(active_name);
118     }
119     for (auto& p : standbys) {
120       ls.insert(p.second.name);
121     }
122     return ls;
123   }
124
125   void encode(bufferlist& bl, uint64_t features) const
126   {
127     ENCODE_START(3, 1, bl);
128     ::encode(epoch, bl);
129     ::encode(active_addr, bl, features);
130     ::encode(active_gid, bl);
131     ::encode(available, bl);
132     ::encode(active_name, bl);
133     ::encode(standbys, bl);
134     ::encode(modules, bl);
135     ::encode(available_modules, bl);
136     ::encode(services, bl);
137     ENCODE_FINISH(bl);
138   }
139
140   void decode(bufferlist::iterator& p)
141   {
142     DECODE_START(2, p);
143     ::decode(epoch, p);
144     ::decode(active_addr, p);
145     ::decode(active_gid, p);
146     ::decode(available, p);
147     ::decode(active_name, p);
148     ::decode(standbys, p);
149     if (struct_v >= 2) {
150       ::decode(modules, p);
151       ::decode(available_modules, p);
152     }
153     if (struct_v >= 3) {
154       ::decode(services, p);
155     }
156     DECODE_FINISH(p);
157   }
158
159   void dump(Formatter *f) const {
160     f->dump_int("epoch", epoch);
161     f->dump_int("active_gid", get_active_gid());
162     f->dump_string("active_name", get_active_name());
163     f->dump_stream("active_addr") << active_addr;
164     f->dump_bool("available", available);
165     f->open_array_section("standbys");
166     for (const auto &i : standbys) {
167       f->open_object_section("standby");
168       f->dump_int("gid", i.second.gid);
169       f->dump_string("name", i.second.name);
170       f->open_array_section("available_modules");
171       for (auto& j : i.second.available_modules) {
172         f->dump_string("module", j);
173       }
174       f->close_section();
175       f->close_section();
176     }
177     f->close_section();
178     f->open_array_section("modules");
179     for (auto& i : modules) {
180       f->dump_string("module", i);
181     }
182     f->close_section();
183     f->open_array_section("available_modules");
184     for (auto& j : available_modules) {
185       f->dump_string("module", j);
186     }
187     f->close_section();
188
189     f->open_object_section("services");
190     for (const auto &i : services) {
191       f->dump_string(i.first.c_str(), i.second);
192     }
193     f->close_section();
194   }
195
196   static void generate_test_instances(list<MgrMap*> &l) {
197     l.push_back(new MgrMap);
198   }
199
200   void print_summary(Formatter *f, std::ostream *ss) const
201   {
202     // One or the other, not both
203     assert((ss != nullptr) != (f != nullptr));
204     if (f) {
205       dump(f);
206     } else {
207       if (get_active_gid() != 0) {
208         *ss << get_active_name();
209         if (!available) {
210           // If the daemon hasn't gone active yet, indicate that.
211           *ss << "(active, starting)";
212         } else {
213           *ss << "(active)";
214         }
215       } else {
216         *ss << "no daemons active";
217       }
218       if (standbys.size()) {
219         *ss << ", standbys: ";
220         bool first = true;
221         for (const auto &i : standbys) {
222           if (!first) {
223             *ss << ", ";
224           }
225           *ss << i.second.name;
226           first = false;
227         }
228       }
229     }
230   }
231
232   friend ostream& operator<<(ostream& out, const MgrMap& m) {
233     ostringstream ss;
234     m.print_summary(nullptr, &ss);
235     return out << ss.str();
236   }
237 };
238
239 WRITE_CLASS_ENCODER_FEATURES(MgrMap)
240
241 #endif
242