mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2024-12-12 10:04:14 +02:00
Improve stop command to honor stanza option.
Improve the stop command, when force and stanza options are specified, to terminate only processes holding lock files for the given stanza. Prior to these changes, termination of all processes holding lock files regardless of stanza occurred.
This commit is contained in:
parent
514137040e
commit
f7ab002aa7
@ -27,6 +27,19 @@
|
||||
|
||||
<p>Increase precision of percent complete logging for <cmd>backup</cmd> and <cmd>restore</cmd>.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
<github-issue id="1608"/>
|
||||
<github-pull-request id="1676"/>
|
||||
|
||||
<release-item-contributor-list>
|
||||
<release-item-ideator id="ragaoua"/>
|
||||
<release-item-contributor id="reid.thompson"/>
|
||||
<release-item-reviewer id="david.steele"/>
|
||||
</release-item-contributor-list>
|
||||
|
||||
<p>Improve <cmd>stop</cmd> command to honor <br-option>stanza</br-option> option.</p>
|
||||
</release-item>
|
||||
</release-improvement-list>
|
||||
|
||||
<release-development-list>
|
||||
@ -11411,6 +11424,11 @@
|
||||
<contributor-id type="github">rachid-casa</contributor-id>
|
||||
</contributor>
|
||||
|
||||
<contributor id="ragaoua">
|
||||
<contributor-name-display>ragaoua</contributor-name-display>
|
||||
<contributor-id type="github">ragaoua</contributor-id>
|
||||
</contributor>
|
||||
|
||||
<contributor id="rakshitha.br">
|
||||
<contributor-name-display>Rakshitha-BR</contributor-name-display>
|
||||
<contributor-id type="github">Rakshitha-BR</contributor-id>
|
||||
|
@ -59,11 +59,19 @@ cmdStop(void)
|
||||
// Find each lock file and send term signals to the processes
|
||||
for (unsigned int lockPathFileIdx = 0; lockPathFileIdx < strLstSize(lockPathFileList); lockPathFileIdx++)
|
||||
{
|
||||
String *lockFile = strNewFmt("%s/%s", strZ(lockPath), strZ(strLstGet(lockPathFileList, lockPathFileIdx)));
|
||||
const String *lockFile = strLstGet(lockPathFileList, lockPathFileIdx);
|
||||
|
||||
// Skip any file that is not a lock file
|
||||
if (!strEndsWithZ(lockFile, LOCK_FILE_EXT))
|
||||
// Skip any file that is not a lock file. Skip lock files for other stanzas if a stanza is provided.
|
||||
if (!strEndsWithZ(lockFile, LOCK_FILE_EXT) ||
|
||||
(cfgOptionTest(cfgOptStanza) &&
|
||||
!strEq(lockFile, lockFileName(cfgOptionStr(cfgOptStanza), lockTypeArchive)) &&
|
||||
!strEq(lockFile, lockFileName(cfgOptionStr(cfgOptStanza), lockTypeBackup))))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add path to the lock file
|
||||
lockFile = strNewFmt("%s/%s", strZ(lockPath), strZ(lockFile));
|
||||
|
||||
// If we cannot open the lock file for any reason then warn and continue to next file
|
||||
if ((fd = open(strZ(lockFile), O_RDONLY, 0)) == -1)
|
||||
|
@ -58,6 +58,18 @@ static struct LockLocal
|
||||
.held = lockTypeNone,
|
||||
};
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
String *
|
||||
lockFileName(const String *const stanza, const LockType lockType)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STRING, stanza);
|
||||
FUNCTION_TEST_PARAM(ENUM, lockType);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
FUNCTION_TEST_RETURN(strNewFmt("%s-%s" LOCK_FILE_EXT, strZ(stanza), lockTypeName[lockType]));
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Read contents of lock file
|
||||
|
||||
@ -285,7 +297,7 @@ lockAcquire(
|
||||
{
|
||||
MEM_CONTEXT_BEGIN(lockLocal.memContext)
|
||||
{
|
||||
lockLocal.file[lockIdx].name = strNewFmt("%s/%s-%s" LOCK_FILE_EXT, strZ(lockPath), strZ(stanza), lockTypeName[lockIdx]);
|
||||
lockLocal.file[lockIdx].name = strNewFmt("%s/%s", strZ(lockPath), strZ(lockFileName(stanza, lockIdx)));
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
|
||||
|
@ -42,4 +42,7 @@ bool lockAcquire(
|
||||
// Release a lock
|
||||
bool lockRelease(bool failOnNoLock);
|
||||
|
||||
// Build lock file name
|
||||
String *lockFileName(const String *stanza, LockType lockType);
|
||||
|
||||
#endif
|
||||
|
@ -687,7 +687,7 @@ unit:
|
||||
test:
|
||||
# ----------------------------------------------------------------------------------------------------------------------------
|
||||
- name: control
|
||||
total: 3
|
||||
total: 4
|
||||
|
||||
coverage:
|
||||
- command/control/common
|
||||
|
@ -139,16 +139,17 @@ testRun(void)
|
||||
TEST_TITLE("unable to open lock file");
|
||||
|
||||
HRN_STORAGE_PUT_EMPTY(
|
||||
hrnStorage, "lock/bad" LOCK_FILE_EXT, .modeFile = 0222, .comment = "create a lock file that cannot be opened");
|
||||
hrnStorage, "lock/db-archive" LOCK_FILE_EXT, .modeFile = 0222,
|
||||
.comment = "create a lock file that cannot be opened");
|
||||
TEST_RESULT_VOID(cmdStop(), "stanza, create stop file but unable to open lock file");
|
||||
TEST_STORAGE_EXISTS(hrnStorage, "lock/db" STOP_FILE_EXT, .comment = "stanza stop file created");
|
||||
TEST_RESULT_LOG("P00 WARN: unable to open lock file " HRN_PATH "/lock/bad" LOCK_FILE_EXT);
|
||||
TEST_RESULT_LOG("P00 WARN: unable to open lock file " HRN_PATH "/lock/db-archive" LOCK_FILE_EXT);
|
||||
HRN_STORAGE_PATH_REMOVE(hrnStorage, "lock", .recurse = true, .errorOnMissing = true, .comment = "remove the lock path");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("lock file removal");
|
||||
|
||||
HRN_STORAGE_PUT_EMPTY(hrnStorage, "lock/empty" LOCK_FILE_EXT, .comment = "create empty lock file");
|
||||
HRN_STORAGE_PUT_EMPTY(hrnStorage, "lock/db-backup" LOCK_FILE_EXT, .comment = "create empty lock file");
|
||||
TEST_RESULT_VOID(cmdStop(), "stanza, create stop file, force - empty lock file");
|
||||
TEST_STORAGE_LIST(
|
||||
hrnStorage, "lock", "db" STOP_FILE_EXT "\n",
|
||||
@ -158,13 +159,13 @@ testRun(void)
|
||||
TEST_TITLE("empty lock file with another process lock, processId == NULL");
|
||||
|
||||
HRN_STORAGE_REMOVE(hrnStorage, "lock/db" STOP_FILE_EXT, .errorOnMissing = true, .comment = "remove stanza stop file");
|
||||
HRN_STORAGE_PUT_EMPTY(hrnStorage, "lock/empty" LOCK_FILE_EXT, .comment = "create empty lock file");
|
||||
HRN_STORAGE_PUT_EMPTY(hrnStorage, "lock/db-backup" LOCK_FILE_EXT, .comment = "create empty lock file");
|
||||
|
||||
HRN_FORK_BEGIN()
|
||||
{
|
||||
HRN_FORK_CHILD_BEGIN()
|
||||
{
|
||||
int lockFd = open(HRN_PATH "/lock/empty" LOCK_FILE_EXT, O_RDONLY, 0);
|
||||
int lockFd = open(HRN_PATH "/lock/db-backup" LOCK_FILE_EXT, O_RDONLY, 0);
|
||||
TEST_RESULT_BOOL(lockFd != -1, true, "file descriptor acquired");
|
||||
TEST_RESULT_INT(flock(lockFd, LOCK_EX | LOCK_NB), 0, "lock the empty file");
|
||||
|
||||
@ -200,13 +201,13 @@ testRun(void)
|
||||
TEST_TITLE("not empty lock file with another process lock, processId size trimmed to 0");
|
||||
|
||||
HRN_STORAGE_REMOVE(hrnStorage, "lock/db" STOP_FILE_EXT, .errorOnMissing = true, .comment = "remove stanza stop file");
|
||||
HRN_STORAGE_PUT_Z(hrnStorage, "lock/empty" LOCK_FILE_EXT, " ", .comment = "create non-empty lock file");
|
||||
HRN_STORAGE_PUT_Z(hrnStorage, "lock/db-backup" LOCK_FILE_EXT, " ", .comment = "create non-empty lock file");
|
||||
|
||||
HRN_FORK_BEGIN()
|
||||
{
|
||||
HRN_FORK_CHILD_BEGIN()
|
||||
{
|
||||
int lockFd = open(HRN_PATH "/lock/empty" LOCK_FILE_EXT, O_RDONLY, 0);
|
||||
int lockFd = open(HRN_PATH "/lock/db-backup" LOCK_FILE_EXT, O_RDONLY, 0);
|
||||
TEST_RESULT_BOOL(lockFd != -1, true, "file descriptor acquired");
|
||||
TEST_RESULT_INT(flock(lockFd, LOCK_EX | LOCK_NB), 0, "lock the non-empty file");
|
||||
|
||||
@ -276,13 +277,13 @@ testRun(void)
|
||||
TEST_TITLE("lock file with another process lock, processId is invalid");
|
||||
|
||||
HRN_STORAGE_REMOVE(hrnStorage, "lock/db" STOP_FILE_EXT, .errorOnMissing = true, .comment = "remove stanza stop file");
|
||||
HRN_STORAGE_PUT_Z(hrnStorage, "lock/badpid" LOCK_FILE_EXT, "-32768", .comment = "create lock file with invalid PID");
|
||||
HRN_STORAGE_PUT_Z(hrnStorage, "lock/db-backup" LOCK_FILE_EXT, "-32768", .comment = "create lock file with invalid PID");
|
||||
|
||||
HRN_FORK_BEGIN()
|
||||
{
|
||||
HRN_FORK_CHILD_BEGIN()
|
||||
{
|
||||
int lockFd = open(HRN_PATH "/lock/badpid" LOCK_FILE_EXT, O_RDONLY, 0);
|
||||
int lockFd = open(HRN_PATH "/lock/db-backup" LOCK_FILE_EXT, O_RDONLY, 0);
|
||||
TEST_RESULT_BOOL(lockFd != -1, true, "file descriptor acquired");
|
||||
TEST_RESULT_INT(flock(lockFd, LOCK_EX | LOCK_NB), 0, "lock the badpid file");
|
||||
|
||||
@ -293,7 +294,7 @@ testRun(void)
|
||||
HRN_FORK_CHILD_NOTIFY_GET();
|
||||
|
||||
// Remove the file and close the file descriptor
|
||||
HRN_STORAGE_REMOVE(hrnStorage, "lock/badpid" LOCK_FILE_EXT);
|
||||
HRN_STORAGE_REMOVE(hrnStorage, "lock/db-backup" LOCK_FILE_EXT);
|
||||
close(lockFd);
|
||||
}
|
||||
HRN_FORK_CHILD_END();
|
||||
@ -316,5 +317,47 @@ testRun(void)
|
||||
HRN_FORK_END();
|
||||
}
|
||||
|
||||
// *****************************************************************************************************************************
|
||||
if (testBegin("cmdStop(), force, no stanza/stanza"))
|
||||
{
|
||||
StringList *argList = strLstNew();
|
||||
hrnCfgArgRawBool(argList, cfgOptForce, true);
|
||||
HRN_CFG_LOAD(cfgCmdStop, argList);
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("no stanza, force stop = process all lock files, ignore non lock files");
|
||||
|
||||
HRN_STORAGE_PUT_EMPTY(hrnStorage, "lock/db-junk.txt", .comment = "create empty non lock file, s/b ignored");
|
||||
HRN_STORAGE_PUT_Z(hrnStorage, "lock/db-backup" LOCK_FILE_EXT, " ", .comment = "create backup lock file for stanza");
|
||||
HRN_STORAGE_PUT_EMPTY(hrnStorage, "lock/db-archive" LOCK_FILE_EXT, .comment = "create empty archive lock file for stanza");
|
||||
HRN_STORAGE_PUT_Z(hrnStorage, "lock/db1-backup" LOCK_FILE_EXT, " ", .comment = "create non-empty lock file other stanza");
|
||||
|
||||
TEST_RESULT_VOID(cmdStop(), "no stanza, create stop file, ignore non lock file");
|
||||
TEST_STORAGE_EXISTS(hrnStorage, "lock/all" STOP_FILE_EXT, .comment = "stanza stop file created");
|
||||
TEST_STORAGE_LIST(
|
||||
hrnStorage, "lock", "all" STOP_FILE_EXT "\n" "db-junk.txt\n", .comment = "stop file created, all lock files processed");
|
||||
TEST_RESULT_LOG("");
|
||||
HRN_STORAGE_PATH_REMOVE(hrnStorage, "lock", .recurse = true, .errorOnMissing = true, .comment = "remove the lock path");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("stanza, force stop = process only stanza lock files, ignore other stanza lock files and other files");
|
||||
|
||||
hrnCfgArgRawZ(argList, cfgOptStanza, "db");
|
||||
HRN_CFG_LOAD(cfgCmdStop, argList);
|
||||
|
||||
HRN_STORAGE_PUT_EMPTY(hrnStorage, "lock/db-junk.txt", .comment = "create empty non lock file, s/b ignored");
|
||||
HRN_STORAGE_PUT_EMPTY(hrnStorage, "lock/db-archive" LOCK_FILE_EXT, .comment = "create stanza empty lock file");
|
||||
HRN_STORAGE_PUT_Z(hrnStorage, "lock/db1-backup" LOCK_FILE_EXT, " ", .comment = "create other stanza non-empty lock file");
|
||||
HRN_STORAGE_PUT_Z(hrnStorage, "lock/db-backup" LOCK_FILE_EXT, " ", .comment = "create stanza non-empty lock file");
|
||||
|
||||
TEST_RESULT_VOID(cmdStop(), "stanza, create stop file, ignore other stanza lock and other files");
|
||||
TEST_STORAGE_EXISTS(hrnStorage, "lock/db" STOP_FILE_EXT, .comment = "stanza stop file created");
|
||||
TEST_STORAGE_LIST(
|
||||
hrnStorage, "lock", "db-junk.txt\ndb" STOP_FILE_EXT "\n" "db1-backup" LOCK_FILE_EXT "\n",
|
||||
.comment = "stop file created, stanza lock file was removed, other stanza lock and other files remain");
|
||||
TEST_RESULT_LOG("");
|
||||
HRN_STORAGE_PATH_REMOVE(hrnStorage, "lock", .recurse = true, .errorOnMissing = true, .comment = "remove the lock path");
|
||||
}
|
||||
|
||||
FUNCTION_HARNESS_RETURN_VOID();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user