Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / mon / MonMap.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_MONMAP_H
16 #define CEPH_MONMAP_H
17
18 #include "include/err.h"
19
20 #include "msg/Message.h"
21 #include "include/types.h"
22 #include "mon/mon_types.h"
23
24 namespace ceph {
25   class Formatter;
26 }
27
28 struct mon_info_t {
29   /**
30    * monitor name
31    *
32    * i.e., 'foo' in 'mon.foo'
33    */
34   string name;
35   /**
36    * monitor's public address
37    *
38    * public facing address, traditionally used to communicate with all clients
39    * and other monitors.
40    */
41   entity_addr_t public_addr;
42   /**
43    * the priority of the mon, the lower value the more preferred
44    */
45   uint16_t priority{0};
46
47   mon_info_t(const string& n, const entity_addr_t& p_addr, uint16_t p)
48     : name(n), public_addr(p_addr), priority(p)
49   {}
50   mon_info_t(const string &n, const entity_addr_t& p_addr)
51     : name(n), public_addr(p_addr)
52   { }
53
54   mon_info_t() { }
55
56
57   void encode(bufferlist& bl, uint64_t features) const;
58   void decode(bufferlist::iterator& p);
59   void print(ostream& out) const;
60 };
61 WRITE_CLASS_ENCODER_FEATURES(mon_info_t)
62
63 inline ostream& operator<<(ostream& out, const mon_info_t& mon) {
64   mon.print(out);
65   return out;
66 }
67
68 class MonMap {
69  public:
70   epoch_t epoch;       // what epoch/version of the monmap
71   uuid_d fsid;
72   utime_t last_changed;
73   utime_t created;
74
75   map<string, mon_info_t> mon_info;
76   map<entity_addr_t, string> addr_mons;
77
78   vector<string> ranks;
79
80   /**
81    * Persistent Features are all those features that once set on a
82    * monmap cannot, and should not, be removed. These will define the
83    * non-negotiable features that a given monitor must support to
84    * properly operate in a given quorum.
85    *
86    * Should be reserved for features that we really want to make sure
87    * are sticky, and are important enough to tolerate not being able
88    * to downgrade a monitor.
89    */
90   mon_feature_t persistent_features;
91   /**
92    * Optional Features are all those features that can be enabled or
93    * disabled following a given criteria -- e.g., user-mandated via the
94    * cli --, and act much like indicators of what the cluster currently
95    * supports.
96    *
97    * They are by no means "optional" in the sense that monitors can
98    * ignore them. Just that they are not persistent.
99    */
100   mon_feature_t optional_features;
101
102   /**
103    * Returns the set of features required by this monmap.
104    *
105    * The features required by this monmap is the union of all the
106    * currently set persistent features and the currently set optional
107    * features.
108    *
109    * @returns the set of features required by this monmap
110    */
111   mon_feature_t get_required_features() const {
112     return (persistent_features | optional_features);
113   }
114
115 public:
116   void sanitize_mons(map<string,entity_addr_t>& o);
117   void calc_ranks();
118
119   MonMap()
120     : epoch(0) {
121     memset(&fsid, 0, sizeof(fsid));
122   }
123
124   uuid_d& get_fsid() { return fsid; }
125
126   unsigned size() const {
127     return mon_info.size();
128   }
129
130   epoch_t get_epoch() const { return epoch; }
131   void set_epoch(epoch_t e) { epoch = e; }
132
133   /**
134    * Obtain list of public facing addresses
135    *
136    * @param ls list to populate with the monitors' addresses
137    */
138   void list_addrs(list<entity_addr_t>& ls) const {
139     for (map<string,mon_info_t>::const_iterator p = mon_info.begin();
140          p != mon_info.end();
141          ++p) {
142       ls.push_back(p->second.public_addr);
143     }
144   }
145
146   /**
147    * Add new monitor to the monmap
148    *
149    * @param m monitor info of the new monitor
150    */
151   void add(mon_info_t &&m) {
152     assert(mon_info.count(m.name) == 0);
153     assert(addr_mons.count(m.public_addr) == 0);
154     mon_info[m.name] = std::move(m);
155     calc_ranks();
156   }
157
158   /**
159    * Add new monitor to the monmap
160    *
161    * @param name Monitor name (i.e., 'foo' in 'mon.foo')
162    * @param addr Monitor's public address
163    */
164   void add(const string &name, const entity_addr_t &addr) {
165     add(mon_info_t(name, addr));
166   }
167
168   /**
169    * Remove monitor from the monmap
170    *
171    * @param name Monitor name (i.e., 'foo' in 'mon.foo')
172    */
173   void remove(const string &name) {
174     assert(mon_info.count(name));
175     mon_info.erase(name);
176     assert(mon_info.count(name) == 0);
177     calc_ranks();
178   }
179
180   /**
181    * Rename monitor from @p oldname to @p newname
182    *
183    * @param oldname monitor's current name (i.e., 'foo' in 'mon.foo')
184    * @param newname monitor's new name (i.e., 'bar' in 'mon.bar')
185    */
186   void rename(string oldname, string newname) {
187     assert(contains(oldname));
188     assert(!contains(newname));
189     mon_info[newname] = mon_info[oldname];
190     mon_info.erase(oldname);
191     mon_info[newname].name = newname;
192     calc_ranks();
193   }
194
195   bool contains(const string& name) const {
196     return mon_info.count(name);
197   }
198
199   /**
200    * Check if monmap contains a monitor with address @p a
201    *
202    * @note checks for all addresses a monitor may have, public or otherwise.
203    *
204    * @param a monitor address
205    * @returns true if monmap contains a monitor with address @p;
206    *          false otherwise.
207    */
208   bool contains(const entity_addr_t &a) const {
209     for (map<string,mon_info_t>::const_iterator p = mon_info.begin();
210          p != mon_info.end();
211          ++p) {
212       if (p->second.public_addr == a)
213         return true;
214     }
215     return false;
216   }
217
218   string get_name(unsigned n) const {
219     assert(n < ranks.size());
220     return ranks[n];
221   }
222   string get_name(const entity_addr_t& a) const {
223     map<entity_addr_t,string>::const_iterator p = addr_mons.find(a);
224     if (p == addr_mons.end())
225       return string();
226     else
227       return p->second;
228   }
229
230   int get_rank(const string& n) {
231     for (unsigned i = 0; i < ranks.size(); i++)
232       if (ranks[i] == n)
233         return i;
234     return -1;
235   }
236   int get_rank(const entity_addr_t& a) {
237     string n = get_name(a);
238     if (n.empty())
239       return -1;
240
241     for (unsigned i = 0; i < ranks.size(); i++)
242       if (ranks[i] == n)
243         return i;
244     return -1;
245   }
246   bool get_addr_name(const entity_addr_t& a, string& name) {
247     if (addr_mons.count(a) == 0)
248       return false;
249     name = addr_mons[a];
250     return true;
251   }
252
253   const entity_addr_t& get_addr(const string& n) const {
254     assert(mon_info.count(n));
255     map<string,mon_info_t>::const_iterator p = mon_info.find(n);
256     return p->second.public_addr;
257   }
258   const entity_addr_t& get_addr(unsigned m) const {
259     assert(m < ranks.size());
260     return get_addr(ranks[m]);
261   }
262   void set_addr(const string& n, const entity_addr_t& a) {
263     assert(mon_info.count(n));
264     mon_info[n].public_addr = a;
265     calc_ranks();
266   }
267   entity_inst_t get_inst(const string& n) {
268     assert(mon_info.count(n));
269     int m = get_rank(n);
270     assert(m >= 0); // vector can't take negative indicies
271     return get_inst(m);
272   }
273   entity_inst_t get_inst(unsigned m) const {
274     assert(m < ranks.size());
275     entity_inst_t i;
276     i.addr = get_addr(m);
277     i.name = entity_name_t::MON(m);
278     return i;
279   }
280
281   void encode(bufferlist& blist, uint64_t con_features) const;
282   void decode(bufferlist& blist) {
283     bufferlist::iterator p = blist.begin();
284     decode(p);
285   }
286   void decode(bufferlist::iterator &p);
287
288   void generate_fsid() {
289     fsid.generate_random();
290   }
291
292   // read from/write to a file
293   int write(const char *fn);
294   int read(const char *fn);
295
296   /**
297    * build an initial bootstrap monmap from conf
298    *
299    * Build an initial bootstrap monmap from the config.  This will
300    * try, in this order:
301    *
302    *   1 monmap   -- an explicitly provided monmap
303    *   2 mon_host -- list of monitors
304    *   3 config [mon.*] sections, and 'mon addr' fields in those sections
305    *
306    * @param cct context (and associated config)
307    * @param errout ostream to send error messages too
308    */
309   int build_initial(CephContext *cct, ostream& errout);
310
311   /**
312    * build a monmap from a list of hosts or ips
313    *
314    * Resolve dns as needed.  Give mons dummy names.
315    *
316    * @param hosts  list of hosts, space or comma separated
317    * @param prefix prefix to prepend to generated mon names
318    * @return 0 for success, -errno on error
319    */
320   int build_from_host_list(std::string hosts, std::string prefix);
321
322   /**
323    * filter monmap given a set of initial members.
324    *
325    * Remove mons that aren't in the initial_members list.  Add missing
326    * mons and give them dummy IPs (blank IPv4, with a non-zero
327    * nonce). If the name matches my_name, then my_addr will be used in
328    * place of a dummy addr.
329    *
330    * @param initial_members list of initial member names
331    * @param my_name name of self, can be blank
332    * @param my_addr my addr
333    * @param removed optional pointer to set to insert removed mon addrs to
334    */
335   void set_initial_members(CephContext *cct,
336                            list<std::string>& initial_members,
337                            string my_name, const entity_addr_t& my_addr,
338                            set<entity_addr_t> *removed);
339
340   void print(ostream& out) const;
341   void print_summary(ostream& out) const;
342   void dump(ceph::Formatter *f) const;
343
344   static void generate_test_instances(list<MonMap*>& o);
345 };
346 WRITE_CLASS_ENCODER_FEATURES(MonMap)
347
348 inline ostream& operator<<(ostream &out, const MonMap &m) {
349   m.print_summary(out);
350   return out;
351 }
352
353 #endif