File 0008-imfile-preliminary-patch-for-msg-loss-in-readmode-0.patch of Package rsyslog.6132
From 6e511e8e8bdf55dd34ae27906e40aadf9b9a7a54 Mon Sep 17 00:00:00 2001
From: Rainer Gerhards <rgerhards@adiscon.com>
Date: Mon, 23 Mar 2015 15:14:40 +0100
Subject: [PATCH] imfile: preliminary patch for msg loss in readmode != 0
This is a preliminary patch, which needs to undergo further testing
in cases where rsyslogd is shut down with partial messages read.
see also https://github.com/rsyslog/rsyslog/issues/144
From 714a914c25144bba5ad8a668618364bd89e040fb Mon Sep 17 00:00:00 2001
From: Nirmoy Das <ndas@suse.de>
Date: Mon, 7 Aug 2017 17:19:02 +0200
Subject: [PATCH] remove debug prints from upstream patch
---
runtime/stream.c | 39 ++++++++++++++++++++++++---------------
runtime/stream.h | 1 +
2 files changed, 25 insertions(+), 15 deletions(-)
diff --git a/runtime/stream.c b/runtime/stream.c
index 9974531..1ee872c 100644
--- a/runtime/stream.c
+++ b/runtime/stream.c
@@ -692,7 +692,6 @@ strmReadLine(strm_t *pThis, cstr_t **ppCStr, uint8_t mode, sbool bEscapeLF)
uchar c;
uchar finished;
rsRetVal readCharRet;
- sbool bPrevWasNL;
DEFiRet;
ASSERT(pThis != NULL);
@@ -701,12 +700,12 @@ strmReadLine(strm_t *pThis, cstr_t **ppCStr, uint8_t mode, sbool bEscapeLF)
CHKiRet(cstrConstruct(ppCStr));
CHKiRet(strmReadChar(pThis, &c));
+ /* append previous message to current message if necessary */
+ if(pThis->prevLineSegment != NULL) {
+ CHKiRet(cstrAppendCStr(*ppCStr, pThis->prevLineSegment));
+ cstrDestruct(&pThis->prevLineSegment);
+ }
if(mode == 0) {
- /* append previous message to current message if necessary */
- if(pThis->prevLineSegment != NULL) {
- CHKiRet(cstrAppendCStr(*ppCStr, pThis->prevLineSegment));
- cstrDestruct(&pThis->prevLineSegment);
- }
while(c != '\n') {
CHKiRet(cstrAppendChar(*ppCStr, c));
readCharRet = strmReadChar(pThis, &c);
@@ -718,15 +717,14 @@ strmReadLine(strm_t *pThis, cstr_t **ppCStr, uint8_t mode, sbool bEscapeLF)
CHKiRet(cstrFinalize(*ppCStr));
} else if(mode == 1) {
finished=0;
- bPrevWasNL = 0;
while(finished == 0){
if(c != '\n') {
CHKiRet(cstrAppendChar(*ppCStr, c));
CHKiRet(strmReadChar(pThis, &c));
- bPrevWasNL = 0;
+ pThis->bPrevWasNL = 0;
} else {
if ((((*ppCStr)->iStrLen) > 0) ){
- if(bPrevWasNL) {
+ if(pThis->bPrevWasNL) {
rsCStrTruncate(*ppCStr, (bEscapeLF) ? 4 : 1); /* remove the prior newline */
finished=1;
} else {
@@ -736,7 +734,7 @@ strmReadLine(strm_t *pThis, cstr_t **ppCStr, uint8_t mode, sbool bEscapeLF)
CHKiRet(cstrAppendChar(*ppCStr, c));
}
CHKiRet(strmReadChar(pThis, &c));
- bPrevWasNL = 1;
+ pThis->bPrevWasNL = 1;
}
} else {
finished=1; /* this is a blank line, a \n with nothing since the last complete record */
@@ -744,10 +742,10 @@ strmReadLine(strm_t *pThis, cstr_t **ppCStr, uint8_t mode, sbool bEscapeLF)
}
}
CHKiRet(cstrFinalize(*ppCStr));
+ pThis->bPrevWasNL = 0;
} else if(mode == 2) {
/* indented follow-up lines */
finished=0;
- bPrevWasNL = 0;
while(finished == 0){
if ((*ppCStr)->iStrLen == 0){
if(c != '\n') {
@@ -758,11 +756,11 @@ strmReadLine(strm_t *pThis, cstr_t **ppCStr, uint8_t mode, sbool bEscapeLF)
finished=1; /* this is a blank line, a \n with nothing since the last complete record */
}
} else {
- if(bPrevWasNL) {
+ if(pThis->bPrevWasNL) {
if ((c == ' ') || (c == '\t')){
CHKiRet(cstrAppendChar(*ppCStr, c));
CHKiRet(strmReadChar(pThis, &c));
- bPrevWasNL = 0;
+ pThis->bPrevWasNL = 0;
} else {
/* clean things up by putting the character we just read back into
* the input buffer and removing the LF character that is currently at the
@@ -773,7 +771,7 @@ strmReadLine(strm_t *pThis, cstr_t **ppCStr, uint8_t mode, sbool bEscapeLF)
}
} else { /* not the first character after a newline, add it to the buffer */
if(c == '\n') {
- bPrevWasNL = 1;
+ pThis->bPrevWasNL = 1;
if(bEscapeLF) {
CHKiRet(rsCStrAppendStrWithLen(*ppCStr, (uchar*)"#012", sizeof("#012")-1));
} else {
@@ -787,11 +785,14 @@ strmReadLine(strm_t *pThis, cstr_t **ppCStr, uint8_t mode, sbool bEscapeLF)
}
}
CHKiRet(cstrFinalize(*ppCStr));
+ pThis->bPrevWasNL = 0;
}
finalize_it:
- if(iRet != RS_RET_OK && *ppCStr != NULL)
+ if(iRet != RS_RET_OK && *ppCStr != NULL) {
+ rsCStrConstructFromCStr(&pThis->prevLineSegment, *ppCStr);
cstrDestruct(ppCStr);
+ }
RETiRet;
}
@@ -810,6 +811,7 @@ BEGINobjConstruct(strm) /* be sure to specify the object type also in END macro!
pThis->tOpenMode = 0600;
pThis->pszSizeLimitCmd = NULL;
pThis->prevLineSegment = NULL;
+ pThis->bPrevWasNL = 0;
ENDobjConstruct(strm)
@@ -936,6 +938,8 @@ CODESTARTobjDestruct(strm)
* IMPORTANT: we MUST free this only AFTER the ansyncWriter has been stopped, else
* we get random errors...
*/
+ if(pThis->prevLineSegment)
+ cstrDestruct(&pThis->prevLineSegment);
free(pThis->pszDir);
free(pThis->pZipBuf);
free(pThis->pszCurrFName);
@@ -1852,6 +1856,9 @@ static rsRetVal strmSerialize(strm_t *pThis, strm_t *pStrm)
objSerializePTR(pStrm, prevLineSegment, PSZ);
+ i = pThis->bPrevWasNL;
+ objSerializeSCALAR_VAR(pStrm, bPrevWasNL, INT, i);
+
CHKiRet(obj.EndSerialize(pStrm));
finalize_it:
@@ -1961,6 +1968,8 @@ static rsRetVal strmSetProperty(strm_t *pThis, var_t *pProp)
CHKiRet(strmSetbDeleteOnClose(pThis, pProp->val.num));
} else if(isProp("prevLineSegment")) {
CHKiRet(rsCStrConstructFromCStr(&pThis->prevLineSegment, pProp->val.pStr));
+ } else if(isProp("bPrevWasNL")) {
+ pThis->bPrevWasNL = (sbool) pProp->val.num;
}
finalize_it:
diff --git a/runtime/stream.h b/runtime/stream.h
index 8f26bdc..cbd0fee 100644
--- a/runtime/stream.h
+++ b/runtime/stream.h
@@ -106,6 +106,7 @@ typedef struct strm_s {
sbool bDeleteOnClose; /* set to 1 to auto-delete on close -- be careful with that setting! */
int64 iCurrOffs;/* current offset */
int64 *pUsrWCntr; /* NULL or a user-provided counter that receives the nbr of bytes written since the last CntrSet() */
+ sbool bPrevWasNL; /* used for readLine() when reading multi-line messages */
/* dynamic properties, valid only during file open, not to be persistet */
sbool bDisabled; /* should file no longer be written to? (currently set only if omfile file size limit fails) */
sbool bSync; /* sync this file after every write? */
--
2.13.2