+++ /dev/null
-// -*- 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 <sage@newdream.net>
- *
- * 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 <map>
-
-#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<uint32_t,std::map<uint64_t,uint64_t>> 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<LevelDBStoreStats*>& 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<string,uint32_t> prefix_crc; ///< prefix -> crc
- map<string,uint64_t> 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<string,uint32_t>::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<string,uint64_t>::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<ScrubResult*>& 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<string, string> 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