diff --git a/doc/xml/release.xml b/doc/xml/release.xml index 69cbf9ea2..f1e782610 100644 --- a/doc/xml/release.xml +++ b/doc/xml/release.xml @@ -27,6 +27,19 @@

Increase precision of percent complete logging for backup and restore.

+ + + + + + + + + + + +

Improve stop command to honor stanza option.

+
@@ -11411,6 +11424,11 @@ rachid-casa + + ragaoua + ragaoua + + Rakshitha-BR Rakshitha-BR diff --git a/src/command/control/stop.c b/src/command/control/stop.c index 8cd4d707e..bccb4d8f2 100644 --- a/src/command/control/stop.c +++ b/src/command/control/stop.c @@ -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) diff --git a/src/common/lock.c b/src/common/lock.c index ada4118f5..f13048413 100644 --- a/src/common/lock.c +++ b/src/common/lock.c @@ -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(); diff --git a/src/common/lock.h b/src/common/lock.h index 0d9f1cb11..6dbfe8106 100644 --- a/src/common/lock.h +++ b/src/common/lock.h @@ -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 diff --git a/test/define.yaml b/test/define.yaml index 113526943..559f0c932 100644 --- a/test/define.yaml +++ b/test/define.yaml @@ -687,7 +687,7 @@ unit: test: # ---------------------------------------------------------------------------------------------------------------------------- - name: control - total: 3 + total: 4 coverage: - command/control/common diff --git a/test/src/module/command/controlTest.c b/test/src/module/command/controlTest.c index d2098577d..6da70a5ee 100644 --- a/test/src/module/command/controlTest.c +++ b/test/src/module/command/controlTest.c @@ -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(); }