X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Fmon%2Fmon_types.h;fp=src%2Fceph%2Fsrc%2Fmon%2Fmon_types.h;h=ef1b90c1eb1db896ed345c4be8abf757e76e0526;hb=812ff6ca9fcd3e629e49d4328905f33eee8ca3f5;hp=0000000000000000000000000000000000000000;hpb=15280273faafb77777eab341909a3f495cf248d9;p=stor4nfv.git diff --git a/src/ceph/src/mon/mon_types.h b/src/ceph/src/mon/mon_types.h new file mode 100644 index 0000000..ef1b90c --- /dev/null +++ b/src/ceph/src/mon/mon_types.h @@ -0,0 +1,565 @@ +// -*- 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_MON_TYPES_H +#define CEPH_MON_TYPES_H + +#include + +#include "include/utime.h" +#include "include/util.h" +#include "common/Formatter.h" +#include "common/bit_str.h" +#include "include/Context.h" + +#define PAXOS_PGMAP 0 // before osd, for pg kick to behave +#define PAXOS_MDSMAP 1 +#define PAXOS_OSDMAP 2 +#define PAXOS_LOG 3 +#define PAXOS_MONMAP 4 +#define PAXOS_AUTH 5 +#define PAXOS_MGR 6 +#define PAXOS_MGRSTAT 7 +#define PAXOS_HEALTH 8 +#define PAXOS_NUM 9 + +inline const char *get_paxos_name(int p) { + switch (p) { + case PAXOS_MDSMAP: return "mdsmap"; + case PAXOS_MONMAP: return "monmap"; + case PAXOS_OSDMAP: return "osdmap"; + case PAXOS_PGMAP: return "pgmap"; + case PAXOS_LOG: return "logm"; + case PAXOS_AUTH: return "auth"; + case PAXOS_MGR: return "mgr"; + case PAXOS_MGRSTAT: return "mgrstat"; + case PAXOS_HEALTH: return "health"; + default: ceph_abort(); return 0; + } +} + +#define CEPH_MON_ONDISK_MAGIC "ceph mon volume v012" + +// map of entity_type -> features -> count +struct FeatureMap { + std::map> m; + + void add(uint32_t type, uint64_t features) { + if (type == CEPH_ENTITY_TYPE_MON) { + return; + } + m[type][features]++; + } + + void add_mon(uint64_t features) { + m[CEPH_ENTITY_TYPE_MON][features]++; + } + + void rm(uint32_t type, uint64_t features) { + if (type == CEPH_ENTITY_TYPE_MON) { + return; + } + auto p = m.find(type); + assert(p != m.end()); + auto q = p->second.find(features); + assert(q != p->second.end()); + if (--q->second == 0) { + p->second.erase(q); + if (p->second.empty()) { + m.erase(p); + } + } + } + + FeatureMap& operator+=(const FeatureMap& o) { + for (auto& p : o.m) { + auto &v = m[p.first]; + for (auto& q : p.second) { + v[q.first] += q.second; + } + } + return *this; + } + + void encode(bufferlist& bl) const { + ENCODE_START(1, 1, bl); + ::encode(m, bl); + ENCODE_FINISH(bl); + } + + void decode(bufferlist::iterator& p) { + DECODE_START(1, p); + ::decode(m, p); + DECODE_FINISH(p); + } + + void dump(Formatter *f) const { + for (auto& p : m) { + f->open_object_section(ceph_entity_type_name(p.first)); + for (auto& q : p.second) { + f->open_object_section("group"); + std::stringstream ss; + ss << "0x" << std::hex << q.first << std::dec; + f->dump_string("features", ss.str()); + f->dump_string("release", ceph_release_name( + ceph_release_from_features(q.first))); + f->dump_unsigned("num", q.second); + f->close_section(); + } + f->close_section(); + } + } +}; +WRITE_CLASS_ENCODER(FeatureMap) + +/** + * leveldb store stats + * + * If we ever decide to support multiple backends for the monitor store, + * we should then create an abstract class 'MonitorStoreStats' of sorts + * and inherit it on LevelDBStoreStats. I'm sure you'll figure something + * out. + */ +struct LevelDBStoreStats { + uint64_t bytes_total; + uint64_t bytes_sst; + uint64_t bytes_log; + uint64_t bytes_misc; + utime_t last_update; + + LevelDBStoreStats() : + bytes_total(0), + bytes_sst(0), + bytes_log(0), + bytes_misc(0) + {} + + void dump(Formatter *f) const { + assert(f != NULL); + f->dump_int("bytes_total", bytes_total); + f->dump_int("bytes_sst", bytes_sst); + f->dump_int("bytes_log", bytes_log); + f->dump_int("bytes_misc", bytes_misc); + f->dump_stream("last_updated") << last_update; + } + + void encode(bufferlist &bl) const { + ENCODE_START(1, 1, bl); + ::encode(bytes_total, bl); + ::encode(bytes_sst, bl); + ::encode(bytes_log, bl); + ::encode(bytes_misc, bl); + ::encode(last_update, bl); + ENCODE_FINISH(bl); + } + + void decode(bufferlist::iterator &p) { + DECODE_START(1, p); + ::decode(bytes_total, p); + ::decode(bytes_sst, p); + ::decode(bytes_log, p); + ::decode(bytes_misc, p); + ::decode(last_update, p); + DECODE_FINISH(p); + } + + static void generate_test_instances(list& ls) { + ls.push_back(new LevelDBStoreStats); + ls.push_back(new LevelDBStoreStats); + ls.back()->bytes_total = 1024*1024; + ls.back()->bytes_sst = 512*1024; + ls.back()->bytes_log = 256*1024; + ls.back()->bytes_misc = 256*1024; + ls.back()->last_update = utime_t(); + } +}; +WRITE_CLASS_ENCODER(LevelDBStoreStats) + +// data stats + +struct DataStats { + ceph_data_stats_t fs_stats; + // data dir + utime_t last_update; + LevelDBStoreStats store_stats; + + void dump(Formatter *f) const { + assert(f != NULL); + f->dump_int("kb_total", (fs_stats.byte_total/1024)); + f->dump_int("kb_used", (fs_stats.byte_used/1024)); + f->dump_int("kb_avail", (fs_stats.byte_avail/1024)); + f->dump_int("avail_percent", fs_stats.avail_percent); + f->dump_stream("last_updated") << last_update; + f->open_object_section("store_stats"); + store_stats.dump(f); + f->close_section(); + } + + void encode(bufferlist &bl) const { + ENCODE_START(3, 1, bl); + ::encode(fs_stats.byte_total, bl); + ::encode(fs_stats.byte_used, bl); + ::encode(fs_stats.byte_avail, bl); + ::encode(fs_stats.avail_percent, bl); + ::encode(last_update, bl); + ::encode(store_stats, bl); + ENCODE_FINISH(bl); + } + void decode(bufferlist::iterator &p) { + DECODE_START(1, p); + // we moved from having fields in kb to fields in byte + if (struct_v > 2) { + ::decode(fs_stats.byte_total, p); + ::decode(fs_stats.byte_used, p); + ::decode(fs_stats.byte_avail, p); + } else { + uint64_t t; + ::decode(t, p); + fs_stats.byte_total = t*1024; + ::decode(t, p); + fs_stats.byte_used = t*1024; + ::decode(t, p); + fs_stats.byte_avail = t*1024; + } + ::decode(fs_stats.avail_percent, p); + ::decode(last_update, p); + if (struct_v > 1) + ::decode(store_stats, p); + + DECODE_FINISH(p); + } +}; +WRITE_CLASS_ENCODER(DataStats) + +struct ScrubResult { + map prefix_crc; ///< prefix -> crc + map prefix_keys; ///< prefix -> key count + + bool operator!=(const ScrubResult& other) { + return prefix_crc != other.prefix_crc || prefix_keys != other.prefix_keys; + } + + void encode(bufferlist& bl) const { + ENCODE_START(1, 1, bl); + ::encode(prefix_crc, bl); + ::encode(prefix_keys, bl); + ENCODE_FINISH(bl); + } + void decode(bufferlist::iterator& p) { + DECODE_START(1, p); + ::decode(prefix_crc, p); + ::decode(prefix_keys, p); + DECODE_FINISH(p); + } + void dump(Formatter *f) const { + f->open_object_section("crc"); + for (map::const_iterator p = prefix_crc.begin(); p != prefix_crc.end(); ++p) + f->dump_unsigned(p->first.c_str(), p->second); + f->close_section(); + f->open_object_section("keys"); + for (map::const_iterator p = prefix_keys.begin(); p != prefix_keys.end(); ++p) + f->dump_unsigned(p->first.c_str(), p->second); + f->close_section(); + } + static void generate_test_instances(list& ls) { + ls.push_back(new ScrubResult); + ls.push_back(new ScrubResult); + ls.back()->prefix_crc["foo"] = 123; + ls.back()->prefix_keys["bar"] = 456; + } +}; +WRITE_CLASS_ENCODER(ScrubResult) + +static inline ostream& operator<<(ostream& out, const ScrubResult& r) { + return out << "ScrubResult(keys " << r.prefix_keys << " crc " << r.prefix_crc << ")"; +} + +/// for information like os, kernel, hostname, memory info, cpu model. +typedef map Metadata; + +namespace ceph { + namespace features { + namespace mon { + /** + * Get a feature's name based on its value. + * + * @param b raw feature value + * + * @remarks + * Consumers should not assume this interface will never change. + * @remarks + * As the number of features increase, so may the internal representation + * of the raw features. When this happens, this interface will change + * accordingly. So should consumers of this interface. + */ + static inline const char *get_feature_name(uint64_t b); + } + } +} + + +inline const char *ceph_mon_feature_name(uint64_t b) +{ + return ceph::features::mon::get_feature_name(b); +}; + +class mon_feature_t { + + static const int HEAD_VERSION = 1; + static const int COMPAT_VERSION = 1; + + // mon-specific features + uint64_t features; + +public: + + explicit constexpr + mon_feature_t(const uint64_t f) : features(f) { } + + mon_feature_t() : + features(0) { } + + constexpr + mon_feature_t(const mon_feature_t &o) : + features(o.features) { } + + mon_feature_t& operator&=(const mon_feature_t other) { + features &= other.features; + return (*this); + } + + /** + * Obtain raw features + * + * @remarks + * Consumers should not assume this interface will never change. + * @remarks + * As the number of features increase, so may the internal representation + * of the raw features. When this happens, this interface will change + * accordingly. So should consumers of this interface. + */ + uint64_t get_raw() const { + return features; + } + + constexpr + friend mon_feature_t operator&(const mon_feature_t a, + const mon_feature_t b) { + return mon_feature_t(a.features & b.features); + } + + mon_feature_t& operator|=(const mon_feature_t other) { + features |= other.features; + return (*this); + } + + constexpr + friend mon_feature_t operator|(const mon_feature_t a, + const mon_feature_t b) { + return mon_feature_t(a.features | b.features); + } + + constexpr + friend mon_feature_t operator^(const mon_feature_t a, + const mon_feature_t b) { + return mon_feature_t(a.features ^ b.features); + } + + mon_feature_t& operator^=(const mon_feature_t other) { + features ^= other.features; + return (*this); + } + + bool operator==(const mon_feature_t other) const { + return (features == other.features); + } + + bool operator!=(const mon_feature_t other) const { + return (features != other.features); + } + + bool empty() const { + return features == 0; + } + + /** + * Set difference of our features in respect to @p other + * + * Returns all the elements in our features that are not in @p other + * + * @returns all the features not in @p other + */ + mon_feature_t diff(const mon_feature_t other) const { + return mon_feature_t((features ^ other.features) & features); + } + + /** + * Set intersection of our features and @p other + * + * Returns all the elements common to both our features and the + * features of @p other + * + * @returns the features common to @p other and us + */ + mon_feature_t intersection(const mon_feature_t other) const { + return mon_feature_t((features & other.features)); + } + + /** + * Checks whether we have all the features in @p other + * + * Returns true if we have all the features in @p other + * + * @returns true if we contain all the features in @p other + * @returns false if we do not contain some of the features in @p other + */ + bool contains_all(const mon_feature_t other) const { + mon_feature_t d = intersection(other); + return d == other; + } + + /** + * Checks whether we contain any of the features in @p other. + * + * @returns true if we contain any of the features in @p other + * @returns false if we don't contain any of the features in @p other + */ + bool contains_any(const mon_feature_t other) const { + mon_feature_t d = intersection(other); + return !d.empty(); + } + + void set_feature(const mon_feature_t f) { + features |= f.features; + } + + void unset_feature(const mon_feature_t f) { + features &= ~(f.features); + } + + void print(ostream& out) const { + out << "["; + print_bit_str(features, out, ceph::features::mon::get_feature_name); + out << "]"; + } + + void print_with_value(ostream& out) const { + out << "["; + print_bit_str(features, out, ceph::features::mon::get_feature_name, true); + out << "]"; + } + + void dump(Formatter *f, const char *sec_name = NULL) const { + f->open_array_section((sec_name ? sec_name : "features")); + dump_bit_str(features, f, ceph::features::mon::get_feature_name); + f->close_section(); + } + + void dump_with_value(Formatter *f, const char *sec_name = NULL) const { + f->open_array_section((sec_name ? sec_name : "features")); + dump_bit_str(features, f, ceph::features::mon::get_feature_name, true); + f->close_section(); + } + + void encode(bufferlist& bl) const { + ENCODE_START(HEAD_VERSION, COMPAT_VERSION, bl); + ::encode(features, bl); + ENCODE_FINISH(bl); + } + void decode(bufferlist::iterator& p) { + DECODE_START(COMPAT_VERSION, p); + ::decode(features, p); + DECODE_FINISH(p); + } +}; +WRITE_CLASS_ENCODER(mon_feature_t) + +namespace ceph { + namespace features { + namespace mon { + constexpr mon_feature_t FEATURE_KRAKEN( (1ULL << 0)); + constexpr mon_feature_t FEATURE_LUMINOUS( (1ULL << 1)); + + constexpr mon_feature_t FEATURE_RESERVED( (1ULL << 63)); + constexpr mon_feature_t FEATURE_NONE( (0ULL)); + + /** + * All the features this monitor supports + * + * If there's a feature above, it should be OR'ed to this list. + */ + constexpr mon_feature_t get_supported() { + return ( + FEATURE_KRAKEN | + FEATURE_LUMINOUS | + FEATURE_NONE + ); + } + /** + * All the features that, once set, cannot be removed. + * + * Features should only be added to this list if you want to make + * sure downgrades are not possible after a quorum supporting all + * these features has been formed. + * + * Any feature in this list will be automatically set on the monmap's + * features once all the monitors in the quorum support it. + */ + constexpr mon_feature_t get_persistent() { + return ( + FEATURE_KRAKEN | + FEATURE_LUMINOUS | + FEATURE_NONE + ); + } + + static inline mon_feature_t get_feature_by_name(std::string n); + } + } +} + +static inline const char *ceph::features::mon::get_feature_name(uint64_t b) { + mon_feature_t f(b); + + if (f == FEATURE_KRAKEN) { + return "kraken"; + } else if (f == FEATURE_LUMINOUS) { + return "luminous"; + } else if (f == FEATURE_RESERVED) { + return "reserved"; + } + return "unknown"; +} + +static inline +mon_feature_t ceph::features::mon::get_feature_by_name(std::string n) { + + if (n == "kraken") { + return FEATURE_KRAKEN; + } else if (n == "luminous") { + return FEATURE_LUMINOUS; + } else if (n == "reserved") { + return FEATURE_RESERVED; + } + return FEATURE_NONE; +} + +static inline ostream& operator<<(ostream& out, const mon_feature_t& f) { + out << "mon_feature_t("; + f.print(out); + out << ")"; + return out; +} + +#endif