]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mon/mon_types.h: add 'mon_feature_t' for mon-specific features
authorJoao Eduardo Luis <joao@suse.de>
Wed, 27 Jan 2016 15:05:08 +0000 (15:05 +0000)
committerJoao Eduardo Luis <joao@suse.de>
Sat, 29 Oct 2016 03:10:22 +0000 (04:10 +0100)
Signed-off-by: Joao Eduardo Luis <joao@suse.de>
src/mon/mon_types.h

index 63e24c1ce3a8c35dc5256f21cc476a51c52f06d7..998851188e57439e17a09789e7854e0ce8d2ef56 100644 (file)
@@ -18,6 +18,7 @@
 #include "include/utime.h"
 #include "include/util.h"
 #include "common/Formatter.h"
+#include "common/bit_str.h"
 #include "include/Context.h"
 #include "mon/MonOpRequest.h"
 
@@ -236,4 +237,227 @@ struct C_MonOp : public Context
   virtual void _finish(int r) = 0;
 };
 
+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);
+  }
+
+  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 print(ostream& out) const {
+    out << "[";
+    print_bit_str(features, out, ceph::features::mon::get_feature_name);
+    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 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_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_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_NONE
+            );
+      }
+    }
+  }
+}
+
+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_RESERVED) {
+    return "reserved";
+  }
+  return "unknown";
+}
+
+static inline ostream& operator<<(ostream& out, const mon_feature_t& f) {
+  out << "mon_feature_t(";
+  f.print(out);
+  out << ")";
+  return out;
+}
+
 #endif