beegfs/storage/source/net/message/fsck/MoveChunkFileMsgEx.cpp
2025-08-10 01:34:16 +02:00

89 lines
2.9 KiB
C++

#include "MoveChunkFileMsgEx.h"
#include <program/Program.h>
bool MoveChunkFileMsgEx::processIncoming(ResponseContext& ctx)
{
ctx.sendResponse(MoveChunkFileRespMsg(moveChunk()));
return true;
}
unsigned MoveChunkFileMsgEx::moveChunk()
{
const char* logContext = "MoveChunkFileMsg incoming";
App* app = Program::getApp();
std::string chunkName = this->getChunkName();
std::string oldPath = this->getOldPath(); // relative path to chunks dir
std::string newPath = this->getNewPath(); // relative path to chunks dir
uint16_t targetID = this->getTargetID();
bool overwriteExisting = this->getOverwriteExisting();
int renameRes;
std::string moveFrom = oldPath + "/" + chunkName;
std::string moveTo = newPath + "/" + chunkName;
auto* const target = app->getStorageTargets()->getTarget(targetID);
if (!target)
{
LogContext(logContext).log(Log_CRITICAL, "Could not open path for target ID; targetID: "
+ StringTk::uintToStr(targetID));
return 1;
}
const auto targetPath = getIsMirrored()
? target->getPath() / CONFIG_BUDDYMIRROR_SUBDIR_NAME
: target->getPath() / CONFIG_CHUNK_SUBDIR_NAME;
const int targetFD = getIsMirrored() ? *target->getMirrorFD() : *target->getChunkFD();
// if overwriteExisting set to false, make sure, that output file does not exist
if (!overwriteExisting)
{
bool pathExists = StorageTk::pathExists(targetFD, moveTo);
if (pathExists)
{
LogContext(logContext).log(Log_CRITICAL,
"Could not move chunk file. Destination file does already exist; chunkID: " + chunkName
+ "; targetID: " + StringTk::uintToStr(targetID) + "; oldChunkPath: " + oldPath
+ "; newChunkPath: " + newPath);
return 1;
}
}
{
// create the parent directory (perhaps it didn't exist)
// can be more efficient if we write a createPathOnDisk that uses mkdirat
const Path moveToPath = targetPath / moveTo;
mode_t dirMode = S_IRWXU | S_IRWXG | S_IRWXO;
bool mkdirRes = StorageTk::createPathOnDisk(moveToPath, true, &dirMode);
if(!mkdirRes)
{
LogContext(logContext).log(Log_CRITICAL,
"Could not create parent directory for chunk; chunkID: " + chunkName + "; targetID: "
+ StringTk::uintToStr(targetID) + "; oldChunkPath: " + oldPath + "; newChunkPath: "
+ newPath);
return 1;
}
}
// perform the actual move
renameRes = renameat(targetFD, moveFrom.c_str(), targetFD, moveTo.c_str() );
if ( renameRes != 0 )
{
LogContext(logContext).log(Log_CRITICAL,
"Could not perform move; chunkID: " + chunkName + "; targetID: "
+ StringTk::uintToStr(targetID) + "; oldChunkPath: " + oldPath + "; newChunkPath: "
+ newPath + "; SysErr: " + System::getErrString());
return 1;
}
else if (getIsMirrored())
target->setBuddyNeedsResync(true);
return 0;
}