From 3f69d083a01a68e29bda7307677aa1cdfb0d5552 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 26 Jun 2017 13:20:58 -0400 Subject: [PATCH] mon: persist ServiceMap Signed-off-by: Sage Weil --- src/messages/MMonMgrReport.h | 3 +++ src/messages/MServiceMap.h | 34 ++++++++++++++++++++++++ src/mon/MgrStatMonitor.cc | 51 ++++++++++++++++++++++++++++++++++++ src/mon/MgrStatMonitor.h | 6 +++++ src/mon/Monitor.cc | 2 ++ src/msg/Message.cc | 5 ++++ src/msg/Message.h | 1 + 7 files changed, 102 insertions(+) create mode 100644 src/messages/MServiceMap.h diff --git a/src/messages/MMonMgrReport.h b/src/messages/MMonMgrReport.h index bf91519eb5c2e..8f3a8fe911540 100644 --- a/src/messages/MMonMgrReport.h +++ b/src/messages/MMonMgrReport.h @@ -37,6 +37,7 @@ class MMonMgrReport : public PaxosServiceMessage { public: // PGMapDigest is in data payload list> health_summary, health_detail; + bufferlist service_map_bl; // encoded ServiceMap MMonMgrReport() : PaxosServiceMessage(MSG_MON_MGR_REPORT, 0, HEAD_VERSION, COMPAT_VERSION) @@ -55,12 +56,14 @@ public: paxos_encode(); ::encode(health_summary, payload); ::encode(health_detail, payload); + ::encode(service_map_bl, payload); } void decode_payload() override { bufferlist::iterator p = payload.begin(); paxos_decode(p); ::decode(health_summary, p); ::decode(health_detail, p); + ::decode(service_map_bl, p); } }; diff --git a/src/messages/MServiceMap.h b/src/messages/MServiceMap.h new file mode 100644 index 0000000000000..b7dd91310f7b6 --- /dev/null +++ b/src/messages/MServiceMap.h @@ -0,0 +1,34 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#pragma once + +#include "msg/Message.h" +#include "mgr/ServiceMap.h" + +class MServiceMap : public Message { +public: + ServiceMap service_map; + + MServiceMap() : Message(MSG_SERVICE_MAP) { } + explicit MServiceMap(const ServiceMap& sm) + : Message(MSG_SERVICE_MAP), + service_map(sm) { + } +private: + ~MServiceMap() override {} + +public: + const char *get_type_name() const override { return "service_map"; } + void print(ostream& out) const override { + out << "service_map(e" << service_map.epoch << " " + << service_map.services.size() << " svc)"; + } + void encode_payload(uint64_t features) override { + ::encode(service_map, payload, features); + } + void decode_payload() override { + bufferlist::iterator p = payload.begin(); + ::decode(service_map, p); + } +}; diff --git a/src/mon/MgrStatMonitor.cc b/src/mon/MgrStatMonitor.cc index 658b7001d6e2c..ab0d4623b877f 100644 --- a/src/mon/MgrStatMonitor.cc +++ b/src/mon/MgrStatMonitor.cc @@ -10,6 +10,7 @@ #include "messages/MMonMgrReport.h" #include "messages/MStatfs.h" #include "messages/MStatfsReply.h" +#include "messages/MServiceMap.h" class MgrPGStatService : public MonPGStatService { PGMapDigest& digest; @@ -72,6 +73,8 @@ void MgrStatMonitor::create_initial() { dout(10) << dendl; version = 0; + service_map.epoch = 1; + ::encode(service_map, pending_service_map_bl, CEPH_FEATURES_ALL); } void MgrStatMonitor::update_from_paxos(bool *need_bootstrap) @@ -86,7 +89,11 @@ void MgrStatMonitor::update_from_paxos(bool *need_bootstrap) ::decode(digest, p); ::decode(health_summary, p); ::decode(health_detail, p); + ::decode(service_map, p); + dout(10) << __func__ << " v" << version + << " service_map e" << service_map.epoch << dendl; } + check_subs(); } void MgrStatMonitor::create_pending() @@ -95,6 +102,8 @@ void MgrStatMonitor::create_pending() pending_digest = digest; pending_health_summary = health_summary; pending_health_detail = health_detail; + pending_service_map_bl.clear(); + ::encode(service_map, pending_service_map_bl, mon->get_quorum_con_features()); } void MgrStatMonitor::encode_pending(MonitorDBStore::TransactionRef t) @@ -110,6 +119,8 @@ void MgrStatMonitor::encode_pending(MonitorDBStore::TransactionRef t) ::encode(pending_digest, bl, mon->get_quorum_con_features()); ::encode(pending_health_summary, bl); ::encode(pending_health_detail, bl); + assert(pending_service_map_bl.length()); + bl.append(pending_service_map_bl); put_version(t, version, bl); put_last_committed(t, version); } @@ -194,6 +205,9 @@ bool MgrStatMonitor::prepare_report(MonOpRequestRef op) dout(10) << __func__ << " " << pending_digest << dendl; pending_health_summary.swap(m->health_summary); pending_health_detail.swap(m->health_detail); + if (m->service_map_bl.length()) { + pending_service_map_bl.swap(m->service_map_bl); + } return true; } @@ -264,3 +278,40 @@ bool MgrStatMonitor::preprocess_statfs(MonOpRequestRef op) mon->send_reply(op, reply); return true; } + +void MgrStatMonitor::check_sub(Subscription *sub) +{ + const auto epoch = mon->monmap->get_epoch(); + dout(10) << __func__ + << " next " << sub->next + << " have " << epoch << dendl; + if (sub->next <= service_map.epoch) { + auto m = new MServiceMap(service_map); + sub->session->con->send_message(m); + if (sub->onetime) { + mon->with_session_map([this, sub](MonSessionMap& session_map) { + session_map.remove_sub(sub); + }); + } else { + sub->next = epoch + 1; + } + } +} + +void MgrStatMonitor::check_subs() +{ + dout(10) << __func__ << dendl; + if (!service_map.epoch) { + return; + } + auto subs = mon->session_map.subs.find("servicemap"); + if (subs == mon->session_map.subs.end()) { + return; + } + auto p = subs->second->begin(); + while (!p.end()) { + auto sub = *p; + ++p; + check_sub(sub); + } +} diff --git a/src/mon/MgrStatMonitor.h b/src/mon/MgrStatMonitor.h index 7ecbc9d377f5d..bd96ec8376e6a 100644 --- a/src/mon/MgrStatMonitor.h +++ b/src/mon/MgrStatMonitor.h @@ -6,6 +6,7 @@ #include "include/Context.h" #include "PaxosService.h" #include "mon/PGMap.h" +#include "mgr/ServiceMap.h" class MonPGStatService; class MgrPGStatService; @@ -16,11 +17,13 @@ class MgrStatMonitor : public PaxosService { PGMapDigest digest; list> health_summary; list> health_detail; + ServiceMap service_map; // pending commit PGMapDigest pending_digest; list> pending_health_summary; list> pending_health_detail; + bufferlist pending_service_map_bl; std::unique_ptr pgservice; @@ -66,6 +69,9 @@ public: void print_summary(Formatter *f, std::ostream *ss) const; MonPGStatService *get_pg_stat_service(); + const ServiceMap& get_service_map() { + return service_map; + } friend class C_Updated; }; diff --git a/src/mon/Monitor.cc b/src/mon/Monitor.cc index 9c936b1c94001..5a22db7a8e338 100644 --- a/src/mon/Monitor.cc +++ b/src/mon/Monitor.cc @@ -4619,6 +4619,8 @@ void Monitor::handle_subscribe(MonOpRequestRef op) logmon()->check_sub(s->sub_map[p->first]); } else if (p->first == "mgrmap" || p->first == "mgrdigest") { mgrmon()->check_sub(s->sub_map[p->first]); + } else if (p->first == "servicemap") { + mgrstatmon()->check_sub(s->sub_map[p->first]); } } diff --git a/src/msg/Message.cc b/src/msg/Message.cc index 8232ba39c438a..4860889989fe9 100644 --- a/src/msg/Message.cc +++ b/src/msg/Message.cc @@ -169,6 +169,7 @@ using namespace std; #include "messages/MMgrOpen.h" #include "messages/MMgrConfigure.h" #include "messages/MMonMgrReport.h" +#include "messages/MServiceMap.h" #include "messages/MLock.h" @@ -751,6 +752,10 @@ Message *decode_message(CephContext *cct, int crcflags, m = new MMonMgrReport(); break; + case MSG_SERVICE_MAP: + m = new MServiceMap(); + break; + case MSG_MGR_MAP: m = new MMgrMap(); break; diff --git a/src/msg/Message.h b/src/msg/Message.h index b7220e2de28aa..611d691df992c 100644 --- a/src/msg/Message.h +++ b/src/msg/Message.h @@ -198,6 +198,7 @@ #define MSG_MGR_DIGEST 0x705 // *** cephmgr -> ceph-mon #define MSG_MON_MGR_REPORT 0x706 +#define MSG_SERVICE_MAP 0x707 // ====================================================== -- 2.39.5