New upstream version 8.1.0

This commit is contained in:
geos_one
2025-08-10 01:34:16 +02:00
commit c891bb7105
4398 changed files with 838833 additions and 0 deletions

1656
meta/source/app/App.cpp Normal file

File diff suppressed because it is too large Load Diff

511
meta/source/app/App.h Normal file
View File

@@ -0,0 +1,511 @@
#pragma once
#include <app/config/Config.h>
#include <common/Common.h>
#include <common/app/log/LogContext.h>
#include <common/app/log/Logger.h>
#include <common/app/AbstractApp.h>
#include <common/components/StatsCollector.h>
#include <common/components/streamlistenerv2/ConnAcceptor.h>
#include <common/components/streamlistenerv2/StreamListenerV2.h>
#include <common/components/worker/Worker.h>
#include <common/components/TimerQueue.h>
#include <common/nodes/MirrorBuddyGroupMapper.h>
#include <common/nodes/NodeCapacityPools.h>
#include <common/nodes/NodeStoreClients.h>
#include <common/nodes/NodeStoreServers.h>
#include <common/nodes/RootInfo.h>
#include <common/nodes/TargetCapacityPools.h>
#include <common/nodes/TargetMapper.h>
#include <common/nodes/TargetStateStore.h>
#include <common/storage/quota/ExceededQuotaPerTarget.h>
#include <common/toolkit/AcknowledgmentStore.h>
#include <common/toolkit/NetFilter.h>
#include <components/DatagramListener.h>
#include <components/FileEventLogger.h>
#include <components/InternodeSyncer.h>
#include <components/buddyresyncer/BuddyResyncer.h>
#include <net/message/NetMessageFactory.h>
#include <nodes/MetaNodeOpStats.h>
#include <session/SessionStore.h>
#include <storage/DirInode.h>
#include <storage/MetaStore.h>
#include <storage/SyncedDiskAccessPath.h>
#ifndef BEEGFS_VERSION
#error BEEGFS_VERSION undefined
#endif
// program return codes
#define APPCODE_NO_ERROR 0
#define APPCODE_INVALID_CONFIG 1
#define APPCODE_INITIALIZATION_ERROR 2
#define APPCODE_RUNTIME_ERROR 3
typedef std::list<Worker*> WorkerList;
typedef WorkerList::iterator WorkerListIter;
typedef std::vector<StreamListenerV2*> StreamLisVec;
typedef StreamLisVec::iterator StreamLisVecIter;
// forward declarations
class LogContext;
class ModificationEventFlusher;
class App : public AbstractApp
{
public:
App(int argc, char** argv);
virtual ~App();
virtual void run() override;
virtual void stopComponents() override;
virtual void handleComponentException(std::exception& e) override;
virtual void handleNetworkInterfaceFailure(const std::string& devname) override;
void handleNetworkInterfacesChanged(NicAddressList nicList);
private:
int appResult;
int argc;
char** argv;
Config* cfg;
LogContext* log;
std::list<std::string> allowedInterfaces;
LockFD pidFileLockFD;
LockFD workingDirLockFD;
NetFilter* netFilter; // empty filter means "all nets allowed"
NetFilter* tcpOnlyFilter; // for IPs that allow only plain TCP (no RDMA etc)
std::shared_ptr<Node> localNode;
NodeStoreServers* mgmtNodes;
NodeStoreServers* metaNodes;
NodeStoreServers* storageNodes;
NodeStoreClients* clientNodes;
RootInfo metaRoot;
NodeCapacityPools* metaCapacityPools;
NodeCapacityPools* metaBuddyCapacityPools;
TargetMapper* targetMapper;
MirrorBuddyGroupMapper* storageBuddyGroupMapper; // maps storage targets to buddy groups
MirrorBuddyGroupMapper* metaBuddyGroupMapper; // maps meta nodes to buddy groups
TargetStateStore* targetStateStore; // map storage targets to a state
TargetStateStore* metaStateStore; // map mds targets (i.e. nodeIDs) to a state
std::unique_ptr<StoragePoolStore> storagePoolStore; // stores (category) storage pools
MultiWorkQueue* workQueue;
MultiWorkQueue* commSlaveQueue;
NetMessageFactory* netMessageFactory;
MetaStore* metaStore;
DirInode* rootDir;
bool isRootBuddyMirrored;
DirInode* disposalDir;
DirInode* buddyMirrorDisposalDir;
SessionStore* sessions;
SessionStore* mirroredSessions;
AcknowledgmentStore* ackStore;
MetaNodeOpStats* nodeOperationStats; // file system operation statistics
std::string metaPathStr; // the general parent directory for all saved data
Path* inodesPath; // contains the actualy file/directory metadata
Path* dentriesPath; // contains the file/directory structural links
Path* buddyMirrorInodesPath; // contains the inodes for buddy mirrored inodes
Path* buddyMirrorDentriesPath; // contains the dentries for buddy mirrored dentries
DatagramListener* dgramListener;
ConnAcceptor* connAcceptor;
StatsCollector* statsCollector;
InternodeSyncer* internodeSyncer;
ModificationEventFlusher* modificationEventFlusher;
TimerQueue* timerQueue;
TimerQueue* gcQueue;
unsigned numStreamListeners; // value copied from cfg (for performance)
StreamLisVec streamLisVec;
WorkerList workerList;
WorkerList commSlaveList; // used by workers for parallel comm tasks
BuddyResyncer* buddyResyncer;
ExceededQuotaPerTarget exceededQuotaStores;
std::unique_ptr<FileEventLogger, decltype(&destroyFileEventLogger)> fileEventLogger { nullptr, &destroyFileEventLogger };
unsigned nextNumaBindTarget; // the numa node to which we will bind the next component thread
void runNormal();
void streamListenersInit();
void streamListenersStart();
void streamListenersStop();
void streamListenersDelete();
void streamListenersJoin();
void workersInit();
void workersStart();
void workersStop();
void workersDelete();
void workersJoin();
void commSlavesInit();
void commSlavesStart();
void commSlavesStop();
void commSlavesDelete();
void commSlavesJoin();
void initLogging();
void initDataObjects();
void initBasicNetwork();
void initLocalNodeIDs(NumNodeID& outLocalNumID);
void initLocalNode(NumNodeID localNodeNumID);
void initLocalNodeNumIDFile(NumNodeID localNodeNumID);
bool preinitStorage();
void checkTargetUUID();
void initStorage();
void initXAttrLimit();
void initRootDir(NumNodeID localNodeNumID);
void initDisposalDir();
void initComponents(TargetConsistencyState initialConsistencyState);
void startComponents();
void joinComponents();
bool waitForMgmtNode();
bool preregisterNode(NumNodeID& outLocalNodeNumID);
bool downloadMgmtInfo(TargetConsistencyState& outInitialConsistencyState);
void logInfos();
void daemonize();
void registerSignalHandler();
static void signalHandler(int sig);
bool restoreSessions();
bool storeSessions();
bool deleteSessionFiles();
public:
// inliners
/**
* @return NULL for invalid node types
*/
NodeStoreServers* getServerStoreFromType(NodeType nodeType) const
{
switch(nodeType)
{
case NODETYPE_Meta:
return metaNodes;
case NODETYPE_Storage:
return storageNodes;
case NODETYPE_Mgmt:
return mgmtNodes;
default:
return NULL;
}
}
/**
* @return NULL for invalid node types
*/
AbstractNodeStore* getAbstractNodeStoreFromType(NodeType nodeType) const
{
switch(nodeType)
{
case NODETYPE_Meta:
return metaNodes;
case NODETYPE_Storage:
return storageNodes;
case NODETYPE_Client:
return clientNodes;
case NODETYPE_Mgmt:
return mgmtNodes;
default:
return NULL;
}
}
/**
* Get one of the available stream listeners based on the socket file descriptor number.
* This is to load-balance the sockets over all available stream listeners and ensure that
* sockets are not bouncing between different stream listeners.
*
* Note that IB connections eat two fd numbers, so 2 and multiples of 2 might not be a good
* value for number of stream listeners.
*/
virtual StreamListenerV2* getStreamListenerByFD(int fd) override
{
return streamLisVec[fd % numStreamListeners];
}
// getters & setters
virtual const ICommonConfig* getCommonConfig() const override
{
return cfg;
}
virtual const NetFilter* getNetFilter() const override
{
return netFilter;
}
virtual const NetFilter* getTcpOnlyFilter() const override
{
return tcpOnlyFilter;
}
virtual const AbstractNetMessageFactory* getNetMessageFactory() const override
{
return netMessageFactory;
}
AcknowledgmentStore* getAckStore() const
{
return ackStore;
}
Config* getConfig() const
{
return cfg;
}
void updateLocalNicList(NicAddressList& localNicList);
/*
* this is just a convenience wrapper for now; old code used to have the localNodeNumID as a
* member of App, but localNodeNumID and the numID in localNode are duplicates
*/
NumNodeID getLocalNodeNumID() const
{
return localNode->getNumID();
}
Node& getLocalNode() const
{
return *localNode;
}
NodeStoreServers* getMgmtNodes() const
{
return mgmtNodes;
}
NodeStoreServers* getMetaNodes() const
{
return metaNodes;
}
NodeStoreServers* getStorageNodes() const
{
return storageNodes;
}
NodeStoreClients* getClientNodes() const
{
return clientNodes;
}
NodeCapacityPools* getMetaCapacityPools() const
{
return metaCapacityPools;
}
TargetMapper* getTargetMapper() const
{
return targetMapper;
}
MirrorBuddyGroupMapper* getStorageBuddyGroupMapper() const
{
return storageBuddyGroupMapper;
}
MirrorBuddyGroupMapper* getMetaBuddyGroupMapper() const
{
return metaBuddyGroupMapper;
}
TargetStateStore* getTargetStateStore() const
{
return targetStateStore;
}
TargetStateStore* getMetaStateStore() const
{
return metaStateStore;
}
NodeCapacityPools* getMetaBuddyCapacityPools() const
{
return metaBuddyCapacityPools;
}
MultiWorkQueue* getWorkQueue() const
{
return workQueue;
}
MultiWorkQueue* getCommSlaveQueue() const
{
return commSlaveQueue;
}
MetaStore* getMetaStore() const
{
return metaStore;
}
DirInode* getRootDir() const
{
return rootDir;
}
DirInode* getDisposalDir() const
{
return disposalDir;
}
DirInode* getBuddyMirrorDisposalDir() const
{
return buddyMirrorDisposalDir;
}
SessionStore* getSessions() const
{
return sessions;
}
SessionStore* getMirroredSessions() const
{
return mirroredSessions;
}
std::string getMetaPath() const
{
return metaPathStr;
}
MetaNodeOpStats* getNodeOpStats() const
{
return nodeOperationStats;
}
const Path* getInodesPath() const
{
return inodesPath;
}
const Path* getDentriesPath() const
{
return dentriesPath;
}
const Path* getBuddyMirrorInodesPath() const
{
return buddyMirrorInodesPath;
}
const Path* getBuddyMirrorDentriesPath() const
{
return buddyMirrorDentriesPath;
}
DatagramListener* getDatagramListener() const
{
return dgramListener;
}
const StreamLisVec* getStreamListenerVec() const
{
return &streamLisVec;
}
StatsCollector* getStatsCollector() const
{
return statsCollector;
}
InternodeSyncer* getInternodeSyncer() const
{
return internodeSyncer;
}
TimerQueue* getTimerQueue() const
{
return timerQueue;
}
TimerQueue* getGcQueue() const
{
return gcQueue;
}
ModificationEventFlusher* getModificationEventFlusher() const
{
return modificationEventFlusher;
}
WorkerList* getWorkers()
{
return &workerList;
}
BuddyResyncer* getBuddyResyncer()
{
return this->buddyResyncer;
}
int getAppResult() const
{
return appResult;
}
const ExceededQuotaPerTarget* getExceededQuotaStores() const
{
return &exceededQuotaStores;
}
StoragePoolStore* getStoragePoolStore() const
{
return storagePoolStore.get();
}
FileEventLogger* getFileEventLogger()
{
return fileEventLogger.get();
}
const RootInfo& getMetaRoot() const { return metaRoot; }
RootInfo& getMetaRoot() { return metaRoot; }
void findAllowedInterfaces(NicAddressList& outList) const;
void findAllowedRDMAInterfaces(NicAddressList& outList) const;
};

View File

@@ -0,0 +1,326 @@
#include <common/nodes/TargetCapacityPools.h>
#include <common/system/System.h>
#include <common/toolkit/StringTk.h>
#include <common/toolkit/UnitTk.h>
#include "Config.h"
#define CONFIG_DEFAULT_CFGFILENAME "/etc/beegfs/beegfs-meta.conf"
#define TARGETCHOOSERTYPE_RANDOMIZED_STR "randomized"
#define TARGETCHOOSERTYPE_ROUNDROBIN_STR "roundrobin"
#define TARGETCHOOSERTYPE_RANDOMROBIN_STR "randomrobin"
#define TARGETCHOOSERTYPE_RANDOMINTERNODE_STR "randominternode"
#define TARGETCHOOSERTYPE_RANDOMINTRANODE_STR "randomintranode"
Config::Config(int argc, char** argv):
AbstractConfig(argc, argv)
{
sysTargetAttachmentMap = NULL;
initConfig(argc, argv, true);
}
Config::~Config()
{
SAFE_DELETE(sysTargetAttachmentMap);
}
/**
* Sets the default values for each configurable in the configMap.
*
* @param addDashes currently unused
*/
void Config::loadDefaults(bool addDashes)
{
AbstractConfig::loadDefaults();
// re-definitions
configMapRedefine("cfgFile", "");
configMapRedefine("connMaxInternodeNum", "16");
// own definitions
configMapRedefine("connInterfacesFile", "");
configMapRedefine("connInterfacesList", "");
configMapRedefine("storeMetaDirectory", "");
configMapRedefine("storeFsUUID", "");
configMapRedefine("storeAllowFirstRunInit", "true");
configMapRedefine("storeUseExtendedAttribs", "true");
configMapRedefine("storeSelfHealEmptyFiles", "true");
configMapRedefine("storeClientXAttrs", "false");
configMapRedefine("storeClientACLs", "false");
configMapRedefine("sysTargetAttachmentFile", "");
configMapRedefine("tuneNumStreamListeners", "1");
configMapRedefine("tuneNumWorkers", "0");
configMapRedefine("tuneWorkerBufSize", "1m");
configMapRedefine("tuneNumCommSlaves", "0");
configMapRedefine("tuneCommSlaveBufSize", "1m");
configMapRedefine("tuneDefaultChunkSize", "512k");
configMapRedefine("tuneDefaultNumStripeTargets","4");
configMapRedefine("tuneProcessFDLimit", "50000");
configMapRedefine("tuneWorkerNumaAffinity", "false");
configMapRedefine("tuneListenerNumaAffinity", "false");
configMapRedefine("tuneBindToNumaZone", "");
configMapRedefine("tuneListenerPrioShift", "-1");
configMapRedefine("tuneDirMetadataCacheLimit", "1024");
configMapRedefine("tuneTargetChooser", TARGETCHOOSERTYPE_RANDOMIZED_STR);
configMapRedefine("tuneLockGrantWaitMS", "333");
configMapRedefine("tuneLockGrantNumRetries", "15");
configMapRedefine("tuneRotateMirrorTargets", "false");
configMapRedefine("tuneEarlyUnlinkResponse", "true");
configMapRedefine("tuneUsePerUserMsgQueues", "false");
configMapRedefine("tuneUseAggressiveStreamPoll","false");
configMapRedefine("tuneNumResyncSlaves", "12");
configMapRedefine("tuneMirrorTimestamps", "true");
configMapRedefine("tuneDisposalGCPeriod", "0");
configMapRedefine("quotaEarlyChownResponse", "true");
configMapRedefine("quotaEnableEnforcement", "false");
configMapRedefine("sysTargetOfflineTimeoutSecs","180");
configMapRedefine("sysAllowUserSetPattern", "false");
configMapRedefine("sysFileEventLogTarget", "");
configMapRedefine("sysFileEventPersistDirectory", "");
configMapRedefine("sysFileEventPersistSize", "0");
configMapRedefine("runDaemonized", "false");
configMapRedefine("pidFile", "");
}
/**
* @param addDashes currently usused
*/
void Config::applyConfigMap(bool enableException, bool addDashes)
{
AbstractConfig::applyConfigMap(false);
for (StringMapIter iter = configMap.begin(); iter != configMap.end();)
{
bool unknownElement = false;
if (iter->first == std::string("logType"))
{
if (iter->second == "syslog")
{
logType = LogType_SYSLOG;
}
else if (iter->second == "logfile")
{
logType = LogType_LOGFILE;
}
else
{
throw InvalidConfigException("The value of config argument logType is invalid.");
}
}
else if (iter->first == std::string("connInterfacesFile"))
connInterfacesFile = iter->second;
else if (iter->first == std::string("connInterfacesList"))
connInterfacesList = iter->second;
else if (iter->first == std::string("storeMetaDirectory"))
storeMetaDirectory = iter->second;
else if (iter->first == std::string("storeFsUUID"))
storeFsUUID = iter->second;
else if (iter->first == std::string("storeAllowFirstRunInit"))
storeAllowFirstRunInit = StringTk::strToBool(iter->second);
else if (iter->first == std::string("storeUseExtendedAttribs"))
storeUseExtendedAttribs = StringTk::strToBool(iter->second);
else if (iter->first == std::string("storeSelfHealEmptyFiles"))
storeSelfHealEmptyFiles = StringTk::strToBool(iter->second);
else if (iter->first == std::string("storeClientXAttrs"))
storeClientXAttrs = StringTk::strToBool(iter->second);
else if (iter->first == std::string("storeClientACLs"))
storeClientACLs = StringTk::strToBool(iter->second);
else if (iter->first == std::string("sysTargetAttachmentFile"))
sysTargetAttachmentFile = iter->second;
else if (iter->first == std::string("tuneNumStreamListeners"))
tuneNumStreamListeners = StringTk::strToUInt(iter->second);
else if (iter->first == std::string("tuneNumWorkers"))
tuneNumWorkers = StringTk::strToUInt(iter->second);
else if (iter->first == std::string("tuneWorkerBufSize"))
tuneWorkerBufSize = UnitTk::strHumanToInt64(iter->second);
else if (iter->first == std::string("tuneNumCommSlaves"))
tuneNumCommSlaves = StringTk::strToUInt(iter->second);
else if (iter->first == std::string("tuneCommSlaveBufSize"))
tuneCommSlaveBufSize = UnitTk::strHumanToInt64(iter->second);
else if (iter->first == std::string("tuneDefaultChunkSize"))
tuneDefaultChunkSize = UnitTk::strHumanToInt64(iter->second);
else if (iter->first == std::string("tuneDefaultNumStripeNodes")) // old "...Nodes" kept for compat
tuneDefaultNumStripeTargets = StringTk::strToUInt(iter->second);
else if (iter->first == std::string("tuneDefaultNumStripeTargets"))
tuneDefaultNumStripeTargets = StringTk::strToUInt(iter->second);
else if (iter->first == std::string("tuneProcessFDLimit"))
tuneProcessFDLimit = StringTk::strToUInt(iter->second);
else if (iter->first == std::string("tuneWorkerNumaAffinity"))
tuneWorkerNumaAffinity = StringTk::strToBool(iter->second);
else if (iter->first == std::string("tuneListenerNumaAffinity"))
tuneListenerNumaAffinity = StringTk::strToBool(iter->second);
else if (iter->first == std::string("tuneBindToNumaZone"))
{
if (iter->second.empty()) // not defined => disable
tuneBindToNumaZone = -1; // -1 means disable binding
else
tuneBindToNumaZone = StringTk::strToInt(iter->second);
}
else if (iter->first == std::string("tuneListenerPrioShift"))
tuneListenerPrioShift = StringTk::strToInt(iter->second);
else if (iter->first == std::string("tuneDirMetadataCacheLimit"))
tuneDirMetadataCacheLimit = StringTk::strToUInt(iter->second);
else if (iter->first == std::string("tuneTargetChooser"))
tuneTargetChooser = iter->second;
else if (iter->first == std::string("tuneLockGrantWaitMS"))
tuneLockGrantWaitMS = StringTk::strToUInt(iter->second);
else if (iter->first == std::string("tuneLockGrantNumRetries"))
tuneLockGrantNumRetries = StringTk::strToUInt(iter->second);
else if (iter->first == std::string("tuneRotateMirrorTargets"))
tuneRotateMirrorTargets = StringTk::strToBool(iter->second);
else if (iter->first == std::string("tuneEarlyUnlinkResponse"))
tuneEarlyUnlinkResponse = StringTk::strToBool(iter->second);
else if (iter->first == std::string("tuneUseAggressiveStreamPoll"))
tuneUseAggressiveStreamPoll = StringTk::strToBool(iter->second);
else if (iter->first == std::string("tuneNumResyncSlaves"))
this->tuneNumResyncSlaves = StringTk::strToUInt(iter->second);
else if (iter->first == std::string("quotaEarlyChownResponse"))
quotaEarlyChownResponse = StringTk::strToBool(iter->second);
else if (iter->first == std::string("quotaEnableEnforcement"))
quotaEnableEnforcement = StringTk::strToBool(iter->second);
else if (iter->first == std::string("sysTargetOfflineTimeoutSecs"))
{
sysTargetOfflineTimeoutSecs = StringTk::strToUInt(iter->second);
if (sysTargetOfflineTimeoutSecs < 30)
{
throw InvalidConfigException("Invalid sysTargetOfflineTimeoutSecs value "
+ iter->second + " (must be at least 30)");
}
}
else if (iter->first == std::string("sysAllowUserSetPattern"))
sysAllowUserSetPattern = StringTk::strToBool(iter->second.c_str());
else if (iter->first == std::string("tuneUsePerUserMsgQueues"))
tuneUsePerUserMsgQueues = StringTk::strToBool(iter->second);
else if (iter->first == std::string("tuneMirrorTimestamps"))
tuneMirrorTimestamps = StringTk::strToBool(iter->second);
else if(iter->first == std::string("tuneDisposalGCPeriod"))
tuneDisposalGCPeriod = StringTk::strToUInt(iter->second);
else if (iter->first == std::string("sysFileEventLogTarget"))
sysFileEventLogTarget = iter->second;
else if (iter->first == std::string("sysFileEventPersistDirectory"))
sysFileEventPersistDirectory = iter->second;
else if (iter->first == std::string("sysFileEventPersistSize"))
sysFileEventPersistSize = UnitTk::strHumanToInt64(iter->second);
else if (iter->first == std::string("runDaemonized"))
runDaemonized = StringTk::strToBool(iter->second);
else if (iter->first == std::string("pidFile"))
pidFile = iter->second;
else
{
// unknown element occurred
unknownElement = true;
if (enableException)
{
throw InvalidConfigException("The config argument '" + iter->first + "' is invalid");
}
}
if (unknownElement)
{
// just skip the unknown element
iter++;
}
else
{
// remove this element from the map
iter = eraseFromConfigMap(iter);
}
}
}
void Config::initImplicitVals()
{
// tuneNumWorkers (note: twice the number of cpu cores is default, but at least 4)
if(!tuneNumWorkers)
tuneNumWorkers = BEEGFS_MAX(System::getNumOnlineCPUs()*2, 4);
// tuneNumCommSlaves
if(!tuneNumCommSlaves)
tuneNumCommSlaves = tuneNumWorkers * 2;
// tuneTargetChooserNum
initTuneTargetChooserNum();
// connInterfacesList(/File)
AbstractConfig::initInterfacesList(connInterfacesFile, connInterfacesList);
AbstractConfig::initSocketBufferSizes();
// connAuthHash
AbstractConfig::initConnAuthHash(connAuthFile, &connAuthHash);
// sysTargetAttachmentMap
initSysTargetAttachmentMap();
}
void Config::initSysTargetAttachmentMap()
{
if(sysTargetAttachmentFile.empty() )
return; // no file given => nothing to do here
// check if file exists
if(!StorageTk::pathExists(sysTargetAttachmentFile) )
throw InvalidConfigException("sysTargetAttachmentFile not found: " +
sysTargetAttachmentFile);
// load as string map
StringMap attachmentStrMap;
MapTk::loadStringMapFromFile(sysTargetAttachmentFile.c_str(), &attachmentStrMap);
// convert from string map to target map
sysTargetAttachmentMap = new TargetMap();
for(StringMapCIter iter = attachmentStrMap.begin(); iter != attachmentStrMap.end(); iter++)
{
(*sysTargetAttachmentMap)[StringTk::strToUInt(iter->first)] =
NumNodeID(StringTk::strToUInt(iter->second) );
}
}
void Config::initTuneTargetChooserNum()
{
if (this->tuneTargetChooser == TARGETCHOOSERTYPE_RANDOMIZED_STR)
this->tuneTargetChooserNum = TargetChooserType_RANDOMIZED;
else if (this->tuneTargetChooser == TARGETCHOOSERTYPE_ROUNDROBIN_STR)
this->tuneTargetChooserNum = TargetChooserType_ROUNDROBIN;
else if (this->tuneTargetChooser == TARGETCHOOSERTYPE_RANDOMROBIN_STR)
this->tuneTargetChooserNum = TargetChooserType_RANDOMROBIN;
else if (this->tuneTargetChooser == TARGETCHOOSERTYPE_RANDOMINTERNODE_STR)
this->tuneTargetChooserNum = TargetChooserType_RANDOMINTERNODE;
// Don't allow RANDOMINTRANODE Target Chooser
else
{
// invalid chooser specified
throw InvalidConfigException("Invalid storage target chooser specified: "
+ tuneTargetChooser);
}
}
std::string Config::createDefaultCfgFilename() const
{
struct stat statBuf;
const int statRes = stat(CONFIG_DEFAULT_CFGFILENAME, &statBuf);
if(!statRes && S_ISREG(statBuf.st_mode) )
return CONFIG_DEFAULT_CFGFILENAME; // there appears to be a config file
return ""; // no default file otherwise
}

View File

@@ -0,0 +1,294 @@
#pragma once
#include <common/app/config/AbstractConfig.h>
#include <common/nodes/TargetCapacityPools.h>
enum TargetChooserType
{
TargetChooserType_RANDOMIZED = 0,
TargetChooserType_ROUNDROBIN = 1, // round-robin in ID order
TargetChooserType_RANDOMROBIN = 2, // randomized round-robin (round-robin, but shuffle result)
TargetChooserType_RANDOMINTERNODE = 3, // select random targets from different nodes/domains
TargetChooserType_RANDOMINTRANODE = 4, // select random targets from the same node/domain
};
class Config : public AbstractConfig
{
public:
Config(int argc, char** argv);
virtual ~Config();
private:
// configurables
std::string connInterfacesFile; // implicitly generates connInterfacesList
std::string connInterfacesList; // comma-separated list
std::string storeMetaDirectory;
std::string storeFsUUID;
bool storeAllowFirstRunInit;
bool storeUseExtendedAttribs;
bool storeSelfHealEmptyFiles;
bool storeClientXAttrs;
bool storeClientACLs;
std::string sysTargetAttachmentFile; // used by randominternode target chooser
TargetMap* sysTargetAttachmentMap; /* implicitly by sysTargetAttachmentFile, NULL if
unset */
unsigned tuneNumStreamListeners;
unsigned tuneNumWorkers; // 0 means automatic
unsigned tuneWorkerBufSize;
unsigned tuneNumCommSlaves; // 0 means automatic
unsigned tuneCommSlaveBufSize;
unsigned tuneDefaultChunkSize;
unsigned tuneDefaultNumStripeTargets;
unsigned tuneProcessFDLimit; // 0 means "don't touch limit"
bool tuneWorkerNumaAffinity;
bool tuneListenerNumaAffinity;
int tuneBindToNumaZone; // bind all threads to this zone, -1 means no binding
int tuneListenerPrioShift; // inc/dec thread priority of listener components
unsigned tuneDirMetadataCacheLimit;
std::string tuneTargetChooser;
TargetChooserType tuneTargetChooserNum; // auto-generated based on tuneTargetChooser
unsigned tuneLockGrantWaitMS; // time to wait for an ack per retry
unsigned tuneLockGrantNumRetries; // number of lock grant send retries until ack recv
bool tuneRotateMirrorTargets; // true to use rotated targets list as mirrors
bool tuneEarlyUnlinkResponse; // true to send response before chunk files unlink
bool tuneUsePerUserMsgQueues; // true to use UserWorkContainer for MultiWorkQueue
bool tuneUseAggressiveStreamPoll; // true to not sleep on epoll in streamlisv2
unsigned tuneNumResyncSlaves;
bool tuneMirrorTimestamps;
unsigned tuneDisposalGCPeriod; // sleep between disposal garbage collector runs [seconds], 0 = disabled
bool quotaEarlyChownResponse; // true to send response before chunk files chown
bool quotaEnableEnforcement;
unsigned sysTargetOfflineTimeoutSecs;
bool sysAllowUserSetPattern;
bool runDaemonized;
std::string pidFile;
bool limitXAttrListLength;
std::string sysFileEventLogTarget;
std::string sysFileEventPersistDirectory;
int64_t sysFileEventPersistSize;
// internals
virtual void loadDefaults(bool addDashes) override;
virtual void applyConfigMap(bool enableException, bool addDashes) override;
virtual void initImplicitVals() override;
void initSysTargetAttachmentMap();
void initTuneTargetChooserNum();
std::string createDefaultCfgFilename() const;
public:
// getters & setters
const std::string& getConnInterfacesList() const
{
return connInterfacesList;
}
const std::string& getStoreMetaDirectory() const
{
return storeMetaDirectory;
}
const std::string& getStoreFsUUID() const
{
return storeFsUUID;
}
bool getStoreAllowFirstRunInit() const
{
return storeAllowFirstRunInit;
}
bool getStoreUseExtendedAttribs() const
{
return storeUseExtendedAttribs;
}
bool getStoreSelfHealEmptyFiles() const
{
return storeSelfHealEmptyFiles;
}
bool getStoreClientXAttrs() const
{
return storeClientXAttrs;
}
bool getStoreClientACLs() const
{
return storeClientACLs;
}
const std::string& getSysTargetAttachmentFile() const
{
return sysTargetAttachmentFile;
}
const TargetMap* getSysTargetAttachmentMap() const
{
return sysTargetAttachmentMap;
}
unsigned getTuneNumStreamListeners() const
{
return tuneNumStreamListeners;
}
unsigned getTuneNumWorkers() const
{
return tuneNumWorkers;
}
unsigned getTuneWorkerBufSize() const
{
return tuneWorkerBufSize;
}
unsigned getTuneNumCommSlaves() const
{
return tuneNumCommSlaves;
}
unsigned getTuneCommSlaveBufSize() const
{
return tuneCommSlaveBufSize;
}
unsigned getTuneDefaultChunkSize() const
{
return tuneDefaultChunkSize;
}
unsigned getTuneDefaultNumStripeTargets() const
{
return tuneDefaultNumStripeTargets;
}
unsigned getTuneProcessFDLimit() const
{
return tuneProcessFDLimit;
}
bool getTuneWorkerNumaAffinity() const
{
return tuneWorkerNumaAffinity;
}
bool getTuneListenerNumaAffinity() const
{
return tuneListenerNumaAffinity;
}
int getTuneBindToNumaZone() const
{
return tuneBindToNumaZone;
}
int getTuneListenerPrioShift() const
{
return tuneListenerPrioShift;
}
unsigned getTuneDirMetadataCacheLimit() const
{
return tuneDirMetadataCacheLimit;
}
TargetChooserType getTuneTargetChooserNum() const
{
return tuneTargetChooserNum;
}
unsigned getTuneLockGrantWaitMS() const
{
return tuneLockGrantWaitMS;
}
unsigned getTuneLockGrantNumRetries() const
{
return tuneLockGrantNumRetries;
}
bool getTuneRotateMirrorTargets() const
{
return tuneRotateMirrorTargets;
}
bool getTuneEarlyUnlinkResponse() const
{
return tuneEarlyUnlinkResponse;
}
bool getTuneUsePerUserMsgQueues() const
{
return tuneUsePerUserMsgQueues;
}
bool getTuneUseAggressiveStreamPoll() const
{
return tuneUseAggressiveStreamPoll;
}
unsigned getTuneNumResyncSlaves() const
{
return tuneNumResyncSlaves;
}
bool getQuotaEarlyChownResponse() const
{
return quotaEarlyChownResponse;
}
bool getQuotaEnableEnforcement() const
{
return quotaEnableEnforcement;
}
void setQuotaEnableEnforcement(bool doQuotaEnforcement)
{
quotaEnableEnforcement = doQuotaEnforcement;
}
unsigned getSysTargetOfflineTimeoutSecs() const
{
return sysTargetOfflineTimeoutSecs;
}
bool getRunDaemonized() const
{
return runDaemonized;
}
const std::string& getPIDFile() const
{
return pidFile;
}
bool getTuneMirrorTimestamps() const { return tuneMirrorTimestamps; }
unsigned getTuneDisposalGCPeriod() const { return tuneDisposalGCPeriod; }
bool getSysAllowUserSetPattern() const { return sysAllowUserSetPattern; }
bool getLimitXAttrListLength() const { return limitXAttrListLength; }
void setLimitXAttrListLength(bool value) { limitXAttrListLength = value; }
const std::string& getFileEventLogTarget() const { return sysFileEventLogTarget; }
const std::string& getFileEventPersistDirectory() const { return sysFileEventPersistDirectory; }
uint64_t getFileEventPersistSize() const { return sysFileEventPersistSize; }
};