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

View File

@@ -0,0 +1,900 @@
#include <common/net/message/nodes/GenericDebugRespMsg.h>
#include <common/net/msghelpers/MsgHelperGenericDebug.h>
#include <common/storage/quota/Quota.h>
#include <common/toolkit/MessagingTk.h>
#include <program/Program.h>
#include <session/SessionStore.h>
#include "GenericDebugMsgEx.h"
#define GENDBGMSG_OP_LISTFILEAPPENDLOCKS "listfileappendlocks"
#define GENDBGMSG_OP_LISTFILEENTRYLOCKS "listfileentrylocks"
#define GENDBGMSG_OP_LISTFILERANGELOCKS "listfilerangelocks"
#define GENDBGMSG_OP_LISTOPENFILES "listopenfiles"
#define GENDBGMSG_OP_REFERENCESTATISTICS "refstats"
#define GENDBGMSG_OP_CACHESTATISTICS "cachestats"
#define GENDBGMSG_OP_VERSION "version"
#define GENDBGMSG_OP_MSGQUEUESTATS "msgqueuestats"
#define GENDBGMSG_OP_LISTPOOLS "listpools"
#define GENDBGMSG_OP_DUMPDENTRY "dumpdentry"
#define GENDBGMSG_OP_DUMPINODE "dumpinode"
#define GENDBGMSG_OP_DUMPINLINEDINODE "dumpinlinedinode"
#ifdef BEEGFS_DEBUG
#define GENDBGMSG_OP_WRITEDIRDENTRY "writedirdentry"
#define GENDBGMSG_OP_WRITEDIRINODE "writedirinode"
#define GENDBGMSG_OP_WRITEFILEINODE "writefileinode"
#endif // BEEGFS_DEBUG
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() ) );
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_LISTFILEAPPENDLOCKS)
responseStr = processOpListFileAppendLocks(commandStream);
else
if(operation == GENDBGMSG_OP_LISTFILEENTRYLOCKS)
responseStr = processOpListFileEntryLocks(commandStream);
else
if(operation == GENDBGMSG_OP_LISTFILERANGELOCKS)
responseStr = processOpListFileRangeLocks(commandStream);
else
if(operation == GENDBGMSG_OP_LISTOPENFILES)
responseStr = processOpListOpenFiles(commandStream);
else
if(operation == GENDBGMSG_OP_REFERENCESTATISTICS)
responseStr = processOpReferenceStatistics(commandStream);
else
if(operation == GENDBGMSG_OP_CACHESTATISTICS)
responseStr = processOpCacheStatistics(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_LISTMETASTATES)
responseStr = MsgHelperGenericDebug::processOpListTargetStates(commandStream,
app->getMetaStateStore() );
else
if(operation == GENDBGMSG_OP_LISTSTORAGESTATES)
responseStr = MsgHelperGenericDebug::processOpListTargetStates(commandStream,
app->getTargetStateStore() );
else
if(operation == GENDBGMSG_OP_LISTPOOLS)
responseStr = processOpListPools(commandStream);
else
if(operation == GENDBGMSG_OP_DUMPDENTRY)
responseStr = processOpDumpDentry(commandStream);
else
if(operation == GENDBGMSG_OP_DUMPINODE)
responseStr = processOpDumpInode(commandStream);
else
if(operation == GENDBGMSG_OP_DUMPINLINEDINODE)
responseStr = processOpDumpInlinedInode(commandStream);
else
if(operation == GENDBGMSG_OP_QUOTAEXCEEDED)
responseStr = processOpQuotaExceeded(commandStream);
else if(operation == GENDBGMSG_OP_LISTSTORAGEPOOLS)
responseStr = MsgHelperGenericDebug::processOpListStoragePools(commandStream,
app->getStoragePoolStore());
#ifdef BEEGFS_DEBUG
else
if(operation == GENDBGMSG_OP_WRITEDIRDENTRY)
responseStr = processOpWriteDirDentry(commandStream);
else
if(operation == GENDBGMSG_OP_WRITEDIRINODE)
responseStr = processOpWriteDirInode(commandStream);
else
if(operation == GENDBGMSG_OP_WRITEFILEINODE)
responseStr = processOpWriteInlinedFileInode(commandStream);
#endif // BEEGFS_DEBUG
else
responseStr = "Unknown/invalid operation";
return responseStr;
}
/**
* Retrieve append lock stats for a certain file.
*/
std::string GenericDebugMsgEx::processOpListFileAppendLocks(std::istringstream& commandStream)
{
// procotol: entryID as only argument
std::string parentEntryID;
std::string entryID;
std::string responseStr;
std::string isBuddyMirroredStr;
bool isBuddyMirrored;
// get entryID from command string
std::getline(commandStream, parentEntryID, ' ');
std::getline(commandStream, entryID, ' ');
std::getline(commandStream, isBuddyMirroredStr, ' ');
if (parentEntryID.empty() )
return "Invalid or missing parentEntryID";
if(entryID.empty() )
return "Invalid or missing entryID";
if(isBuddyMirroredStr.empty())
isBuddyMirrored = false;
else
isBuddyMirrored = StringTk::strToBool(isBuddyMirroredStr);
MetaStore* metaStore = Program::getApp()->getMetaStore();
MetaFileHandle inode = metaStore->referenceLoadedFile(parentEntryID, isBuddyMirrored, entryID);
if(!inode)
return "FileID not exists: " + entryID;
responseStr = inode->flockAppendGetAllAsStr();
metaStore->releaseFile(parentEntryID, inode);
return responseStr;
}
std::string GenericDebugMsgEx::processOpListFileEntryLocks(std::istringstream& commandStream)
{
// procotol: entryID as only argument
std::string parentEntryID;
std::string entryID;
std::string responseStr;
std::string isBuddyMirroredStr;
bool isBuddyMirrored;
// get entryID from command string
std::getline(commandStream, parentEntryID, ' ');
std::getline(commandStream, entryID, ' ');
std::getline(commandStream, isBuddyMirroredStr, ' ');
if (parentEntryID.empty() )
return "Invalid or missing parentEntryID";
if(entryID.empty() )
return "Invalid or missing entryID";
if(isBuddyMirroredStr.empty())
isBuddyMirrored = false;
else
isBuddyMirrored = StringTk::strToBool(isBuddyMirroredStr);
MetaStore* metaStore = Program::getApp()->getMetaStore();
MetaFileHandle inode = metaStore->referenceLoadedFile(parentEntryID, isBuddyMirrored, entryID);
if(!inode)
return "FileID not exists: " + entryID;
responseStr = inode->flockEntryGetAllAsStr();
metaStore->releaseFile(parentEntryID, inode);
return responseStr;
}
std::string GenericDebugMsgEx::processOpListFileRangeLocks(std::istringstream& commandStream)
{
// procotol: entryID as only argument
std::string parentEntryID;
std::string entryID;
std::string isBuddyMirroredStr;
bool isBuddyMirrored;
// get parentEntryID from command string
std::getline(commandStream, parentEntryID, ' ');
if(parentEntryID.empty() )
return "Invalid or missing parentEntryID";
// get entryID from command string
std::getline(commandStream, entryID, ' ');
if(entryID.empty() )
return "Invalid or missing entryID";
// get isBuddyMirrored from command string
std::getline(commandStream, isBuddyMirroredStr, ' ');
if(isBuddyMirroredStr.empty())
isBuddyMirrored = false;
else
isBuddyMirrored = StringTk::strToBool(isBuddyMirroredStr);
MetaStore* metaStore = Program::getApp()->getMetaStore();
MetaFileHandle file = metaStore->referenceLoadedFile(parentEntryID, isBuddyMirrored, entryID);
if(!file)
return "FileID not found: " + entryID;
std::string responseStr = file->flockRangeGetAllAsStr();
metaStore->releaseFile(parentEntryID, file);
return responseStr;
}
std::string GenericDebugMsgEx::processOpListOpenFiles(std::istringstream& commandStream)
{
// protocol: no arguments
App* app = Program::getApp();
SessionStore* sessions = app->getSessions();
SessionStore* mirroredSessions = app->getMirroredSessions();
std::ostringstream responseStream;
size_t numFilesTotal = 0;
size_t numCheckedSessions = 0; // may defer from number of initially queried sessions
NumNodeIDList sessionIDs = sessions->getAllSessionIDs();
NumNodeIDList mirroredSessionIDs = mirroredSessions->getAllSessionIDs();
responseStream << "Found " << sessionIDs.size() << " non-mirrored sessions and "
<< mirroredSessionIDs.size() << " mirrored sessions." << std::endl;
responseStream << std::endl;
responseStream << "Non-mirrored sessions:" << std::endl;
// walk over all sessions
for(NumNodeIDListCIter iter = sessionIDs.begin(); iter != sessionIDs.end(); iter++)
{
Session* session = sessions->referenceSession(*iter, false);
// note: sessionID might have been removed since we queried it, e.g. because client is gone
if(!session)
continue;
numCheckedSessions++;
SessionFileStore* sessionFiles = session->getFiles();
size_t numFiles = sessionFiles->getSize();
sessions->releaseSession(session);
if(!numFiles)
continue; // only print sessions with open files
numFilesTotal += numFiles;
responseStream << *iter << ": " << numFiles << std::endl;
}
responseStream << "Mirrored sessions:" << std::endl;
// ...and the mirrored sessions
for(NumNodeIDListCIter iter = mirroredSessionIDs.begin(); iter != mirroredSessionIDs.end();
++iter)
{
Session* session = mirroredSessions->referenceSession(*iter, false);
if (!session)
continue;
numCheckedSessions++;
SessionFileStore* sessionFiles = session->getFiles();
size_t numFiles = sessionFiles->getSize();
mirroredSessions->releaseSession(session);
if (!numFiles)
continue;
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::processOpReferenceStatistics(std::istringstream& commandStream)
{
// protocol: no arguments
App* app = Program::getApp();
MetaStore* metaStore = app->getMetaStore();
std::ostringstream responseStream;
size_t numDirs;
size_t numFiles;
metaStore->getReferenceStats(&numDirs, &numFiles);
responseStream << "Dirs: " << numDirs << std::endl;
responseStream << "Files: " << numFiles;
return responseStream.str();
}
std::string GenericDebugMsgEx::processOpCacheStatistics(std::istringstream& commandStream)
{
// protocol: no arguments
App* app = Program::getApp();
MetaStore* metaStore = app->getMetaStore();
std::ostringstream responseStream;
size_t numDirs;
metaStore->getCacheStats(&numDirs);
responseStream << "Dirs: " << numDirs;
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();
MultiWorkQueue* workQ = app->getWorkQueue();
std::ostringstream responseStream;
std::string indirectQueueStats;
std::string directQueueStats;
std::string busyStats;
workQ->getStatsAsStr(indirectQueueStats, directQueueStats, busyStats);
responseStream << "general queue stats: " << std::endl <<
indirectQueueStats << std::endl;
responseStream << "direct queue stats: " << std::endl <<
directQueueStats << std::endl;
responseStream << "busy worker stats: " << std::endl <<
busyStats << std::endl;
return responseStream.str();
}
/**
* List internal state of meta and storage capacity pools.
*/
std::string GenericDebugMsgEx::processOpListPools(std::istringstream& commandStream)
{
// protocol: no arguments
const App* app = Program::getApp();
const NodeCapacityPools* metaPools = app->getMetaCapacityPools();
std::ostringstream responseStream;
responseStream << "META POOLS STATE: " << std::endl << metaPools->getStateAsStr() << std::endl;
const StoragePoolPtrVec storagePools = app->getStoragePoolStore()->getPoolsAsVec();
for (auto iter = storagePools.begin(); iter != storagePools.end(); iter++)
{
const TargetCapacityPools* capPool = (*iter)->getTargetCapacityPools();
responseStream << "STORAGE CAPACITY POOLS STATE (STORAGE POOL ID: " << (*iter)->getId()
<< "): " << std::endl << capPool->getStateAsStr() << std::endl;
}
for (auto iter = storagePools.begin(); iter != storagePools.end(); iter++)
{
const NodeCapacityPools* capPool = (*iter)->getBuddyCapacityPools();
responseStream << "STORAGE BUDDY CAPACITY POOLS STATE (STORAGE POOL ID: "
<< (*iter)->getId() << "): " << std::endl << capPool->getStateAsStr()
<< std::endl;
}
return responseStream.str();
}
std::string GenericDebugMsgEx::processOpDumpDentry(std::istringstream& commandStream)
{
MetaStore* metaStore = Program::getApp()->getMetaStore();
std::ostringstream responseStream;
StringList parameterList;
StringTk::explode(commandStream.str(), ' ', &parameterList);
if ( parameterList.size() < 3 || parameterList.size() > 4 )
return "Invalid or missing parameters; Parameter format: parentDirID entryName "
"[isBuddyMirrored]";
StringListIter iter = parameterList.begin();
iter++;
std::string parentDirID = *iter;
iter++;
std::string entryName = *iter;
iter++;
bool isBuddyMirrored = false;
if (iter != parameterList.end())
{
isBuddyMirrored = StringTk::strToBool(*iter);
}
DirInode* parentDirInode = metaStore->referenceDir(parentDirID, isBuddyMirrored, false);
if (!parentDirInode)
return "Unable to reference parent directory.";
DirEntry dentry(entryName);
bool getDentryRes = parentDirInode->getDentry(entryName, dentry);
metaStore->releaseDir(parentDirID);
if (!getDentryRes)
return "Unable to get dentry from parent directory.";
responseStream << "entryType: " << dentry.getEntryType() << std::endl;
responseStream << "ID: " << dentry.getID() << std::endl;
responseStream << "ownerNodeID: " << dentry.getOwnerNodeID() << std::endl;
responseStream << "featureFlags: " << dentry.getDentryFeatureFlags() << std::endl;
return responseStream.str();
}
#ifdef BEEGFS_DEBUG
std::string GenericDebugMsgEx::processOpWriteDirDentry(std::istringstream& commandStream)
{
MetaStore* metaStore = Program::getApp()->getMetaStore();
std::string dentriesPath = Program::getApp()->getDentriesPath()->str();
std::ostringstream responseStream;
StringList parameterList;
StringTk::explode(commandStream.str(), ' ', &parameterList);
if ( parameterList.size() < 4 || parameterList.size() > 5 )
return "Invalid or missing parameters; Parameter format: parentDirID entryName ownerNodeID "
"[isBuddyMirrored]";
StringListIter iter = parameterList.begin();
iter++;
std::string parentDirID = *iter;
iter++;
std::string entryName = *iter;
iter++;
NumNodeID ownerNodeID(StringTk::strToUInt(*iter) );
iter++;
bool isBuddyMirrored = false;
if (iter!=parameterList.end())
{
isBuddyMirrored = StringTk::strToBool(*iter);
}
DirInode* parentDirInode = metaStore->referenceDir(parentDirID, isBuddyMirrored, true);
if (!parentDirInode)
return "Unable to reference parent directory.";
DirEntry dentry(entryName);
bool getDentryRes = parentDirInode->getDentry(entryName, dentry);
metaStore->releaseDir(parentDirID);
if (!getDentryRes)
return "Unable to get dentry from parent directory.";
bool setOwnerRes = dentry.setOwnerNodeID(
MetaStorageTk::getMetaDirEntryPath(dentriesPath, parentDirID), ownerNodeID);
if (!setOwnerRes)
return "Unable to set new owner node ID in dentry.";
return "OK";
}
#endif // BEEGFS_DEBUG
std::string GenericDebugMsgEx::processOpDumpInode(std::istringstream& commandStream)
{
// commandStream: ID of inode
MetaStore* metaStore = Program::getApp()->getMetaStore();
std::ostringstream responseStream;
std::string inodeID;
std::string isBuddyMirroredStr;
bool isBuddyMirrored;
// get inodeID from command string
std::getline(commandStream, inodeID, ' ');
if(inodeID.empty() )
return "Invalid or missing inode ID";
// get isBuddyMirrored from command string
std::getline(commandStream, isBuddyMirroredStr, ' ');
if(isBuddyMirroredStr.empty())
isBuddyMirrored = false;
else
isBuddyMirrored = StringTk::strToBool(isBuddyMirroredStr);
MetaFileHandle fileInode;
DirInode* dirInode = NULL;
metaStore->referenceInode(inodeID, isBuddyMirrored, fileInode, dirInode);
if (fileInode)
{
StatData statData;
if (fileInode->getStatData(statData) != FhgfsOpsErr_SUCCESS)
{ // stat data retrieval failed
metaStore->releaseFile("", fileInode);
return "Could not get stat data for requested file inode";
}
DirEntryType dirEntryType = MetadataTk::posixFileTypeToDirEntryType(fileInode->getMode() );
std::string parentDirID = "cannotBeUsed";
uint16_t parentNodeID = 0;
responseStream << "entryType: " << dirEntryType << std::endl;
responseStream << "parentEntryID: " << parentDirID << std::endl;
responseStream << "parentNodeID: " << StringTk::uintToStr(parentNodeID) << std::endl;
responseStream << "mode: " << StringTk::intToStr(statData.getMode()) << std::endl;
responseStream << "uid: " << StringTk::uintToStr(statData.getUserID()) << std::endl;
responseStream << "gid: " << StringTk::uintToStr(statData.getGroupID()) << std::endl;
responseStream << "filesize: " << StringTk::int64ToStr(statData.getFileSize()) << std::endl;
responseStream << "ctime: " << StringTk::int64ToStr(statData.getCreationTimeSecs()) << std::endl;
responseStream << "atime: " << StringTk::int64ToStr(statData.getLastAccessTimeSecs()) << std::endl;
responseStream << "mtime: " << StringTk::int64ToStr(statData.getModificationTimeSecs()) << std::endl;
responseStream << "hardlinks: " << StringTk::intToStr(statData.getNumHardlinks()) << std::endl;
responseStream << "stripeTargets: "
<< StringTk::uint16VecToStr(fileInode->getStripePattern()->getStripeTargetIDs())
<< std::endl;
responseStream << "chunkSize: "
<< StringTk::uintToStr(fileInode->getStripePattern()->getChunkSize()) << std::endl;
responseStream << "featureFlags: " << fileInode->getFeatureFlags() << std::endl;
metaStore->releaseFile("", fileInode);
}
else
if (dirInode)
{
StatData statData;
if (dirInode->getStatData(statData) != FhgfsOpsErr_SUCCESS)
{ // stat data retrieval failed
metaStore->releaseDir(inodeID);
return "Could not get stat data for requested dir inode";
}
DirEntryType dirEntryType = MetadataTk::posixFileTypeToDirEntryType(dirInode->getMode() );
std::string parentDirID;
NumNodeID parentNodeID;
dirInode->getParentInfo(&parentDirID, &parentNodeID);
responseStream << "entryType: " << dirEntryType << std::endl;
responseStream << "parentEntryID: " << parentDirID << std::endl;
responseStream << "parentNodeID: " << parentNodeID.str() << std::endl;
responseStream << "ownerNodeID: " << dirInode->getOwnerNodeID().str() << std::endl;
responseStream << "mode: " << StringTk::intToStr(statData.getMode()) << std::endl;
responseStream << "uid: " << StringTk::uintToStr(statData.getUserID()) << std::endl;
responseStream << "gid: " << StringTk::uintToStr(statData.getGroupID()) << std::endl;
responseStream << "size: " << StringTk::int64ToStr(statData.getFileSize()) << std::endl;
responseStream << "numLinks: " << StringTk::int64ToStr(statData.getNumHardlinks())
<< std::endl;
responseStream << "ctime: " << StringTk::int64ToStr(statData.getCreationTimeSecs())
<< std::endl;
responseStream << "atime: " << StringTk::int64ToStr(statData.getLastAccessTimeSecs())
<< std::endl;
responseStream << "mtime: " << StringTk::int64ToStr(statData.getModificationTimeSecs())
<< std::endl;
responseStream << "featureFlags: " << dirInode->getFeatureFlags() << std::endl;
metaStore->releaseDir(inodeID);
}
else
{
return "Could not read requested inode";
}
return responseStream.str();
}
std::string GenericDebugMsgEx::processOpDumpInlinedInode(std::istringstream& commandStream)
{
// commandStream: parentID, name
MetaStore* metaStore = Program::getApp()->getMetaStore();
NumNodeID localNodeID = Program::getApp()->getLocalNode().getNumID();
std::ostringstream responseStream;
StringList parameterList;
StringTk::explode(commandStream.str(), ' ', &parameterList);
if ( parameterList.size() < 3 || parameterList.size() > 4 )
return "Invalid or missing parameters; Parameter format: parentDirID entryName "
"[isBuddyMirrored]";
StringListIter iter = parameterList.begin();
iter++;
std::string parentEntryID = *iter;
iter++;
std::string entryName = *iter;
iter++;
bool isBuddyMirrored = false;
if (iter != parameterList.end())
{
isBuddyMirrored = StringTk::strToBool(*iter);
}
EntryInfo entryInfo(localNodeID, parentEntryID, "unknown", entryName, DirEntryType_REGULARFILE,
0);
DirInode* parentInode = metaStore->referenceDir(parentEntryID, isBuddyMirrored, false);
if ( !parentInode )
return "Could not open parent directory";
DirEntry dirEntry(entryName);
bool getDentryRes = parentInode->getDentry(entryName, dirEntry);
if ( !getDentryRes )
{
metaStore->releaseDir(parentEntryID);
return "Could not open dir entry";
}
FileInodeStoreData* inodeData = dirEntry.getInodeStoreData();
if ( !inodeData )
{
metaStore->releaseDir(parentEntryID);
return "Could not get inlined inode data";
}
StatData* statData = inodeData->getInodeStatData();
if ( !statData )
{
metaStore->releaseDir(parentEntryID);
return "Could not get stat data for requested file inode";
}
responseStream << "entryID: " << inodeData->getEntryID() << std::endl;
responseStream << "mode: " << StringTk::intToStr(statData->getMode()) << std::endl;
responseStream << "uid: " << StringTk::uintToStr(statData->getUserID()) << std::endl;
responseStream << "gid: " << StringTk::uintToStr(statData->getGroupID()) << std::endl;
responseStream << "filesize: " << StringTk::int64ToStr(statData->getFileSize()) << std::endl;
responseStream << "ctime: " << StringTk::int64ToStr(statData->getCreationTimeSecs()) << std::endl;
responseStream << "atime: " << StringTk::int64ToStr(statData->getLastAccessTimeSecs())
<< std::endl;
responseStream << "mtime: " << StringTk::int64ToStr(statData->getModificationTimeSecs())
<< std::endl;
responseStream << "hardlinks: " << StringTk::intToStr(statData->getNumHardlinks()) << std::endl;
responseStream << "stripeTargets: "
<< StringTk::uint16VecToStr(inodeData->getPattern()->getStripeTargetIDs()) << std::endl;
responseStream << "chunkSize: "
<< StringTk::uintToStr(inodeData->getPattern()->getChunkSize()) << std::endl;
responseStream << "featureFlags: " << inodeData->getInodeFeatureFlags() << std::endl;
metaStore->releaseDir(parentEntryID);
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);
std::string returnString;
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());
}
#ifdef BEEGFS_DEBUG
std::string GenericDebugMsgEx::processOpWriteDirInode(std::istringstream& commandStream)
{
MetaStore* metaStore = Program::getApp()->getMetaStore();
// get parameters from command string
StringVector paramVec;
StringTk::explode(commandStream.str(), ' ', &paramVec);
std::string entryID;
std::string parentDirID;
NumNodeID parentNodeID;
NumNodeID ownerNodeID;
int mode;
uint uid;
uint gid;
int64_t size;
unsigned numLinks;
bool isBuddyMirrored;
try
{
unsigned i = 1;
entryID = paramVec.at(i++);
parentDirID = paramVec.at(i++);
parentNodeID = NumNodeID(StringTk::strToUInt(paramVec.at(i++)));
ownerNodeID = NumNodeID(StringTk::strToUInt(paramVec.at(i++)));
mode = StringTk::strToInt(paramVec.at(i++));
uid = StringTk::strToUInt(paramVec.at(i++));
gid = StringTk::strToUInt(paramVec.at(i++));
size = StringTk::strToInt64(paramVec.at(i++));
numLinks = StringTk::strToUInt(paramVec.at(i++));
if (i<paramVec.size())
isBuddyMirrored = StringTk::strToBool(paramVec.at(i));
else
isBuddyMirrored = false;
}
catch (std::out_of_range& e)
{
std::string paramFormatStr =
"entryID parentDirID parentNodeID ownerNodeID mode uid gid size numLinks "
"[isBuddyMirrored]";
return "Invalid or missing parameters; Parameter format: " + paramFormatStr;
}
DirInode* dirInode = metaStore->referenceDir(entryID, isBuddyMirrored, true);
if ( !dirInode )
return "Could not find directory with ID: " + entryID;
StatData statData;
if ( dirInode->getStatData(statData) != FhgfsOpsErr_SUCCESS )
{
metaStore->releaseDir(entryID);
return "Could not get stat data for requested dir inode";
}
dirInode->setParentInfoInitial(parentDirID, parentNodeID);
dirInode->setOwnerNodeID(ownerNodeID);
statData.setMode(mode);
statData.setUserID(uid);
statData.setGroupID(gid);
statData.setFileSize(size);
statData.setNumHardLinks(numLinks);
dirInode->setStatData(statData);
metaStore->releaseDir(entryID);
return "OK";
}
std::string GenericDebugMsgEx::processOpWriteInlinedFileInode(std::istringstream& commandStream)
{
MetaStore* metaStore = Program::getApp()->getMetaStore();
std::string retStr = "OK";
// get parameters from command string
StringVector paramVec;
StringTk::explode(commandStream.str(), ' ', &paramVec);
std::string parentDirID;
std::string name;
std::string entryID;
int mode;
uint uid;
uint gid;
int64_t filesize;
unsigned numLinks;
UInt16Vector stripeTargets;
// UInt16Vector* origStripeTargets;
try
{
unsigned i = 1;
parentDirID = paramVec.at(i++);
name = paramVec.at(i++);
entryID = paramVec.at(i++);
mode = StringTk::strToInt(paramVec.at(i++));
uid = StringTk::strToUInt(paramVec.at(i++));
gid = StringTk::strToUInt(paramVec.at(i++));
filesize = StringTk::strToInt64(paramVec.at(i++));
numLinks = StringTk::strToUInt(paramVec.at(i++));
StringTk::strToUint16Vec(paramVec.at(i++), &stripeTargets);
}
catch (std::out_of_range& e)
{
std::string paramFormatStr =
"parentDirID entryName entryID mode uid gid filesize numLinks stripeTargets";
return "Invalid or missing parameters; Parameter format: " + paramFormatStr;
}
EntryInfo entryInfo(Program::getApp()->getLocalNodeNumID(), parentDirID, entryID, name,
DirEntryType_REGULARFILE, 0);
auto [fileInode, referenceRes] = metaStore->referenceFile(&entryInfo);
if (!fileInode)
return "Could not reference inode";
StatData statData;
fileInode->getStatData(statData);
statData.setMode(mode);
statData.setUserID(uid);
statData.setGroupID(gid);
statData.setFileSize(filesize);
statData.setNumHardLinks(numLinks);
fileInode->setStatData(statData);
StripePattern* pattern = fileInode->getStripePattern();
UInt16Vector* origTargets = pattern->getStripeTargetIDsModifyable();
*origTargets = stripeTargets;
fileInode->updateInodeOnDisk(&entryInfo, pattern);
metaStore->releaseFile(parentDirID, fileInode);
return retStr;
}
#endif // BEEGFS_DEBUG

View File

@@ -0,0 +1,36 @@
#pragma once
#include <common/net/message/nodes/GenericDebugMsg.h>
#include <common/Common.h>
class GenericDebugMsgEx : public GenericDebugMsg
{
public:
virtual bool processIncoming(ResponseContext& ctx);
private:
std::string processCommand();
std::string processOpListFileAppendLocks(std::istringstream& commandStream);
std::string processOpListFileEntryLocks(std::istringstream& commandStream);
std::string processOpListFileRangeLocks(std::istringstream& commandStream);
std::string processOpListOpenFiles(std::istringstream& commandStream);
std::string processOpReferenceStatistics(std::istringstream& commandStream);
std::string processOpCacheStatistics(std::istringstream& commandStream);
std::string processOpVersion(std::istringstream& commandStream);
std::string processOpMsgQueueStats(std::istringstream& commandStream);
std::string processOpListPools(std::istringstream& commandStream);
std::string processOpDumpDentry(std::istringstream& commandStream);
std::string processOpDumpInode(std::istringstream& commandStream);
std::string processOpDumpInlinedInode(std::istringstream& commandStream);
std::string processOpQuotaExceeded(std::istringstream& commandStream);
#ifdef BEEGFS_DEBUG
std::string processOpWriteDirDentry(std::istringstream& commandStream);
std::string processOpWriteDirInode(std::istringstream& commandStream);
std::string processOpWriteInlinedFileInode(std::istringstream& commandStream);
#endif // BEEGFS_DEBUG
};

View File

@@ -0,0 +1,32 @@
#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/MetaNodeOpStats.h>
#include <common/net/message/nodes/GetClientStatsRespMsg.h>
/**
* Server side gets a GetClientStatsMsgEx request
*/
bool GetClientStatsMsgEx::processIncoming(ResponseContext& ctx)
{
LogContext log("GetClientStatsMsgEx incoming");
uint64_t cookieIP = getCookieIP(); // requested is cookie+1
// get stats
MetaNodeOpStats* opStats = Program::getApp()->getNodeOpStats();
bool wantPerUserStats = isMsgHeaderFeatureFlagSet(GETCLIENTSTATSMSG_FLAG_PERUSERSTATS);
UInt64Vector opStatsVec;
opStats->mapToUInt64Vec(
cookieIP, GETCLIENTSTATSRESP_MAX_PAYLOAD_LEN, wantPerUserStats, &opStatsVec);
ctx.sendResponse(GetClientStatsRespMsg(&opStatsVec) );
return true;
}

View File

@@ -0,0 +1,12 @@
#pragma once
#include <common/storage/StorageErrors.h>
#include <common/net/message/nodes/GetClientStatsMsg.h>
class GetClientStatsMsgEx : public GetClientStatsMsg
{
public:
virtual bool processIncoming(ResponseContext& ctx);
};

View File

@@ -0,0 +1,65 @@
#include <common/net/message/nodes/GetNodeCapacityPoolsRespMsg.h>
#include <common/storage/StoragePool.h>
#include <program/Program.h>
#include "GetNodeCapacityPoolsMsgEx.h"
bool GetNodeCapacityPoolsMsgEx::processIncoming(ResponseContext& ctx)
{
const char* logContext = "GetNodeCapacityPools incoming";
CapacityPoolQueryType poolType = getCapacityPoolQueryType();
LOG_DEBUG(logContext, Log_SPAM, "PoolType: " + StringTk::intToStr(poolType) );
const App* app = Program::getApp();
GetNodeCapacityPoolsRespMsg::PoolsMap capacityPoolsMap;
switch(poolType)
{
case CapacityPoolQuery_META:
{
const NodeCapacityPools* capPools = app->getMetaCapacityPools();
capacityPoolsMap[StoragePoolId(StoragePoolStore::INVALID_POOL_ID)] =
capPools->getPoolsAsLists();
} break;
case CapacityPoolQuery_STORAGE:
{
const StoragePoolPtrVec storagePools = app->getStoragePoolStore()->getPoolsAsVec();
for (auto iter = storagePools.begin(); iter != storagePools.end(); iter++)
{
const TargetCapacityPools* capPools = (*iter)->getTargetCapacityPools();
capacityPoolsMap[(*iter)->getId()] = capPools->getPoolsAsLists();
}
} break;
case CapacityPoolQuery_STORAGEBUDDIES:
{
const StoragePoolPtrVec storagePools = app->getStoragePoolStore()->getPoolsAsVec();
for (auto iter = storagePools.begin(); iter != storagePools.end(); iter++)
{
const NodeCapacityPools* capPools = (*iter)->getBuddyCapacityPools();
capacityPoolsMap[(*iter)->getId()] = capPools->getPoolsAsLists();
}
} break;
default:
{
LogContext(logContext).logErr("Invalid pool type: " + StringTk::intToStr(poolType) );
return false;
} break;
}
ctx.sendResponse(GetNodeCapacityPoolsRespMsg(&capacityPoolsMap));
return true;
}

View File

@@ -0,0 +1,10 @@
#pragma once
#include <common/net/message/nodes/GetNodeCapacityPoolsMsg.h>
class GetNodeCapacityPoolsMsgEx : public GetNodeCapacityPoolsMsg
{
public:
virtual bool processIncoming(ResponseContext& ctx);
};

View File

@@ -0,0 +1,37 @@
#include <common/net/message/nodes/GetNodesRespMsg.h>
#include <program/Program.h>
#include "GetNodesMsgEx.h"
#include <boost/lexical_cast.hpp>
bool GetNodesMsgEx::processIncoming(ResponseContext& ctx)
{
LogContext log("GetNodes incoming");
NodeType nodeType = (NodeType)getValue();
LOG_DEBUG_CONTEXT(log, 5, "NodeType: " + boost::lexical_cast<std::string>(nodeType));
App* app = Program::getApp();
NodeStore* nodes = app->getServerStoreFromType(nodeType);
if(unlikely(!nodes) )
{
LOG(GENERAL, ERR, "Invalid node type.",
("Node Type", getNodeType()),
("Sender", ctx.peerName())
);
return true;
}
auto nodeList = nodes->referenceAllNodes();
NumNodeID rootID = app->getMetaRoot().getID();
bool rootIsBuddyMirrored = app->getMetaRoot().getIsMirrored();
ctx.sendResponse(GetNodesRespMsg(rootID, rootIsBuddyMirrored, nodeList) );
return true;
}

View File

@@ -0,0 +1,10 @@
#pragma once
#include <common/net/message/nodes/GetNodesMsg.h>
class GetNodesMsgEx : public GetNodesMsg
{
public:
virtual bool processIncoming(ResponseContext& ctx);
};

View File

@@ -0,0 +1,16 @@
#include <common/net/message/nodes/GetTargetMappingsRespMsg.h>
#include <common/toolkit/MessagingTk.h>
#include <program/Program.h>
#include "GetTargetMappingsMsgEx.h"
bool GetTargetMappingsMsgEx::processIncoming(ResponseContext& ctx)
{
App* app = Program::getApp();
TargetMapper* targetMapper = app->getTargetMapper();
ctx.sendResponse(GetTargetMappingsRespMsg(targetMapper->getMapping()));
return true;
}

View File

@@ -0,0 +1,11 @@
#pragma once
#include <common/net/message/nodes/GetTargetMappingsMsg.h>
class GetTargetMappingsMsgEx : public GetTargetMappingsMsg
{
public:
virtual bool processIncoming(ResponseContext& ctx);
};

View File

@@ -0,0 +1,90 @@
#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 = app->getAbstractNodeStoreFromType(getNodeType() );
if(!nodes)
{
log.logErr("Invalid node type: " + StringTk::intToStr(getNodeType() ) +
"(" + boost::lexical_cast<std::string>(getNodeType()) + ")");
goto ack_resp;
}
isNodeNew = (nodes->addOrUpdateNode(std::move(node)) == NodeStoreResult::Added);
if( (isNodeNew) && (getNodeType() != NODETYPE_Client) )
{ // log info about new server
bool supportsRDMA = NetworkInterfaceCard::supportsRDMA(&nicList);
std::string supports;
if (supportsRDMA)
supports = "; RDMA.";
log.log(Log_WARNING, std::string("New node: ") + nodeIDWithTypeStr + supports);
log.log(Log_DEBUG, "Number of nodes: "
"Meta: " + StringTk::intToStr(app->getMetaNodes()->getSize() ) + "; "
"Storage: " + StringTk::intToStr(app->getStorageNodes()->getSize() ) );
}
processIncomingRoot();
ack_resp:
acknowledge(ctx);
return true;
}
/**
* Handles the contained root information.
*/
void HeartbeatMsgEx::processIncomingRoot()
{
LogContext log("Heartbeat incoming");
// check whether root info is defined
if( (getNodeType() != NODETYPE_Meta) || !getRootNumID() )
return;
// try to apply the contained root info
if(Program::getApp()->getMetaRoot().setIfDefault(getRootNumID(), getRootIsBuddyMirrored()))
{
log.log(Log_CRITICAL, "Root (by Heartbeat): " + getRootNumID().str() );
Program::getApp()->getRootDir()->setOwnerNodeID(getRootNumID() );
if (getRootIsBuddyMirrored())
Program::getApp()->getRootDir()->setIsBuddyMirroredFlag(true);
}
}

View File

@@ -0,0 +1,13 @@
#pragma once
#include <common/net/message/nodes/HeartbeatMsg.h>
class HeartbeatMsgEx : public HeartbeatMsg
{
public:
virtual bool processIncoming(ResponseContext& ctx);
private:
void processIncomingRoot();
};

View File

@@ -0,0 +1,24 @@
#include <common/net/message/nodes/HeartbeatMsg.h>
#include <common/toolkit/MessagingTk.h>
#include <program/Program.h>
#include "HeartbeatRequestMsgEx.h"
bool HeartbeatRequestMsgEx::processIncoming(ResponseContext& ctx)
{
App* app = Program::getApp();
Config* cfg = app->getConfig();
Node& localNode = app->getLocalNode();
NumNodeID localNodeNumID = localNode.getNumID();
NumNodeID rootNodeID = app->getMetaRoot().getID();
NicAddressList nicList(localNode.getNicList());
HeartbeatMsg hbMsg(localNode.getAlias(), localNodeNumID, NODETYPE_Meta, &nicList);
hbMsg.setRootNumID(rootNodeID);
hbMsg.setPorts(cfg->getConnMetaPort(), cfg->getConnMetaPort() );
ctx.sendResponse(hbMsg);
return true;
}

View File

@@ -0,0 +1,10 @@
#pragma once
#include <common/net/message/nodes/HeartbeatRequestMsg.h>
class HeartbeatRequestMsgEx : public HeartbeatRequestMsg
{
public:
virtual bool processIncoming(ResponseContext& ctx);
};

View File

@@ -0,0 +1,45 @@
#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;
}

View File

@@ -0,0 +1,11 @@
#pragma once
#include <common/net/message/nodes/MapTargetsMsg.h>
class MapTargetsMsgEx : public MapTargetsMsg
{
public:
virtual bool processIncoming(ResponseContext& ctx);
};

View File

@@ -0,0 +1,23 @@
#include <common/toolkit/MessagingTk.h>
#include <program/Program.h>
#include "PublishCapacitiesMsgEx.h"
bool PublishCapacitiesMsgEx::processIncoming(ResponseContext& ctx)
{
LogContext log("PublishCapacitiesMsg incoming");
App* app = Program::getApp();
InternodeSyncer* syncer = app->getInternodeSyncer();
// force upload of capacity information
syncer->setForcePublishCapacities();
// send response
acknowledge(ctx);
return true;
}

View File

@@ -0,0 +1,12 @@
#pragma once
#include <common/net/message/nodes/PublishCapacitiesMsg.h>
class PublishCapacitiesMsgEx : public PublishCapacitiesMsg
{
public:
virtual bool processIncoming(ResponseContext& ctx);
};

View File

@@ -0,0 +1,23 @@
#include <common/toolkit/MessagingTk.h>
#include <program/Program.h>
#include "RefreshCapacityPoolsMsgEx.h"
bool RefreshCapacityPoolsMsgEx::processIncoming(ResponseContext& ctx)
{
LogContext log("RefreshCapacityPoolsMsg incoming");
App* app = Program::getApp();
InternodeSyncer* syncer = app->getInternodeSyncer();
// force update of capacity pools
syncer->setForcePoolsUpdate();
// send response
acknowledge(ctx);
return true;
}

View File

@@ -0,0 +1,11 @@
#pragma once
#include <common/net/message/nodes/RefreshCapacityPoolsMsg.h>
class RefreshCapacityPoolsMsgEx : public RefreshCapacityPoolsMsg
{
public:
virtual bool processIncoming(ResponseContext& ctx);
};

View File

@@ -0,0 +1,22 @@
#include <common/toolkit/MessagingTk.h>
#include <program/Program.h>
#include "RefreshTargetStatesMsgEx.h"
bool RefreshTargetStatesMsgEx::processIncoming(ResponseContext& ctx)
{
LogContext log("RefreshTargetStatesMsg incoming");
App* app = Program::getApp();
InternodeSyncer* syncer = app->getInternodeSyncer();
// force update of target states
syncer->setForceTargetStatesUpdate();
// send response
acknowledge(ctx);
return true;
}

View File

@@ -0,0 +1,11 @@
#pragma once
#include <common/net/message/nodes/RefreshTargetStatesMsg.h>
class RefreshTargetStatesMsgEx : public RefreshTargetStatesMsg
{
public:
virtual bool processIncoming(ResponseContext& ctx);
};

View File

@@ -0,0 +1,34 @@
#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_Meta || getNodeType() == NODETYPE_Storage)
{
NodeStoreServers* nodes = app->getServerStoreFromType(getNodeType());
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));
return true;
}

View File

@@ -0,0 +1,11 @@
#pragma once
#include <common/net/message/nodes/RemoveNodeMsg.h>
class RemoveNodeMsgEx : public RemoveNodeMsg
{
public:
virtual bool processIncoming(ResponseContext& ctx);
};

View File

@@ -0,0 +1,48 @@
#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)
{
LogContext log("SetMirrorBuddyGroupMsg incoming");
App* app = Program::getApp();
MirrorBuddyGroupMapper* buddyGroupMapper;
NodeType nodeType = getNodeType();
switch (nodeType)
{
case NODETYPE_Storage:
buddyGroupMapper = app->getStorageBuddyGroupMapper();
break;
case NODETYPE_Meta:
buddyGroupMapper = app->getMetaBuddyGroupMapper();
break;
default:
log.logErr("Node type mismatch");
return false;
}
uint16_t buddyGroupID = this->getBuddyGroupID();
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;
}

View File

@@ -0,0 +1,11 @@
#pragma once
#include <common/net/message/nodes/SetMirrorBuddyGroupMsg.h>
class SetMirrorBuddyGroupMsgEx : public SetMirrorBuddyGroupMsg
{
public:
virtual bool processIncoming(ResponseContext& ctx);
};

View File

@@ -0,0 +1,37 @@
#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)
{
const char* logContext = "Set target states incoming";
App* app = Program::getApp();
InternodeSyncer* internodeSyncer = app->getInternodeSyncer();
FhgfsOpsErr result = FhgfsOpsErr_SUCCESS;
if (getTargetIDs().size() != 1 || getStates().size() != 1)
{
LogContext(logContext).logErr("Invalid list size of target ID or state List (must be 1).");
result = FhgfsOpsErr_INTERNAL;
goto send_response;
}
if (getTargetIDs().front() != app->getLocalNodeNumID().val() )
{
LogContext(logContext).logErr("ID in message does not match local node ID.");
result = FhgfsOpsErr_INTERNAL;
goto send_response;
}
internodeSyncer->setNodeConsistencyState(
static_cast<TargetConsistencyState>(getStates().front() ) );
send_response:
ctx.sendResponse(SetTargetConsistencyStatesRespMsg(result) );
return true;
}

View File

@@ -0,0 +1,10 @@
#pragma once
#include <common/net/message/nodes/SetTargetConsistencyStatesMsg.h>
class SetTargetConsistencyStatesMsgEx : public SetTargetConsistencyStatesMsg
{
public:
virtual bool processIncoming(ResponseContext& ctx);
};

View File

@@ -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;
}

View File

@@ -0,0 +1,10 @@
#pragma once
#include <common/net/message/nodes/storagepools/RefreshStoragePoolsMsg.h>
class RefreshStoragePoolsMsgEx : public RefreshStoragePoolsMsg
{
public:
virtual bool processIncoming(ResponseContext& ctx);
};