Commit f27b145b authored by Christian Mohrbacher's avatar Christian Mohrbacher

updated to release 6.7

parent 686383f5
......@@ -483,7 +483,15 @@ bool _Config_applyConfigMap(Config* this, bool enableException)
this->sysUpdateTargetStatesSecs = StringTk_strToUInt(valueStr);
else
if(!strcmp(keyStr, "sysTargetOfflineTimeoutSecs") )
{
this->sysTargetOfflineTimeoutSecs = StringTk_strToUInt(valueStr);
if (this->sysTargetOfflineTimeoutSecs < 30)
{
printk_fhgfs(KERN_WARNING, "Invalid argument for sysTargetOfflineTimeoutSecs: %s "
"(must be at least 30)\n", valueStr);
return false;
}
}
else
if(!strcmp(keyStr, "sysXAttrsEnabled") )
this->sysXAttrsEnabled = StringTk_strToBool(valueStr);
......
......@@ -340,7 +340,7 @@ err_invalidateSock:
err_fault:
_this->errState = -1;
return -1;
return -EFAULT;
}
......
......@@ -530,6 +530,10 @@ static void __commkit_socketinvalidate_generic(CommKitContext* context,
Logger_logErrFormatted(context->log, context->ops->logContext,
"Communication with inactive node. Node: %s", Node_getNodeIDWithTypeStr(info->node) );
}
else if (info->nodeResult == -FhgfsOpsErr_ADDRESSFAULT)
{
// not a commkit error. release all resources and treat this CTI as done during cleanup.
}
else
{ // "normal" connection error
info->nodeResult = -FhgfsOpsErr_COMMUNICATION;
......@@ -1003,8 +1007,8 @@ static ssize_t __commkit_readfile_receive(CommKitContext* context, ReadfileState
if(unlikely(recvRes < 0) )
{
Logger_logFormatted(context->log, Log_SPAM, context->ops->logContext,
"Request details: receive from %s: %lld bytes",
Node_getNodeIDWithTypeStr(currentState->base.node), (long long)length);
"Request details: receive from %s: %lld bytes (error %zi)",
Node_getNodeIDWithTypeStr(currentState->base.node), (long long)length, recvRes);
}
return recvRes;
......
......@@ -220,7 +220,12 @@ void Config::applyConfigMap(bool enableException, bool addDashes) throw(InvalidC
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("sysResyncSafetyThresholMins") )
sysResyncSafetyThresholdMins = StringTk::strToInt64(iter->second.c_str() );
......
......@@ -93,7 +93,7 @@ std::unique_ptr<UnlinkFileMsgEx::ResponseState> UnlinkFileMsgEx::executePrimary(
if(cfg->getTuneEarlyUnlinkResponse() && !isMirrored())
{ // alternative 1: response before chunk files unlink
FileInode* unlinkedInode = NULL;
std::unique_ptr<FileInode> unlinkedInode;
FhgfsOpsErr unlinkMetaRes = MsgHelperUnlink::unlinkMetaFile(*dir,
getDelFileName(), &unlinkedInode);
......@@ -105,13 +105,13 @@ std::unique_ptr<UnlinkFileMsgEx::ResponseState> UnlinkFileMsgEx::executePrimary(
/* note: if the file is still opened or if there were hardlinks then unlinkedInode will be
NULL even on FhgfsOpsErr_SUCCESS */
if( (unlinkMetaRes == FhgfsOpsErr_SUCCESS) && unlinkedInode)
MsgHelperUnlink::unlinkChunkFiles(unlinkedInode, getMsgHeaderUserID() );
MsgHelperUnlink::unlinkChunkFiles(unlinkedInode.release(), getMsgHeaderUserID() );
return {};
}
// alternative 2: response after chunk files unlink
FileInode* unlinkedInode = NULL;
std::unique_ptr<FileInode> unlinkedInode;
FhgfsOpsErr unlinkRes = MsgHelperUnlink::unlinkMetaFile(*dir,
getDelFileName(), &unlinkedInode);
......@@ -135,7 +135,8 @@ std::unique_ptr<UnlinkFileMsgEx::ResponseState> UnlinkFileMsgEx::executePrimary(
NULL even on FhgfsOpsErr_SUCCESS */
if( (unlinkRes == FhgfsOpsErr_SUCCESS) && unlinkedInode)
{
unlinkRes = MsgHelperUnlink::unlinkChunkFiles(unlinkedInode, getMsgHeaderUserID());
unlinkRes = MsgHelperUnlink::unlinkChunkFiles(unlinkedInode.release(),
getMsgHeaderUserID());
}
app->getMetaStore()->releaseDir(dir->getID());
......@@ -147,7 +148,7 @@ std::unique_ptr<UnlinkFileMsgEx::ResponseState> UnlinkFileMsgEx::executeSecondar
ResponseContext& ctx)
{
MetaStore* const metaStore = Program::getApp()->getMetaStore();
FileInode* unlinkedInode = NULL;
std::unique_ptr<FileInode> unlinkedInode;
// we do not need to load the directory here - if the dentry does not exist, it will not be
// modified. if the dentry does exist, it will be loaded.
......
......@@ -29,7 +29,7 @@ std::unique_ptr<MirroredMessageResponseState> MovingFileInsertMsgEx::executeLoca
EntryInfo* toDirInfo = this->getToDirInfo();
std::string newName = this->getNewName();
FileInode* unlinkInode = NULL;
std::unique_ptr<FileInode> unlinkInode;
unsigned inodeBufLen;
std::unique_ptr<char[]> inodeBuf;
......@@ -91,8 +91,6 @@ std::unique_ptr<MirroredMessageResponseState> MovingFileInsertMsgEx::executeLoca
unlinkInode->serializeMetaData(ser);
inodeBufLen = ser.size();
}
delete unlinkInode;
}
else
{ // no file overwritten
......
......@@ -382,10 +382,10 @@ FhgfsOpsErr RenameV2MsgEx::renameInSameDir(DirInode& fromParent, const std::stri
/* we are passing here the very same fromParent pointer also a toParent pointer, which is
* essential in order not to dead-lock */
FileInode* unlinkInode; // inode belong to a possibly existing toName file
std::unique_ptr<FileInode> unlinkInode; // inode belong to a possibly existing toName file
FhgfsOpsErr renameRes = metaStore->renameInSameDir(fromParent, oldName, toName,
&unlinkInode);
&unlinkInode);
if (renameRes == FhgfsOpsErr_SUCCESS)
{
......@@ -425,7 +425,7 @@ FhgfsOpsErr RenameV2MsgEx::renameInSameDir(DirInode& fromParent, const std::stri
unlinkedEntryID = unlinkInode->getEntryID();
FhgfsOpsErr chunkUnlinkRes = MsgHelperUnlink::unlinkChunkFiles(
unlinkInode, getMsgHeaderUserID() );
unlinkInode.release(), getMsgHeaderUserID() );
if (chunkUnlinkRes != FhgfsOpsErr_SUCCESS)
{
......
......@@ -16,14 +16,14 @@
FhgfsOpsErr MsgHelperUnlink::unlinkFile(DirInode& parentDir, const std::string& removeName,
unsigned msgUserID)
{
FileInode* unlinkedInode = NULL;
std::unique_ptr<FileInode> unlinkedInode;
FhgfsOpsErr unlinkMetaRes = unlinkMetaFile(parentDir, removeName, &unlinkedInode);
/* note: if the file is still opened or if there are/were hardlinks then unlinkedInode will be
NULL even on FhgfsOpsErr_SUCCESS */
if (unlinkMetaRes == FhgfsOpsErr_SUCCESS && unlinkedInode)
unlinkMetaRes = unlinkChunkFiles(unlinkedInode, msgUserID);
unlinkMetaRes = unlinkChunkFiles(unlinkedInode.release(), msgUserID);
return unlinkMetaRes;
}
......@@ -35,7 +35,7 @@ FhgfsOpsErr MsgHelperUnlink::unlinkFile(DirInode& parentDir, const std::string&
* the chunk files via unlinkChunkFiles().
*/
FhgfsOpsErr MsgHelperUnlink::unlinkMetaFile(DirInode& parentDir,
const std::string& removeName, FileInode** outUnlinkedFile)
const std::string& removeName, std::unique_ptr<FileInode>* outUnlinkedFile)
{
MetaStore* metaStore = Program::getApp()->getMetaStore();
ModificationEventFlusher* modEventFlusher = Program::getApp()->getModificationEventFlusher();
......
......@@ -12,7 +12,7 @@ class MsgHelperUnlink
static FhgfsOpsErr unlinkFile(DirInode& parentDir, const std::string& removeName,
unsigned msgUserID);
static FhgfsOpsErr unlinkMetaFile(DirInode& parentDir, const std::string& removeName,
FileInode** outUnlinkedFile);
std::unique_ptr<FileInode>* outUnlinkedFile);
static FhgfsOpsErr unlinkChunkFiles(FileInode* inode, unsigned msgUserID);
private:
......
......@@ -334,10 +334,11 @@ FhgfsOpsErr InodeFileStore::isUnlinkable(EntryInfo* entryInfo)
* other. So no need to return an error here. Update all code path to handle
* *outInode = NULL, even is the return code is FhgfsOpsErr_SUCCESS
*/
FhgfsOpsErr InodeFileStore::unlinkFileInodeUnlocked(EntryInfo* entryInfo, FileInode** outInode)
FhgfsOpsErr InodeFileStore::unlinkFileInodeUnlocked(EntryInfo* entryInfo,
std::unique_ptr<FileInode>* outInode)
{
if(outInode)
*outInode = NULL;
outInode->reset();
std::string entryID = entryInfo->getEntryID();
......@@ -347,7 +348,7 @@ FhgfsOpsErr InodeFileStore::unlinkFileInodeUnlocked(EntryInfo* entryInfo, FileIn
if (outInode)
{
*outInode = createUnreferencedInodeUnlocked(entryInfo);
outInode->reset(createUnreferencedInodeUnlocked(entryInfo));
if (!*outInode)
return FhgfsOpsErr_PATHNOTEXISTS;
}
......@@ -356,10 +357,7 @@ FhgfsOpsErr InodeFileStore::unlinkFileInodeUnlocked(EntryInfo* entryInfo, FileIn
if(!unlinkRes)
{
if(outInode)
{
delete(*outInode);
*outInode = NULL;
}
outInode->reset();
return FhgfsOpsErr_INTERNAL;
}
......@@ -371,7 +369,8 @@ FhgfsOpsErr InodeFileStore::unlinkFileInodeUnlocked(EntryInfo* entryInfo, FileIn
* @param outFile will be set to the unlinked file and the object must then be deleted by the caller
* (can be NULL if the caller is not interested in the file)
*/
FhgfsOpsErr InodeFileStore::unlinkFileInode(EntryInfo* entryInfo, FileInode** outInode)
FhgfsOpsErr InodeFileStore::unlinkFileInode(EntryInfo* entryInfo,
std::unique_ptr<FileInode>* outInode)
{
SafeRWLock safeLock(&rwlock, SafeRWLock_WRITE); // L O C K
......
......@@ -37,7 +37,7 @@ class InodeFileStore
FileInode* referenceFileInode(EntryInfo* entryInfo, bool loadFromDisk);
FileInode* referenceLoadedFile(const std::string& entryID);
bool releaseFileInode(FileInode* inode);
FhgfsOpsErr unlinkFileInode(EntryInfo* entryInfo, FileInode** outFile);
FhgfsOpsErr unlinkFileInode(EntryInfo* entryInfo, std::unique_ptr<FileInode>* outFile);
void unlinkAllFiles();
FhgfsOpsErr moveRemoteBegin(EntryInfo* entryInfo, char* buf, size_t bufLen,
......@@ -71,7 +71,8 @@ class InodeFileStore
FhgfsOpsErr makeFileInode(FileInode* file);
FhgfsOpsErr makeFileInodeUnlocked(FileInode* file);
FhgfsOpsErr unlinkFileInodeUnlocked(EntryInfo* entryInfo, FileInode** outFile);
FhgfsOpsErr unlinkFileInodeUnlocked(EntryInfo* entryInfo,
std::unique_ptr<FileInode>* outFile);
bool existsUnlocked(std::string fileID);
bool loadAndInsertFileInodeUnlocked(EntryInfo* entryInfo, InodeMapIter& newElemIter);
......
......@@ -823,7 +823,7 @@ FhgfsOpsErr MetaStore::fsckUnlinkFileInode(const std::string& entryID)
* @param subDir may be NULL and then needs to be referenced
*/
FhgfsOpsErr MetaStore::unlinkInodeUnlocked(EntryInfo* entryInfo, DirInode* subDir,
FileInode** outInode)
std::unique_ptr<FileInode>* outInode)
{
if (this->fileStore.isInStore(entryInfo->getEntryID()))
return fileStore.unlinkFileInode(entryInfo, outInode);
......@@ -856,10 +856,10 @@ FhgfsOpsErr MetaStore::unlinkInodeUnlocked(EntryInfo* entryInfo, DirInode* subDi
* @param outFile will be set to the unlinked file and the object must then be deleted by the caller
* (can be NULL if the caller is not interested in the file)
*/
FhgfsOpsErr MetaStore::unlinkInode(EntryInfo* entryInfo, FileInode** outInode)
FhgfsOpsErr MetaStore::unlinkInode(EntryInfo* entryInfo, std::unique_ptr<FileInode>* outInode)
{
UniqueRWLock lock(rwlock, SafeRWLock_READ);
return this->unlinkInodeUnlocked(entryInfo, NULL, outInode);
return unlinkInodeUnlocked(entryInfo, NULL, outInode);
}
/**
......@@ -871,7 +871,7 @@ FhgfsOpsErr MetaStore::unlinkInode(EntryInfo* entryInfo, FileInode** outInode)
* note: caller needs to delete storage chunk files. E.g. via MsgHelperUnlink::unlinkLocalFile()
*/
FhgfsOpsErr MetaStore::unlinkFileUnlocked(DirInode& subdir, const std::string& fileName,
FileInode** outInode, EntryInfo* outEntryInfo, bool& outWasInlined)
std::unique_ptr<FileInode>* outInode, EntryInfo* outEntryInfo, bool& outWasInlined)
{
FhgfsOpsErr retVal;
......@@ -925,7 +925,7 @@ FhgfsOpsErr MetaStore::unlinkFileUnlocked(DirInode& subdir, const std::string& f
* note: caller needs to delete storage chunk files. E.g. via MsgHelperUnlink::unlinkLocalFile()
*/
FhgfsOpsErr MetaStore::unlinkFile(DirInode& dir, const std::string& fileName,
EntryInfo* outEntryInfo, FileInode** outInode)
EntryInfo* outEntryInfo, std::unique_ptr<FileInode>* outInode)
{
const char* logContext = "Unlink File";
FhgfsOpsErr retVal = FhgfsOpsErr_PATHNOTEXISTS;
......@@ -975,12 +975,13 @@ FhgfsOpsErr MetaStore::unlinkFile(DirInode& dir, const std::string& fileName,
* Unlink a dirEntry with an inlined inode
*/
FhgfsOpsErr MetaStore::unlinkDirEntryWithInlinedInodeUnlocked(const std::string& entryName,
DirInode& subDir, DirEntry* dirEntry, unsigned unlinkTypeFlags, FileInode** outInode)
DirInode& subDir, DirEntry* dirEntry, unsigned unlinkTypeFlags,
std::unique_ptr<FileInode>* outInode)
{
const char* logContext = "Unlink DirEntry with inlined inode";
if (outInode)
*outInode = nullptr;
outInode->reset();
std::string parentEntryID = subDir.getID();
......@@ -1095,7 +1096,7 @@ FhgfsOpsErr MetaStore::unlinkDirEntryWithInlinedInodeUnlocked(const std::string&
if (outInode && numHardlinks < 2)
{
inode->setIsInlined(false); // last dirEntry gone, so not inlined anymore
*outInode = inode->clone();
outInode->reset(inode->clone());
}
releaseFileUnlocked(subDir, inode);
......@@ -1107,7 +1108,8 @@ FhgfsOpsErr MetaStore::unlinkDirEntryWithInlinedInodeUnlocked(const std::string&
* Unlink seperated dirEntry and Inode
*/
FhgfsOpsErr MetaStore::unlinkDentryAndInodeUnlocked(const std::string& fileName,
DirInode& subdir, DirEntry* dirEntry, unsigned unlinkTypeFlags, FileInode** outInode)
DirInode& subdir, DirEntry* dirEntry, unsigned unlinkTypeFlags,
std::unique_ptr<FileInode>* outInode)
{
// unlink dirEntry first
FhgfsOpsErr retVal = subdir.unlinkDirEntryUnlocked(fileName, dirEntry, unlinkTypeFlags);
......@@ -1125,7 +1127,7 @@ FhgfsOpsErr MetaStore::unlinkDentryAndInodeUnlocked(const std::string& fileName,
dirEntry->getEntryInfo(parentEntryID, addionalEntryInfoFlags, &entryInfo);
FhgfsOpsErr unlinkFileRes = this->unlinkInodeUnlocked(&entryInfo, &subdir, outInode);
FhgfsOpsErr unlinkFileRes = unlinkInodeUnlocked(&entryInfo, &subdir, outInode);
if(unlinkFileRes != FhgfsOpsErr_SUCCESS && unlinkFileRes == FhgfsOpsErr_INUSE)
retVal = FhgfsOpsErr_INUSE;
......
......@@ -56,20 +56,20 @@ class MetaStore
FhgfsOpsErr makeDirInode(DirInode& dir, const CharVector& defaultACLXAttr,
const CharVector& accessACLXAttr);
FhgfsOpsErr removeDirInode(const std::string& dirID, bool isBuddyMirrored);
FhgfsOpsErr unlinkInode(EntryInfo* entryInfo, FileInode** outInode);
FhgfsOpsErr unlinkInode(EntryInfo* entryInfo, std::unique_ptr<FileInode>* outInode);
FhgfsOpsErr fsckUnlinkFileInode(const std::string& entryID);
FhgfsOpsErr unlinkFile(DirInode& dir, const std::string& fileName,
EntryInfo* outEntryInfo, FileInode** outFile);
EntryInfo* outEntryInfo, std::unique_ptr<FileInode>* outFile);
FhgfsOpsErr unlinkInodeLater(EntryInfo* entryInfo, bool wasInlined);
FhgfsOpsErr renameInSameDir(DirInode& parentDir, const std::string& fromName,
const std::string& toName, FileInode** outUnlinkInode);
const std::string& toName, std::unique_ptr<FileInode>* outUnlinkInode);
FhgfsOpsErr moveRemoteFileInsert(EntryInfo* fromFileInfo, DirInode& toParent,
const std::string& newEntryName, const char* buf,
uint32_t bufLen, FileInode** outUnlinkedFile, EntryInfo& newFileInfo,
FileIDLock& newFileLock);
const std::string& newEntryName, const char* buf,
uint32_t bufLen, std::unique_ptr<FileInode>* outUnlinkedFile, EntryInfo& newFileInfo,
FileIDLock& newFileLock);
FhgfsOpsErr moveRemoteFileBegin(DirInode& dir, EntryInfo* entryInfo, char* buf, size_t bufLen,
size_t* outUsedBufLen);
......@@ -119,21 +119,22 @@ class MetaStore
DirEntryType entryType, FileInode* inode);
FhgfsOpsErr unlinkInodeUnlocked(EntryInfo* entryInfo, DirInode* subDir,
FileInode** outInode);
std::unique_ptr<FileInode>* outInode);
FhgfsOpsErr unlinkInodeLaterUnlocked(EntryInfo* entryInfo, bool wasInlined);
FhgfsOpsErr unlinkFileUnlocked(DirInode& subdir, const std::string& fileName,
FileInode** outInode, EntryInfo* outEntryInfo, bool& outWasInlined);
std::unique_ptr<FileInode>* outInode, EntryInfo* outEntryInfo, bool& outWasInlined);
FhgfsOpsErr unlinkDirEntryWithInlinedInodeUnlocked(const std::string& fileName,
DirInode& subdir, DirEntry* dirEntry, unsigned unlinkTypeFlags, FileInode** outInode);
DirInode& subdir, DirEntry* dirEntry, unsigned unlinkTypeFlags,
std::unique_ptr<FileInode>* outInode);
FhgfsOpsErr unlinkDentryAndInodeUnlocked(const std::string& fileName, DirInode& subdir,
DirEntry* dirEntry, unsigned unlinkTypeFlags, FileInode** outInode);
DirEntry* dirEntry, unsigned unlinkTypeFlags, std::unique_ptr<FileInode>* outInode);
FhgfsOpsErr unlinkOverwrittenEntry(DirInode& parentDir, DirEntry* overWrittenEntry,
FileInode** outInode);
std::unique_ptr<FileInode>* outInode);
FhgfsOpsErr unlinkOverwrittenEntryUnlocked(DirInode& parentDir, DirEntry* overWrittenEntry,
FileInode** outInode);
std::unique_ptr<FileInode>* outInode);
DirInode* referenceDirUnlocked(const std::string& dirID, bool isBuddyMirrored,
......
......@@ -22,7 +22,7 @@
* existed).
*/
FhgfsOpsErr MetaStore::renameInSameDir(DirInode& parentDir, const std::string& fromName,
const std::string& toName, FileInode** outUnlinkInode)
const std::string& toName, std::unique_ptr<FileInode>* outUnlinkInode)
{
const char* logContext = "Rename in dir";
......@@ -59,7 +59,7 @@ FhgfsOpsErr MetaStore::renameInSameDir(DirInode& parentDir, const std::string& f
}
else
{
*outUnlinkInode = nullptr;
outUnlinkInode->reset();
// irrelevant values, just to please the compiler
unlinkRes = FhgfsOpsErr_SUCCESS;
......@@ -129,7 +129,7 @@ FhgfsOpsErr MetaStore::renameInSameDir(DirInode& parentDir, const std::string& f
* We lock everything ourself
*/
FhgfsOpsErr MetaStore::unlinkOverwrittenEntry(DirInode& parentDir,
DirEntry* overWrittenEntry, FileInode** outInode)
DirEntry* overWrittenEntry, std::unique_ptr<FileInode>* outInode)
{
SafeRWLock safeLock(&rwlock, SafeRWLock_READ); // L O C K
SafeRWLock parentLock(&parentDir.rwlock, SafeRWLock_WRITE);
......@@ -150,7 +150,7 @@ FhgfsOpsErr MetaStore::unlinkOverwrittenEntry(DirInode& parentDir,
* parentDir : Write-lock
*/
FhgfsOpsErr MetaStore::unlinkOverwrittenEntryUnlocked(DirInode& parentDir,
DirEntry* overWrittenEntry, FileInode** outInode)
DirEntry* overWrittenEntry, std::unique_ptr<FileInode>* outInode)
{
FhgfsOpsErr unlinkRes;
......@@ -159,7 +159,7 @@ FhgfsOpsErr MetaStore::unlinkOverwrittenEntryUnlocked(DirInode& parentDir,
/* We advise the calling code not to try to delete the entryName dentry,
* as renameEntryUnlocked() already did that */
unlinkRes = unlinkDirEntryWithInlinedInodeUnlocked("", parentDir, overWrittenEntry,
DirEntry_UNLINK_ID, outInode);
DirEntry_UNLINK_ID, outInode);
}
else
{
......@@ -330,15 +330,15 @@ FhgfsOpsErr MetaStore::checkRenameOverwrite(EntryInfo* fromEntry, EntryInfo* ove
* corresponding object; may not be NULL
*/
FhgfsOpsErr MetaStore::moveRemoteFileInsert(EntryInfo* fromFileInfo, DirInode& toParent,
const std::string& newEntryName, const char* buf, uint32_t bufLen,
FileInode** outUnlinkedInode, EntryInfo& newFileInfo, FileIDLock& newFileLock)
const std::string& newEntryName, const char* buf, uint32_t bufLen,
std::unique_ptr<FileInode>* outUnlinkedInode, EntryInfo& newFileInfo, FileIDLock& newFileLock)
{
// note: we do not allow newEntry to be a file if the old entry was a directory (and vice versa)
const char* logContext = "rename(): Insert remote entry";
FhgfsOpsErr retVal = FhgfsOpsErr_INTERNAL;
*outUnlinkedInode = nullptr;
outUnlinkedInode->reset();
SafeRWLock safeMetaStoreLock(&rwlock, SafeRWLock_READ); // L O C K
......
......@@ -238,7 +238,12 @@ void Config::applyConfigMap(bool enableException, bool addDashes) throw(InvalidC
sysAllowNewTargets = 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("runDaemonized") )
runDaemonized = StringTk::strToBool(iter->second);
......
......@@ -180,7 +180,12 @@ void Config::applyConfigMap(bool enableException, bool addDashes) throw(InvalidC
sysResyncSafetyThresholdMins = StringTk::strToInt64(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("runDaemonized") )
runDaemonized = StringTk::strToBool(iter->second);
......
......@@ -550,6 +550,54 @@ out:
return retVal;
}
std::pair<FhgfsOpsErr, int> ChunkStore::openAndChown(const int targetFD, const std::string& path,
const int openFlags, const SessionQuotaInfo& quota)
{
// if we aren't using quota, we don't care about the file owner at all and may simply create the
// file if it does exist (and if openFlags requests it).
//
// if we are using quota, we must ensure that the owner information in of the file is correct.
// this is slightly complicated by the fact that chunk files are created *at first write*, not
// during file create itself. lazily creating chunk files enables races:
// * process A creates the chunk file by writing to it, with quota information (U1, G1)
// * process B runs chown on the file with quota information (U2, G2)
// if the chown is processed before the write the chunk file to be chowned does not exist yet,
// and subsequently will be created with incorrect quota information. fsck will detect these as
// incorrect chunk attributes when run.
//
// to reduce the impact of this, we chown() the file every time we open it - even when we open
// it only for reading. this enables the same race as before, but since reads and writes are
// expected to happen much more often than chown it is more likely that we fix a previously
// "broken" attribute set than break it.
//
// the previous implementation used setfsuid/setfsgid to create files with the same correct(racy)
// owner information, but never changed the owner afterwards. performance testing has shown that
// always calling chown() is as expensive or even cheaper than changing fsuid/fsgid twice per
// open. always calling chown() is also cheaper than checking whether the file was created (by
// calling create with O_EXCL first, then without O_CREAT if that failed).
const int fd = openat(targetFD, path.c_str(), openFlags, STORAGETK_DEFAULTCHUNKFILEMODE);
if (fd < 0)
{
if (errno == EACCES)
return {FhgfsOpsErr_NOTOWNER, -1};
else
return {FhgfsOpsErrTk::fromSysErr(errno), -1};
}
if (!quota.useQuota)
return {FhgfsOpsErr_SUCCESS, fd};
if (fchown(fd, quota.uid, quota.gid))
{
LOG(ERR, "Failed to chown().", path);
unlink(path.c_str());
close(fd);
return {FhgfsOpsErr_INTERNAL, -1};
}
return {FhgfsOpsErr_SUCCESS, fd};
}
/**
* Create the chunkFile given by chunkFilePathStr and if that fails try to create the
......@@ -564,17 +612,6 @@ FhgfsOpsErr ChunkStore::openChunkFile(int targetFD, Path* chunkDirPath,
const char* logContext = "ChunkStore create chunkFile";
FhgfsOpsErr retVal = FhgfsOpsErr_INTERNAL;
mode_t openMode = STORAGETK_DEFAULTCHUNKFILEMODE;
int fd;
unsigned quotaUID = quotaInfo->uid;
unsigned quotaGID = quotaInfo->gid;
unsigned processUID;
unsigned processGID;
unsigned previousUID;
unsigned previousGID;
ExceededQuotaStore* exQuotaStore = Program::getApp()->getExceededQuotaStore();
// enforce quota only when the client has quota enabled
......@@ -596,97 +633,54 @@ FhgfsOpsErr ChunkStore::openChunkFile(int targetFD, Path* chunkDirPath,
exceededError) + " UID: " + StringTk::uintToStr(quotaInfo->uid) + " ; GID: " +
StringTk::uintToStr(quotaInfo->gid) );
retVal = FhgfsOpsErr_DQUOT;
goto out;
return FhgfsOpsErr_DQUOT;
}
}
}
}
if (quotaInfo->useQuota)
System::setFsIDs(quotaUID, quotaGID, &processUID, &processGID); // S E T _ U I D
fd = openat(targetFD, chunkFilePathStr.c_str(), openFlags, openMode);
if (fd == -1)
{ // hash dir didn't exist yet or real error?
// reset IDs to process ID
if (quotaInfo->useQuota)
System::setFsIDs(processUID, processGID, &previousUID, &previousGID); //R E S E T _ U I D
if(errno == ENOENT)
{ // hash dir just didn't exist yet => create it and open again
Path chunkDirPathTmp;
if (!chunkDirPath)
{
chunkDirPathTmp = chunkFilePathStr;
chunkDirPathTmp = chunkDirPathTmp.dirname();
chunkDirPath = &chunkDirPathTmp;
}
ChunkDir* lastChunkDirElement;
bool createPathRes = mkdirChunkDirPath(targetFD, chunkDirPath, hasOrigFeature,
&lastChunkDirElement);
if(!createPathRes)
{
int errCode = errno;
LogContext(logContext).logErr("Unable to create path for file: " +
chunkFilePathStr + ". " + "SysErr: " + System::getErrString(errCode) );
retVal = FhgfsOpsErrTk::fromSysErr(errCode);
goto out;
}
if (quotaInfo->useQuota)
System::setFsIDs(quotaUID, quotaGID, &processUID, &processGID); // S E T _ U I D
std::tie(retVal, *outFD) = openAndChown(targetFD, chunkFilePathStr, openFlags, *quotaInfo);
if (retVal == FhgfsOpsErr_SUCCESS)
return FhgfsOpsErr_SUCCESS;
// dir created => try file open/create again...
fd = openat(targetFD, chunkFilePathStr.c_str(), openFlags, openMode);
// hash dir didn't exist yet or real error?
if (retVal == FhgfsOpsErr_PATHNOTEXISTS)
{ // hash dir just didn't exist yet => create it and open again
Path chunkDirPathTmp;
if (!chunkDirPath)
{
chunkDirPathTmp = chunkFilePathStr;
chunkDirPathTmp = chunkDirPathTmp.dirname();
chunkDirPath = &chunkDirPathTmp;
}
// reset IDs to process ID
if (quotaInfo->useQuota)
System::setFsIDs(processUID, processGID, &previousUID, &previousGID);//R E S E T _ U I D
ChunkDir* lastChunkDirElement;
if (lastChunkDirElement) // old V2 files do not get this
{
/* Unlock and release the last element once we have created
* (or at least tried to create) the file. */
lastChunkDirElement->unlock();
releaseDir(lastChunkDirElement->getID() );
}
}
else
if (errno == EACCES)
bool createPathRes = mkdirChunkDirPath(targetFD, chunkDirPath, hasOrigFeature,
&lastChunkDirElement);
if(!createPathRes)
{
retVal = FhgfsOpsErr_NOTOWNER;
goto out;
int errCode = errno;
LOG(ERR, "Unable to create path for file.", chunkFilePathStr, sysErr());
return FhgfsOpsErrTk::fromSysErr(errCode);
}
if(unlikely(fd == -1) )
{ // error
LogContext(logContext).logErr(
"Failed to create file: " + chunkFilePathStr + ". " +
"SysErr: " + System::getErrString() );
// dir created => try file open/create again...
std::tie(retVal, *outFD) = openAndChown(targetFD, chunkFilePathStr, openFlags, *quotaInfo);
retVal = FhgfsOpsErrTk::fromSysErr(errno);
goto out;
if (lastChunkDirElement) // old V2 files do not get this
{
/* Unlock and release the last element once we have created
* (or at least tried to create) the file. */
lastChunkDirElement->unlock();
releaseDir(lastChunkDirElement->getID() );
}
}
else
{ // success
// reset IDs to process ID
if (quotaInfo->useQuota)
System::setFsIDs(processUID, processGID, &previousUID, &previousGID); // R E S E T _ U I D
}
// success
if (retVal != FhgfsOpsErr_SUCCESS)
LOG(ERR, "Failed to create file.", chunkFilePathStr, retVal);
retVal = FhgfsOpsErr_SUCCESS;
*outFD = fd;
out:
return retVal;
}
......
......@@ -86,6 +86,9 @@ class ChunkStore
bool mkdirChunkDirPath(int targetFD, Path* chunkDirPath, bool hasOrigFeature,
ChunkDir** outChunkDir);
std::pair<FhgfsOpsErr, int> openAndChown(const int targetFD, const std::string& path,
const int openFlags, const SessionQuotaInfo& quota);
// inlined
/**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment