X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Fmon%2FMonMap.h;fp=src%2Fceph%2Fsrc%2Fmon%2FMonMap.h;h=63cc2209021a2e701241786a2fc30fa6eb8e13ba;hb=812ff6ca9fcd3e629e49d4328905f33eee8ca3f5;hp=0000000000000000000000000000000000000000;hpb=15280273faafb77777eab341909a3f495cf248d9;p=stor4nfv.git diff --git a/src/ceph/src/mon/MonMap.h b/src/ceph/src/mon/MonMap.h new file mode 100644 index 0000000..63cc220 --- /dev/null +++ b/src/ceph/src/mon/MonMap.h @@ -0,0 +1,353 @@ +// -*- 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) 2004-2006 Sage Weil + * + * 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 CEPH_MONMAP_H +#define CEPH_MONMAP_H + +#include "include/err.h" + +#include "msg/Message.h" +#include "include/types.h" +#include "mon/mon_types.h" + +namespace ceph { + class Formatter; +} + +struct mon_info_t { + /** + * monitor name + * + * i.e., 'foo' in 'mon.foo' + */ + string name; + /** + * monitor's public address + * + * public facing address, traditionally used to communicate with all clients + * and other monitors. + */ + entity_addr_t public_addr; + /** + * the priority of the mon, the lower value the more preferred + */ + uint16_t priority{0}; + + mon_info_t(const string& n, const entity_addr_t& p_addr, uint16_t p) + : name(n), public_addr(p_addr), priority(p) + {} + mon_info_t(const string &n, const entity_addr_t& p_addr) + : name(n), public_addr(p_addr) + { } + + mon_info_t() { } + + + void encode(bufferlist& bl, uint64_t features) const; + void decode(bufferlist::iterator& p); + void print(ostream& out) const; +}; +WRITE_CLASS_ENCODER_FEATURES(mon_info_t) + +inline ostream& operator<<(ostream& out, const mon_info_t& mon) { + mon.print(out); + return out; +} + +class MonMap { + public: + epoch_t epoch; // what epoch/version of the monmap + uuid_d fsid; + utime_t last_changed; + utime_t created; + + map mon_info; + map addr_mons; + + vector ranks; + + /** + * Persistent Features are all those features that once set on a + * monmap cannot, and should not, be removed. These will define the + * non-negotiable features that a given monitor must support to + * properly operate in a given quorum. + * + * Should be reserved for features that we really want to make sure + * are sticky, and are important enough to tolerate not being able + * to downgrade a monitor. + */ + mon_feature_t persistent_features; + /** + * Optional Features are all those features that can be enabled or + * disabled following a given criteria -- e.g., user-mandated via the + * cli --, and act much like indicators of what the cluster currently + * supports. + * + * They are by no means "optional" in the sense that monitors can + * ignore them. Just that they are not persistent. + */ + mon_feature_t optional_features; + + /** + * Returns the set of features required by this monmap. + * + * The features required by this monmap is the union of all the + * currently set persistent features and the currently set optional + * features. + * + * @returns the set of features required by this monmap + */ + mon_feature_t get_required_features() const { + return (persistent_features | optional_features); + } + +public: + void sanitize_mons(map& o); + void calc_ranks(); + + MonMap() + : epoch(0) { + memset(&fsid, 0, sizeof(fsid)); + } + + uuid_d& get_fsid() { return fsid; } + + unsigned size() const { + return mon_info.size(); + } + + epoch_t get_epoch() const { return epoch; } + void set_epoch(epoch_t e) { epoch = e; } + + /** + * Obtain list of public facing addresses + * + * @param ls list to populate with the monitors' addresses + */ + void list_addrs(list& ls) const { + for (map::const_iterator p = mon_info.begin(); + p != mon_info.end(); + ++p) { + ls.push_back(p->second.public_addr); + } + } + + /** + * Add new monitor to the monmap + * + * @param m monitor info of the new monitor + */ + void add(mon_info_t &&m) { + assert(mon_info.count(m.name) == 0); + assert(addr_mons.count(m.public_addr) == 0); + mon_info[m.name] = std::move(m); + calc_ranks(); + } + + /** + * Add new monitor to the monmap + * + * @param name Monitor name (i.e., 'foo' in 'mon.foo') + * @param addr Monitor's public address + */ + void add(const string &name, const entity_addr_t &addr) { + add(mon_info_t(name, addr)); + } + + /** + * Remove monitor from the monmap + * + * @param name Monitor name (i.e., 'foo' in 'mon.foo') + */ + void remove(const string &name) { + assert(mon_info.count(name)); + mon_info.erase(name); + assert(mon_info.count(name) == 0); + calc_ranks(); + } + + /** + * Rename monitor from @p oldname to @p newname + * + * @param oldname monitor's current name (i.e., 'foo' in 'mon.foo') + * @param newname monitor's new name (i.e., 'bar' in 'mon.bar') + */ + void rename(string oldname, string newname) { + assert(contains(oldname)); + assert(!contains(newname)); + mon_info[newname] = mon_info[oldname]; + mon_info.erase(oldname); + mon_info[newname].name = newname; + calc_ranks(); + } + + bool contains(const string& name) const { + return mon_info.count(name); + } + + /** + * Check if monmap contains a monitor with address @p a + * + * @note checks for all addresses a monitor may have, public or otherwise. + * + * @param a monitor address + * @returns true if monmap contains a monitor with address @p; + * false otherwise. + */ + bool contains(const entity_addr_t &a) const { + for (map::const_iterator p = mon_info.begin(); + p != mon_info.end(); + ++p) { + if (p->second.public_addr == a) + return true; + } + return false; + } + + string get_name(unsigned n) const { + assert(n < ranks.size()); + return ranks[n]; + } + string get_name(const entity_addr_t& a) const { + map::const_iterator p = addr_mons.find(a); + if (p == addr_mons.end()) + return string(); + else + return p->second; + } + + int get_rank(const string& n) { + for (unsigned i = 0; i < ranks.size(); i++) + if (ranks[i] == n) + return i; + return -1; + } + int get_rank(const entity_addr_t& a) { + string n = get_name(a); + if (n.empty()) + return -1; + + for (unsigned i = 0; i < ranks.size(); i++) + if (ranks[i] == n) + return i; + return -1; + } + bool get_addr_name(const entity_addr_t& a, string& name) { + if (addr_mons.count(a) == 0) + return false; + name = addr_mons[a]; + return true; + } + + const entity_addr_t& get_addr(const string& n) const { + assert(mon_info.count(n)); + map::const_iterator p = mon_info.find(n); + return p->second.public_addr; + } + const entity_addr_t& get_addr(unsigned m) const { + assert(m < ranks.size()); + return get_addr(ranks[m]); + } + void set_addr(const string& n, const entity_addr_t& a) { + assert(mon_info.count(n)); + mon_info[n].public_addr = a; + calc_ranks(); + } + entity_inst_t get_inst(const string& n) { + assert(mon_info.count(n)); + int m = get_rank(n); + assert(m >= 0); // vector can't take negative indicies + return get_inst(m); + } + entity_inst_t get_inst(unsigned m) const { + assert(m < ranks.size()); + entity_inst_t i; + i.addr = get_addr(m); + i.name = entity_name_t::MON(m); + return i; + } + + void encode(bufferlist& blist, uint64_t con_features) const; + void decode(bufferlist& blist) { + bufferlist::iterator p = blist.begin(); + decode(p); + } + void decode(bufferlist::iterator &p); + + void generate_fsid() { + fsid.generate_random(); + } + + // read from/write to a file + int write(const char *fn); + int read(const char *fn); + + /** + * build an initial bootstrap monmap from conf + * + * Build an initial bootstrap monmap from the config. This will + * try, in this order: + * + * 1 monmap -- an explicitly provided monmap + * 2 mon_host -- list of monitors + * 3 config [mon.*] sections, and 'mon addr' fields in those sections + * + * @param cct context (and associated config) + * @param errout ostream to send error messages too + */ + int build_initial(CephContext *cct, ostream& errout); + + /** + * build a monmap from a list of hosts or ips + * + * Resolve dns as needed. Give mons dummy names. + * + * @param hosts list of hosts, space or comma separated + * @param prefix prefix to prepend to generated mon names + * @return 0 for success, -errno on error + */ + int build_from_host_list(std::string hosts, std::string prefix); + + /** + * filter monmap given a set of initial members. + * + * Remove mons that aren't in the initial_members list. Add missing + * mons and give them dummy IPs (blank IPv4, with a non-zero + * nonce). If the name matches my_name, then my_addr will be used in + * place of a dummy addr. + * + * @param initial_members list of initial member names + * @param my_name name of self, can be blank + * @param my_addr my addr + * @param removed optional pointer to set to insert removed mon addrs to + */ + void set_initial_members(CephContext *cct, + list& initial_members, + string my_name, const entity_addr_t& my_addr, + set *removed); + + void print(ostream& out) const; + void print_summary(ostream& out) const; + void dump(ceph::Formatter *f) const; + + static void generate_test_instances(list& o); +}; +WRITE_CLASS_ENCODER_FEATURES(MonMap) + +inline ostream& operator<<(ostream &out, const MonMap &m) { + m.print_summary(out); + return out; +} + +#endif