Blame SOURCES/rsyslog-8.24.0-rhbz1419228-journal-switch-persistent.patch

b65758
diff -up ./plugins/imjournal/imjournal.c.journal ./plugins/imjournal/imjournal.c
b65758
--- ./plugins/imjournal/imjournal.c.journal	2017-03-13 14:38:11.820000000 +0100
b65758
+++ ./plugins/imjournal/imjournal.c	2017-03-13 14:45:16.006000000 +0100
b65758
@@ -115,6 +115,25 @@ static const char *pid_field_name;	/* re
b65758
 static ratelimit_t *ratelimiter = NULL;
b65758
 static sd_journal *j;
b65758
 
b65758
+static rsRetVal persistJournalState(void);
b65758
+static rsRetVal loadJournalState(void);
b65758
+
b65758
+static rsRetVal openJournal(sd_journal** jj) {
b65758
+	DEFiRet;
b65758
+
b65758
+	if (sd_journal_open(jj, SD_JOURNAL_LOCAL_ONLY) < 0)
b65758
+		iRet = RS_RET_IO_ERROR;
b65758
+	RETiRet;
b65758
+}
b65758
+
b65758
+static void closeJournal(sd_journal** jj) {
b65758
+
b65758
+	if (cs.stateFile) { /* can't persist without a state file */
b65758
+		persistJournalState();
b65758
+	}
b65758
+	sd_journal_close(*jj);
b65758
+}
b65758
+
b65758
 
b65758
 /* ugly workaround to handle facility numbers; values
b65758
  * derived from names need to be eight times smaller,
b65758
@@ -436,20 +455,25 @@ persistJournalState (void)
b65758
 }
b65758
 
b65758
 
b65758
+static rsRetVal skipOldMessages(void);
b65758
 /* Polls the journal for new messages. Similar to sd_journal_wait()
b65758
  * except for the special handling of EINTR.
b65758
  */
b65758
+
b65758
+#define POLL_TIMEOUT 1000 /* timeout for poll is 1s */
b65758
+
b65758
 static rsRetVal
b65758
 pollJournal(void)
b65758
 {
b65758
 	DEFiRet;
b65758
 	struct pollfd pollfd;
b65758
-	int r;
b65758
+	int pr = 0;
b65758
+	int jr = 0;
b65758
 
b65758
 	pollfd.fd = sd_journal_get_fd(j);
b65758
 	pollfd.events = sd_journal_get_events(j);
b65758
-	r = poll(&pollfd, 1, -1);
b65758
-	if (r == -1) {
b65758
+	pr = poll(&pollfd, 1, POLL_TIMEOUT);
b65758
+	if (pr == -1) {
b65758
 		if (errno == EINTR) {
b65758
 			/* EINTR is also received during termination
b65758
 			 * so return now to check the term state.
b65758
@@ -465,12 +489,30 @@ pollJournal(void)
b65758
 		}
b65758
 	}
b65758
 
b65758
-	assert(r == 1);
b65758
 
b65758
-	r = sd_journal_process(j);
b65758
-	if (r < 0) {
b65758
-		char errStr[256];
b65758
+	jr = sd_journal_process(j);
b65758
+	
b65758
+	if (pr == 1 && jr == SD_JOURNAL_INVALIDATE) {
b65758
+		/* do not persist stateFile sd_journal_get_cursor will fail! */
b65758
+		char* tmp = cs.stateFile;
b65758
+		cs.stateFile = NULL;
b65758
+		closeJournal(&j);
b65758
+		cs.stateFile = tmp;
b65758
+
b65758
+		iRet = openJournal(&j);
b65758
+		if (iRet != RS_RET_OK) {
b65758
+			char errStr[256];
b65758
+			rs_strerror_r(errno, errStr, sizeof(errStr));
b65758
+			errmsg.LogError(0, RS_RET_IO_ERROR,
b65758
+				"sd_journal_open() failed: '%s'", errStr);
b65758
+			ABORT_FINALIZE(RS_RET_ERR);
b65758
+		}
b65758
 
b65758
+		iRet = loadJournalState();
b65758
+		errmsg.LogError(0, RS_RET_OK, "imjournal: "
b65758
+			"journal reloaded...");	
b65758
+	} else if (jr < 0) {
b65758
+		char errStr[256];
b65758
 		rs_strerror_r(errno, errStr, sizeof(errStr));
b65758
 		errmsg.LogError(0, RS_RET_ERR,
b65758
 			"sd_journal_process() failed: '%s'", errStr);
b65758
@@ -694,20 +736,13 @@ ENDfreeCnf
b65758
 /* open journal */
b65758
 BEGINwillRun
b65758
 CODESTARTwillRun
b65758
-	int ret;
b65758
-	ret = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY);
b65758
-	if (ret < 0) {
b65758
-		iRet = RS_RET_IO_ERROR;
b65758
-	}
b65758
+	iRet = openJournal(&j);
b65758
 ENDwillRun
b65758
 
b65758
 /* close journal */
b65758
 BEGINafterRun
b65758
 CODESTARTafterRun
b65758
-	if (cs.stateFile) { /* can't persist without a state file */
b65758
-		persistJournalState();
b65758
-	}
b65758
-	sd_journal_close(j);
b65758
+	closeJournal(&j);
b65758
 	ratelimitDestruct(ratelimiter);
b65758
 ENDafterRun
b65758