From: John Spray Date: Sun, 3 Jul 2016 18:45:28 +0000 (+0100) Subject: mgr: s/DaemonMetadata/DaemonState/g X-Git-Tag: v11.0.1~60^2~46 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=d9dfb436ea588a43be135a0808b28039d9ca2546;p=ceph.git mgr: s/DaemonMetadata/DaemonState/g Signed-off-by: John Spray --- diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index de1713c0ebb6..5a73b26053fb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -517,7 +517,7 @@ add_subdirectory(libradosstriper) if (WITH_MGR) set(mgr_srcs ceph_mgr.cc - mgr/DaemonMetadata.cc + mgr/DaemonState.cc mgr/DaemonServer.cc mgr/ClusterState.cc mgr/PyModules.cc diff --git a/src/mgr/DaemonMetadata.cc b/src/mgr/DaemonMetadata.cc deleted file mode 100644 index 7ac0e3cb611a..000000000000 --- a/src/mgr/DaemonMetadata.cc +++ /dev/null @@ -1,142 +0,0 @@ -// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- -// vim: ts=8 sw=2 smarttab -/* - * Ceph - scalable distributed file system - * - * Copyright (C) 2016 John Spray - * - * This is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software - * Foundation. See file COPYING. - */ - -#include "DaemonMetadata.h" - -#define dout_subsys ceph_subsys_mgr -#undef dout_prefix -#define dout_prefix *_dout << "mgr " << __func__ << " " - -void DaemonMetadataIndex::insert(DaemonMetadataPtr dm) -{ - Mutex::Locker l(lock); - - if (all.count(dm->key)) { - _erase(dm->key); - } - - by_server[dm->hostname][dm->key] = dm; - all[dm->key] = dm; -} - -void DaemonMetadataIndex::_erase(DaemonKey dmk) -{ - assert(lock.is_locked_by_me()); - - const auto dm = all.at(dmk); - auto &server_collection = by_server[dm->hostname]; - server_collection.erase(dm->key); - if (server_collection.empty()) { - by_server.erase(dm->hostname); - } - - all.erase(dmk); -} - -DaemonMetadataCollection DaemonMetadataIndex::get_by_type(uint8_t type) const -{ - Mutex::Locker l(lock); - - DaemonMetadataCollection result; - - for (const auto &i : all) { - if (i.first.first == type) { - result[i.first] = i.second; - } - } - - return result; -} - -DaemonMetadataCollection DaemonMetadataIndex::get_by_server(const std::string &hostname) const -{ - Mutex::Locker l(lock); - - if (by_server.count(hostname)) { - return by_server.at(hostname); - } else { - return {}; - } -} - -bool DaemonMetadataIndex::exists(const DaemonKey &key) const -{ - Mutex::Locker l(lock); - - return all.count(key) > 0; -} - -DaemonMetadataPtr DaemonMetadataIndex::get(const DaemonKey &key) -{ - Mutex::Locker l(lock); - - return all.at(key); -} - -void DaemonMetadataIndex::cull(entity_type_t daemon_type, - std::set names_exist) -{ - Mutex::Locker l(lock); - - std::set victims; - - for (const auto &i : all) { - if (i.first.first != daemon_type) { - continue; - } - - if (names_exist.count(i.first.second) == 0) { - victims.insert(i.first); - } - } - - for (const auto &i : victims) { - dout(4) << "Removing data for " << i << dendl; - _erase(i); - } -} - -void DaemonPerfCounters::update(MMgrReport *report) -{ - dout(20) << "loading " << report->declare_types.size() << " new types, " - << report->packed.length() << " bytes of data" << dendl; - - // Load any newly declared types - for (const auto &t : report->declare_types) { - types.insert(std::make_pair(t.path, t)); - declared_types.insert(t.path); - } - - // Parse packed data according to declared set of types - bufferlist::iterator p = report->packed.begin(); - DECODE_START(1, p); - for (const auto &t_path : declared_types) { - const auto &t = types.at(t_path); - uint64_t val = 0; - uint64_t avgcount = 0; - uint64_t avgcount2 = 0; - - ::decode(val, p); - if (t.type & PERFCOUNTER_LONGRUNAVG) { - ::decode(avgcount, p); - ::decode(avgcount2, p); - } - // TODO: interface for insertion of avgs, add timestamp - instances[t_path].push(val); - } - // TODO: handle badly encoded things without asserting out - DECODE_FINISH(p); -} - - - diff --git a/src/mgr/DaemonMetadata.h b/src/mgr/DaemonMetadata.h deleted file mode 100644 index b5c00a9ada16..000000000000 --- a/src/mgr/DaemonMetadata.h +++ /dev/null @@ -1,149 +0,0 @@ -// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- -// vim: ts=8 sw=2 smarttab -/* - * Ceph - scalable distributed file system - * - * Copyright (C) 2016 John Spray - * - * This is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software - * Foundation. See file COPYING. - */ - -#ifndef DAEMON_METADATA_H_ -#define DAEMON_METADATA_H_ - -// TODO: rename me to DaemonState from DaemonMetadata - -#include -#include -#include -#include - -#include "common/Mutex.h" - -#include "msg/msg_types.h" - -// For PerfCounterType -#include "messages/MMgrReport.h" - - -// Unique reference to a daemon within a cluster -typedef std::pair DaemonKey; - -// An instance of a performance counter type, within -// a particular daemon. -class PerfCounterInstance -{ - // TODO: store some short history or whatever - uint64_t current; - public: - void push(uint64_t const &v) {current = v;} -}; - - -typedef std::map PerfCounterTypes; - -// Performance counters for one daemon -class DaemonPerfCounters -{ - public: - // The record of perf stat types, shared between daemons - PerfCounterTypes &types; - - DaemonPerfCounters(PerfCounterTypes &types_) - : types(types_) - {} - - std::map instances; - - // FIXME: this state is really local to DaemonServer, it's part - // of the protocol rather than being part of what other classes - // mgiht want to read. Maybe have a separate session object - // inside DaemonServer instead of stashing session-ish state here? - std::set declared_types; - - void update(MMgrReport *report); -}; - -// The state that we store about one daemon -class DaemonMetadata -{ - public: - DaemonKey key; - - // The hostname where daemon was last seen running (extracted - // from the metadata) - std::string hostname; - - // The metadata (hostname, version, etc) sent from the daemon - std::map metadata; - - // The perf counters received in MMgrReport messages - DaemonPerfCounters perf_counters; - - DaemonMetadata(PerfCounterTypes &types_) - : perf_counters(types_) - { - } -}; - -typedef std::shared_ptr DaemonMetadataPtr; -typedef std::map DaemonMetadataCollection; - - - - -/** - * Fuse the collection of per-daemon metadata from Ceph into - * a view that can be queried by service type, ID or also - * by server (aka fqdn). - */ -class DaemonMetadataIndex -{ - private: - std::map by_server; - DaemonMetadataCollection all; - - std::set updating; - - mutable Mutex lock; - - public: - - DaemonMetadataIndex() : lock("DaemonState") {} - - // FIXME: shouldn't really be public, maybe construct DaemonMetadata - // objects internally to avoid this. - PerfCounterTypes types; - - void insert(DaemonMetadataPtr dm); - void _erase(DaemonKey dmk); - - bool exists(const DaemonKey &key) const; - DaemonMetadataPtr get(const DaemonKey &key); - DaemonMetadataCollection get_by_server(const std::string &hostname) const; - DaemonMetadataCollection get_by_type(uint8_t type) const; - - const DaemonMetadataCollection &get_all() const {return all;} - const std::map &get_all_servers() const - { - return by_server; - } - - void notify_updating(const DaemonKey &k) { updating.insert(k); } - void clear_updating(const DaemonKey &k) { updating.erase(k); } - bool is_updating(const DaemonKey &k) { return updating.count(k) > 0; } - - /** - * Remove state for all daemons of this type whose names are - * not present in `names_exist`. Use this function when you have - * a cluster map and want to ensure that anything absent in the map - * is also absent in this class. - */ - void cull(entity_type_t daemon_type, std::set names_exist); -}; - -#endif - diff --git a/src/mgr/DaemonServer.cc b/src/mgr/DaemonServer.cc index bfd551d12257..b2f7882ea348 100644 --- a/src/mgr/DaemonServer.cc +++ b/src/mgr/DaemonServer.cc @@ -23,7 +23,7 @@ #define dout_prefix *_dout << "mgr.server " << __func__ << " " DaemonServer::DaemonServer(MonClient *monc_, - DaemonMetadataIndex &daemon_state_, + DaemonStateIndex &daemon_state_, PyModules &py_modules_) : Dispatcher(g_ceph_context), msgr(nullptr), monc(monc_), daemon_state(daemon_state_), @@ -166,11 +166,11 @@ bool DaemonServer::handle_report(MMgrReport *m) dout(4) << "from " << m->get_connection() << " name " << m->daemon_name << dendl; - DaemonMetadataPtr daemon; + DaemonStatePtr daemon; if (daemon_state.exists(key)) { daemon = daemon_state.get(key); } else { - daemon = std::make_shared(daemon_state.types); + daemon = std::make_shared(daemon_state.types); // FIXME: crap, we don't know the hostname at this stage. daemon->key = key; daemon_state.insert(daemon); diff --git a/src/mgr/DaemonServer.h b/src/mgr/DaemonServer.h index ab9357436002..f37e7f015b62 100644 --- a/src/mgr/DaemonServer.h +++ b/src/mgr/DaemonServer.h @@ -26,7 +26,7 @@ #include "auth/AuthAuthorizeHandler.h" -#include "DaemonMetadata.h" +#include "DaemonState.h" class MMgrReport; class MMgrOpen; @@ -42,7 +42,7 @@ class DaemonServer : public Dispatcher protected: Messenger *msgr; MonClient *monc; - DaemonMetadataIndex &daemon_state; + DaemonStateIndex &daemon_state; PyModules &py_modules; AuthAuthorizeHandlerRegistry auth_registry; @@ -57,7 +57,7 @@ public: entity_addr_t get_myaddr() const; DaemonServer(MonClient *monc_, - DaemonMetadataIndex &daemon_state_, + DaemonStateIndex &daemon_state_, PyModules &py_modules_); ~DaemonServer(); diff --git a/src/mgr/DaemonState.cc b/src/mgr/DaemonState.cc new file mode 100644 index 000000000000..9ec95ffbfb03 --- /dev/null +++ b/src/mgr/DaemonState.cc @@ -0,0 +1,142 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2016 John Spray + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + */ + +#include "DaemonState.h" + +#define dout_subsys ceph_subsys_mgr +#undef dout_prefix +#define dout_prefix *_dout << "mgr " << __func__ << " " + +void DaemonStateIndex::insert(DaemonStatePtr dm) +{ + Mutex::Locker l(lock); + + if (all.count(dm->key)) { + _erase(dm->key); + } + + by_server[dm->hostname][dm->key] = dm; + all[dm->key] = dm; +} + +void DaemonStateIndex::_erase(DaemonKey dmk) +{ + assert(lock.is_locked_by_me()); + + const auto dm = all.at(dmk); + auto &server_collection = by_server[dm->hostname]; + server_collection.erase(dm->key); + if (server_collection.empty()) { + by_server.erase(dm->hostname); + } + + all.erase(dmk); +} + +DaemonStateCollection DaemonStateIndex::get_by_type(uint8_t type) const +{ + Mutex::Locker l(lock); + + DaemonStateCollection result; + + for (const auto &i : all) { + if (i.first.first == type) { + result[i.first] = i.second; + } + } + + return result; +} + +DaemonStateCollection DaemonStateIndex::get_by_server(const std::string &hostname) const +{ + Mutex::Locker l(lock); + + if (by_server.count(hostname)) { + return by_server.at(hostname); + } else { + return {}; + } +} + +bool DaemonStateIndex::exists(const DaemonKey &key) const +{ + Mutex::Locker l(lock); + + return all.count(key) > 0; +} + +DaemonStatePtr DaemonStateIndex::get(const DaemonKey &key) +{ + Mutex::Locker l(lock); + + return all.at(key); +} + +void DaemonStateIndex::cull(entity_type_t daemon_type, + std::set names_exist) +{ + Mutex::Locker l(lock); + + std::set victims; + + for (const auto &i : all) { + if (i.first.first != daemon_type) { + continue; + } + + if (names_exist.count(i.first.second) == 0) { + victims.insert(i.first); + } + } + + for (const auto &i : victims) { + dout(4) << "Removing data for " << i << dendl; + _erase(i); + } +} + +void DaemonPerfCounters::update(MMgrReport *report) +{ + dout(20) << "loading " << report->declare_types.size() << " new types, " + << report->packed.length() << " bytes of data" << dendl; + + // Load any newly declared types + for (const auto &t : report->declare_types) { + types.insert(std::make_pair(t.path, t)); + declared_types.insert(t.path); + } + + // Parse packed data according to declared set of types + bufferlist::iterator p = report->packed.begin(); + DECODE_START(1, p); + for (const auto &t_path : declared_types) { + const auto &t = types.at(t_path); + uint64_t val = 0; + uint64_t avgcount = 0; + uint64_t avgcount2 = 0; + + ::decode(val, p); + if (t.type & PERFCOUNTER_LONGRUNAVG) { + ::decode(avgcount, p); + ::decode(avgcount2, p); + } + // TODO: interface for insertion of avgs, add timestamp + instances[t_path].push(val); + } + // TODO: handle badly encoded things without asserting out + DECODE_FINISH(p); +} + + + diff --git a/src/mgr/DaemonState.h b/src/mgr/DaemonState.h new file mode 100644 index 000000000000..a5aef3b3993a --- /dev/null +++ b/src/mgr/DaemonState.h @@ -0,0 +1,147 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2016 John Spray + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + */ + +#ifndef DAEMON_STATE_H_ +#define DAEMON_STATE_H_ + +#include +#include +#include +#include + +#include "common/Mutex.h" + +#include "msg/msg_types.h" + +// For PerfCounterType +#include "messages/MMgrReport.h" + + +// Unique reference to a daemon within a cluster +typedef std::pair DaemonKey; + +// An instance of a performance counter type, within +// a particular daemon. +class PerfCounterInstance +{ + // TODO: store some short history or whatever + uint64_t current; + public: + void push(uint64_t const &v) {current = v;} +}; + + +typedef std::map PerfCounterTypes; + +// Performance counters for one daemon +class DaemonPerfCounters +{ + public: + // The record of perf stat types, shared between daemons + PerfCounterTypes &types; + + DaemonPerfCounters(PerfCounterTypes &types_) + : types(types_) + {} + + std::map instances; + + // FIXME: this state is really local to DaemonServer, it's part + // of the protocol rather than being part of what other classes + // mgiht want to read. Maybe have a separate session object + // inside DaemonServer instead of stashing session-ish state here? + std::set declared_types; + + void update(MMgrReport *report); +}; + +// The state that we store about one daemon +class DaemonState +{ + public: + DaemonKey key; + + // The hostname where daemon was last seen running (extracted + // from the metadata) + std::string hostname; + + // The metadata (hostname, version, etc) sent from the daemon + std::map metadata; + + // The perf counters received in MMgrReport messages + DaemonPerfCounters perf_counters; + + DaemonState(PerfCounterTypes &types_) + : perf_counters(types_) + { + } +}; + +typedef std::shared_ptr DaemonStatePtr; +typedef std::map DaemonStateCollection; + + + + +/** + * Fuse the collection of per-daemon metadata from Ceph into + * a view that can be queried by service type, ID or also + * by server (aka fqdn). + */ +class DaemonStateIndex +{ + private: + std::map by_server; + DaemonStateCollection all; + + std::set updating; + + mutable Mutex lock; + + public: + + DaemonStateIndex() : lock("DaemonState") {} + + // FIXME: shouldn't really be public, maybe construct DaemonState + // objects internally to avoid this. + PerfCounterTypes types; + + void insert(DaemonStatePtr dm); + void _erase(DaemonKey dmk); + + bool exists(const DaemonKey &key) const; + DaemonStatePtr get(const DaemonKey &key); + DaemonStateCollection get_by_server(const std::string &hostname) const; + DaemonStateCollection get_by_type(uint8_t type) const; + + const DaemonStateCollection &get_all() const {return all;} + const std::map &get_all_servers() const + { + return by_server; + } + + void notify_updating(const DaemonKey &k) { updating.insert(k); } + void clear_updating(const DaemonKey &k) { updating.erase(k); } + bool is_updating(const DaemonKey &k) { return updating.count(k) > 0; } + + /** + * Remove state for all daemons of this type whose names are + * not present in `names_exist`. Use this function when you have + * a cluster map and want to ensure that anything absent in the map + * is also absent in this class. + */ + void cull(entity_type_t daemon_type, std::set names_exist); +}; + +#endif + diff --git a/src/mgr/Mgr.cc b/src/mgr/Mgr.cc index 128426c8b626..35c6b075ba20 100644 --- a/src/mgr/Mgr.cc +++ b/src/mgr/Mgr.cc @@ -66,18 +66,18 @@ Mgr::~Mgr() /** * Context for completion of metadata mon commands: take - * the result and stash it in DaemonMetadataIndex + * the result and stash it in DaemonStateIndex */ class MetadataUpdate : public Context { - DaemonMetadataIndex &daemon_state; + DaemonStateIndex &daemon_state; DaemonKey key; public: bufferlist outbl; std::string outs; - MetadataUpdate(DaemonMetadataIndex &daemon_state_, const DaemonKey &key_) + MetadataUpdate(DaemonStateIndex &daemon_state_, const DaemonKey &key_) : daemon_state(daemon_state_), key(key_) {} void finish(int r) @@ -97,7 +97,7 @@ public: json_spirit::mObject daemon_meta = json_result.get_obj(); - DaemonMetadataPtr dm = std::make_shared(daemon_state.types); + DaemonStatePtr dm = std::make_shared(daemon_state.types); dm->key = key; dm->hostname = daemon_meta.at("hostname").get_str(); @@ -243,7 +243,7 @@ void Mgr::load_all_metadata() continue; } - DaemonMetadataPtr dm = std::make_shared(daemon_state.types); + DaemonStatePtr dm = std::make_shared(daemon_state.types); dm->key = DaemonKey(CEPH_ENTITY_TYPE_MDS, daemon_meta.at("name").get_str()); dm->hostname = daemon_meta.at("hostname").get_str(); @@ -265,7 +265,7 @@ void Mgr::load_all_metadata() continue; } - DaemonMetadataPtr dm = std::make_shared(daemon_state.types); + DaemonStatePtr dm = std::make_shared(daemon_state.types); dm->key = DaemonKey(CEPH_ENTITY_TYPE_MON, daemon_meta.at("name").get_str()); dm->hostname = daemon_meta.at("hostname").get_str(); @@ -288,7 +288,7 @@ void Mgr::load_all_metadata() } dout(4) << osd_metadata.at("hostname").get_str() << dendl; - DaemonMetadataPtr dm = std::make_shared(daemon_state.types); + DaemonStatePtr dm = std::make_shared(daemon_state.types); dm->key = DaemonKey(CEPH_ENTITY_TYPE_OSD, stringify(osd_metadata.at("id").get_int())); dm->hostname = osd_metadata.at("hostname").get_str(); diff --git a/src/mgr/Mgr.h b/src/mgr/Mgr.h index bc33c6adfafe..4a2ce779c8ff 100644 --- a/src/mgr/Mgr.h +++ b/src/mgr/Mgr.h @@ -35,7 +35,7 @@ #include "DaemonServer.h" #include "PyModules.h" -#include "DaemonMetadata.h" +#include "DaemonState.h" #include "ClusterState.h" class MCommand; @@ -57,7 +57,7 @@ protected: Context *waiting_for_fs_map; PyModules py_modules; - DaemonMetadataIndex daemon_state; + DaemonStateIndex daemon_state; ClusterState cluster_state; DaemonServer server; diff --git a/src/mgr/PyModules.cc b/src/mgr/PyModules.cc index 82fd2c19f7dd..f4b25f72e1b2 100644 --- a/src/mgr/PyModules.cc +++ b/src/mgr/PyModules.cc @@ -27,7 +27,7 @@ #define dout_prefix *_dout << "mgr " << __func__ << " " void PyModules::dump_server(const std::string &hostname, - const DaemonMetadataCollection &dmc, + const DaemonStateCollection &dmc, Formatter *f) { f->dump_string("hostname", hostname); diff --git a/src/mgr/PyModules.h b/src/mgr/PyModules.h index 302063697315..93e373409158 100644 --- a/src/mgr/PyModules.h +++ b/src/mgr/PyModules.h @@ -20,7 +20,7 @@ #include "common/Mutex.h" -#include "DaemonMetadata.h" +#include "DaemonState.h" #include "ClusterState.h" @@ -32,7 +32,7 @@ class PyModules protected: std::map modules; - DaemonMetadataIndex &daemon_state; + DaemonStateIndex &daemon_state; ClusterState &cluster_state; MonClient &monc; Finisher &finisher; @@ -42,7 +42,7 @@ class PyModules public: static constexpr auto config_prefix = "mgr."; - PyModules(DaemonMetadataIndex &ds, ClusterState &cs, MonClient &mc, + PyModules(DaemonStateIndex &ds, ClusterState &cs, MonClient &mc, Finisher &f) : daemon_state(ds), cluster_state(cs), monc(mc), finisher(f), lock("PyModules") @@ -76,7 +76,7 @@ public: int main(std::vector args); void dump_server(const std::string &hostname, - const DaemonMetadataCollection &dmc, + const DaemonStateCollection &dmc, Formatter *f); bool get_config(const std::string &handle,