diff --git a/src/common/lock.c b/src/common/lock.c index 29b4d0b6c..c88298c6e 100644 --- a/src/common/lock.c +++ b/src/common/lock.c @@ -245,37 +245,6 @@ lockAcquire( FUNCTION_LOG_RETURN(BOOL, result); } -/**********************************************************************************************************************************/ -bool -lockClear(bool failOnNoLock) -{ - FUNCTION_LOG_BEGIN(logLevelTrace); - FUNCTION_LOG_PARAM(BOOL, failOnNoLock); - FUNCTION_LOG_END(); - - bool result = false; - - if (lockTypeHeld == lockTypeNone) - { - if (failOnNoLock) - THROW(AssertError, "no lock is held by this process"); - } - else - { - // Clear locks - LockType lockMin = lockTypeHeld == lockTypeAll ? lockTypeArchive : lockTypeHeld; - LockType lockMax = lockTypeHeld == lockTypeAll ? (lockTypeAll - 1) : lockTypeHeld; - - for (LockType lockIdx = lockMin; lockIdx <= lockMax; lockIdx++) - strFree(lockFile[lockIdx]); - - lockTypeHeld = lockTypeNone; - result = true; - } - - FUNCTION_LOG_RETURN(BOOL, result); -} - /**********************************************************************************************************************************/ bool lockRelease(bool failOnNoLock) diff --git a/src/common/lock.h b/src/common/lock.h index 42cc4df72..11c4cc479 100644 --- a/src/common/lock.h +++ b/src/common/lock.h @@ -34,10 +34,6 @@ Functions bool lockAcquire( const String *lockPath, const String *stanza, const String *execId, LockType lockType, TimeMSec lockTimeout, bool failOnNoLock); -// Clear the lock without releasing it. This is used by a master process after it has spawned a child so the child can keep the -// lock and the master process won't try to free it. -bool lockClear(bool failOnNoLock); - // Release a lock bool lockRelease(bool failOnNoLock); diff --git a/test/src/module/command/archiveGetTest.c b/test/src/module/command/archiveGetTest.c index 5bb68d387..b766ac599 100644 --- a/test/src/module/command/archiveGetTest.c +++ b/test/src/module/command/archiveGetTest.c @@ -6,6 +6,8 @@ Test Archive Get Command #include "common/harnessFork.h" #include "common/io/bufferRead.h" #include "common/io/bufferWrite.h" +#include "common/io/fdRead.h" +#include "common/io/fdWrite.h" #include "postgres/interface.h" #include "postgres/version.h" #include "storage/posix/storage.h" @@ -701,16 +703,52 @@ testRun(void) // Make sure the process times out when it can't get a lock // ------------------------------------------------------------------------------------------------------------------------- + HARNESS_FORK_BEGIN() + { + HARNESS_FORK_CHILD_BEGIN(0, true) + { + IoRead *read = ioFdReadNew(strNew("child read"), HARNESS_FORK_CHILD_READ(), 2000); + ioReadOpen(read); + IoWrite *write = ioFdWriteNew(strNew("child write"), HARNESS_FORK_CHILD_WRITE(), 2000); + ioWriteOpen(write); + TEST_RESULT_VOID( lockAcquire( - cfgOptionStr(cfgOptLockPath), cfgOptionStr(cfgOptStanza), STRDEF("999-dededede"), cfgLockType(), 30000, true), + cfgOptionStr(cfgOptLockPath), cfgOptionStr(cfgOptStanza), STRDEF("999-dededede"), cfgLockType(), 30000, + true), "acquire lock"); - TEST_RESULT_VOID(lockClear(true), "clear lock"); + + // Let the parent know the lock has been acquired and wait for the parent to allow lock release + ioWriteStrLine(write, strNew("")); + ioWriteFlush(write); + ioReadLine(read); + + lockRelease(true); + } + HARNESS_FORK_CHILD_END(); + + HARNESS_FORK_PARENT_BEGIN() + { + IoRead *read = ioFdReadNew(strNew("parent read"), HARNESS_FORK_PARENT_READ_PROCESS(0), 2000); + ioReadOpen(read); + IoWrite *write = ioFdWriteNew(strNew("parent write"), HARNESS_FORK_PARENT_WRITE_PROCESS(0), 2000); + ioWriteOpen(write); + + // Wait for the child to acquire the lock + ioReadLine(read); TEST_RESULT_INT(cmdArchiveGet(), 1, "timeout waiting for lock"); harnessLogResult("P00 INFO: unable to find 000000010000000100000001 in the archive asynchronously"); + // Notify the child to release the lock + ioWriteLine(write, bufNew(0)); + ioWriteFlush(write); + } + HARNESS_FORK_PARENT_END(); + } + HARNESS_FORK_END(); + // ------------------------------------------------------------------------------------------------------------------------- strLstAddZ(argList, BOGUS_STR); harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList)); diff --git a/test/src/module/common/lockTest.c b/test/src/module/common/lockTest.c index 27a78449b..db533095e 100644 --- a/test/src/module/common/lockTest.c +++ b/test/src/module/common/lockTest.c @@ -117,7 +117,7 @@ testRun(void) } // ***************************************************************************************************************************** - if (testBegin("lockAcquire(), lockRelease(), and lockClear()")) + if (testBegin("lockAcquire(), lockRelease()")) { String *stanza = strNew("test"); String *lockPath = strNew(testPath()); @@ -129,9 +129,6 @@ testRun(void) TEST_ERROR(lockRelease(true), AssertError, "no lock is held by this process"); TEST_RESULT_BOOL(lockRelease(false), false, "release when there is no lock"); - TEST_ERROR(lockClear(true), AssertError, "no lock is held by this process"); - TEST_RESULT_BOOL(lockClear(false), false, "release when there is no lock"); - // ------------------------------------------------------------------------------------------------------------------------- TEST_ASSIGN(lockFdTest, lockAcquireFile(archiveLockFile, STRDEF("1-test"), 0, true), "archive lock by file"); TEST_RESULT_BOOL( @@ -178,38 +175,26 @@ testRun(void) TEST_ERROR( lockAcquire(lockPath, stanza, STRDEF("1-test"), lockTypeAll, 0, false), AssertError, "assertion 'failOnNoLock || lockType != lockTypeAll' failed"); - TEST_RESULT_VOID(lockRelease(true), "release all lock"); + TEST_RESULT_VOID(lockRelease(true), "release all locks"); - // ------------------------------------------------------------------------------------------------------------------------- - TEST_RESULT_BOOL(lockAcquire(lockPath, stanza, STRDEF("1-test"), lockTypeBackup, 0, true), true, "backup lock"); - - lockFdTest = lockFd[lockTypeBackup]; - String *lockFileTest = strDup(lockFile[lockTypeBackup]); - - TEST_RESULT_VOID(lockClear(true), "clear backup lock"); - TEST_RESULT_BOOL(storageExistsP(storageTest, backupLockFile), true, "backup lock file still exists"); - lockReleaseFile(lockFdTest, lockFileTest); + TEST_RESULT_BOOL(storageExistsP(storageTest, archiveLockFile), false, "archive lock file was removed"); + TEST_RESULT_BOOL(storageExistsP(storageTest, backupLockFile), false, "backup lock file was removed"); // ------------------------------------------------------------------------------------------------------------------------- TEST_TITLE("acquire lock on the same exec-id and release"); TEST_RESULT_BOOL(lockAcquire(lockPath, stanza, STRDEF("1-test"), lockTypeBackup, 0, true), true, "backup lock"); + // Make it look there is no lock lockFdTest = lockFd[lockTypeBackup]; - lockFileTest = strDup(lockFile[lockTypeBackup]); - - TEST_RESULT_VOID(lockClear(true), "clear backup lock"); + String *lockFileTest = strDup(lockFile[lockTypeBackup]); + lockTypeHeld = lockTypeNone; TEST_RESULT_BOOL(lockAcquire(lockPath, stanza, STRDEF("1-test"), lockTypeBackup, 0, true), true, "backup lock again"); TEST_RESULT_VOID(lockRelease(true), "release backup lock"); + // Release lock manually lockReleaseFile(lockFdTest, lockFileTest); - - // ------------------------------------------------------------------------------------------------------------------------- - TEST_RESULT_BOOL(lockAcquire(lockPath, stanza, STRDEF("1-test"), lockTypeAll, 0, true), true, "all lock"); - TEST_RESULT_VOID(lockClear(true), "clear all lock"); - TEST_RESULT_BOOL(storageExistsP(storageTest, archiveLockFile), true, "archive lock file still exists"); - TEST_RESULT_BOOL(storageExistsP(storageTest, backupLockFile), true, "backup lock file still exists"); } FUNCTION_HARNESS_RETURN_VOID();