X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Fmgr%2FDaemonState.h;fp=src%2Fceph%2Fsrc%2Fmgr%2FDaemonState.h;h=846ce5dd8d9fcbe6e6580eecb55f2c7146c44ed2;hb=812ff6ca9fcd3e629e49d4328905f33eee8ca3f5;hp=0000000000000000000000000000000000000000;hpb=15280273faafb77777eab341909a3f495cf248d9;p=stor4nfv.git diff --git a/src/ceph/src/mgr/DaemonState.h b/src/ceph/src/mgr/DaemonState.h new file mode 100644 index 0000000..846ce5d --- /dev/null +++ b/src/ceph/src/mgr/DaemonState.h @@ -0,0 +1,187 @@ +// -*- 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 + +#include "common/RWLock.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 +{ + class DataPoint + { + public: + utime_t t; + uint64_t v; + DataPoint(utime_t t_, uint64_t v_) + : t(t_), v(v_) + {} + }; + + boost::circular_buffer buffer; + uint64_t get_current() const; + + public: + const boost::circular_buffer & get_data() const + { + return buffer; + } + void push(utime_t t, uint64_t const &v); + PerfCounterInstance() + : buffer(20) {} +}; + + +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; + + void update(MMgrReport *report); + + void clear() + { + instances.clear(); + } +}; + +// The state that we store about one daemon +class DaemonState +{ + public: + Mutex lock = {"DaemonState::lock"}; + + 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; + + // Ephemeral state + bool service_daemon = false; + utime_t service_status_stamp; + std::map service_status; + utime_t last_service_beacon; + + // 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: + mutable RWLock lock = {"DaemonStateIndex", true, true, true}; + + std::map by_server; + DaemonStateCollection all; + std::set updating; + + void _erase(const DaemonKey& dmk); + + public: + DaemonStateIndex() {} + + // FIXME: shouldn't really be public, maybe construct DaemonState + // objects internally to avoid this. + PerfCounterTypes types; + + void insert(DaemonStatePtr dm); + bool exists(const DaemonKey &key) const; + DaemonStatePtr get(const DaemonKey &key); + + // Note that these return by value rather than reference to avoid + // callers needing to stay in lock while using result. Callers must + // still take the individual DaemonState::lock on each entry though. + DaemonStateCollection get_by_server(const std::string &hostname) const; + DaemonStateCollection get_by_service(const std::string &svc_name) const; + DaemonStateCollection get_all() const {return all;} + + template + auto with_daemons_by_server(Callback&& cb, Args&&... args) const -> + decltype(cb(by_server, std::forward(args)...)) { + RWLock::RLocker l(lock); + + return std::forward(cb)(by_server, std::forward(args)...); + } + + void notify_updating(const DaemonKey &k) { + RWLock::WLocker l(lock); + updating.insert(k); + } + void clear_updating(const DaemonKey &k) { + RWLock::WLocker l(lock); + updating.erase(k); + } + bool is_updating(const DaemonKey &k) { + RWLock::RLocker l(lock); + 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(const std::string& svc_name, + const std::set& names_exist); +}; + +#endif +