//------------------------------------------------------------------------------ // File: FsView.hh // Author: Andreas-Joachim Peters - CERN //------------------------------------------------------------------------------ /************************************************************************ * EOS - the CERN Disk Storage System * * Copyright (C) 2011 CERN/Switzerland * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see .* ************************************************************************/ #ifndef __EOSMGM_FSVIEW__HH__ #define __EOSMGM_FSVIEW__HH__ #include "mgm/Namespace.hh" #include "mgm/FileSystem.hh" #include "mgm/utils/FilesystemUuidMapper.hh" #include "mgm/utils/FileSystemRegistry.hh" #include "common/RWMutex.hh" #include "common/SymKeys.hh" #include "common/Logging.hh" #include "common/Locators.hh" #include "common/InstanceName.hh" #include "common/AssistedThread.hh" #include "qclient/shared/SharedHashSubscription.hh" #include #ifndef __APPLE__ #include #else #include #include #endif namespace eos::common { class TransferQueue; } //------------------------------------------------------------------------------ //! @file FsView.hh //! @brief Class representing the cluster configuration of EOS //! There are three views on EOS filesystems by space, group and node. //------------------------------------------------------------------------------ EOSMGMNAMESPACE_BEGIN struct GeoTreeElement; class GeoTree; class TableFormatterBase; class Balancer; class GroupBalancer; class GroupDrainer; class GeoBalancer; class Converter; class IConfigEngine; class FsBalancer; class FileInspector; //------------------------------------------------------------------------------ //! Struct holding file system info for balancing operations //------------------------------------------------------------------------------ struct FsBalanceInfo { eos::common::FileSystem::fsid_t mFsId; ///< File ssytem id std::string mNodeInfo; ///< FQDN:port //---------------------------------------------------------------------------- //! Constructor //---------------------------------------------------------------------------- FsBalanceInfo() = default; //---------------------------------------------------------------------------- //! Constructor with parameters //---------------------------------------------------------------------------- FsBalanceInfo(eos::common::FileSystem::fsid_t fsid, const std::string& node_host): mFsId(fsid), mNodeInfo(node_host) {} //---------------------------------------------------------------------------- //! Operator < implementation for storing such objects in sets //---------------------------------------------------------------------------- bool operator< (const FsBalanceInfo& rhs) const { return mFsId < rhs.mFsId; } }; //------------------------------------------------------------------------------ //! Priority sets of file systems to be used for balancing operations, //! containing 4 sets for fs'es with fill ratio in the following intervals: //! [0, mean - threshold) - low prio //! [mean - threshold, mean) - low //! [mean, mean + threshold ) - high //! [mean + threshold, 100] - high prio //------------------------------------------------------------------------------ struct FsPrioritySets { static constexpr double sThreshold = 5.0; std::set mPrioLow; std::set mLow; std::set mHigh; std::set mPrioHigh; }; //------------------------------------------------------------------------------ //! Base class representing any element in a GeoTree //------------------------------------------------------------------------------ struct GeoTreeElement { //------------------------------------------------------------------------------ //! Destructor //------------------------------------------------------------------------------ ~GeoTreeElement(); //! Pointer to father node in the tree GeoTreeElement* mFather; //! Tag token for example BBB in AA::BBB:CC std::string mTagToken; //! Full geo tag for example AA::BBB:CC in AA::BBB:CC std::string mFullTag; //! An auxiliary numbering to run the aggregator mutable size_t mId; //! All the FileSystems attached to this node of the tree std::set mFsIds; //! Map geoTreeTag -> son branches std::map mSons; }; //------------------------------------------------------------------------------ //! @brief A helper class to order branches in a GeoTree in the proper display //! order. //------------------------------------------------------------------------------ class GeoTreeNodeOrderHelper { public: bool operator()(const GeoTreeElement* const& left, const GeoTreeElement* const& right) const { return (left->mFullTag > right->mFullTag); } }; //------------------------------------------------------------------------------ //! Base class representing a functor to compute statistics along a GeoTree //------------------------------------------------------------------------------ class GeoTreeAggregator { public: //---------------------------------------------------------------------------- //! Destructor //---------------------------------------------------------------------------- virtual ~GeoTreeAggregator() = default; // Initialize the aggregator virtual bool init(const std::vector& geotags, const std::vector& depthLevelsIndexes) = 0; // Aggregate the leaves at the last level of the tree virtual bool aggregateLeaves(const std::set& leaves, const size_t& idx) = 0; //---------------------------------------------------------------------------- // Aggregate the nodes at intermediate levels // WARNING target node might be part of the nodes to aggregate. // Careful before overwriting the target node. //---------------------------------------------------------------------------- virtual bool aggregateNodes(const std::map& nodes, const size_t& idx, bool includeSelf = false) = 0; // Aggregate the leaves and the nodes at any level of the tree virtual bool aggregateLeavesAndNodes( const std::set& leaves, const std::map& nodes, const size_t& idx) { return (leaves.empty() ? true : aggregateLeaves(leaves, idx)) && (nodes.empty() ? true : aggregateNodes(nodes, idx, !leaves.empty())); } }; //------------------------------------------------------------------------------ //! Class representing a tree-structured set of fsids //------------------------------------------------------------------------------ class GeoTree { typedef eos::common::FileSystem::fsid_t fsid_t; public: //---------------------------------------------------------------------------- //! Constructor //---------------------------------------------------------------------------- GeoTree(); //---------------------------------------------------------------------------- //! Destructor //---------------------------------------------------------------------------- virtual ~GeoTree(); //---------------------------------------------------------------------------- //! Insert a file system into the tree //! //! @parma fs file system id //! //! @return true if successful, otherwise false //---------------------------------------------------------------------------- bool insert(const fsid_t& fs); //---------------------------------------------------------------------------- //! Remove a file system from the tree //! //! @parma fs file system id //! //! @return true if successful, otherwise false //---------------------------------------------------------------------------- bool erase(const fsid_t& fs); //---------------------------------------------------------------------------- //! Get the geotag at which the fs is stored if found //! //! @param fs file system id //! @param geoTag returned geotag if fs found //! // @return true if successful, otherwise false //---------------------------------------------------------------------------- bool getGeoTagInTree(const fsid_t& fs , std::string& geoTag); //---------------------------------------------------------------------------- //! Get number of file systems in the tree //---------------------------------------------------------------------------- size_t size() const; //---------------------------------------------------------------------------- //! Run an aggregator through the tree //! @note At any depth level, the aggregator is fed ONLY with the data of //! the ONE deeper level in the tree //! //! @param aggregator the aggregator to be run //! //! @return true if successful, otherwise false //---------------------------------------------------------------------------- bool runAggregator(GeoTreeAggregator* aggregator) const; //---------------------------------------------------------------------------- //! STL const_iterator class //! //! Only the leaves are iterated in alphabetical order of their geotag //---------------------------------------------------------------------------- class const_iterator: public std::iterator { friend class GeoTree; using ContainerT = std::map; ContainerT::const_iterator mIt; ///< Iterator inside the container ContainerT* mCont; ///< Pointer to original container public: //-------------------------------------------------------------------------- //! Default constructor //-------------------------------------------------------------------------- const_iterator() = default; //-------------------------------------------------------------------------- //! Constructor //! //! @param iterator inside map //-------------------------------------------------------------------------- const_iterator(ContainerT::const_iterator it, ContainerT& cont): mIt(it), mCont(&cont) {} //-------------------------------------------------------------------------- //! Destructor //-------------------------------------------------------------------------- ~const_iterator() = default; //-------------------------------------------------------------------------- //! Copy assignment operator //-------------------------------------------------------------------------- const_iterator& operator= (const const_iterator& it); //-------------------------------------------------------------------------- //! Copy constructor //-------------------------------------------------------------------------- const_iterator(const const_iterator& it) { *this = it; } //-------------------------------------------------------------------------- //! Pre-increment //-------------------------------------------------------------------------- const_iterator& operator++(); //-------------------------------------------------------------------------- //! Post-increment //-------------------------------------------------------------------------- const_iterator operator++(int); //-------------------------------------------------------------------------- //! Pre-decrement //-------------------------------------------------------------------------- const_iterator& operator--(); //-------------------------------------------------------------------------- //! Post-decrement //-------------------------------------------------------------------------- const_iterator operator--(int); //-------------------------------------------------------------------------- //! Indirection operator //-------------------------------------------------------------------------- const eos::common::FileSystem::fsid_t& operator*() const; //-------------------------------------------------------------------------- // Inequality operator //-------------------------------------------------------------------------- inline bool operator !=(const const_iterator& rhs) const { return mIt != rhs.mIt; } //-------------------------------------------------------------------------- // Equality operator //-------------------------------------------------------------------------- inline bool operator ==(const const_iterator& rhs) const { return mIt == rhs.mIt; } }; //---------------------------------------------------------------------------- // begin() //---------------------------------------------------------------------------- inline const_iterator begin() const { const_iterator it(pLeaves.begin(), pLeaves); return it; } //---------------------------------------------------------------------------- // cbegin() //---------------------------------------------------------------------------- inline const_iterator cbegin() const { return begin(); } //---------------------------------------------------------------------------- // end() //---------------------------------------------------------------------------- inline const_iterator end() const { const_iterator it(pLeaves.end(), pLeaves); return it; } //---------------------------------------------------------------------------- // cend() //---------------------------------------------------------------------------- inline const_iterator cend() const { return end(); } private: //---------------------------------------------------------------------------- //! Get file system geotag //! //! @param fs file system id //! //! @return geotag //---------------------------------------------------------------------------- std::string getGeoTag(const fsid_t& fs) const; GeoTreeElement* pRoot; ///< The root branch of the tree //! All the elements of the tree collected by depth std::vector > pLevels; mutable std::map pLeaves; ///< All the leaves of the tree }; //------------------------------------------------------------------------------ //! Class representing a grouped set of filesystems //------------------------------------------------------------------------------ class BaseView : public GeoTree { public: std::string mName; ///< Name of the base view std::string mType; ///< type of the base view //---------------------------------------------------------------------------- //! Constructor //---------------------------------------------------------------------------- BaseView(const common::SharedHashLocator& locator): mLocator(locator), mHeartBeat(0), mStatus("unknown") {} //---------------------------------------------------------------------------- //! Destructor //---------------------------------------------------------------------------- virtual ~BaseView() = default; //---------------------------------------------------------------------------- //! Return a member variable in the view //---------------------------------------------------------------------------- virtual std::string GetMember(const std::string& member) const; //---------------------------------------------------------------------------- //! Return a configuration member //---------------------------------------------------------------------------- virtual std::string GetConfigMember(std::string key) const; //---------------------------------------------------------------------------- //! Return a map of configuration values given a vector of keys //---------------------------------------------------------------------------- virtual bool GetConfigMembers(const std::vector& keys, std::map& out) const; //---------------------------------------------------------------------------- //! Delete a configuration member //---------------------------------------------------------------------------- virtual bool DeleteConfigMember(std::string key) const; //---------------------------------------------------------------------------- //! Print the view contents //! //! @param table table info //! @param table_format format for table from MGM side //! @param table_mq_format format for table from MQ side //! @param outdepth ouput depth for geoscheduling //! @param filter view filter //---------------------------------------------------------------------------- void Print(TableFormatterBase& table, std::string table_format, const std::string& table_mq_format, unsigned outdepth, const std::string& filter = "", const bool dont_color = false); //---------------------------------------------------------------------------- //! Return all configuration keys //---------------------------------------------------------------------------- bool GetConfigKeys(std::vector& keys); //---------------------------------------------------------------------------- //! Set the heartbeat time //! @param hb heart beat time to set //---------------------------------------------------------------------------- void SetHeartBeat(time_t hb) { mHeartBeat = hb; } //---------------------------------------------------------------------------- //! Get the heartbeat timestamp //---------------------------------------------------------------------------- time_t GetHeartBeat() { return mHeartBeat; } //---------------------------------------------------------------------------- //! Set the status //! @param status status to set //---------------------------------------------------------------------------- void SetStatus(const std::string& status) { mStatus = status; } //---------------------------------------------------------------------------- //! Return the status //---------------------------------------------------------------------------- const std::string GetStatus() const { return mStatus; } //---------------------------------------------------------------------------- //! Should the provided fsid participate in statistics calculations? //! Yes, if: //! - The filesystem exists (duh) //! - The filesystem is at-least-RO, booted and online //! //! Call with fsview lock at-least-read locked. //---------------------------------------------------------------------------- static bool ConsiderForStatistics(FileSystem* fs); //---------------------------------------------------------------------------- //! Calculate the sum of as long long //---------------------------------------------------------------------------- long long SumLongLong(const char* param, bool lock = true, const std::set* subset = nullptr); //---------------------------------------------------------------------------- //! Calculate the sum of as double //---------------------------------------------------------------------------- double SumDouble(const char* param, bool lock = true, const std::set* subset = nullptr); //---------------------------------------------------------------------------- //! Calculates the average of as double //---------------------------------------------------------------------------- double AverageDouble(const char* param, bool lock = true, const std::set* subset = nullptr); //---------------------------------------------------------------------------- //! Calculates the maximum deviation from the average in a group //--------------------------------------------------------------------------- virtual double MaxAbsDeviation(const char* param, bool lock = true, const std::set* subset = nullptr); double MaxDeviation(const char* param, bool lock = true, const std::set* subset = nullptr); double MinDeviation(const char* param, bool lock = true, const std::set* subset = nullptr); //---------------------------------------------------------------------------- //! Calculates the standard deviation of as double //---------------------------------------------------------------------------- double SigmaDouble(const char* param, bool lock = true, const std::set* subset = nullptr); //---------------------------------------------------------------------------- //! Calculates the number of fsid considered for average //---------------------------------------------------------------------------- long long ConsiderCount(bool lock, const std::set* subset); //---------------------------------------------------------------------------- //! Set a member variable in a view //---------------------------------------------------------------------------- bool SetConfigMember(std::string key, string value, bool isstatus = false); protected: common::SharedHashLocator mLocator; ///< Locator for shared hash std::atomic mHeartBeat; ///< Last heartbeat time private: std::string mStatus; ///< Status (meaning depends on inheritor) std::string mSize; ///< Size of base object (meaning depends on inheritor) }; //------------------------------------------------------------------------------ //! Class FsSpace describing a space (set of filesystems) //------------------------------------------------------------------------------ class FsSpace: public BaseView { public: //! Set when a configuration gets loaded to avoid overwriting of the loaded //! values by default values static std::atomic gDisableDefaults; static std::string gConfigQueuePrefix; ///< Configuration queue prefix std::unique_ptr mFsBalancer; ///< File system balancer Converter* mConverter; ///< Threaded object running layout conversion jobs GroupBalancer* mGroupBalancer; ///< Threaded object running group balancing GeoBalancer* mGeoBalancer; ///< Threaded object running geotag balancing std::unique_ptr mGroupDrainer; ///< Threaded object running group drainer std::unique_ptr mFileInspector; ///< Space file inspector //---------------------------------------------------------------------------- //! Constructor //! //! @param name name of the space to construct //---------------------------------------------------------------------------- FsSpace(const char* name); //---------------------------------------------------------------------------- //! Destructor //---------------------------------------------------------------------------- virtual ~FsSpace(); //---------------------------------------------------------------------------- //! Stop function stopping threads before destruction //---------------------------------------------------------------------------- void Stop(); //---------------------------------------------------------------------------- //! Apply the default space parameters //---------------------------------------------------------------------------- bool ApplySpaceDefaultParameters(eos::mgm::FileSystem* fs, bool force = false); //---------------------------------------------------------------------------- //! Reset the Drain state - to be removed?! //---------------------------------------------------------------------------- void ResetDraining(); //---------------------------------------------------------------------------- //! Get status of the balancer thread pool //---------------------------------------------------------------------------- std::string GetBalancerPoolInfo() const; }; //------------------------------------------------------------------------------ //! Class FsGroup describing a group (set of filesystems) //------------------------------------------------------------------------------ class FsGroup : public BaseView { friend class FsView; public: //---------------------------------------------------------------------------- //! Constructor //! @param name name of the group e.g. 'default.0' //---------------------------------------------------------------------------- FsGroup(const char* name) : BaseView(common::SharedHashLocator::makeForGroup(name)), mIndex(0) { mName = name; mType = "groupview"; } //---------------------------------------------------------------------------- //! Destructor //---------------------------------------------------------------------------- virtual ~FsGroup() = default; //---------------------------------------------------------------------------- //! Return index of the group //---------------------------------------------------------------------------- unsigned int GetIndex() { return mIndex; } protected: unsigned int mIndex; ///< Group index i.e 0,1,2,3 ... }; //------------------------------------------------------------------------------ //! Class FsNode describing a node (set of filesystems) //------------------------------------------------------------------------------ class FsNode : public BaseView { public: //---------------------------------------------------------------------------- //! Constructor //! //! @param name nodeview name //---------------------------------------------------------------------------- explicit FsNode(const char* name); //---------------------------------------------------------------------------- //! Destructor //---------------------------------------------------------------------------- virtual ~FsNode(); //---------------------------------------------------------------------------- //! Return a member variable //---------------------------------------------------------------------------- virtual std::string GetMember(const std::string& name) const override; //---------------------------------------------------------------------------- //! Get active status //---------------------------------------------------------------------------- eos::common::ActiveStatus GetActiveStatus(); //---------------------------------------------------------------------------- //! Set active status //---------------------------------------------------------------------------- bool SetActiveStatus(eos::common::ActiveStatus active); //---------------------------------------------------------------------------- //! Set the configuration default values for a node //---------------------------------------------------------------------------- void SetNodeConfigDefault(); //---------------------------------------------------------------------------- //! Check if node has a recent enough heartbeat //---------------------------------------------------------------------------- bool HasHeartbeat() const; //---------------------------------------------------------------------------- //! Callback to process update for the shared hash //! //! @param upd SharedHashUpdate object //---------------------------------------------------------------------------- void ProcessUpdateCb(qclient::SharedHashUpdate&& upd); //---------------------------------------------------------------------------- //! Set refresh marker for the FST //---------------------------------------------------------------------------- void SignalRefresh(); private: static std::string msRefreshTag; std::unique_ptr mSubscription {nullptr}; }; //------------------------------------------------------------------------------ //! Class ConfigResetMonitor - reset the current configuration engine object //! used by the FsView to null during construction and put it back to the //! initial value during destruction. //------------------------------------------------------------------------------ class ConfigResetMonitor final { public: //------------------------------------------------------------------------------ //! Constructor //------------------------------------------------------------------------------ ConfigResetMonitor(); //------------------------------------------------------------------------------ //! Destructor //------------------------------------------------------------------------------ ~ConfigResetMonitor(); private: IConfigEngine* mOrigConfEngine; ///< Initial config engine object }; //------------------------------------------------------------------------------ //! Class describing an EOS pool including views //------------------------------------------------------------------------------ class FsView : public eos::common::LogId { friend class ConfigResetMonitor; // @todo (esindril): this is just for the call in SetConfigMember when // accessing mConfigEngine. Should be refactored. friend class BaseView; public: //! Static singleton object hosting the filesystem view object static FsView gFsView; //---------------------------------------------------------------------------- //! Return printout formats //---------------------------------------------------------------------------- static std::string GetNodeFormat(std::string option); static std::string GetGroupFormat(std::string option); static std::string GetSpaceFormat(std::string option); static std::string GetFileSystemFormat(std::string option); //---------------------------------------------------------------------------- //! Constructor //! //! @param start_heartbeat control whether heartbeat thread is started - for //! testing purposes //---------------------------------------------------------------------------- FsView() : mConfigEngine(nullptr) { mHeartBeatThread.reset(&FsView::HeartBeatCheck, this); } //---------------------------------------------------------------------------- //! Destructor //---------------------------------------------------------------------------- virtual ~FsView() { StopHeartBeat(); } //---------------------------------------------------------------------------- //! Add FsChangeListener to all the existing file systems //! //! @param fs_listener file system change listener object //! @param interests set of interest keys for the listener //---------------------------------------------------------------------------- void AddFsChangeListener(std::shared_ptr fs_lst, const std::set& interests); //---------------------------------------------------------------------------- //! Add or modify a filesystem //! //! @param fs filesystem to register //! @parma registerInGeoTreeEngine //! //! @return true if done, otherwise false //---------------------------------------------------------------------------- bool Register(FileSystem* fs, const common::FileSystemCoreParams& coreParams, bool registerInGeoTreeEngine = true); //---------------------------------------------------------------------------- //! Move a filesystem to another group //! //! @param fs filesystem object to move //! @param group target group //! //! @return true if moved otherwise false //---------------------------------------------------------------------------- bool MoveGroup(FileSystem* fs, std::string group); //---------------------------------------------------------------------------- //! Move a filesystem to another node //! //! @param fs filesystem object to move //! @param target node //! //! @return true if moved otherwise false //---------------------------------------------------------------------------- bool MoveNode(FileSystem* fs, std::string node); //---------------------------------------------------------------------------- //! Store the filesystem configuration into the config engine. Should be //! called whenever a filesystem wide parameters is changed. //! //! @param fs file system object //! @param save_config mark if the config should be saved or not //! @note this requires at least the read lock on the gFsView.ViewMutex //---------------------------------------------------------------------------- void StoreFsConfig(FileSystem* fs, bool save_config = true); //---------------------------------------------------------------------------- //! Remove a filesystem //! //! @param fs file system object //! @param unreg_from_geo_tree if true unregister from GeoTree //! @param notify_fst if true delete the shared hash object corresponding //! to the current file system //! //! @return true if successful, otherwise false //---------------------------------------------------------------------------- bool UnRegister(FileSystem* fs, bool unreg_from_geo_tree = true, bool notify_fst = false); //---------------------------------------------------------------------------- //! Check's if a queue+path exists already //---------------------------------------------------------------------------- bool ExistsQueue(std::string queue, std::string queuepath); //---------------------------------------------------------------------------- //! Add or modify an fst node //---------------------------------------------------------------------------- bool RegisterNode(const char* nodequeue); //---------------------------------------------------------------------------- //! Remove a node //---------------------------------------------------------------------------- bool UnRegisterNode(const char* nodequeue); //---------------------------------------------------------------------------- //! Add or modify a space //---------------------------------------------------------------------------- bool RegisterSpace(const char* spacename); //---------------------------------------------------------------------------- //! Remove a space //---------------------------------------------------------------------------- bool UnRegisterSpace(const char* spacename); //---------------------------------------------------------------------------- //! Add or modify a group //---------------------------------------------------------------------------- bool RegisterGroup(const char* groupname); //---------------------------------------------------------------------------- //! Remove a group //---------------------------------------------------------------------------- bool UnRegisterGroup(const char* groupname); //---------------------------------------------------------------------------- //! Check if quota is enabled for space //! //! @param space space name //! //! @return true if quota enabled for space, otherwise false //! @warning needs to be called with a read-lock on the ViewMutex //---------------------------------------------------------------------------- bool IsQuotaEnabled(const std::string& space); //---------------------------------------------------------------------------- //! Find filesystem by queue path //---------------------------------------------------------------------------- FileSystem* FindByQueuePath(std::string& queuepath); //---------------------------------------------------------------------------- //! Create a filesystem mapping //---------------------------------------------------------------------------- eos::common::FileSystem::fsid_t CreateMapping(std::string fsuuid); //---------------------------------------------------------------------------- //! Provide a filesystem mapping //---------------------------------------------------------------------------- bool ProvideMapping(std::string fsuuid, eos::common::FileSystem::fsid_t fsid); //---------------------------------------------------------------------------- //! Get a filesystem mapping by unique ID //---------------------------------------------------------------------------- eos::common::FileSystem::fsid_t GetMapping(std::string fsuuid); //---------------------------------------------------------------------------- //! Check for an existing mapping by filesystem id //---------------------------------------------------------------------------- inline bool HasMapping(eos::common::FileSystem::fsid_t fsid) { return mFilesystemMapper.hasFsid(fsid); } //---------------------------------------------------------------------------- //! Remove a mapping providing filesystem ID and unique ID //---------------------------------------------------------------------------- bool RemoveMapping(eos::common::FileSystem::fsid_t fsid, std::string fsuuid); //---------------------------------------------------------------------------- //! Remove a mapping providing filesystem ID //---------------------------------------------------------------------------- bool RemoveMapping(eos::common::FileSystem::fsid_t fsid); //---------------------------------------------------------------------------- //! Print views (space,group,nodes) //---------------------------------------------------------------------------- void PrintGroups(std::string& out, const std::string& headerformat, const std::string& listformat, unsigned int geodepth = 0, const char* selection = 0, bool dont_color = false); void PrintNodes(std::string& out, const std::string& headerformat, const std::string& listformat, unsigned int geodepth = 0, const char* selection = 0, bool dont_color = false); void PrintSpaces(std::string& out, const std::string& headerformat, const std::string& listformat, unsigned int geodepth = 0, const char* selection = 0, const std::string& filter = "", bool dont_color = false); //---------------------------------------------------------------------------- //! Clear all mappings and filesystem objects obtaining locks //---------------------------------------------------------------------------- void Reset(); //---------------------------------------------------------------------------- //! Clear all maps and delete all filesystem/group/space objects //---------------------------------------------------------------------------- void Clear(); //---------------------------------------------------------------------------- //! Thread loop function checking heartbeats //---------------------------------------------------------------------------- void HeartBeatCheck(ThreadAssistant& assistant) noexcept; //---------------------------------------------------------------------------- //! Stop the heartbeat thread //---------------------------------------------------------------------------- void StopHeartBeat() { mHeartBeatThread.join(); } //---------------------------------------------------------------------------- //! Set the configuration engine object //---------------------------------------------------------------------------- inline void SetConfigEngine(IConfigEngine* engine) { mConfigEngine = engine; } //---------------------------------------------------------------------------- //! Apply all filesystem configuration key-val pair //! //! @param key fs configuration key //! @param val fs configuration to be applied //! @param first_unregister if true then unregister the file system before //! applying any of the changes. This is needed for slave MGMs when //! following changes from the master MGM. [default false] //---------------------------------------------------------------------------- bool ApplyFsConfig(const char* key, const std::string& val, bool first_unregister = false); //---------------------------------------------------------------------------- //! Apply a global configuration key-val pair //---------------------------------------------------------------------------- bool ApplyGlobalConfig(const char* key, std::string& val); //---------------------------------------------------------------------------- //! Set a global configuration key-val pair //---------------------------------------------------------------------------- virtual bool SetGlobalConfig(const std::string& key, const std::string& value); //---------------------------------------------------------------------------- //! Set a global configuration key-val pair given as boolean //---------------------------------------------------------------------------- bool SetGlobalConfig(const std::string& key, bool value) { return SetGlobalConfig(key, (value ? std::string("true") : std::string("false"))); } //---------------------------------------------------------------------------- //! Get a global configuration value //---------------------------------------------------------------------------- virtual std::string GetGlobalConfig(const std::string& key); //---------------------------------------------------------------------------- //! Get a global configuration value as boolean //---------------------------------------------------------------------------- bool GetBoolGlobalConfig(const std::string& key) { return (GetGlobalConfig(key) == "true"); } //---------------------------------------------------------------------------- //! Broadcast new manager id to all the FST nodes //! //! @param master_id master identity : //---------------------------------------------------------------------------- void BroadcastMasterId(const std::string master_id); //---------------------------------------------------------------------------- //! Get number of filesystems registered //---------------------------------------------------------------------------- inline size_t GetNumFileSystems() const { eos::common::RWMutexReadLock fs_rd_lock(ViewMutex); return mIdView.size(); } //---------------------------------------------------------------------------- //! Df Command output //---------------------------------------------------------------------------- std::string Df(bool monitoring = false, bool si = false, bool readable = true, std::string path = "", bool json = false); //---------------------------------------------------------------------------- //! Physical bytes available //---------------------------------------------------------------------------- bool UnderNominalQuota(const std::string& space, bool isroot = false); //---------------------------------------------------------------------------- //! Collect all endpoints (:) matching the given queue or //! pattern //! //! @return set of matching endpoints //---------------------------------------------------------------------------- std::set CollectEndpoints(const std::string& queue) const; //---------------------------------------------------------------------------- //! Re-apply drain status for file systems to re-trigger draining. This is //! needed in case the drain engine is stopped and then restatred the fs-es //! which where in draning mode are not reactivated so we need to go through //! them and reapply the drain status so that draining is activated. //---------------------------------------------------------------------------- void ReapplyDrainStatus(); //---------------------------------------------------------------------------- //! Get map of unbalanced groups given the threshold and their max dev. //! //! @param space_name space name //! @param threshold deviation cut-off value used for selecting groups //! //! @return groups that are unbalanced with respect to the given thereshold //---------------------------------------------------------------------------- std::map GetUnbalancedGroups(const std::string& space_name, double threshold) const; //---------------------------------------------------------------------------- //! Get sets of file systems from given group that should be balanced //! //! @parma group_name group name //! @param threshold cut-off value used for selecting file systems //! //! @return tuple of sets of file systems //---------------------------------------------------------------------------- FsPrioritySets GetFsToBalance(const std::string& group_name, double threshold) const; //---------------------------------------------------------------------------- //! Dump balancer thread pool info for each of the existing spaces //! //! @param oss output string stream where info is appended //! @param prefix prefix string for each entry to be displayed //---------------------------------------------------------------------------- void DumpBalancerPoolInfo(std::ostringstream& oss, std::string_view prefix) const; //! Mutex protecting all ...View variables mutable eos::common::RWMutexR ViewMutex; //! Map translating a space name to a set of group objects std::map > mSpaceGroupView; //! Map translating a space name to a space view object std::map mSpaceView; //! Map translating a group name to a group view object std::map mGroupView; //! Map translating a node name to a node view object std::map mNodeView; //! Map translating a filesystem ID to a file system object FileSystemRegistry mIdView; private: IConfigEngine* mConfigEngine; AssistedThread mHeartBeatThread; ///< Thread monitoring heart-beats //! Object to map between fsid <-> uuid FilesystemUuidMapper mFilesystemMapper; std::map> mUsageOk; XrdSysMutex mUsageMutex; }; //------------------------------------------------------------------------------ //! Aggregator implementation to compute double precision statistics //! Statistics are sum, average, std dev, min dev, max dev, max abs dev //! It calls the underlying unstructured versions of the statistics computation //! DoubleSum, DoubleAverage, DoubleStdDev, ... //------------------------------------------------------------------------------ class DoubleAggregator : public GeoTreeAggregator { typedef eos::common::FileSystem::fsid_t fsid_t; //! Name of the parameter for which the statistics is to be computed std::string pParam; std::vector pSums; ///< Sums at the elements of the tree std::vector pMeans; ///< Averages at the elements of the tree std::vector pMaxDevs; ///< Max deviations at the elements of the tree std::vector pMinDevs; ///< Min deviations at the elements of the tree std::vector pMaxAbsDevs; ///< Min abs. deviations at the elements of the tree std::vector pStdDevs; ///< Std. deviations at the elements of the tree //! Number of entries considered in the statistics at the elements of the tree std::vector pNb; BaseView* pView; ///< The base view ordering the statistics //! End index (excluded) of each depth level in the statistics vectors std::vector pDepthLevelsIndexes; std::vector pGeoTags; ///< Full geotags at the elements of the tree public: //---------------------------------------------------------------------------- //! Get the sums at each tree element //---------------------------------------------------------------------------- const std::vector* getSums() const; //---------------------------------------------------------------------------- //! Get the averages at each tree element //---------------------------------------------------------------------------- const std::vector* getMeans() const; //---------------------------------------------------------------------------- //! Get the max absolute deviations at each tree element //---------------------------------------------------------------------------- const std::vector* getMaxAbsDevs() const; //---------------------------------------------------------------------------- //! Get the standard deviations at each tree element //---------------------------------------------------------------------------- const std::vector* getStdDevs() const; //---------------------------------------------------------------------------- //! Get the full geotags at each tree element //---------------------------------------------------------------------------- const std::vector* getGeoTags() const; //---------------------------------------------------------------------------- //! Get the end index (excluded) for a given depth level //---------------------------------------------------------------------------- size_t getEndIndex(int depth = -1) const; //---------------------------------------------------------------------------- //! Constructor given the name of the parameter to compute the statistics for //---------------------------------------------------------------------------- DoubleAggregator(const char* param); //---------------------------------------------------------------------------- //! Destructor //---------------------------------------------------------------------------- virtual ~DoubleAggregator(); //---------------------------------------------------------------------------- //! Set the view ordering the statistics. Needs to be set before running //! the aggregator. //---------------------------------------------------------------------------- void setView(BaseView* view); virtual bool init(const std::vector& geotags, const std::vector& depthLevelsIndexes); virtual bool aggregateLeaves( const std::set& leaves, const size_t& idx); virtual bool aggregateNodes( const std::map& nodes, const size_t& idx, bool includeSelf = false); }; //------------------------------------------------------------------------------ //! Aggregator implementation to compute long long integer statistics //! //! Statistics is only sum //! It calls the underlying unstructured versions of the statistics computation //! LongLongSum, so it benefits from the same filtering and special cases //! implemented there. //------------------------------------------------------------------------------ class LongLongAggregator : public GeoTreeAggregator { typedef eos::common::FileSystem::fsid_t fsid_t; //! Name of the parameter for which the statistics are to be computed std::string pParam; std::vector pSums; ///< Sums at the elements of the tree //! End index (excluded) of each depth level in the statistics vectors std::vector pDepthLevelsIndexes; std::vector pGeoTags; ///< Full geotags at the elements of the tree BaseView* pView; ///< The base view ordering the statistics public: //---------------------------------------------------------------------------- //! Constructor given the name of the parameter to compute the statistics for //---------------------------------------------------------------------------- LongLongAggregator(const char* param); //---------------------------------------------------------------------------- //! Destructor //---------------------------------------------------------------------------- virtual ~LongLongAggregator(); //---------------------------------------------------------------------------- //! Set the view ordering the statistics. Needs to be set before running //! the aggregator. //---------------------------------------------------------------------------- void setView(BaseView* view); //---------------------------------------------------------------------------- //! Get the sums at each tree element //---------------------------------------------------------------------------- const std::vector* getSums() const; //---------------------------------------------------------------------------- //! Get the full geotags at each tree element //---------------------------------------------------------------------------- const std::vector* getGeoTags() const; //---------------------------------------------------------------------------- //! Get the end index (excluded) for a given depth level //---------------------------------------------------------------------------- size_t getEndIndex(int depth = -1) const; virtual bool init(const std::vector& geotags, const std::vector& depthLevelsIndexes); virtual bool aggregateLeaves( const std::set& leaves, const size_t& idx); virtual bool aggregateNodes( const std::map& nodes, const size_t& idx, bool includeSelf = false); }; EOSMGMNAMESPACE_END #endif