{
auto& addr = session->info.inst.addr;
- session->set_client_metadata(client_metadata_t(m->metadata, m->supported_features));
+ session->set_client_metadata(client_metadata_t(m->metadata, m->supported_features, m->metric_spec));
auto& client_metadata = session->info.client_metadata;
auto log_session_status = [this, m, session](std::string_view status, std::string_view err) {
infer_supported_features(session, client_metadata);
dout(20) << __func__ << " CEPH_SESSION_REQUEST_OPEN metadata entries:" << dendl;
- dout(20) << " features: '" << client_metadata.features << dendl;
+ dout(20) << " features: '" << client_metadata.features << "'" << dendl;
+ dout(20) << " metric specification: [" << client_metadata.metric_spec << "]" << dendl;
for (const auto& p : client_metadata) {
dout(20) << " " << p.first << ": " << p.second << dendl;
}
out.flags(f);
}
+/*
+ * metric_spec_t
+ */
+void metric_spec_t::encode(bufferlist& bl) const {
+ using ceph::encode;
+ ENCODE_START(1, 1, bl);
+ encode(metric_flags, bl);
+ ENCODE_FINISH(bl);
+}
+
+void metric_spec_t::decode(bufferlist::const_iterator &p) {
+ using ceph::decode;
+ DECODE_START(1, p);
+ decode(metric_flags, p);
+ DECODE_FINISH(p);
+}
+
+void metric_spec_t::dump(Formatter *f) const {
+ f->dump_object("metric_flags", metric_flags);
+}
+
+void metric_spec_t::print(ostream& out) const
+{
+ out << "{metric_flags: '" << metric_flags << "'}";
+}
+
/*
* client_metadata_t
*/
void client_metadata_t::encode(bufferlist& bl) const
{
- ENCODE_START(2, 1, bl);
+ ENCODE_START(3, 1, bl);
encode(kv_map, bl);
encode(features, bl);
+ encode(metric_spec, bl);
ENCODE_FINISH(bl);
}
void client_metadata_t::decode(bufferlist::const_iterator& p)
{
- DECODE_START(2, p);
+ DECODE_START(3, p);
decode(kv_map, p);
if (struct_v >= 2)
decode(features, p);
+ if (struct_v >= 3) {
+ decode(metric_spec, p);
+ }
DECODE_FINISH(p);
}
void client_metadata_t::dump(Formatter *f) const
{
f->dump_object("client_features", features);
+ f->dump_object("metric_spec", metric_spec);
for (const auto& [name, val] : kv_map)
f->dump_string(name.c_str(), val);
}
return out;
}
+/*
+ * metric_spec_t
+ */
+struct metric_spec_t {
+ // set of metrics that a client is capable of forwarding
+ feature_bitset_t metric_flags;
+
+ metric_spec_t() {}
+ metric_spec_t(const metric_spec_t& other) :
+ metric_flags(other.metric_flags) {}
+ metric_spec_t(metric_spec_t&& other) :
+ metric_flags(std::move(other.metric_flags)) {}
+ metric_spec_t(const feature_bitset_t& mf) :
+ metric_flags(mf) {}
+ metric_spec_t(feature_bitset_t&& mf) :
+ metric_flags(std::move(mf)) {}
+
+ metric_spec_t& operator=(const metric_spec_t& other) {
+ metric_flags = other.metric_flags;
+ return *this;
+ }
+ metric_spec_t& operator=(metric_spec_t&& other) {
+ metric_flags = std::move(other.metric_flags);
+ return *this;
+ }
+
+ bool empty() const {
+ return metric_flags.empty();
+ }
+
+ void clear() {
+ metric_flags.clear();
+ }
+
+ void encode(bufferlist& bl) const;
+ void decode(bufferlist::const_iterator& p);
+ void dump(Formatter *f) const;
+ void print(ostream& out) const;
+};
+WRITE_CLASS_ENCODER(metric_spec_t)
+
+inline std::ostream& operator<<(std::ostream& out, const metric_spec_t& mst) {
+ mst.print(out);
+ return out;
+}
+
/*
* client_metadata_t
*/
kv_map_t kv_map;
feature_bitset_t features;
+ metric_spec_t metric_spec;
client_metadata_t() {}
client_metadata_t(const client_metadata_t& other) :
- kv_map(other.kv_map), features(other.features) {}
+ kv_map(other.kv_map),
+ features(other.features),
+ metric_spec(other.metric_spec) {}
client_metadata_t(client_metadata_t&& other) :
- kv_map(std::move(other.kv_map)), features(std::move(other.features)) {}
- client_metadata_t(kv_map_t&& kv, feature_bitset_t &&f) :
- kv_map(std::move(kv)), features(std::move(f)) {}
- client_metadata_t(const kv_map_t& kv, const feature_bitset_t &f) :
- kv_map(kv), features(f) {}
+ kv_map(std::move(other.kv_map)),
+ features(std::move(other.features)),
+ metric_spec(std::move(other.metric_spec)) {}
+ client_metadata_t(kv_map_t&& kv, feature_bitset_t &&f, metric_spec_t &&mst) :
+ kv_map(std::move(kv)),
+ features(std::move(f)),
+ metric_spec(std::move(mst)) {}
+ client_metadata_t(const kv_map_t& kv, const feature_bitset_t &f, const metric_spec_t &mst) :
+ kv_map(kv),
+ features(f),
+ metric_spec(mst) {}
client_metadata_t& operator=(const client_metadata_t& other) {
kv_map = other.kv_map;
features = other.features;
+ metric_spec = other.metric_spec;
return *this;
}
- bool empty() const { return kv_map.empty() && features.empty(); }
+ bool empty() const { return kv_map.empty() && features.empty() && metric_spec.empty(); }
iterator find(const std::string& key) const { return kv_map.find(key); }
iterator begin() const { return kv_map.begin(); }
iterator end() const { return kv_map.end(); }
void merge(const client_metadata_t& other) {
kv_map.insert(other.kv_map.begin(), other.kv_map.end());
features = other.features;
+ metric_spec = other.metric_spec;
}
void clear() {
kv_map.clear();
features.clear();
+ metric_spec.clear();
}
void encode(bufferlist& bl) const;
class MClientSession : public SafeMessage {
private:
- static constexpr int HEAD_VERSION = 3;
+ static constexpr int HEAD_VERSION = 4;
static constexpr int COMPAT_VERSION = 1;
public:
std::map<std::string, std::string> metadata;
feature_bitset_t supported_features;
+ metric_spec_t metric_spec;
int get_op() const { return head.op; }
version_t get_seq() const { return head.seq; }
decode(metadata, p);
if (header.version >= 3)
decode(supported_features, p);
+ if (header.version >= 4) {
+ decode(metric_spec, p);
+ }
}
void encode_payload(uint64_t features) override {
using ceph::encode;
encode(metadata, payload);
encode(supported_features, payload);
}
+ encode(metric_spec, payload);
}
private:
template<class T, typename... Args>