--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "mgr/ServiceMap.h"
+
+#include "common/Formatter.h"
+
+// Daemon
+
+void ServiceMap::Daemon::encode(bufferlist& bl, uint64_t features) const
+{
+ ENCODE_START(1, 1, bl);
+ ::encode(gid, bl);
+ ::encode(addr, bl, features);
+ ::encode(start_epoch, bl);
+ ::encode(start_stamp, bl);
+ ::encode(metadata, bl);
+ ENCODE_FINISH(bl);
+}
+
+void ServiceMap::Daemon::decode(bufferlist::iterator& p)
+{
+ DECODE_START(1, p);
+ ::decode(gid, p);
+ ::decode(addr, p);
+ ::decode(start_epoch, p);
+ ::decode(start_stamp, p);
+ ::decode(metadata, p);
+ DECODE_FINISH(p);
+}
+
+void ServiceMap::Daemon::dump(Formatter *f) const
+{
+ f->dump_unsigned("start_epoch", start_epoch);
+ f->dump_stream("start_stamp") << start_stamp;
+ f->dump_unsigned("gid", gid);
+ f->dump_stream("addr") << addr;
+ f->open_object_section("metadata");
+ for (auto& p : metadata) {
+ f->dump_string(p.first.c_str(), p.second);
+ }
+ f->close_section();
+}
+
+void ServiceMap::Daemon::generate_test_instances(std::list<Daemon*>& ls)
+{
+ ls.push_back(new Daemon);
+ ls.push_back(new Daemon);
+ ls.back()->gid = 222;
+ ls.back()->metadata["this"] = "that";
+}
+
+// Service
+
+void ServiceMap::Service::encode(bufferlist& bl, uint64_t features) const
+{
+ ENCODE_START(1, 1, bl);
+ ::encode(daemons, bl, features);
+ ENCODE_FINISH(bl);
+}
+
+void ServiceMap::Service::decode(bufferlist::iterator& p)
+{
+ DECODE_START(1, p);
+ ::decode(daemons, p);
+ DECODE_FINISH(p);
+}
+
+void ServiceMap::Service::dump(Formatter *f) const
+{
+ f->open_object_section("daemons");
+ for (auto& p : daemons) {
+ f->dump_object(p.first.c_str(), p.second);
+ }
+ f->close_section();
+}
+
+void ServiceMap::Service::generate_test_instances(std::list<Service*>& ls)
+{
+ ls.push_back(new Service);
+ ls.push_back(new Service);
+ ls.back()->daemons["one"].gid = 1;
+ ls.back()->daemons["two"].gid = 2;
+}
+
+// ServiceMap
+
+void ServiceMap::encode(bufferlist& bl, uint64_t features) const
+{
+ ENCODE_START(1, 1, bl);
+ ::encode(epoch, bl);
+ ::encode(modified, bl);
+ ::encode(services, bl, features);
+ ENCODE_FINISH(bl);
+}
+
+void ServiceMap::decode(bufferlist::iterator& p)
+{
+ DECODE_START(1, p);
+ ::decode(epoch, p);
+ ::decode(modified, p);
+ ::decode(services, p);
+ DECODE_FINISH(p);
+}
+
+void ServiceMap::dump(Formatter *f) const
+{
+ f->dump_unsigned("epoch", epoch);
+ f->dump_stream("modified") << modified;
+ f->open_object_section("services");
+ for (auto& p : services) {
+ f->dump_object(p.first.c_str(), p.second);
+ }
+ f->close_section();
+}
+
+void ServiceMap::generate_test_instances(std::list<ServiceMap*>& ls)
+{
+ ls.push_back(new ServiceMap);
+ ls.push_back(new ServiceMap);
+ ls.back()->epoch = 123;
+ ls.back()->services["rgw"].daemons["one"].gid = 123;
+ ls.back()->services["rgw"].daemons["two"].gid = 344;
+ ls.back()->services["iscsi"].daemons["foo"].gid = 3222;
+}
--- /dev/null
+// -*- 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 "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
+
+ void encode(bufferlist& bl, uint64_t features) const;
+ void decode(bufferlist::iterator& p);
+ void dump(Formatter *f) const;
+ static void generate_test_instances(std::list<Daemon*>& ls);
+ };
+
+ struct Service {
+ map<std::string,Daemon> daemons;
+
+ void encode(bufferlist& bl, uint64_t features) const;
+ void decode(bufferlist::iterator& p);
+ void dump(Formatter *f) const;
+ static void generate_test_instances(std::list<Service*>& ls);
+ };
+
+ epoch_t epoch = 0;
+ utime_t modified;
+ map<std::string,Service> services;
+
+ void encode(bufferlist& bl, uint64_t features) const;
+ void decode(bufferlist::iterator& p);
+ void dump(Formatter *f) const;
+ static void generate_test_instances(std::list<ServiceMap*>& ls);
+
+ Daemon* get_daemon(const std::string& service,
+ const std::string& daemon) {
+ return &services[service].daemons[daemon];
+ }
+
+ 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;
+ }
+};
+WRITE_CLASS_ENCODER_FEATURES(ServiceMap)
+WRITE_CLASS_ENCODER_FEATURES(ServiceMap::Service)
+WRITE_CLASS_ENCODER_FEATURES(ServiceMap::Daemon)