New upstream version 8.1.0
This commit is contained in:
428
storage/source/net/message/nodes/GenericDebugMsgEx.cpp
Normal file
428
storage/source/net/message/nodes/GenericDebugMsgEx.cpp
Normal file
@@ -0,0 +1,428 @@
|
||||
#include <common/net/message/nodes/GenericDebugRespMsg.h>
|
||||
#include <common/net/msghelpers/MsgHelperGenericDebug.h>
|
||||
#include <common/storage/quota/Quota.h>
|
||||
#include <common/storage/StoragePoolId.h>
|
||||
#include <common/toolkit/MessagingTk.h>
|
||||
#include <program/Program.h>
|
||||
#include <session/ZfsSession.h>
|
||||
#include <toolkit/QuotaTk.h>
|
||||
#include "GenericDebugMsgEx.h"
|
||||
|
||||
|
||||
|
||||
#define GENDBGMSG_OP_LISTOPENFILES "listopenfiles"
|
||||
#define GENDBGMSG_OP_VERSION "version"
|
||||
#define GENDBGMSG_OP_MSGQUEUESTATS "msgqueuestats"
|
||||
#define GENDBGMSG_OP_RESYNCQUEUELEN "resyncqueuelen"
|
||||
#define GENDBGMSG_OP_CHUNKLOCKSTORESIZE "chunklockstoresize"
|
||||
#define GENDBGMSG_OP_CHUNKLOCKSTORECONTENTS "chunklockstore"
|
||||
#define GENDBGMSG_OP_SETREJECTIONRATE "setrejectionrate"
|
||||
|
||||
|
||||
bool GenericDebugMsgEx::processIncoming(ResponseContext& ctx)
|
||||
{
|
||||
LogContext log("GenericDebugMsg incoming");
|
||||
|
||||
LOG_DEBUG_CONTEXT(log, 5, std::string("Command string: ") + getCommandStr() );
|
||||
|
||||
std::string cmdRespStr = processCommand();
|
||||
|
||||
ctx.sendResponse(GenericDebugRespMsg(cmdRespStr.c_str() ) );
|
||||
|
||||
App* app = Program::getApp();
|
||||
app->getNodeOpStats()->updateNodeOp(ctx.getSocket()->getPeerIP(), StorageOpCounter_GENERICDEBUG,
|
||||
getMsgHeaderUserID() );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return command response string
|
||||
*/
|
||||
std::string GenericDebugMsgEx::processCommand()
|
||||
{
|
||||
App* app = Program::getApp();
|
||||
Config* cfg = app->getConfig();
|
||||
|
||||
std::string responseStr;
|
||||
std::string operation;
|
||||
|
||||
// load command string into a stream to allow us to use getline
|
||||
std::istringstream commandStream(getCommandStr() );
|
||||
|
||||
// get operation type from command string
|
||||
std::getline(commandStream, operation, ' ');
|
||||
|
||||
if(operation == GENDBGMSG_OP_LISTOPENFILES)
|
||||
responseStr = processOpListOpenFiles(commandStream);
|
||||
else
|
||||
if(operation == GENDBGMSG_OP_VERSION)
|
||||
responseStr = processOpVersion(commandStream);
|
||||
else
|
||||
if(operation == GENDBGMSG_OP_MSGQUEUESTATS)
|
||||
responseStr = processOpMsgQueueStats(commandStream);
|
||||
else
|
||||
if(operation == GENDBGMSG_OP_VARLOGMESSAGES)
|
||||
responseStr = MsgHelperGenericDebug::processOpVarLogMessages(commandStream);
|
||||
else
|
||||
if(operation == GENDBGMSG_OP_VARLOGKERNLOG)
|
||||
responseStr = MsgHelperGenericDebug::processOpVarLogKernLog(commandStream);
|
||||
else
|
||||
if(operation == GENDBGMSG_OP_FHGFSLOG)
|
||||
responseStr = MsgHelperGenericDebug::processOpFhgfsLog(commandStream);
|
||||
else
|
||||
if(operation == GENDBGMSG_OP_LOADAVG)
|
||||
responseStr = MsgHelperGenericDebug::processOpLoadAvg(commandStream);
|
||||
else
|
||||
if(operation == GENDBGMSG_OP_DROPCACHES)
|
||||
responseStr = MsgHelperGenericDebug::processOpDropCaches(commandStream);
|
||||
else
|
||||
if(operation == GENDBGMSG_OP_GETCFG)
|
||||
responseStr = MsgHelperGenericDebug::processOpCfgFile(commandStream, cfg->getCfgFile() );
|
||||
else
|
||||
if(operation == GENDBGMSG_OP_GETLOGLEVEL)
|
||||
responseStr = MsgHelperGenericDebug::processOpGetLogLevel(commandStream);
|
||||
else
|
||||
if(operation == GENDBGMSG_OP_SETLOGLEVEL)
|
||||
responseStr = MsgHelperGenericDebug::processOpSetLogLevel(commandStream);
|
||||
else
|
||||
if(operation == GENDBGMSG_OP_NETOUT)
|
||||
responseStr = MsgHelperGenericDebug::processOpNetOut(commandStream,
|
||||
app->getMgmtNodes(), app->getMetaNodes(), app->getStorageNodes() );
|
||||
else
|
||||
if(operation == GENDBGMSG_OP_QUOTAEXCEEDED)
|
||||
responseStr = processOpQuotaExceeded(commandStream);
|
||||
else
|
||||
if(operation == GENDBGMSG_OP_USEDQUOTA)
|
||||
responseStr = processOpUsedQuota(commandStream);
|
||||
else
|
||||
if(operation == GENDBGMSG_OP_RESYNCQUEUELEN)
|
||||
responseStr = processOpResyncQueueLen(commandStream);
|
||||
else
|
||||
if(operation == GENDBGMSG_OP_CHUNKLOCKSTORESIZE)
|
||||
responseStr = processOpChunkLockStoreSize(commandStream);
|
||||
else
|
||||
if(operation == GENDBGMSG_OP_CHUNKLOCKSTORECONTENTS)
|
||||
responseStr = processOpChunkLockStoreContents(commandStream);
|
||||
else
|
||||
if(operation == GENDBGMSG_OP_LISTSTORAGESTATES)
|
||||
responseStr = MsgHelperGenericDebug::processOpListTargetStates(commandStream,
|
||||
app->getTargetStateStore() );
|
||||
else
|
||||
if(operation == GENDBGMSG_OP_SETREJECTIONRATE)
|
||||
responseStr = processOpSetRejectionRate(commandStream);
|
||||
else
|
||||
responseStr = "Unknown/invalid operation";
|
||||
|
||||
return responseStr;
|
||||
}
|
||||
|
||||
std::string GenericDebugMsgEx::processOpListOpenFiles(std::istringstream& commandStream)
|
||||
{
|
||||
// protocol: no arguments
|
||||
|
||||
App* app = Program::getApp();
|
||||
SessionStore* sessions = app->getSessions();
|
||||
|
||||
std::ostringstream responseStream;
|
||||
NumNodeIDList sessionIDs;
|
||||
size_t numFilesTotal = 0;
|
||||
size_t numCheckedSessions = 0; // may defer from number of initially queried sessions
|
||||
|
||||
size_t numSessions = sessions->getAllSessionIDs(&sessionIDs);
|
||||
|
||||
responseStream << "Found " << numSessions << " sessions." << std::endl;
|
||||
|
||||
responseStream << std::endl;
|
||||
|
||||
// walk over all sessions
|
||||
for(NumNodeIDListCIter iter = sessionIDs.begin(); iter != sessionIDs.end(); iter++)
|
||||
{
|
||||
// note: sessionID might have become removed since we queried it, e.g. because client is gone
|
||||
|
||||
auto session = sessions->referenceSession(*iter);
|
||||
if(!session)
|
||||
continue;
|
||||
|
||||
numCheckedSessions++;
|
||||
|
||||
SessionLocalFileStore* sessionFiles = session->getLocalFiles();
|
||||
|
||||
size_t numFiles = sessionFiles->getSize();
|
||||
|
||||
if(!numFiles)
|
||||
continue; // only print sessions with open files
|
||||
|
||||
numFilesTotal += numFiles;
|
||||
|
||||
responseStream << *iter << ": " << numFiles << std::endl;
|
||||
}
|
||||
|
||||
responseStream << std::endl;
|
||||
|
||||
responseStream << "Final results: " << numFilesTotal << " open files in " <<
|
||||
numCheckedSessions << " checked sessions";
|
||||
|
||||
return responseStream.str();
|
||||
}
|
||||
|
||||
std::string GenericDebugMsgEx::processOpVersion(std::istringstream& commandStream)
|
||||
{
|
||||
return BEEGFS_VERSION;
|
||||
}
|
||||
|
||||
std::string GenericDebugMsgEx::processOpMsgQueueStats(std::istringstream& commandStream)
|
||||
{
|
||||
// protocol: no arguments
|
||||
|
||||
App* app = Program::getApp();
|
||||
MultiWorkQueueMap* workQueueMap = app->getWorkQueueMap();
|
||||
|
||||
std::ostringstream responseStream;
|
||||
std::string indirectQueueStats;
|
||||
std::string directQueueStats;
|
||||
std::string busyStats;
|
||||
|
||||
for(MultiWorkQueueMapCIter iter = workQueueMap->begin(); iter != workQueueMap->end(); iter++)
|
||||
{
|
||||
MultiWorkQueue* workQ = iter->second;
|
||||
|
||||
workQ->getStatsAsStr(indirectQueueStats, directQueueStats, busyStats);
|
||||
|
||||
responseStream << "* [queue id " << iter->first << "] "
|
||||
"general queue stats: " << std::endl <<
|
||||
indirectQueueStats << std::endl;
|
||||
|
||||
responseStream << "* [queue id " << iter->first << "] "
|
||||
"direct queue stats: " << std::endl <<
|
||||
directQueueStats << std::endl;
|
||||
|
||||
responseStream << "* [queue id " << iter->first << "] "
|
||||
"busy worker stats: " << std::endl <<
|
||||
busyStats << std::endl;
|
||||
}
|
||||
|
||||
return responseStream.str();
|
||||
}
|
||||
|
||||
std::string GenericDebugMsgEx::processOpQuotaExceeded(std::istringstream& commandStream)
|
||||
{
|
||||
App* app = Program::getApp();
|
||||
|
||||
std::string targetIdStr;
|
||||
std::getline(commandStream, targetIdStr, ' ');
|
||||
uint16_t targetId = StringTk::strToUInt(targetIdStr);
|
||||
|
||||
if(!app->getConfig()->getQuotaEnableEnforcement() )
|
||||
return "No quota exceeded IDs on this storage daemon because quota enforcement is"
|
||||
"disabled.";
|
||||
|
||||
ExceededQuotaStorePtr exQuotaStore = app->getExceededQuotaStores()->get(targetId);
|
||||
// exQuotaStore may be null;needs to be checked in MsgHelperGenericDebug::processOpQuotaExceeded
|
||||
return MsgHelperGenericDebug::processOpQuotaExceeded(commandStream, exQuotaStore.get());
|
||||
}
|
||||
|
||||
std::string GenericDebugMsgEx::processOpUsedQuota(std::istringstream& commandStream)
|
||||
{
|
||||
App *app = Program::getApp();
|
||||
|
||||
std::ostringstream responseStream;
|
||||
|
||||
ZfsSession session;
|
||||
QuotaDataType quotaDataType = QuotaDataType_NONE;
|
||||
std::string quotaDataTypeStr;
|
||||
bool forEachTarget = false;
|
||||
unsigned rangeStart = 0;
|
||||
unsigned rangeEnd = 0;
|
||||
|
||||
// get parameter from command string
|
||||
std::string inputString;
|
||||
while(!commandStream.eof() )
|
||||
{
|
||||
std::getline(commandStream, inputString, ' ');
|
||||
|
||||
if(inputString == "uid")
|
||||
{
|
||||
quotaDataType = QuotaDataType_USER;
|
||||
quotaDataTypeStr = "user";
|
||||
}
|
||||
else
|
||||
if(inputString == "gid")
|
||||
{
|
||||
quotaDataType = QuotaDataType_GROUP;
|
||||
quotaDataTypeStr = "group";
|
||||
}
|
||||
else
|
||||
if(inputString == "forEachTarget")
|
||||
forEachTarget = true;
|
||||
else
|
||||
if(inputString == "range")
|
||||
{
|
||||
std::string rangeValue;
|
||||
std::getline(commandStream, rangeValue, ' ');
|
||||
rangeStart = StringTk::strToUInt(rangeValue);
|
||||
std::getline(commandStream, rangeValue, ' ');
|
||||
rangeEnd = StringTk::strToUInt(rangeValue);
|
||||
}
|
||||
}
|
||||
|
||||
// verify given parameters
|
||||
if(quotaDataType == QuotaDataType_NONE)
|
||||
return "Invalid or missing quota data type argument.";
|
||||
if(rangeStart == 0 && rangeEnd == 0)
|
||||
return "Invalid or missing range argument.";
|
||||
|
||||
|
||||
if(forEachTarget)
|
||||
{
|
||||
const auto& targets = app->getStorageTargets()->getTargets();
|
||||
|
||||
responseStream << "Quota data of " << targets.size() << " targets." << std::endl;
|
||||
|
||||
for (const auto& mapping : targets)
|
||||
{
|
||||
const auto& target = *mapping.second;
|
||||
|
||||
QuotaDataList outQuotaDataList;
|
||||
|
||||
QuotaBlockDeviceMap quotaBlockDevices = {
|
||||
{mapping.first, target.getQuotaBlockDevice()}
|
||||
};
|
||||
|
||||
QuotaTk::requestQuotaForRange("aBlockDevices, rangeStart, rangeEnd, quotaDataType,
|
||||
&outQuotaDataList, &session);
|
||||
|
||||
responseStream << outQuotaDataList.size() << " used quota for " << quotaDataTypeStr
|
||||
<< " IDs on target: " << mapping.first << std::endl;
|
||||
|
||||
QuotaData::quotaDataListToString(outQuotaDataList, &responseStream);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto& targets = app->getStorageTargets()->getTargets();
|
||||
|
||||
QuotaBlockDeviceMap quotaBlockDevices;
|
||||
|
||||
std::transform(
|
||||
targets.begin(), targets.end(),
|
||||
std::inserter(quotaBlockDevices, quotaBlockDevices.end()),
|
||||
[] (const auto& target) {
|
||||
return std::make_pair(target.first, target.second->getQuotaBlockDevice());
|
||||
});
|
||||
|
||||
QuotaDataList outQuotaDataList;
|
||||
|
||||
QuotaTk::requestQuotaForRange("aBlockDevices, rangeStart, rangeEnd, quotaDataType,
|
||||
&outQuotaDataList, &session);
|
||||
|
||||
QuotaData::quotaDataListToString(outQuotaDataList, &responseStream);
|
||||
}
|
||||
|
||||
return responseStream.str();
|
||||
}
|
||||
|
||||
|
||||
std::string GenericDebugMsgEx::processOpResyncQueueLen(std::istringstream& commandStream)
|
||||
{
|
||||
// protocol: targetID files/dirs as argument (e.g. "resyncqueuelen 1234 files")
|
||||
|
||||
// get parameter from command string
|
||||
std::string targetIDStr;
|
||||
uint16_t targetID;
|
||||
std::string typeStr;
|
||||
std::getline(commandStream, targetIDStr, ' ');
|
||||
std::getline(commandStream, typeStr, ' ');
|
||||
targetID = StringTk::strToUInt(targetIDStr);
|
||||
|
||||
if (targetID == 0)
|
||||
return "Invalid or missing targetID";
|
||||
|
||||
BuddyResyncJob* resyncJob = Program::getApp()->getBuddyResyncer()->getResyncJob(targetID);
|
||||
|
||||
if (!resyncJob)
|
||||
return "0";
|
||||
|
||||
if (typeStr == "files")
|
||||
{
|
||||
size_t count = resyncJob->syncCandidates.getNumFiles();
|
||||
return StringTk::uintToStr(count);
|
||||
}
|
||||
else
|
||||
if (typeStr == "dirs")
|
||||
{
|
||||
size_t count = resyncJob->syncCandidates.getNumDirs();
|
||||
return StringTk::uintToStr(count);
|
||||
}
|
||||
else
|
||||
return "Invalid or missing queue type";
|
||||
}
|
||||
|
||||
std::string GenericDebugMsgEx::processOpChunkLockStoreSize(std::istringstream& commandStream)
|
||||
{
|
||||
// protocol: targetID as argument (e.g. "chunklockstoresize 1234")
|
||||
|
||||
// get parameter from command string
|
||||
std::string targetIDStr;
|
||||
uint16_t targetID;
|
||||
std::getline(commandStream, targetIDStr, ' ');
|
||||
targetID = StringTk::strToUInt(targetIDStr);
|
||||
|
||||
if (targetID == 0)
|
||||
return "Invalid or missing targetID";
|
||||
|
||||
size_t lockStoreSize = Program::getApp()->getChunkLockStore()->getSize(targetID);
|
||||
|
||||
return StringTk::uintToStr(lockStoreSize);
|
||||
}
|
||||
|
||||
std::string GenericDebugMsgEx::processOpChunkLockStoreContents(std::istringstream& commandStream)
|
||||
{
|
||||
// protocol: targetID and size limit (optional) as argument (e.g. "chunklockstoresize 1234 50")
|
||||
std::stringstream outStream;
|
||||
|
||||
// get parameter from command string
|
||||
std::string targetIDStr;
|
||||
uint16_t targetID;
|
||||
std::string maxEntriesStr;
|
||||
unsigned maxEntries;
|
||||
std::getline(commandStream, targetIDStr, ' ');
|
||||
targetID = StringTk::strToUInt(targetIDStr);
|
||||
std::getline(commandStream, maxEntriesStr, ' ');
|
||||
maxEntries = StringTk::strToUInt(maxEntriesStr);
|
||||
|
||||
if (targetID == 0)
|
||||
return "Invalid or missing targetID";
|
||||
|
||||
StringSet lockStoreContents = Program::getApp()->getChunkLockStore()->getLockStoreCopy(targetID);
|
||||
unsigned lockStoreSize = lockStoreContents.size();
|
||||
StringSetIter lockStoreIter = lockStoreContents.begin();
|
||||
|
||||
if ( (maxEntries == 0) || (maxEntries > lockStoreSize) )
|
||||
maxEntries = lockStoreSize;
|
||||
|
||||
for (unsigned i = 0; i < maxEntries; i++)
|
||||
{
|
||||
outStream << *lockStoreIter << std::endl;
|
||||
lockStoreIter++;
|
||||
}
|
||||
|
||||
return outStream.str();
|
||||
}
|
||||
|
||||
std::string GenericDebugMsgEx::processOpSetRejectionRate(std::istringstream& commandStream)
|
||||
{
|
||||
App* app = Program::getApp();
|
||||
Config* cfg = app->getConfig();
|
||||
std::string rejectionRateStr;
|
||||
std::ostringstream responseStream;
|
||||
|
||||
std::getline(commandStream, rejectionRateStr, ' ');
|
||||
unsigned rejectionRate = StringTk::strToUInt(rejectionRateStr);
|
||||
|
||||
cfg->setConnectionRejectionRate(rejectionRate);
|
||||
|
||||
responseStream << "Setting connection reject rate to " << rejectionRate << std::endl;
|
||||
return responseStream.str();
|
||||
}
|
||||
|
||||
24
storage/source/net/message/nodes/GenericDebugMsgEx.h
Normal file
24
storage/source/net/message/nodes/GenericDebugMsgEx.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/net/message/nodes/GenericDebugMsg.h>
|
||||
|
||||
|
||||
class GenericDebugMsgEx : public GenericDebugMsg
|
||||
{
|
||||
public:
|
||||
virtual bool processIncoming(ResponseContext& ctx);
|
||||
|
||||
private:
|
||||
std::string processCommand();
|
||||
|
||||
std::string processOpListOpenFiles(std::istringstream& commandStream);
|
||||
std::string processOpVersion(std::istringstream& commandStream);
|
||||
std::string processOpMsgQueueStats(std::istringstream& commandStream);
|
||||
std::string processOpQuotaExceeded(std::istringstream& commandStream);
|
||||
std::string processOpUsedQuota(std::istringstream& commandStream);
|
||||
std::string processOpResyncQueueLen(std::istringstream& commandStream);
|
||||
std::string processOpChunkLockStoreSize(std::istringstream& commandStream);
|
||||
std::string processOpChunkLockStoreContents(std::istringstream& commandStream);
|
||||
std::string processOpSetRejectionRate(std::istringstream& commandStream);
|
||||
};
|
||||
|
||||
30
storage/source/net/message/nodes/GetClientStatsMsgEx.cpp
Normal file
30
storage/source/net/message/nodes/GetClientStatsMsgEx.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
#include <program/Program.h>
|
||||
#include <common/net/message/storage/GetHighResStatsRespMsg.h>
|
||||
#include <common/toolkit/MessagingTk.h>
|
||||
#include <common/nodes/OpCounter.h>
|
||||
#include "GetClientStatsMsgEx.h"
|
||||
#include <nodes/StorageNodeOpStats.h>
|
||||
#include <common/net/message/nodes/GetClientStatsRespMsg.h>
|
||||
|
||||
|
||||
/**
|
||||
* Server side, called when the server gets a GetClientStatsMsgEx request
|
||||
*/
|
||||
bool GetClientStatsMsgEx::processIncoming(ResponseContext& ctx)
|
||||
{
|
||||
uint64_t cookieIP = getCookieIP(); // requested is cookie+1
|
||||
|
||||
// get stats
|
||||
StorageNodeOpStats* clientOpStats = Program::getApp()->getNodeOpStats();
|
||||
|
||||
bool wantPerUserStats = isMsgHeaderFeatureFlagSet(GETCLIENTSTATSMSG_FLAG_PERUSERSTATS);
|
||||
UInt64Vector opStatsVec;
|
||||
|
||||
clientOpStats->mapToUInt64Vec(
|
||||
cookieIP, GETCLIENTSTATSRESP_MAX_PAYLOAD_LEN, wantPerUserStats, &opStatsVec);
|
||||
|
||||
ctx.sendResponse(GetClientStatsRespMsg(&opStatsVec) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
15
storage/source/net/message/nodes/GetClientStatsMsgEx.h
Normal file
15
storage/source/net/message/nodes/GetClientStatsMsgEx.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/storage/StorageErrors.h>
|
||||
#include <common/net/message/nodes/GetClientStatsMsg.h>
|
||||
|
||||
|
||||
// NOTE: The message factory requires this object to have 'deserialize' and
|
||||
// 'processIncoming' methods. 'deserialize' is derived from other classes.
|
||||
|
||||
class GetClientStatsMsgEx : public GetClientStatsMsg
|
||||
{
|
||||
public:
|
||||
virtual bool processIncoming(ResponseContext& ctx);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
#include <program/Program.h>
|
||||
#include <storage/StorageTargets.h>
|
||||
|
||||
#include <common/net/message/nodes/GetTargetConsistencyStatesRespMsg.h>
|
||||
|
||||
#include "GetTargetConsistencyStatesMsgEx.h"
|
||||
|
||||
bool GetTargetConsistencyStatesMsgEx::processIncoming(ResponseContext& ctx)
|
||||
{
|
||||
StorageTargets* storageTargets = Program::getApp()->getStorageTargets();
|
||||
|
||||
TargetConsistencyStateVec states;
|
||||
std::transform(
|
||||
targetIDs.begin(), targetIDs.end(),
|
||||
std::back_inserter(states),
|
||||
[storageTargets] (uint16_t targetID) {
|
||||
auto* const target = storageTargets->getTarget(targetID);
|
||||
return target ? target->getConsistencyState() : TargetConsistencyState_BAD;
|
||||
});
|
||||
|
||||
ctx.sendResponse(GetTargetConsistencyStatesRespMsg(states));
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/net/message/nodes/GetTargetConsistencyStatesMsg.h>
|
||||
|
||||
class GetTargetConsistencyStatesMsgEx : public GetTargetConsistencyStatesMsg
|
||||
{
|
||||
public:
|
||||
virtual bool processIncoming(ResponseContext& ctx);
|
||||
};
|
||||
|
||||
76
storage/source/net/message/nodes/HeartbeatMsgEx.cpp
Normal file
76
storage/source/net/message/nodes/HeartbeatMsgEx.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
#include <common/net/sock/NetworkInterfaceCard.h>
|
||||
#include <program/Program.h>
|
||||
#include "HeartbeatMsgEx.h"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
bool HeartbeatMsgEx::processIncoming(ResponseContext& ctx)
|
||||
{
|
||||
LogContext log("Heartbeat incoming");
|
||||
|
||||
App* app = Program::getApp();
|
||||
bool isNodeNew;
|
||||
|
||||
// construct node
|
||||
|
||||
NicAddressList& nicList = getNicList();
|
||||
|
||||
auto node = std::make_shared<Node>(getNodeType(), getNodeID(), getNodeNumID(), getPortUDP(),
|
||||
getPortTCP(), nicList);
|
||||
|
||||
// set local nic capabilities
|
||||
|
||||
NicAddressList localNicList(app->getLocalNicList() );
|
||||
NicListCapabilities localNicCaps;
|
||||
|
||||
NetworkInterfaceCard::supportedCapabilities(&localNicList, &localNicCaps);
|
||||
node->getConnPool()->setLocalNicList(localNicList, localNicCaps);
|
||||
|
||||
std::string nodeIDWithTypeStr = node->getNodeIDWithTypeStr();
|
||||
|
||||
log.log(Log_DEBUG, std::string("Heartbeat node: ") + nodeIDWithTypeStr);
|
||||
|
||||
// add/update node in store
|
||||
|
||||
AbstractNodeStore* nodes;
|
||||
|
||||
switch(getNodeType() )
|
||||
{
|
||||
case NODETYPE_Meta:
|
||||
nodes = app->getMetaNodes(); break;
|
||||
|
||||
case NODETYPE_Mgmt:
|
||||
nodes = app->getMgmtNodes(); break;
|
||||
|
||||
case NODETYPE_Storage:
|
||||
nodes = app->getStorageNodes(); break;
|
||||
|
||||
default:
|
||||
{
|
||||
log.logErr("Invalid/unexpected node type: "
|
||||
+ boost::lexical_cast<std::string>(getNodeType()));
|
||||
|
||||
goto ack_resp;
|
||||
} break;
|
||||
}
|
||||
|
||||
isNodeNew = (nodes->addOrUpdateNode(std::move(node)) == NodeStoreResult::Added);
|
||||
if(isNodeNew)
|
||||
{ // log info about new server
|
||||
bool supportsRDMA = NetworkInterfaceCard::supportsRDMA(&nicList);
|
||||
|
||||
log.log(Log_WARNING, std::string("New node: ") +
|
||||
nodeIDWithTypeStr + "; " +
|
||||
std::string(supportsRDMA ? "RDMA; " : "") );
|
||||
}
|
||||
|
||||
|
||||
ack_resp:
|
||||
acknowledge(ctx);
|
||||
|
||||
app->getNodeOpStats()->updateNodeOp(ctx.getSocket()->getPeerIP(), StorageOpCounter_HEARTBEAT,
|
||||
getMsgHeaderUserID() );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
10
storage/source/net/message/nodes/HeartbeatMsgEx.h
Normal file
10
storage/source/net/message/nodes/HeartbeatMsgEx.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/net/message/nodes/HeartbeatMsg.h>
|
||||
|
||||
class HeartbeatMsgEx : public HeartbeatMsg
|
||||
{
|
||||
public:
|
||||
virtual bool processIncoming(ResponseContext& ctx);
|
||||
};
|
||||
|
||||
28
storage/source/net/message/nodes/HeartbeatRequestMsgEx.cpp
Normal file
28
storage/source/net/message/nodes/HeartbeatRequestMsgEx.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#include <common/net/message/nodes/HeartbeatMsg.h>
|
||||
#include <common/toolkit/MessagingTk.h>
|
||||
#include <program/Program.h>
|
||||
#include "HeartbeatRequestMsgEx.h"
|
||||
|
||||
bool HeartbeatRequestMsgEx::processIncoming(ResponseContext& ctx)
|
||||
{
|
||||
LogContext log("Heartbeat request incoming");
|
||||
App* app = Program::getApp();
|
||||
Config* cfg = app->getConfig();
|
||||
|
||||
Node& localNode = app->getLocalNode();
|
||||
NumNodeID localNodeNumID = localNode.getNumID();
|
||||
NicAddressList nicList(localNode.getNicList() );
|
||||
|
||||
HeartbeatMsg hbMsg(localNode.getAlias(), localNodeNumID, NODETYPE_Storage, &nicList);
|
||||
hbMsg.setPorts(cfg->getConnStoragePort(), cfg->getConnStoragePort() );
|
||||
|
||||
ctx.sendResponse(hbMsg);
|
||||
|
||||
log.log(Log_DEBUG, std::string("Heartbeat req ip:") + StringTk::uintToHexStr(ctx.getSocket()->getPeerIP()));
|
||||
|
||||
app->getNodeOpStats()->updateNodeOp(ctx.getSocket()->getPeerIP(), StorageOpCounter_HEARTBEAT,
|
||||
getMsgHeaderUserID() );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
10
storage/source/net/message/nodes/HeartbeatRequestMsgEx.h
Normal file
10
storage/source/net/message/nodes/HeartbeatRequestMsgEx.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/net/message/nodes/HeartbeatRequestMsg.h>
|
||||
|
||||
class HeartbeatRequestMsgEx : public HeartbeatRequestMsg
|
||||
{
|
||||
public:
|
||||
virtual bool processIncoming(ResponseContext& ctx);
|
||||
};
|
||||
|
||||
44
storage/source/net/message/nodes/MapTargetsMsgEx.cpp
Normal file
44
storage/source/net/message/nodes/MapTargetsMsgEx.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#include <common/net/message/nodes/MapTargetsRespMsg.h>
|
||||
#include <common/toolkit/MessagingTk.h>
|
||||
#include <common/toolkit/ZipIterator.h>
|
||||
#include <program/Program.h>
|
||||
#include "MapTargetsMsgEx.h"
|
||||
|
||||
|
||||
bool MapTargetsMsgEx::processIncoming(ResponseContext& ctx)
|
||||
{
|
||||
LogContext log("MapTargetsMsg incoming");
|
||||
|
||||
const App* app = Program::getApp();
|
||||
const NodeStoreServers* storageNodes = app->getStorageNodes();
|
||||
TargetMapper* targetMapper = app->getTargetMapper();
|
||||
|
||||
const NumNodeID nodeID = getNodeID();
|
||||
std::map<uint16_t, FhgfsOpsErr> results;
|
||||
|
||||
for (const auto mapping : getTargets())
|
||||
{
|
||||
const auto targetId = mapping.first;
|
||||
const auto poolId = mapping.second;
|
||||
|
||||
const auto mapRes = targetMapper->mapTarget(targetId, nodeID, poolId);
|
||||
|
||||
results[targetId] = mapRes.first;
|
||||
|
||||
if ( (mapRes.first != FhgfsOpsErr_SUCCESS) && (mapRes.second) )
|
||||
{ // target could be mapped and is new
|
||||
LOG_DEBUG_CONTEXT(log, Log_WARNING, "Mapping "
|
||||
"target " + StringTk::uintToStr(targetId) +
|
||||
" => " +
|
||||
storageNodes->getNodeIDWithTypeStr(nodeID) );
|
||||
|
||||
IGNORE_UNUSED_VARIABLE(storageNodes);
|
||||
}
|
||||
}
|
||||
|
||||
if(!acknowledge(ctx) )
|
||||
ctx.sendResponse(MapTargetsRespMsg(results));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
11
storage/source/net/message/nodes/MapTargetsMsgEx.h
Normal file
11
storage/source/net/message/nodes/MapTargetsMsgEx.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/net/message/nodes/MapTargetsMsg.h>
|
||||
|
||||
class MapTargetsMsgEx : public MapTargetsMsg
|
||||
{
|
||||
public:
|
||||
virtual bool processIncoming(ResponseContext& ctx);
|
||||
};
|
||||
|
||||
|
||||
21
storage/source/net/message/nodes/PublishCapacitiesMsgEx.cpp
Normal file
21
storage/source/net/message/nodes/PublishCapacitiesMsgEx.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#include <common/toolkit/MessagingTk.h>
|
||||
#include <program/Program.h>
|
||||
|
||||
#include "PublishCapacitiesMsgEx.h"
|
||||
|
||||
|
||||
bool PublishCapacitiesMsgEx::processIncoming(ResponseContext& ctx)
|
||||
{
|
||||
App* app = Program::getApp();
|
||||
InternodeSyncer* syncer = app->getInternodeSyncer();
|
||||
|
||||
|
||||
// force upload of capacity information
|
||||
syncer->setForcePublishCapacities();
|
||||
|
||||
// send response
|
||||
acknowledge(ctx);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
12
storage/source/net/message/nodes/PublishCapacitiesMsgEx.h
Normal file
12
storage/source/net/message/nodes/PublishCapacitiesMsgEx.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/net/message/nodes/PublishCapacitiesMsg.h>
|
||||
|
||||
|
||||
class PublishCapacitiesMsgEx : public PublishCapacitiesMsg
|
||||
{
|
||||
public:
|
||||
virtual bool processIncoming(ResponseContext& ctx);
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
#include <common/toolkit/MessagingTk.h>
|
||||
#include <program/Program.h>
|
||||
|
||||
#include "RefreshTargetStatesMsgEx.h"
|
||||
|
||||
|
||||
bool RefreshTargetStatesMsgEx::processIncoming(ResponseContext& ctx)
|
||||
{
|
||||
App* app = Program::getApp();
|
||||
InternodeSyncer* syncer = app->getInternodeSyncer();
|
||||
|
||||
|
||||
// force update of capacity pools
|
||||
syncer->setForceTargetStatesUpdate();
|
||||
|
||||
// send response
|
||||
acknowledge(ctx);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
11
storage/source/net/message/nodes/RefreshTargetStatesMsgEx.h
Normal file
11
storage/source/net/message/nodes/RefreshTargetStatesMsgEx.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/net/message/nodes/RefreshTargetStatesMsg.h>
|
||||
|
||||
|
||||
class RefreshTargetStatesMsgEx : public RefreshTargetStatesMsg
|
||||
{
|
||||
public:
|
||||
virtual bool processIncoming(ResponseContext& ctx);
|
||||
};
|
||||
|
||||
124
storage/source/net/message/nodes/RemoveBuddyGroupMsgEx.cpp
Normal file
124
storage/source/net/message/nodes/RemoveBuddyGroupMsgEx.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
#include "RemoveBuddyGroupMsgEx.h"
|
||||
|
||||
#include <common/net/message/nodes/RemoveBuddyGroupRespMsg.h>
|
||||
#include <net/message/storage/listing/ListChunkDirIncrementalMsgEx.h>
|
||||
#include <program/Program.h>
|
||||
|
||||
static FhgfsOpsErr checkChunkDirRemovable(const int dirFD)
|
||||
{
|
||||
DIR* dir = fdopendir(dirFD);
|
||||
std::unique_ptr<DIR, StorageTk::CloseDirDeleter> _dir(dir);
|
||||
|
||||
while (true)
|
||||
{
|
||||
struct dirent* result;
|
||||
|
||||
#if USE_READDIR_R
|
||||
struct dirent buffer;
|
||||
if (readdir_r(dir, &buffer, &result) != 0)
|
||||
break;
|
||||
#else
|
||||
errno = 0;
|
||||
result = readdir(dir);
|
||||
if (!result && errno)
|
||||
break;
|
||||
#endif
|
||||
|
||||
if (!result)
|
||||
return FhgfsOpsErr_SUCCESS;
|
||||
|
||||
if (strcmp(result->d_name, ".") == 0 || strcmp(result->d_name, "..") == 0)
|
||||
continue;
|
||||
|
||||
struct stat statData;
|
||||
|
||||
const int statRes = ::fstatat(dirfd(dir), result->d_name, &statData, AT_SYMLINK_NOFOLLOW);
|
||||
if (statRes != 0)
|
||||
{
|
||||
LOG(MIRRORING, ERR, "Could not stat something in chunk directory.");
|
||||
return FhgfsOpsErr_INTERNAL;
|
||||
}
|
||||
|
||||
if (!S_ISDIR(statData.st_mode))
|
||||
return FhgfsOpsErr_NOTEMPTY;
|
||||
|
||||
const int subdir = ::openat(dirfd(dir), result->d_name, O_RDONLY);
|
||||
if (subdir < 0)
|
||||
{
|
||||
LOG(MIRRORING, ERR, "Could not open directory in chunk path.");
|
||||
return FhgfsOpsErr_INTERNAL;
|
||||
}
|
||||
|
||||
const FhgfsOpsErr checkRes = checkChunkDirRemovable(subdir);
|
||||
if (checkRes != FhgfsOpsErr_SUCCESS)
|
||||
return checkRes;
|
||||
}
|
||||
|
||||
return FhgfsOpsErr_INTERNAL;
|
||||
}
|
||||
|
||||
bool RemoveBuddyGroupMsgEx::processIncoming(ResponseContext& ctx)
|
||||
{
|
||||
App* app = Program::getApp();
|
||||
|
||||
if (type != NODETYPE_Storage)
|
||||
{
|
||||
ctx.sendResponse(RemoveBuddyGroupRespMsg(FhgfsOpsErr_INTERNAL));
|
||||
return true;
|
||||
}
|
||||
|
||||
uint16_t targetID = app->getMirrorBuddyGroupMapper()->getPrimaryTargetID(groupID);
|
||||
if (app->getTargetMapper()->getNodeID(targetID) != app->getLocalNode().getNumID())
|
||||
targetID = app->getMirrorBuddyGroupMapper()->getSecondaryTargetID(groupID);
|
||||
if (app->getTargetMapper()->getNodeID(targetID) != app->getLocalNode().getNumID())
|
||||
{
|
||||
LOG(MIRRORING, ERR, "Group is not mapped on this target.", groupID);
|
||||
ctx.sendResponse(RemoveBuddyGroupRespMsg(FhgfsOpsErr_INTERNAL));
|
||||
return true;
|
||||
}
|
||||
|
||||
auto* const target = app->getStorageTargets()->getTarget(targetID);
|
||||
if (!target)
|
||||
{
|
||||
LOG(MIRRORING, ERR, "Could not open directory file descriptor.", groupID);
|
||||
ctx.sendResponse(RemoveBuddyGroupRespMsg(FhgfsOpsErr_INTERNAL));
|
||||
return true;
|
||||
}
|
||||
|
||||
const int dirFD = openat(*target->getMirrorFD(), ".", O_RDONLY);
|
||||
if (dirFD < 0)
|
||||
{
|
||||
LOG(MIRRORING, ERR, "Could not open directory file descriptor.", groupID);
|
||||
ctx.sendResponse(RemoveBuddyGroupRespMsg(FhgfsOpsErr_INTERNAL));
|
||||
return true;
|
||||
}
|
||||
|
||||
const FhgfsOpsErr checkRes = checkChunkDirRemovable(dirFD);
|
||||
|
||||
const bool forceAndNotEmpty = checkRes == FhgfsOpsErr_NOTEMPTY && force;
|
||||
|
||||
if (checkRes == FhgfsOpsErr_SUCCESS || forceAndNotEmpty)
|
||||
{
|
||||
if (!checkOnly)
|
||||
{
|
||||
auto* const bgm = Program::getApp()->getMirrorBuddyGroupMapper();
|
||||
const NumNodeID localID = Program::getApp()->getLocalNode().getNumID();
|
||||
|
||||
if (!bgm->unmapMirrorBuddyGroup(groupID, localID))
|
||||
{
|
||||
ctx.sendResponse(RemoveBuddyGroupRespMsg(FhgfsOpsErr_INTERNAL));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
ctx.sendResponse(RemoveBuddyGroupRespMsg(FhgfsOpsErr_SUCCESS));
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx.sendResponse(RemoveBuddyGroupRespMsg(checkRes));
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
10
storage/source/net/message/nodes/RemoveBuddyGroupMsgEx.h
Normal file
10
storage/source/net/message/nodes/RemoveBuddyGroupMsgEx.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/net/message/nodes/RemoveBuddyGroupMsg.h>
|
||||
|
||||
class RemoveBuddyGroupMsgEx : public RemoveBuddyGroupMsg
|
||||
{
|
||||
public:
|
||||
virtual bool processIncoming(ResponseContext& ctx);
|
||||
};
|
||||
|
||||
37
storage/source/net/message/nodes/RemoveNodeMsgEx.cpp
Normal file
37
storage/source/net/message/nodes/RemoveNodeMsgEx.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
#include <common/net/message/nodes/RemoveNodeRespMsg.h>
|
||||
#include <common/toolkit/MessagingTk.h>
|
||||
#include <program/Program.h>
|
||||
#include "RemoveNodeMsgEx.h"
|
||||
|
||||
|
||||
bool RemoveNodeMsgEx::processIncoming(ResponseContext& ctx)
|
||||
{
|
||||
App* app = Program::getApp();
|
||||
|
||||
LOG_DBG(GENERAL, SPAM, "Removing node.", getNodeNumID());
|
||||
|
||||
if (getNodeType() == NODETYPE_Storage)
|
||||
{
|
||||
NodeStoreServers* nodes = app->getStorageNodes();
|
||||
auto node = nodes->referenceNode(getNodeNumID());
|
||||
bool delRes = nodes->deleteNode(getNodeNumID());
|
||||
|
||||
// log
|
||||
if (delRes)
|
||||
{
|
||||
LOG(GENERAL, WARNING, "Node removed.", ("node", node->getNodeIDWithTypeStr()));
|
||||
LOG(GENERAL, WARNING, "Number of nodes in the system:",
|
||||
("meta", app->getMetaNodes()->getSize()),
|
||||
("storage", app->getStorageNodes()->getSize()));
|
||||
}
|
||||
}
|
||||
|
||||
if (!acknowledge(ctx))
|
||||
ctx.sendResponse(RemoveNodeRespMsg(0));
|
||||
|
||||
app->getNodeOpStats()->updateNodeOp(ctx.getSocket()->getPeerIP(), StorageOpCounter_REMOVENODE,
|
||||
getMsgHeaderUserID() );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
11
storage/source/net/message/nodes/RemoveNodeMsgEx.h
Normal file
11
storage/source/net/message/nodes/RemoveNodeMsgEx.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/net/message/nodes/RemoveNodeMsg.h>
|
||||
|
||||
class RemoveNodeMsgEx : public RemoveNodeMsg
|
||||
{
|
||||
public:
|
||||
virtual bool processIncoming(ResponseContext& ctx);
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
#include <common/net/message/nodes/SetMirrorBuddyGroupRespMsg.h>
|
||||
#include <common/nodes/MirrorBuddyGroupMapper.h>
|
||||
#include <common/toolkit/MessagingTk.h>
|
||||
|
||||
#include <program/Program.h>
|
||||
|
||||
#include "SetMirrorBuddyGroupMsgEx.h"
|
||||
|
||||
bool SetMirrorBuddyGroupMsgEx::processIncoming(ResponseContext& ctx)
|
||||
{
|
||||
uint16_t buddyGroupID = this->getBuddyGroupID();
|
||||
|
||||
if (getNodeType() != NODETYPE_Storage)
|
||||
{
|
||||
// The storage server has no mapper for meta buddy groups - nothing to do, just acknowledge
|
||||
if (!acknowledge(ctx))
|
||||
ctx.sendResponse(SetMirrorBuddyGroupRespMsg(FhgfsOpsErr_SUCCESS, buddyGroupID));
|
||||
return true;
|
||||
}
|
||||
|
||||
App* app = Program::getApp();
|
||||
MirrorBuddyGroupMapper* buddyGroupMapper = app->getMirrorBuddyGroupMapper();
|
||||
|
||||
uint16_t primaryTargetID = this->getPrimaryTargetID();
|
||||
uint16_t secondaryTargetID = this->getSecondaryTargetID();
|
||||
bool allowUpdate = this->getAllowUpdate();
|
||||
uint16_t newBuddyGroupID = 0;
|
||||
|
||||
FhgfsOpsErr mapResult = buddyGroupMapper->mapMirrorBuddyGroup(buddyGroupID, primaryTargetID,
|
||||
secondaryTargetID, app->getLocalNode().getNumID(), allowUpdate, &newBuddyGroupID);
|
||||
|
||||
if(!acknowledge(ctx) )
|
||||
ctx.sendResponse(SetMirrorBuddyGroupRespMsg(mapResult, newBuddyGroupID) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
11
storage/source/net/message/nodes/SetMirrorBuddyGroupMsgEx.h
Normal file
11
storage/source/net/message/nodes/SetMirrorBuddyGroupMsgEx.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/net/message/nodes/SetMirrorBuddyGroupMsg.h>
|
||||
|
||||
class SetMirrorBuddyGroupMsgEx : public SetMirrorBuddyGroupMsg
|
||||
{
|
||||
public:
|
||||
virtual bool processIncoming(ResponseContext& ctx);
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
#include <common/net/message/nodes/SetTargetConsistencyStatesRespMsg.h>
|
||||
#include <common/nodes/TargetStateStore.h>
|
||||
#include <common/toolkit/ZipIterator.h>
|
||||
#include <program/Program.h>
|
||||
|
||||
#include "SetTargetConsistencyStatesMsgEx.h"
|
||||
|
||||
bool SetTargetConsistencyStatesMsgEx::processIncoming(ResponseContext& ctx)
|
||||
{
|
||||
App* app = Program::getApp();
|
||||
StorageTargets* storageTargets = app->getStorageTargets();
|
||||
FhgfsOpsErr result = FhgfsOpsErr_SUCCESS;
|
||||
|
||||
if (getTargetIDs().size() != getStates().size())
|
||||
{
|
||||
LogContext(__func__).logErr("Different list size of targetIDs and states");
|
||||
result = FhgfsOpsErr_INTERNAL;
|
||||
goto send_response;
|
||||
}
|
||||
|
||||
for (ZipIterRange<UInt16List, UInt8List> idStateIter(getTargetIDs(), getStates());
|
||||
!idStateIter.empty(); ++idStateIter)
|
||||
{
|
||||
auto* const target = storageTargets->getTarget(*idStateIter()->first);
|
||||
if (!target)
|
||||
{
|
||||
LogContext(__func__).logErr("Unknown targetID: " +
|
||||
StringTk::uintToStr(*(idStateIter()->first) ) );
|
||||
result = FhgfsOpsErr_UNKNOWNTARGET;
|
||||
goto send_response;
|
||||
}
|
||||
|
||||
target->setState(TargetConsistencyState(*idStateIter()->second));
|
||||
}
|
||||
|
||||
send_response:
|
||||
ctx.sendResponse(SetTargetConsistencyStatesRespMsg(result) );
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/net/message/nodes/SetTargetConsistencyStatesMsg.h>
|
||||
|
||||
class SetTargetConsistencyStatesMsgEx : public SetTargetConsistencyStatesMsg
|
||||
{
|
||||
public:
|
||||
virtual bool processIncoming(ResponseContext& ctx);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
#include <app/App.h>
|
||||
#include <common/net/message/nodes/StorageBenchControlMsgResp.h>
|
||||
#include <components/benchmarker/StorageBenchOperator.h>
|
||||
#include <program/Program.h>
|
||||
#include "StorageBenchControlMsgEx.h"
|
||||
|
||||
bool StorageBenchControlMsgEx::processIncoming(ResponseContext& ctx)
|
||||
{
|
||||
const char* logContext = "StorageBenchControlMsg incoming";
|
||||
|
||||
StorageBenchResultsMap results;
|
||||
int cmdErrorCode = STORAGEBENCH_ERROR_NO_ERROR;
|
||||
|
||||
App* app = Program::getApp();
|
||||
StorageBenchOperator* storageBench = app->getStorageBenchOperator();
|
||||
|
||||
switch(getAction())
|
||||
{
|
||||
case StorageBenchAction_START:
|
||||
{
|
||||
cmdErrorCode = storageBench->initAndStartStorageBench(&getTargetIDs(), getBlocksize(),
|
||||
getSize(), getThreads(), getODirect(), getType() );
|
||||
} break;
|
||||
|
||||
case StorageBenchAction_STOP:
|
||||
{
|
||||
cmdErrorCode = storageBench->stopBenchmark();
|
||||
} break;
|
||||
|
||||
case StorageBenchAction_STATUS:
|
||||
{
|
||||
storageBench->getStatusWithResults(&getTargetIDs(), &results);
|
||||
cmdErrorCode = STORAGEBENCH_ERROR_NO_ERROR;
|
||||
} break;
|
||||
|
||||
case StorageBenchAction_CLEANUP:
|
||||
{
|
||||
cmdErrorCode = storageBench->cleanup(&getTargetIDs());
|
||||
} break;
|
||||
|
||||
default:
|
||||
{
|
||||
LogContext(logContext).logErr("unknown action!");
|
||||
} break;
|
||||
}
|
||||
|
||||
int errorCode;
|
||||
|
||||
// check if the last command from the fhgfs_cmd was successful,
|
||||
// if not send the error code of the command to the fhgfs_cmd
|
||||
// if it was successful, send the error code of the last run or acutely run of the benchmark
|
||||
if (cmdErrorCode != STORAGEBENCH_ERROR_NO_ERROR)
|
||||
{
|
||||
errorCode = cmdErrorCode;
|
||||
}
|
||||
else
|
||||
{
|
||||
errorCode = storageBench->getLastRunErrorCode();
|
||||
}
|
||||
|
||||
ctx.sendResponse(
|
||||
StorageBenchControlMsgResp(storageBench->getStatus(), getAction(),
|
||||
storageBench->getType(), errorCode, results) );
|
||||
|
||||
return true;
|
||||
}
|
||||
11
storage/source/net/message/nodes/StorageBenchControlMsgEx.h
Normal file
11
storage/source/net/message/nodes/StorageBenchControlMsgEx.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/net/message/nodes/StorageBenchControlMsg.h>
|
||||
#include <common/Common.h>
|
||||
|
||||
class StorageBenchControlMsgEx: public StorageBenchControlMsg
|
||||
{
|
||||
public:
|
||||
virtual bool processIncoming(ResponseContext& ctx);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
#include "RefreshStoragePoolsMsgEx.h"
|
||||
|
||||
#include <program/Program.h>
|
||||
|
||||
bool RefreshStoragePoolsMsgEx::processIncoming(ResponseContext& ctx)
|
||||
{
|
||||
Program::getApp()->getInternodeSyncer()->setForceStoragePoolsUpdate();
|
||||
|
||||
// can only come as an AcknowledgableMsg from mgmtd
|
||||
acknowledge(ctx);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/net/message/nodes/storagepools/RefreshStoragePoolsMsg.h>
|
||||
|
||||
class RefreshStoragePoolsMsgEx : public RefreshStoragePoolsMsg
|
||||
{
|
||||
public:
|
||||
virtual bool processIncoming(ResponseContext& ctx);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user