summaryrefslogtreecommitdiffstats
path: root/src/mgr/ServiceMap.h
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 18:24:20 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 18:24:20 +0000
commit483eb2f56657e8e7f419ab1a4fab8dce9ade8609 (patch)
treee5d88d25d870d5dedacb6bbdbe2a966086a0a5cf /src/mgr/ServiceMap.h
parentInitial commit. (diff)
downloadceph-upstream.tar.xz
ceph-upstream.zip
Adding upstream version 14.2.21.upstream/14.2.21upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/mgr/ServiceMap.h')
-rw-r--r--src/mgr/ServiceMap.h156
1 files changed, 156 insertions, 0 deletions
diff --git a/src/mgr/ServiceMap.h b/src/mgr/ServiceMap.h
new file mode 100644
index 00000000..c0cd65c8
--- /dev/null
+++ b/src/mgr/ServiceMap.h
@@ -0,0 +1,156 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#pragma once
+
+#include <string>
+#include <map>
+#include <list>
+#include <sstream>
+
+#include "include/utime.h"
+#include "include/buffer.h"
+#include "msg/msg_types.h"
+
+namespace ceph {
+ class Formatter;
+}
+
+struct ServiceMap {
+ struct Daemon {
+ uint64_t gid = 0;
+ entity_addr_t addr;
+ epoch_t start_epoch = 0; ///< epoch first registered
+ utime_t start_stamp; ///< timestamp daemon started/registered
+ std::map<std::string,std::string> metadata; ///< static metadata
+ std::map<std::string,std::string> task_status; ///< running task status
+
+ void encode(bufferlist& bl, uint64_t features) const;
+ void decode(bufferlist::const_iterator& p);
+ void dump(Formatter *f) const;
+ static void generate_test_instances(std::list<Daemon*>& ls);
+ };
+
+ struct Service {
+ map<std::string,Daemon> daemons;
+ std::string summary; ///< summary status string for 'ceph -s'
+
+ void encode(bufferlist& bl, uint64_t features) const;
+ void decode(bufferlist::const_iterator& p);
+ void dump(Formatter *f) const;
+ static void generate_test_instances(std::list<Service*>& ls);
+
+ std::string get_summary() const {
+ if (summary.size()) {
+ return summary;
+ }
+ if (daemons.empty()) {
+ return "no daemons active";
+ }
+ std::ostringstream ss;
+ ss << daemons.size() << (daemons.size() > 1 ? " daemons" : " daemon")
+ << " active";
+
+ if (!daemons.empty()) {
+ ss << " (";
+ for (auto p = daemons.begin(); p != daemons.end(); ++p) {
+ if (p != daemons.begin()) {
+ ss << ", ";
+ }
+ ss << p->first;
+ }
+ ss << ")";
+ }
+
+ return ss.str();
+ }
+
+ std::string get_task_summary(const std::string_view task_prefix) const {
+ // contruct a map similar to:
+ // {"service1 status" -> {"service1.0" -> "running"}}
+ // {"service2 status" -> {"service2.0" -> "idle"},
+ // {"service2.1" -> "running"}}
+ std::map<std::string, std::map<std::string, std::string>> by_task;
+ for (const auto &p : daemons) {
+ std::stringstream d;
+ d << task_prefix << "." << p.first;
+ for (const auto &q : p.second.task_status) {
+ auto p1 = by_task.emplace(q.first, std::map<std::string, std::string>{}).first;
+ auto p2 = p1->second.emplace(d.str(), std::string()).first;
+ p2->second = q.second;
+ }
+ }
+
+ std::stringstream ss;
+ for (const auto &p : by_task) {
+ ss << "\n " << p.first << ":";
+ for (auto q : p.second) {
+ ss << "\n " << q.first << ": " << q.second;
+ }
+ }
+
+ return ss.str();
+ }
+
+ void count_metadata(const std::string& field,
+ std::map<std::string,int> *out) const {
+ for (auto& p : daemons) {
+ auto q = p.second.metadata.find(field);
+ if (q == p.second.metadata.end()) {
+ (*out)["unknown"]++;
+ } else {
+ (*out)[q->second]++;
+ }
+ }
+ }
+
+ };
+
+ epoch_t epoch = 0;
+ utime_t modified;
+ map<std::string,Service> services;
+
+ void encode(bufferlist& bl, uint64_t features) const;
+ void decode(bufferlist::const_iterator& p);
+ void dump(Formatter *f) const;
+ static void generate_test_instances(std::list<ServiceMap*>& ls);
+
+ std::pair<Daemon*,bool> get_daemon(const std::string& service,
+ const std::string& daemon) {
+ auto& s = services[service];
+ auto [d, added] = s.daemons.try_emplace(daemon);
+ return {&d->second, added};
+ }
+
+ bool rm_daemon(const std::string& service,
+ const std::string& daemon) {
+ auto p = services.find(service);
+ if (p == services.end()) {
+ return false;
+ }
+ auto q = p->second.daemons.find(daemon);
+ if (q == p->second.daemons.end()) {
+ return false;
+ }
+ p->second.daemons.erase(q);
+ if (p->second.daemons.empty()) {
+ services.erase(p);
+ }
+ return true;
+ }
+
+ static inline bool is_normal_ceph_entity(std::string_view type) {
+ if (type == "osd" ||
+ type == "client" ||
+ type == "mon" ||
+ type == "mds" ||
+ type == "mgr") {
+ return true;
+ }
+
+ return false;
+ }
+};
+WRITE_CLASS_ENCODER_FEATURES(ServiceMap)
+WRITE_CLASS_ENCODER_FEATURES(ServiceMap::Service)
+WRITE_CLASS_ENCODER_FEATURES(ServiceMap::Daemon)