1    	// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2    	// vim: ts=8 sw=2 smarttab
3    	/*
4    	 * Ceph - scalable distributed file system
5    	 *
6    	 * Copyright (C) 2016 John Spray <john.spray@redhat.com>
7    	 *
8    	 * This is free software; you can redistribute it and/or
9    	 * modify it under the terms of the GNU Lesser General Public
10   	 * License version 2.1, as published by the Free Software
11   	 * Foundation.  See file COPYING.
12   	 */
13   	
14   	
15   	#ifndef CEPH_MMGRREPORT_H_
16   	#define CEPH_MMGRREPORT_H_
17   	
18   	#include <boost/optional.hpp>
19   	
20   	#include "msg/Message.h"
21   	#include "mgr/OSDPerfMetricTypes.h"
22   	
23   	#include "common/perf_counters.h"
24   	#include "mgr/DaemonHealthMetric.h"
25   	
26   	class PerfCounterType
27   	{
28   	public:
29   	  std::string path;
30   	  std::string description;
31   	  std::string nick;
32   	  enum perfcounter_type_d type;
33   	
34   	  // For older clients that did not send priority, pretend everything
35   	  // is "useful" so that mgr plugins filtering on prio will get some
36   	  // data (albeit probably more than they wanted)
37   	  uint8_t priority = PerfCountersBuilder::PRIO_USEFUL;
38   	  enum unit_t unit;
39   	
40   	  void encode(ceph::buffer::list &bl) const
41   	  {
42   	    // TODO: decide whether to drop the per-type
43   	    // encoding here, we could rely on the MgrReport
44   	    // verisoning instead.
45   	    ENCODE_START(3, 1, bl);
46   	    encode(path, bl);
47   	    encode(description, bl);
48   	    encode(nick, bl);
49   	    static_assert(sizeof(type) == 1, "perfcounter_type_d must be one byte");
50   	    encode((uint8_t)type, bl);
(1) Event overrun-buffer-val: Overrunning buffer pointed to by "this->priority" of 7 bytes by passing it to a function which accesses it at byte offset 7. [details]
51   	    encode(priority, bl);
52   	    encode((uint8_t)unit, bl);
53   	    ENCODE_FINISH(bl);
54   	  }
55   	  
56   	  void decode(ceph::buffer::list::const_iterator &p)
57   	  {
58   	    DECODE_START(3, p);
59   	    decode(path, p);
60   	    decode(description, p);
61   	    decode(nick, p);
62   	    decode((uint8_t&)type, p);
63   	    if (struct_v >= 2) {
64   	      decode(priority, p);
65   	    }
66   	    if (struct_v >= 3) {
67   	      decode((uint8_t&)unit, p);
68   	    }
69   	    DECODE_FINISH(p);
70   	  }
71   	};
72   	WRITE_CLASS_ENCODER(PerfCounterType)
73   	
74   	class MMgrReport : public Message {
75   	private:
76   	  static constexpr int HEAD_VERSION = 8;
77   	  static constexpr int COMPAT_VERSION = 1;
78   	
79   	public:
80   	  /**
81   	   * Client is responsible for remembering whether it has introduced
82   	   * each perf counter to the server.  When first sending a particular
83   	   * counter, it must inline the counter's schema here.
84   	   */
85   	  std::vector<PerfCounterType> declare_types;
86   	  std::vector<std::string> undeclare_types;
87   	
88   	  // For all counters present, sorted by idx, output
89   	  // as many bytes as are needed to represent them
90   	
91   	  // Decode: iterate over the types we know about, sorted by idx,
92   	  // and use the current type's type to decide how to decode
93   	  // the next bytes from the ceph::buffer::list.
94   	  ceph::buffer::list packed;
95   	
96   	  std::string daemon_name;
97   	  std::string service_name;  // optional; otherwise infer from entity type
98   	
99   	  // for service registration
100  	  boost::optional<std::map<std::string,std::string>> daemon_status;
101  	  boost::optional<std::map<std::string,std::string>> task_status;
102  	
103  	  std::vector<DaemonHealthMetric> daemon_health_metrics;
104  	
105  	  // encode map<string,map<int32_t,string>> of current config
106  	  ceph::buffer::list config_bl;
107  	
108  	  std::map<OSDPerfMetricQuery, OSDPerfMetricReport>  osd_perf_metric_reports;
109  	
110  	  void decode_payload() override
111  	  {
112  	    using ceph::decode;
113  	    auto p = payload.cbegin();
114  	    decode(daemon_name, p);
115  	    decode(declare_types, p);
116  	    decode(packed, p);
117  	    if (header.version >= 2)
118  	      decode(undeclare_types, p);
119  	    if (header.version >= 3) {
120  	      decode(service_name, p);
121  	      decode(daemon_status, p);
122  	    }
123  	    if (header.version >= 5) {
124  	      decode(daemon_health_metrics, p);
125  	    }
126  	    if (header.version >= 6) {
127  	      decode(config_bl, p);
128  	    }
129  	    if (header.version >= 7) {
130  	      decode(osd_perf_metric_reports, p);
131  	    }
132  	    if (header.version >= 8) {
133  	      decode(task_status, p);
134  	    }
135  	  }
136  	
137  	  void encode_payload(uint64_t features) override {
138  	    using ceph::encode;
139  	    encode(daemon_name, payload);
140  	    encode(declare_types, payload);
141  	    encode(packed, payload);
142  	    encode(undeclare_types, payload);
143  	    encode(service_name, payload);
144  	    encode(daemon_status, payload);
145  	    encode(daemon_health_metrics, payload);
146  	    encode(config_bl, payload);
147  	    encode(osd_perf_metric_reports, payload);
148  	    encode(task_status, payload);
149  	  }
150  	
151  	  std::string_view get_type_name() const override { return "mgrreport"; }
152  	  void print(std::ostream& out) const override {
153  	    out << get_type_name() << "(";
154  	    if (service_name.length()) {
155  	      out << service_name;
156  	    } else {
157  	      out << ceph_entity_type_name(get_source().type());
158  	    }
159  	    out << "." << daemon_name
160  		<< " +" << declare_types.size()
161  		<< "-" << undeclare_types.size()
162  	        << " packed " << packed.length();
163  	    if (daemon_status) {
164  	      out << " status=" << daemon_status->size();
165  	    }
166  	    if (!daemon_health_metrics.empty()) {
167  	      out << " daemon_metrics=" << daemon_health_metrics.size();
168  	    }
169  	    if (task_status) {
170  	      out << " task_status=" << task_status->size();
171  	    }
172  	    out << ")";
173  	  }
174  	
175  	private:
176  	  MMgrReport()
177  	    : Message{MSG_MGR_REPORT, HEAD_VERSION, COMPAT_VERSION}
178  	  {}
179  	  using RefCountedObject::put;
180  	  using RefCountedObject::get;
181  	  template<class T, typename... Args>
182  	  friend boost::intrusive_ptr<T> ceph::make_message(Args&&... args);
183  	};
184  	
185  	#endif
186