mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2024-12-14 10:13:05 +02:00
Add lock module initialization.
Each call to lockAcquireP() passed enough information to initialize the lock system. This was somewhat inefficient and as locks become more complicated it will lead to more code duplication. Since a process can only take one type of lock it makes sense to do most of the initialization up front. Also reduce the log level of lockRelease() since it is only called at exit and the lock will be released in any case.
This commit is contained in:
parent
f1caecc4ff
commit
8ff956ad7e
@ -463,9 +463,7 @@ HRN_FORK_BEGIN()
|
|||||||
{
|
{
|
||||||
HRN_FORK_CHILD_BEGIN()
|
HRN_FORK_CHILD_BEGIN()
|
||||||
{
|
{
|
||||||
TEST_RESULT_INT_NE(
|
TEST_RESULT_INT_NE(lockAcquireP(), -1, "create backup/expire lock");
|
||||||
lockAcquireP(cfgOptionStr(cfgOptLockPath), STRDEF("stanza1"), STRDEF("999-ffffffff"), lockTypeBackup), -1,
|
|
||||||
"create backup/expire lock");
|
|
||||||
|
|
||||||
// Notify parent that lock has been acquired
|
// Notify parent that lock has been acquired
|
||||||
HRN_FORK_CHILD_NOTIFY_PUT();
|
HRN_FORK_CHILD_NOTIFY_PUT();
|
||||||
|
@ -530,9 +530,7 @@ HRN_FORK_BEGIN()
|
|||||||
{
|
{
|
||||||
HRN_FORK_CHILD_BEGIN()
|
HRN_FORK_CHILD_BEGIN()
|
||||||
{
|
{
|
||||||
TEST_RESULT_INT_NE(
|
TEST_RESULT_INT_NE(lockAcquireP(), -1, "create backup/expire lock");
|
||||||
lockAcquireP(cfgOptionStr(cfgOptLockPath), STRDEF("stanza1"), STRDEF("999-ffffffff"), lockTypeBackup), -1,
|
|
||||||
"create backup/expire lock");
|
|
||||||
|
|
||||||
// Notify parent that lock has been acquired
|
// Notify parent that lock has been acquired
|
||||||
HRN_FORK_CHILD_NOTIFY_PUT();
|
HRN_FORK_CHILD_NOTIFY_PUT();
|
||||||
|
@ -718,10 +718,7 @@ cmdArchiveGet(void)
|
|||||||
// If the WAL segment has not already been found then start the async process to get it. There's no point in
|
// If the WAL segment has not already been found then start the async process to get it. There's no point in
|
||||||
// forking the async process off more than once so track that as well. Use an archive lock to prevent forking if
|
// forking the async process off more than once so track that as well. Use an archive lock to prevent forking if
|
||||||
// the async process was launched by another process.
|
// the async process was launched by another process.
|
||||||
if (!forked && (!found || !queueFull) &&
|
if (!forked && (!found || !queueFull) && lockAcquireP(.returnOnNoLock = true))
|
||||||
lockAcquireP(
|
|
||||||
cfgOptionStr(cfgOptLockPath), cfgOptionStr(cfgOptStanza), cfgOptionStr(cfgOptExecId), cfgLockType(),
|
|
||||||
.returnOnNoLock = true))
|
|
||||||
{
|
{
|
||||||
// Get control info
|
// Get control info
|
||||||
PgControl pgControl = pgControlFromFile(storagePg(), cfgOptionStrNull(cfgOptPgVersionForce));
|
PgControl pgControl = pgControlFromFile(storagePg(), cfgOptionStrNull(cfgOptPgVersionForce));
|
||||||
|
@ -361,10 +361,7 @@ cmdArchivePush(void)
|
|||||||
// If the WAL segment has not already been pushed then start the async process to push it. There's no point in
|
// If the WAL segment has not already been pushed then start the async process to push it. There's no point in
|
||||||
// forking the async process off more than once so track that as well. Use an archive lock to prevent more than
|
// forking the async process off more than once so track that as well. Use an archive lock to prevent more than
|
||||||
// one async process being launched.
|
// one async process being launched.
|
||||||
if (!pushed && !forked &&
|
if (!pushed && !forked && lockAcquireP(.returnOnNoLock = true))
|
||||||
lockAcquireP(
|
|
||||||
cfgOptionStr(cfgOptLockPath), cfgOptionStr(cfgOptStanza), cfgOptionStr(cfgOptExecId), cfgLockType(),
|
|
||||||
.returnOnNoLock = true))
|
|
||||||
{
|
{
|
||||||
// The async process should not output on the console at all
|
// The async process should not output on the console at all
|
||||||
KeyValue *optionReplace = kvNew();
|
KeyValue *optionReplace = kvNew();
|
||||||
|
@ -77,8 +77,7 @@ cmdRemote(ProtocolServer *const server)
|
|||||||
lockStopTest();
|
lockStopTest();
|
||||||
|
|
||||||
// Acquire the lock
|
// Acquire the lock
|
||||||
lockAcquireP(
|
lockAcquireP();
|
||||||
cfgOptionStr(cfgOptLockPath), cfgOptionStr(cfgOptStanza), cfgOptionStr(cfgOptExecId), cfgLockType());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,18 +51,48 @@ Mem context and local variables
|
|||||||
static struct LockLocal
|
static struct LockLocal
|
||||||
{
|
{
|
||||||
MemContext *memContext; // Mem context for locks
|
MemContext *memContext; // Mem context for locks
|
||||||
LockType held; // Current lock type held
|
const String *path; // Lock path
|
||||||
const String *execId; // Process exec id
|
const String *execId; // Process exec id
|
||||||
|
const String *stanza; // Stanza
|
||||||
|
LockType type; // Lock type
|
||||||
|
bool held; // Is the lock being held?
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
String *name; // Name of lock file
|
String *name; // Name of lock file
|
||||||
int fd; // File descriptor for lock file
|
int fd; // File descriptor for lock file
|
||||||
} file[lockTypeAll];
|
} file[lockTypeAll];
|
||||||
} lockLocal =
|
} lockLocal;
|
||||||
|
|
||||||
|
/**********************************************************************************************************************************/
|
||||||
|
FN_EXTERN void
|
||||||
|
lockInit(const String *const path, const String *const execId, const String *const stanza, const LockType type)
|
||||||
{
|
{
|
||||||
.held = lockTypeNone,
|
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||||
};
|
FUNCTION_LOG_PARAM(STRING, path);
|
||||||
|
FUNCTION_LOG_PARAM(STRING, execId);
|
||||||
|
FUNCTION_LOG_PARAM(ENUM, type);
|
||||||
|
FUNCTION_LOG_END();
|
||||||
|
|
||||||
|
ASSERT(lockLocal.memContext == NULL);
|
||||||
|
|
||||||
|
// Allocate a mem context to hold lock info
|
||||||
|
MEM_CONTEXT_BEGIN(memContextTop())
|
||||||
|
{
|
||||||
|
MEM_CONTEXT_NEW_BEGIN(Lock, .childQty = MEM_CONTEXT_QTY_MAX)
|
||||||
|
{
|
||||||
|
lockLocal.memContext = MEM_CONTEXT_NEW();
|
||||||
|
lockLocal.path = strDup(path);
|
||||||
|
lockLocal.execId = strDup(execId);
|
||||||
|
lockLocal.stanza = strDup(stanza);
|
||||||
|
lockLocal.type = type;
|
||||||
|
}
|
||||||
|
MEM_CONTEXT_NEW_END();
|
||||||
|
}
|
||||||
|
MEM_CONTEXT_END();
|
||||||
|
|
||||||
|
FUNCTION_LOG_RETURN_VOID();
|
||||||
|
}
|
||||||
|
|
||||||
/**********************************************************************************************************************************/
|
/**********************************************************************************************************************************/
|
||||||
FN_EXTERN String *
|
FN_EXTERN String *
|
||||||
@ -257,7 +287,7 @@ lockWriteData(const LockType lockType, const LockWriteDataParam param)
|
|||||||
|
|
||||||
jsonWriteObjectEnd(json);
|
jsonWriteObjectEnd(json);
|
||||||
|
|
||||||
if (lockType == lockTypeBackup && lockLocal.held != lockTypeNone)
|
if (lockType == lockTypeBackup && lockLocal.held)
|
||||||
{
|
{
|
||||||
// Seek to beginning of backup lock file
|
// Seek to beginning of backup lock file
|
||||||
THROW_ON_SYS_ERROR_FMT(
|
THROW_ON_SYS_ERROR_FMT(
|
||||||
@ -391,59 +421,34 @@ lockAcquireFile(const String *const lockFile, const TimeMSec lockTimeout, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
FN_EXTERN bool
|
FN_EXTERN bool
|
||||||
lockAcquire(
|
lockAcquire(const LockAcquireParam param)
|
||||||
const String *const lockPath, const String *const stanza, const String *const execId, const LockType lockType,
|
|
||||||
const LockAcquireParam param)
|
|
||||||
{
|
{
|
||||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||||
FUNCTION_LOG_PARAM(STRING, lockPath);
|
|
||||||
FUNCTION_LOG_PARAM(STRING, stanza);
|
|
||||||
FUNCTION_LOG_PARAM(STRING, execId);
|
|
||||||
FUNCTION_LOG_PARAM(ENUM, lockType);
|
|
||||||
FUNCTION_LOG_PARAM(TIMEMSEC, param.timeout);
|
FUNCTION_LOG_PARAM(TIMEMSEC, param.timeout);
|
||||||
FUNCTION_LOG_PARAM(BOOL, param.returnOnNoLock);
|
FUNCTION_LOG_PARAM(BOOL, param.returnOnNoLock);
|
||||||
FUNCTION_LOG_END();
|
FUNCTION_LOG_END();
|
||||||
|
|
||||||
ASSERT(lockPath != NULL);
|
ASSERT(lockLocal.memContext != NULL);
|
||||||
ASSERT(stanza != NULL);
|
|
||||||
ASSERT(execId != NULL);
|
|
||||||
|
|
||||||
bool result = true;
|
bool result = true;
|
||||||
|
|
||||||
// Don't allow failures when locking more than one file. This makes cleanup difficult and there are no known use cases.
|
// Don't allow failures when locking more than one file. This makes cleanup difficult and there are no known use cases.
|
||||||
ASSERT(!param.returnOnNoLock || lockType != lockTypeAll);
|
ASSERT(!param.returnOnNoLock || lockLocal.type != lockTypeAll);
|
||||||
|
|
||||||
// Don't allow another lock if one is already held
|
// Don't allow another lock if one is already held
|
||||||
if (lockLocal.held != lockTypeNone)
|
if (lockLocal.held)
|
||||||
THROW(AssertError, "lock is already held by this process");
|
THROW(AssertError, "lock is already held by this process");
|
||||||
|
|
||||||
// Allocate a mem context to hold lock filenames if one does not already exist
|
|
||||||
if (lockLocal.memContext == NULL)
|
|
||||||
{
|
|
||||||
MEM_CONTEXT_BEGIN(memContextTop())
|
|
||||||
{
|
|
||||||
MEM_CONTEXT_NEW_BEGIN(Lock, .childQty = MEM_CONTEXT_QTY_MAX)
|
|
||||||
{
|
|
||||||
lockLocal.memContext = MEM_CONTEXT_NEW();
|
|
||||||
lockLocal.execId = strDup(execId);
|
|
||||||
}
|
|
||||||
MEM_CONTEXT_NEW_END();
|
|
||||||
}
|
|
||||||
MEM_CONTEXT_END();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Exec id should never change
|
|
||||||
ASSERT(strEq(execId, lockLocal.execId));
|
|
||||||
|
|
||||||
// Lock files
|
// Lock files
|
||||||
LockType lockMin = lockType == lockTypeAll ? lockTypeArchive : lockType;
|
LockType lockMin = lockLocal.type == lockTypeAll ? lockTypeArchive : lockLocal.type;
|
||||||
LockType lockMax = lockType == lockTypeAll ? (lockTypeAll - 1) : lockType;
|
LockType lockMax = lockLocal.type == lockTypeAll ? (lockTypeAll - 1) : lockLocal.type;
|
||||||
|
|
||||||
for (LockType lockIdx = lockMin; lockIdx <= lockMax; lockIdx++)
|
for (LockType lockIdx = lockMin; lockIdx <= lockMax; lockIdx++)
|
||||||
{
|
{
|
||||||
MEM_CONTEXT_BEGIN(lockLocal.memContext)
|
MEM_CONTEXT_BEGIN(lockLocal.memContext)
|
||||||
{
|
{
|
||||||
lockLocal.file[lockIdx].name = strNewFmt("%s/%s", strZ(lockPath), strZ(lockFileName(stanza, lockIdx)));
|
strFree(lockLocal.file[lockIdx].name);
|
||||||
|
lockLocal.file[lockIdx].name = strNewFmt("%s/%s", strZ(lockLocal.path), strZ(lockFileName(lockLocal.stanza, lockIdx)));
|
||||||
}
|
}
|
||||||
MEM_CONTEXT_END();
|
MEM_CONTEXT_END();
|
||||||
|
|
||||||
@ -451,10 +456,8 @@ lockAcquire(
|
|||||||
|
|
||||||
if (lockLocal.file[lockIdx].fd == -1)
|
if (lockLocal.file[lockIdx].fd == -1)
|
||||||
{
|
{
|
||||||
// Free the lock context and reset lock data
|
// Free the lock
|
||||||
memContextFree(lockLocal.memContext);
|
lockLocal.held = false;
|
||||||
lockLocal = (struct LockLocal){.held = lockTypeNone};
|
|
||||||
|
|
||||||
result = false;
|
result = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -464,7 +467,7 @@ lockAcquire(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (result)
|
if (result)
|
||||||
lockLocal.held = lockType;
|
lockLocal.held = true;
|
||||||
|
|
||||||
FUNCTION_LOG_RETURN(BOOL, result);
|
FUNCTION_LOG_RETURN(BOOL, result);
|
||||||
}
|
}
|
||||||
@ -497,13 +500,13 @@ lockReleaseFile(const int lockFd, const String *const lockFile)
|
|||||||
FN_EXTERN bool
|
FN_EXTERN bool
|
||||||
lockRelease(bool failOnNoLock)
|
lockRelease(bool failOnNoLock)
|
||||||
{
|
{
|
||||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||||
FUNCTION_LOG_PARAM(BOOL, failOnNoLock);
|
FUNCTION_LOG_PARAM(BOOL, failOnNoLock);
|
||||||
FUNCTION_LOG_END();
|
FUNCTION_LOG_END();
|
||||||
|
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
if (lockLocal.held == lockTypeNone)
|
if (!lockLocal.held)
|
||||||
{
|
{
|
||||||
if (failOnNoLock)
|
if (failOnNoLock)
|
||||||
THROW(AssertError, "no lock is held by this process");
|
THROW(AssertError, "no lock is held by this process");
|
||||||
@ -511,8 +514,8 @@ lockRelease(bool failOnNoLock)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Release locks
|
// Release locks
|
||||||
LockType lockMin = lockLocal.held == lockTypeAll ? lockTypeArchive : lockLocal.held;
|
LockType lockMin = lockLocal.type == lockTypeAll ? lockTypeArchive : lockLocal.type;
|
||||||
LockType lockMax = lockLocal.held == lockTypeAll ? (lockTypeAll - 1) : lockLocal.held;
|
LockType lockMax = lockLocal.type == lockTypeAll ? (lockTypeAll - 1) : lockLocal.type;
|
||||||
|
|
||||||
for (LockType lockIdx = lockMin; lockIdx <= lockMax; lockIdx++)
|
for (LockType lockIdx = lockMin; lockIdx <= lockMax; lockIdx++)
|
||||||
{
|
{
|
||||||
@ -520,10 +523,8 @@ lockRelease(bool failOnNoLock)
|
|||||||
lockReleaseFile(lockLocal.file[lockIdx].fd, lockLocal.file[lockIdx].name);
|
lockReleaseFile(lockLocal.file[lockIdx].fd, lockLocal.file[lockIdx].name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free the lock context and reset lock data
|
// Free the lock context
|
||||||
memContextFree(lockLocal.memContext);
|
lockLocal.held = false;
|
||||||
lockLocal = (struct LockLocal){.held = lockTypeNone};
|
|
||||||
|
|
||||||
result = true;
|
result = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,6 +37,9 @@ Constants
|
|||||||
/***********************************************************************************************************************************
|
/***********************************************************************************************************************************
|
||||||
Functions
|
Functions
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
|
// Initialize lock module
|
||||||
|
FN_EXTERN void lockInit(const String *path, const String *execId, const String *stanza, LockType type);
|
||||||
|
|
||||||
// Acquire a lock type. This will involve locking one or more files on disk depending on the lock type. Most operations only take a
|
// Acquire a lock type. This will involve locking one or more files on disk depending on the lock type. Most operations only take a
|
||||||
// single lock (archive or backup), but the stanza commands all need to lock both.
|
// single lock (archive or backup), but the stanza commands all need to lock both.
|
||||||
typedef struct LockAcquireParam
|
typedef struct LockAcquireParam
|
||||||
@ -46,11 +49,10 @@ typedef struct LockAcquireParam
|
|||||||
bool returnOnNoLock; // Return when no lock acquired (rather than throw an error)
|
bool returnOnNoLock; // Return when no lock acquired (rather than throw an error)
|
||||||
} LockAcquireParam;
|
} LockAcquireParam;
|
||||||
|
|
||||||
#define lockAcquireP(lockPath, stanza, execId, lockType, ...) \
|
#define lockAcquireP(...) \
|
||||||
lockAcquire(lockPath, stanza, execId, lockType, (LockAcquireParam) {VAR_PARAM_INIT, __VA_ARGS__})
|
lockAcquire((LockAcquireParam) {VAR_PARAM_INIT, __VA_ARGS__})
|
||||||
|
|
||||||
FN_EXTERN bool lockAcquire(
|
FN_EXTERN bool lockAcquire(LockAcquireParam param);
|
||||||
const String *lockPath, const String *stanza, const String *execId, LockType lockType, LockAcquireParam param);
|
|
||||||
|
|
||||||
// Release a lock
|
// Release a lock
|
||||||
FN_EXTERN bool lockRelease(bool failOnNoLock);
|
FN_EXTERN bool lockRelease(bool failOnNoLock);
|
||||||
|
@ -501,9 +501,15 @@ cfgLoad(unsigned int argListSize, const char *argList[])
|
|||||||
// Begin the command
|
// Begin the command
|
||||||
cmdBegin();
|
cmdBegin();
|
||||||
|
|
||||||
// Acquire a lock if this command requires a lock
|
// Init lock module if this command can lock
|
||||||
if (cfgLockRequired() && !cfgCommandHelp())
|
if (cfgLockType() != lockTypeNone && !cfgCommandHelp())
|
||||||
lockAcquireP(cfgOptionStr(cfgOptLockPath), cfgOptionStr(cfgOptStanza), cfgOptionStr(cfgOptExecId), cfgLockType());
|
{
|
||||||
|
lockInit(cfgOptionStr(cfgOptLockPath), cfgOptionStr(cfgOptExecId), cfgOptionStr(cfgOptStanza), cfgLockType());
|
||||||
|
|
||||||
|
// Acquire a lock if this command requires a lock
|
||||||
|
if (cfgLockRequired())
|
||||||
|
lockAcquireP();
|
||||||
|
}
|
||||||
|
|
||||||
// Update options that have complex rules
|
// Update options that have complex rules
|
||||||
cfgLoadUpdateOption();
|
cfgLoadUpdateOption();
|
||||||
|
@ -401,6 +401,12 @@ unit:
|
|||||||
name: storageHelper
|
name: storageHelper
|
||||||
shim:
|
shim:
|
||||||
storage/helper: ~
|
storage/helper: ~
|
||||||
|
harness:
|
||||||
|
name: lock
|
||||||
|
shim:
|
||||||
|
common/lock:
|
||||||
|
function:
|
||||||
|
- lockInit
|
||||||
|
|
||||||
coverage:
|
coverage:
|
||||||
- common/lock
|
- common/lock
|
||||||
|
@ -29,7 +29,8 @@ hrnCmdBackup(void)
|
|||||||
{
|
{
|
||||||
FUNCTION_HARNESS_VOID();
|
FUNCTION_HARNESS_VOID();
|
||||||
|
|
||||||
lockAcquireP(STR(testPath()), cfgOptionStr(cfgOptStanza), cfgOptionStr(cfgOptExecId), lockTypeBackup);
|
lockInit(STR(testPath()), cfgOptionStr(cfgOptExecId), cfgOptionStr(cfgOptStanza), lockTypeBackup);
|
||||||
|
lockAcquireP();
|
||||||
|
|
||||||
TRY_BEGIN()
|
TRY_BEGIN()
|
||||||
{
|
{
|
||||||
|
@ -17,6 +17,7 @@ Harness for Loading Test Configurations
|
|||||||
|
|
||||||
#include "common/harnessConfig.h"
|
#include "common/harnessConfig.h"
|
||||||
#include "common/harnessDebug.h"
|
#include "common/harnessDebug.h"
|
||||||
|
#include "common/harnessLock.h"
|
||||||
#include "common/harnessLog.h"
|
#include "common/harnessLog.h"
|
||||||
#include "common/harnessStorageHelper.h"
|
#include "common/harnessStorageHelper.h"
|
||||||
#include "common/harnessTest.h"
|
#include "common/harnessTest.h"
|
||||||
@ -99,6 +100,11 @@ hrnCfgLoad(ConfigCommand commandId, const StringList *argListParam, const HrnCfg
|
|||||||
if (cfgOptionValid(cfgOptExecId) && !cfgOptionTest(cfgOptExecId))
|
if (cfgOptionValid(cfgOptExecId) && !cfgOptionTest(cfgOptExecId))
|
||||||
cfgOptionSet(cfgOptExecId, cfgSourceParam, VARSTRDEF("1-test"));
|
cfgOptionSet(cfgOptExecId, cfgSourceParam, VARSTRDEF("1-test"));
|
||||||
|
|
||||||
|
if (cfgOptionTest(cfgOptExecId) && cfgOptionTest(cfgOptLockPath) && cfgOptionTest(cfgOptStanza))
|
||||||
|
lockInit(cfgOptionStr(cfgOptLockPath), cfgOptionStr(cfgOptExecId), cfgOptionStr(cfgOptStanza), cfgLockType());
|
||||||
|
else
|
||||||
|
hrnLockUnInit();
|
||||||
|
|
||||||
FUNCTION_HARNESS_RETURN_VOID();
|
FUNCTION_HARNESS_RETURN_VOID();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
45
test/src/common/harnessLock.c
Normal file
45
test/src/common/harnessLock.c
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/***********************************************************************************************************************************
|
||||||
|
Lock Test Harness
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
#include "build.auto.h"
|
||||||
|
|
||||||
|
#include "common/harnessDebug.h"
|
||||||
|
#include "common/harnessLock.h"
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Include shimmed C modules
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
{[SHIM_MODULE]}
|
||||||
|
|
||||||
|
/**********************************************************************************************************************************/
|
||||||
|
FN_EXTERN void
|
||||||
|
lockInit(const String *const path, const String *const execId, const String *const stanza, const LockType type)
|
||||||
|
{
|
||||||
|
FUNCTION_HARNESS_BEGIN();
|
||||||
|
FUNCTION_HARNESS_PARAM(STRING, path);
|
||||||
|
FUNCTION_HARNESS_PARAM(STRING, execId);
|
||||||
|
FUNCTION_HARNESS_PARAM(STRING, stanza);
|
||||||
|
FUNCTION_HARNESS_PARAM(ENUM, type);
|
||||||
|
FUNCTION_HARNESS_END();
|
||||||
|
|
||||||
|
hrnLockUnInit();
|
||||||
|
lockInit_SHIMMED(path, execId, stanza, type);
|
||||||
|
|
||||||
|
FUNCTION_HARNESS_RETURN_VOID();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************************************************************************/
|
||||||
|
FN_EXTERN void
|
||||||
|
hrnLockUnInit(void)
|
||||||
|
{
|
||||||
|
FUNCTION_HARNESS_VOID();
|
||||||
|
|
||||||
|
// Free mem context it it exists
|
||||||
|
if (lockLocal.memContext != NULL)
|
||||||
|
{
|
||||||
|
memContextFree(lockLocal.memContext);
|
||||||
|
lockLocal = (struct LockLocal){0};
|
||||||
|
}
|
||||||
|
|
||||||
|
FUNCTION_HARNESS_RETURN_VOID();
|
||||||
|
}
|
15
test/src/common/harnessLock.h
Normal file
15
test/src/common/harnessLock.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
/***********************************************************************************************************************************
|
||||||
|
Lock Test Harness
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
#ifndef TEST_COMMON_HARNESSLOCK_H
|
||||||
|
#define TEST_COMMON_HARNESSLOCK_H
|
||||||
|
|
||||||
|
#include "common/lock.h"
|
||||||
|
|
||||||
|
/***********************************************************************************************************************************
|
||||||
|
Functions
|
||||||
|
***********************************************************************************************************************************/
|
||||||
|
// Uninitialize lock module
|
||||||
|
FN_EXTERN void hrnLockUnInit(void);
|
||||||
|
|
||||||
|
#endif
|
@ -725,11 +725,8 @@ testRun(void)
|
|||||||
{
|
{
|
||||||
HRN_FORK_CHILD_BEGIN()
|
HRN_FORK_CHILD_BEGIN()
|
||||||
{
|
{
|
||||||
TEST_RESULT_VOID(
|
lockInit(cfgOptionStr(cfgOptLockPath), STRDEF("999-dededede"), cfgOptionStr(cfgOptStanza), cfgLockType());
|
||||||
lockAcquireP(
|
TEST_RESULT_VOID(lockAcquireP(.timeout = 30000, .returnOnNoLock = true), "acquire lock");
|
||||||
cfgOptionStr(cfgOptLockPath), cfgOptionStr(cfgOptStanza), STRDEF("999-dededede"), cfgLockType(),
|
|
||||||
.timeout = 30000, .returnOnNoLock = true),
|
|
||||||
"acquire lock");
|
|
||||||
|
|
||||||
// Notify parent that lock has been acquired
|
// Notify parent that lock has been acquired
|
||||||
HRN_FORK_CHILD_NOTIFY_PUT();
|
HRN_FORK_CHILD_NOTIFY_PUT();
|
||||||
|
@ -749,9 +749,8 @@ testRun(void)
|
|||||||
{
|
{
|
||||||
HRN_FORK_CHILD_BEGIN()
|
HRN_FORK_CHILD_BEGIN()
|
||||||
{
|
{
|
||||||
lockAcquireP(
|
lockInit(cfgOptionStr(cfgOptLockPath), STRDEF("555-fefefefe"), cfgOptionStr(cfgOptStanza), cfgLockType());
|
||||||
cfgOptionStr(cfgOptLockPath), cfgOptionStr(cfgOptStanza), STRDEF("555-fefefefe"), cfgLockType(),
|
lockAcquireP(.timeout = 30000, .returnOnNoLock = true);
|
||||||
.timeout = 30000, .returnOnNoLock = true);
|
|
||||||
|
|
||||||
// Notify parent that lock has been acquired
|
// Notify parent that lock has been acquired
|
||||||
HRN_FORK_CHILD_NOTIFY_PUT();
|
HRN_FORK_CHILD_NOTIFY_PUT();
|
||||||
|
@ -2126,9 +2126,9 @@ testRun(void)
|
|||||||
uint64_t sizeProgress = 0;
|
uint64_t sizeProgress = 0;
|
||||||
currentPercentComplete = 4567;
|
currentPercentComplete = 4567;
|
||||||
|
|
||||||
TEST_RESULT_VOID(
|
lockInit(TEST_PATH_STR, cfgOptionStr(cfgOptExecId), cfgOptionStr(cfgOptStanza), lockTypeBackup);
|
||||||
lockAcquireP(TEST_PATH_STR, cfgOptionStr(cfgOptStanza), cfgOptionStr(cfgOptExecId), lockTypeBackup),
|
TEST_RESULT_VOID(lockAcquireP(), "acquire backup lock");
|
||||||
"acquire backup lock");
|
|
||||||
TEST_RESULT_VOID(
|
TEST_RESULT_VOID(
|
||||||
backupJobResult(
|
backupJobResult(
|
||||||
manifest, STRDEF("host"), storageTest, strLstNew(), job, false, 0, &sizeProgress, ¤tPercentComplete),
|
manifest, STRDEF("host"), storageTest, strLstNew(), job, false, 0, &sizeProgress, ¤tPercentComplete),
|
||||||
|
@ -253,11 +253,8 @@ testRun(void)
|
|||||||
{
|
{
|
||||||
HRN_FORK_CHILD_BEGIN()
|
HRN_FORK_CHILD_BEGIN()
|
||||||
{
|
{
|
||||||
TEST_RESULT_BOOL(
|
lockInit(STRDEF(HRN_PATH "/lock"), cfgOptionStr(cfgOptExecId), cfgOptionStr(cfgOptStanza), lockTypeArchive);
|
||||||
lockAcquireP(
|
TEST_RESULT_BOOL(lockAcquireP(.timeout = 30000), true, "child process acquires lock");
|
||||||
STRDEF(HRN_PATH "/lock"), cfgOptionStr(cfgOptStanza), cfgOptionStr(cfgOptExecId), lockTypeArchive,
|
|
||||||
.timeout = 30000),
|
|
||||||
true, "child process acquires lock");
|
|
||||||
|
|
||||||
// Notify parent that lock has been acquired
|
// Notify parent that lock has been acquired
|
||||||
HRN_FORK_CHILD_NOTIFY_PUT();
|
HRN_FORK_CHILD_NOTIFY_PUT();
|
||||||
|
@ -107,8 +107,6 @@ testRun(void)
|
|||||||
" ERR_STACK_TRACE\n"
|
" ERR_STACK_TRACE\n"
|
||||||
" --------------------------------------------------------------------\n"
|
" --------------------------------------------------------------------\n"
|
||||||
"P00 INFO: archive-push:async command end: aborted with exception [122]\n"
|
"P00 INFO: archive-push:async command end: aborted with exception [122]\n"
|
||||||
"P00 DEBUG: " TEST_PGB_PATH "/src/common/lock::lockRelease: (failOnNoLock: false)\n"
|
|
||||||
"P00 DEBUG: " TEST_PGB_PATH "/src/common/lock::lockRelease: => false\n"
|
|
||||||
"P00 DEBUG: " TEST_PGB_PATH "/src/command/exit::exitSafe: => 122");
|
"P00 DEBUG: " TEST_PGB_PATH "/src/command/exit::exitSafe: => 122");
|
||||||
}
|
}
|
||||||
TRY_END();
|
TRY_END();
|
||||||
|
@ -236,9 +236,8 @@ testRun(void)
|
|||||||
{
|
{
|
||||||
HRN_FORK_CHILD_BEGIN()
|
HRN_FORK_CHILD_BEGIN()
|
||||||
{
|
{
|
||||||
TEST_RESULT_INT_NE(
|
lockInit(cfgOptionStr(cfgOptLockPath), STRDEF("999-ffffffff"), STRDEF("stanza1"), lockTypeBackup);
|
||||||
lockAcquireP(cfgOptionStr(cfgOptLockPath), STRDEF("stanza1"), STRDEF("999-ffffffff"), lockTypeBackup), -1,
|
TEST_RESULT_INT_NE(lockAcquireP(), -1, "create backup/expire lock");
|
||||||
"create backup/expire lock");
|
|
||||||
|
|
||||||
// Notify parent that lock has been acquired
|
// Notify parent that lock has been acquired
|
||||||
HRN_FORK_CHILD_NOTIFY_PUT();
|
HRN_FORK_CHILD_NOTIFY_PUT();
|
||||||
@ -429,9 +428,8 @@ testRun(void)
|
|||||||
{
|
{
|
||||||
HRN_FORK_CHILD_BEGIN()
|
HRN_FORK_CHILD_BEGIN()
|
||||||
{
|
{
|
||||||
TEST_RESULT_INT_NE(
|
lockInit(cfgOptionStr(cfgOptLockPath), STRDEF("777-afafafaf"), STRDEF("stanza1"), lockTypeBackup);
|
||||||
lockAcquireP(cfgOptionStr(cfgOptLockPath), STRDEF("stanza1"), STRDEF("777-afafafaf"), lockTypeBackup), -1,
|
TEST_RESULT_INT_NE(lockAcquireP(), -1, "create backup/expire lock");
|
||||||
"create backup/expire lock");
|
|
||||||
TEST_RESULT_VOID(lockWriteDataP(lockTypeBackup), "write lock data");
|
TEST_RESULT_VOID(lockWriteDataP(lockTypeBackup), "write lock data");
|
||||||
|
|
||||||
// Notify parent that lock has been acquired
|
// Notify parent that lock has been acquired
|
||||||
@ -1025,9 +1023,8 @@ testRun(void)
|
|||||||
{
|
{
|
||||||
HRN_FORK_CHILD_BEGIN()
|
HRN_FORK_CHILD_BEGIN()
|
||||||
{
|
{
|
||||||
TEST_RESULT_INT_NE(
|
lockInit(cfgOptionStr(cfgOptLockPath), STRDEF("999-ffffffff"), STRDEF("stanza2"), lockTypeBackup);
|
||||||
lockAcquireP(cfgOptionStr(cfgOptLockPath), STRDEF("stanza2"), STRDEF("999-ffffffff"), lockTypeBackup), -1,
|
TEST_RESULT_INT_NE(lockAcquireP(), -1, "create backup/expire lock");
|
||||||
"create backup/expire lock");
|
|
||||||
TEST_RESULT_VOID(lockWriteDataP(lockTypeBackup, .percentComplete = VARUINT(4545)), "write lock data");
|
TEST_RESULT_VOID(lockWriteDataP(lockTypeBackup, .percentComplete = VARUINT(4545)), "write lock data");
|
||||||
|
|
||||||
// Notify parent that lock has been acquired
|
// Notify parent that lock has been acquired
|
||||||
@ -1465,9 +1462,8 @@ testRun(void)
|
|||||||
{
|
{
|
||||||
HRN_FORK_CHILD_BEGIN()
|
HRN_FORK_CHILD_BEGIN()
|
||||||
{
|
{
|
||||||
TEST_RESULT_INT_NE(
|
lockInit(cfgOptionStr(cfgOptLockPath), STRDEF("999-ffffffff"), STRDEF("stanza2"), lockTypeBackup);
|
||||||
lockAcquireP(cfgOptionStr(cfgOptLockPath), STRDEF("stanza2"), STRDEF("999-ffffffff"), lockTypeBackup), -1,
|
TEST_RESULT_INT_NE(lockAcquireP(), -1, "create backup/expire lock");
|
||||||
"create backup/expire lock");
|
|
||||||
TEST_RESULT_VOID(lockWriteDataP(lockTypeBackup, .percentComplete = VARUINT(5555)), "write lock data");
|
TEST_RESULT_VOID(lockWriteDataP(lockTypeBackup, .percentComplete = VARUINT(5555)), "write lock data");
|
||||||
|
|
||||||
// Notify parent that lock has been acquired
|
// Notify parent that lock has been acquired
|
||||||
|
@ -158,53 +158,55 @@ testRun(void)
|
|||||||
TEST_RESULT_BOOL(lockRelease(false), false, "release when there is no lock");
|
TEST_RESULT_BOOL(lockRelease(false), false, "release when there is no lock");
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
lockLocal.execId = STRDEF("1-test");
|
lockInit(TEST_PATH_STR, STRDEF("1-test"), stanza, lockTypeArchive);
|
||||||
|
|
||||||
TEST_ASSIGN(lockFdTest, lockAcquireFile(archiveLockFile, 0, true), "archive lock by file");
|
TEST_ASSIGN(lockFdTest, lockAcquireFile(archiveLockFile, 0, true), "archive lock by file");
|
||||||
TEST_RESULT_BOOL(
|
TEST_RESULT_BOOL(lockAcquireP(.returnOnNoLock = true), false, "archive already locked");
|
||||||
lockAcquireP(TEST_PATH_STR, stanza, STRDEF("2-test"), lockTypeArchive, .returnOnNoLock = true), false,
|
|
||||||
"archive already locked");
|
|
||||||
TEST_ERROR_FMT(
|
TEST_ERROR_FMT(
|
||||||
lockAcquireP(TEST_PATH_STR, stanza, STRDEF("2-test"), lockTypeArchive), LockAcquireError,
|
lockAcquireP(), LockAcquireError,
|
||||||
"unable to acquire lock on file '%s': Resource temporarily unavailable\n"
|
"unable to acquire lock on file '%s': Resource temporarily unavailable\n"
|
||||||
"HINT: is another pgBackRest process running?",
|
"HINT: is another pgBackRest process running?",
|
||||||
strZ(archiveLockFile));
|
strZ(archiveLockFile));
|
||||||
|
|
||||||
|
lockLocal.type = lockTypeAll;
|
||||||
|
|
||||||
TEST_ERROR_FMT(
|
TEST_ERROR_FMT(
|
||||||
lockAcquireP(TEST_PATH_STR, stanza, STRDEF("2-test"), lockTypeAll), LockAcquireError,
|
lockAcquireP(), LockAcquireError,
|
||||||
"unable to acquire lock on file '%s': Resource temporarily unavailable\n"
|
"unable to acquire lock on file '%s': Resource temporarily unavailable\n"
|
||||||
"HINT: is another pgBackRest process running?", strZ(archiveLockFile));
|
"HINT: is another pgBackRest process running?", strZ(archiveLockFile));
|
||||||
TEST_RESULT_VOID(lockReleaseFile(lockFdTest, archiveLockFile), "release lock");
|
TEST_RESULT_VOID(lockReleaseFile(lockFdTest, archiveLockFile), "release lock");
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
lockLocal.execId = STRDEF("1-test");
|
lockInit(TEST_PATH_STR, STRDEF("1-test"), stanza, lockTypeArchive);
|
||||||
|
|
||||||
TEST_RESULT_BOOL(lockAcquireP(TEST_PATH_STR, stanza, STRDEF("1-test"), lockTypeArchive), true, "archive lock");
|
TEST_RESULT_BOOL(lockAcquireP(), true, "archive lock");
|
||||||
TEST_RESULT_BOOL(storageExistsP(storageTest, archiveLockFile), true, "archive lock file was created");
|
TEST_RESULT_BOOL(storageExistsP(storageTest, archiveLockFile), true, "archive lock file was created");
|
||||||
TEST_ERROR(
|
TEST_ERROR(lockAcquireP(.returnOnNoLock = true), AssertError, "lock is already held by this process");
|
||||||
lockAcquireP(TEST_PATH_STR, stanza, STRDEF("1-test"), lockTypeArchive, .returnOnNoLock = true), AssertError,
|
|
||||||
"lock is already held by this process");
|
|
||||||
TEST_RESULT_VOID(lockRelease(true), "release archive lock");
|
TEST_RESULT_VOID(lockRelease(true), "release archive lock");
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
lockLocal.execId = STRDEF("2-test");
|
lockInit(TEST_PATH_STR, STRDEF("1-test"), stanza, lockTypeBackup);
|
||||||
|
|
||||||
TEST_ASSIGN(lockFdTest, lockAcquireFile(backupLockFile, 0, true), "backup lock by file");
|
TEST_ASSIGN(lockFdTest, lockAcquireFile(backupLockFile, 0, true), "backup lock by file");
|
||||||
|
|
||||||
TEST_ERROR_FMT(
|
TEST_ERROR_FMT(
|
||||||
lockAcquireP(TEST_PATH_STR, stanza, STRDEF("2-test"), lockTypeBackup), LockAcquireError,
|
lockAcquireP(), LockAcquireError,
|
||||||
"unable to acquire lock on file '%s': Resource temporarily unavailable\n"
|
"unable to acquire lock on file '%s': Resource temporarily unavailable\n"
|
||||||
"HINT: is another pgBackRest process running?", strZ(backupLockFile));
|
"HINT: is another pgBackRest process running?", strZ(backupLockFile));
|
||||||
|
|
||||||
|
lockLocal.type = lockTypeAll;
|
||||||
|
|
||||||
TEST_ERROR_FMT(
|
TEST_ERROR_FMT(
|
||||||
lockAcquireP(TEST_PATH_STR, stanza, STRDEF("2-test"), lockTypeAll), LockAcquireError,
|
lockAcquireP(), LockAcquireError,
|
||||||
"unable to acquire lock on file '%s': Resource temporarily unavailable\n"
|
"unable to acquire lock on file '%s': Resource temporarily unavailable\n"
|
||||||
"HINT: is another pgBackRest process running?", strZ(backupLockFile));
|
"HINT: is another pgBackRest process running?", strZ(backupLockFile));
|
||||||
TEST_RESULT_VOID(lockReleaseFile(lockFdTest, archiveLockFile), "release archive lock");
|
TEST_RESULT_VOID(lockReleaseFile(lockFdTest, archiveLockFile), "release archive lock");
|
||||||
TEST_RESULT_VOID(lockReleaseFile(lockFdTest, backupLockFile), "release backup lock");
|
TEST_RESULT_VOID(lockReleaseFile(lockFdTest, backupLockFile), "release backup lock");
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
lockLocal.execId = STRDEF("1-test");
|
lockInit(TEST_PATH_STR, STRDEF("1-test"), stanza, lockTypeAll);
|
||||||
|
|
||||||
TEST_RESULT_BOOL(lockAcquireP(TEST_PATH_STR, stanza, STRDEF("1-test"), lockTypeAll), true, "all lock");
|
TEST_RESULT_BOOL(lockAcquireP(), true, "all lock");
|
||||||
TEST_RESULT_BOOL(storageExistsP(storageTest, archiveLockFile), true, "archive lock file was created");
|
TEST_RESULT_BOOL(storageExistsP(storageTest, archiveLockFile), true, "archive lock file was created");
|
||||||
TEST_RESULT_BOOL(storageExistsP(storageTest, backupLockFile), true, "backup lock file was created");
|
TEST_RESULT_BOOL(storageExistsP(storageTest, backupLockFile), true, "backup lock file was created");
|
||||||
|
|
||||||
@ -239,8 +241,8 @@ testRun(void)
|
|||||||
"verify percentComplete");
|
"verify percentComplete");
|
||||||
|
|
||||||
TEST_ERROR(
|
TEST_ERROR(
|
||||||
lockAcquireP(TEST_PATH_STR, stanza, STRDEF("1-test"), lockTypeAll, .returnOnNoLock = true), AssertError,
|
lockAcquireP(.returnOnNoLock = true), AssertError,
|
||||||
"assertion '!param.returnOnNoLock || lockType != lockTypeAll' failed");
|
"assertion '!param.returnOnNoLock || lockLocal.type != lockTypeAll' failed");
|
||||||
TEST_RESULT_VOID(lockRelease(true), "release all locks");
|
TEST_RESULT_VOID(lockRelease(true), "release all locks");
|
||||||
|
|
||||||
TEST_RESULT_BOOL(storageExistsP(storageTest, archiveLockFile), false, "archive lock file was removed");
|
TEST_RESULT_BOOL(storageExistsP(storageTest, archiveLockFile), false, "archive lock file was removed");
|
||||||
@ -249,15 +251,16 @@ testRun(void)
|
|||||||
// -------------------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
TEST_TITLE("acquire lock on the same exec-id and release");
|
TEST_TITLE("acquire lock on the same exec-id and release");
|
||||||
|
|
||||||
TEST_RESULT_BOOL(lockAcquireP(TEST_PATH_STR, stanza, STRDEF("1-test"), lockTypeBackup), true, "backup lock");
|
lockInit(TEST_PATH_STR, STRDEF("1-test"), stanza, lockTypeBackup);
|
||||||
|
|
||||||
|
TEST_RESULT_BOOL(lockAcquireP(), true, "backup lock");
|
||||||
|
|
||||||
// Make it look there is no lock
|
// Make it look there is no lock
|
||||||
lockFdTest = lockLocal.file[lockTypeBackup].fd;
|
lockFdTest = lockLocal.file[lockTypeBackup].fd;
|
||||||
String *lockFileTest = strDup(lockLocal.file[lockTypeBackup].name);
|
String *lockFileTest = strDup(lockLocal.file[lockTypeBackup].name);
|
||||||
lockLocal.held = lockTypeNone;
|
lockLocal.held = false;
|
||||||
|
|
||||||
TEST_RESULT_BOOL(
|
TEST_RESULT_BOOL(lockAcquireP(), true, "backup lock again");
|
||||||
lockAcquireP(TEST_PATH_STR, stanza, STRDEF("1-test"), lockTypeBackup), true, "backup lock again");
|
|
||||||
TEST_RESULT_VOID(lockRelease(true), "release backup lock");
|
TEST_RESULT_VOID(lockRelease(true), "release backup lock");
|
||||||
|
|
||||||
// Release lock manually
|
// Release lock manually
|
||||||
@ -281,10 +284,9 @@ testRun(void)
|
|||||||
// -------------------------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------------------------
|
||||||
TEST_TITLE("execId && pid valid file");
|
TEST_TITLE("execId && pid valid file");
|
||||||
|
|
||||||
const String *stanza = STRDEF("1-test");
|
lockInit(TEST_PATH_STR, STRDEF("1-test"), STRDEF("1-test"), lockTypeBackup);
|
||||||
lockLocal.execId = STRDEF("1-test");
|
|
||||||
|
|
||||||
TEST_RESULT_BOOL(lockAcquireP(TEST_PATH_STR, stanza, STRDEF("1-test"), lockTypeBackup), true, "backup lock");
|
TEST_RESULT_BOOL(lockAcquireP(), true, "backup lock");
|
||||||
TEST_RESULT_BOOL(storageExistsP(storageTest, lockLocal.file[lockTypeBackup].name), true, "backup lock file was created");
|
TEST_RESULT_BOOL(storageExistsP(storageTest, lockLocal.file[lockTypeBackup].name), true, "backup lock file was created");
|
||||||
|
|
||||||
// Overwrite backup lock file with execId of 1-test and pid of 12345
|
// Overwrite backup lock file with execId of 1-test and pid of 12345
|
||||||
@ -317,7 +319,9 @@ testRun(void)
|
|||||||
{
|
{
|
||||||
HRN_FORK_CHILD_BEGIN()
|
HRN_FORK_CHILD_BEGIN()
|
||||||
{
|
{
|
||||||
TEST_RESULT_BOOL(lockAcquireP(TEST_PATH_STR, STRDEF("test"), STRDEF("test"), lockTypeBackup), true, "acquire lock");
|
lockInit(TEST_PATH_STR, STRDEF("1-test"), STRDEF("test"), lockTypeBackup);
|
||||||
|
|
||||||
|
TEST_RESULT_BOOL(lockAcquireP(), true, "acquire lock");
|
||||||
|
|
||||||
// Overwrite lock file with bogus data
|
// Overwrite lock file with bogus data
|
||||||
THROW_ON_SYS_ERROR_FMT(
|
THROW_ON_SYS_ERROR_FMT(
|
||||||
@ -361,7 +365,9 @@ testRun(void)
|
|||||||
{
|
{
|
||||||
HRN_FORK_CHILD_BEGIN()
|
HRN_FORK_CHILD_BEGIN()
|
||||||
{
|
{
|
||||||
TEST_RESULT_BOOL(lockAcquireP(TEST_PATH_STR, STRDEF("test"), STRDEF("test"), lockTypeBackup), true, "acquire lock");
|
lockInit(TEST_PATH_STR, STRDEF("1-test"), STRDEF("test"), lockTypeBackup);
|
||||||
|
|
||||||
|
TEST_RESULT_BOOL(lockAcquireP(), true, "acquire lock");
|
||||||
|
|
||||||
// Notify parent that lock has been acquired
|
// Notify parent that lock has been acquired
|
||||||
HRN_FORK_CHILD_NOTIFY_PUT();
|
HRN_FORK_CHILD_NOTIFY_PUT();
|
||||||
@ -380,7 +386,7 @@ testRun(void)
|
|||||||
TEST_ASSIGN(result, lockRead(TEST_PATH_STR, STRDEF("test"), lockTypeBackup), "lock read");
|
TEST_ASSIGN(result, lockRead(TEST_PATH_STR, STRDEF("test"), lockTypeBackup), "lock read");
|
||||||
|
|
||||||
TEST_RESULT_BOOL(result.data.processId != 0, true, "check processId");
|
TEST_RESULT_BOOL(result.data.processId != 0, true, "check processId");
|
||||||
TEST_RESULT_STR_Z(result.data.execId, "test", "check execId");
|
TEST_RESULT_STR_Z(result.data.execId, "1-test", "check execId");
|
||||||
|
|
||||||
TEST_STORAGE_LIST(storageTest, NULL, "test-backup.lock\n");
|
TEST_STORAGE_LIST(storageTest, NULL, "test-backup.lock\n");
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user