mirror of
https://github.com/rsyslog/rsyslog.git
synced 2025-12-19 23:10:41 +01:00
queue subsystem: .qi file is automically rewritten
previously, a kill -9 during the .qi write could keep the file in inconsistent state. Now, we first write a temp file, and (automically) rename it to "the real thing". So if something happens during writing the .qi, at least the old state still is consistent. This is inspired by the way the pid file is handled sind v8.19.
This commit is contained in:
parent
7d0116b7f3
commit
24bab3b108
@ -2434,7 +2434,9 @@ static rsRetVal
|
||||
qqueuePersist(qqueue_t *pThis, int bIsCheckpoint)
|
||||
{
|
||||
DEFiRet;
|
||||
char *tmpQIFName = NULL;
|
||||
strm_t *psQIF = NULL; /* Queue Info File */
|
||||
char errStr[1024];
|
||||
|
||||
ASSERT(pThis != NULL);
|
||||
|
||||
@ -2463,11 +2465,15 @@ qqueuePersist(qqueue_t *pThis, int bIsCheckpoint)
|
||||
FINALIZE; /* nothing left to do, so be happy */
|
||||
}
|
||||
|
||||
const int lentmpQIFName = asprintf((char **)&tmpQIFName, "%s.tmp", pThis->pszQIFNam);
|
||||
if(tmpQIFName == NULL)
|
||||
tmpQIFName = (char*)pThis->pszQIFNam;
|
||||
|
||||
CHKiRet(strm.Construct(&psQIF));
|
||||
CHKiRet(strm.SettOperationsMode(psQIF, STREAMMODE_WRITE_TRUNC));
|
||||
CHKiRet(strm.SetbSync(psQIF, pThis->bSyncQueueFiles));
|
||||
CHKiRet(strm.SetsType(psQIF, STREAMTYPE_FILE_SINGLE));
|
||||
CHKiRet(strm.SetFName(psQIF, pThis->pszQIFNam, pThis->lenQIFNam));
|
||||
CHKiRet(strm.SetFName(psQIF, (uchar*) tmpQIFName, lentmpQIFName));
|
||||
CHKiRet(strm.ConstructFinalize(psQIF));
|
||||
|
||||
/* first, write the property bag for ourselfs
|
||||
@ -2487,6 +2493,17 @@ qqueuePersist(qqueue_t *pThis, int bIsCheckpoint)
|
||||
if(pThis->tVars.disk.pReadDel != NULL)
|
||||
CHKiRet(strm.Serialize(pThis->tVars.disk.pReadDel, psQIF));
|
||||
|
||||
strm.Destruct(&psQIF);
|
||||
if(tmpQIFName != (char*)pThis->pszQIFNam) { /* pointer, not string comparison! */
|
||||
if(rename(tmpQIFName, (char*)pThis->pszQIFNam) != 0) {
|
||||
rs_strerror_r(errno, errStr, sizeof(errStr));
|
||||
DBGOPRINT((obj_t*) pThis,
|
||||
"FATAL error: renaming temporary .qi file failed: %s\n",
|
||||
errStr);
|
||||
ABORT_FINALIZE(RS_RET_RENAME_TMP_QI_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/* tell the input file object that it must not delete the file on close if the queue
|
||||
* is non-empty - but only if we are not during a simple checkpoint
|
||||
*/
|
||||
@ -2501,6 +2518,8 @@ qqueuePersist(qqueue_t *pThis, int bIsCheckpoint)
|
||||
pThis->bNeedDelQIF = 1;
|
||||
|
||||
finalize_it:
|
||||
if(tmpQIFName != (char*)pThis->pszQIFNam) /* pointer, not string comparison! */
|
||||
free(tmpQIFName);
|
||||
if(psQIF != NULL)
|
||||
strm.Destruct(&psQIF);
|
||||
|
||||
|
||||
@ -454,6 +454,7 @@ enum rsRetVal_ /** return value. All methods return this if not specified oth
|
||||
RS_RET_ERR_DROP_PRIV = -2432,/**< error droping privileges */
|
||||
RS_RET_FILE_OPEN_ERROR = -2433, /**< error other than "not found" occured during open() */
|
||||
RS_RET_FILE_CHOWN_ERROR = -2434, /**< error during chown() */
|
||||
RS_RET_RENAME_TMP_QI_ERROR = -2435, /**< renaming temporary .qi file failed */
|
||||
|
||||
/* RainerScript error messages (range 1000.. 1999) */
|
||||
RS_RET_SYSVAR_NOT_FOUND = 1001, /**< system variable could not be found (maybe misspelled) */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user