Skip to content

Commit

Permalink
imkmsg: add params "readMode" and "expectedBootCompleteSeconds"
Browse files Browse the repository at this point in the history
These parameters permit to control when imkmsg reads the full
kernel log upon startup.

Parameter "readMode" provides the following options:

  * full-boot - (default) read full klog, but only "immediately" after
    boot. "Immediately" is hereby meant in seconds of system
    uptime given in "expectedBootCompleteSeconds"
  * full-always - read full klog on every rsyslog startup. Most
    probably causes messag duplication
  * new-only - never emit existing kernel log message, read only
    new ones.

Note that some message loss can happen if rsyslog is stopped
in "full-boot" and "new-only" read mode. The longer rsyslog is
inactive, the higher the message loss probability and potential
number of messages lost. For typical restart scenarios, this
should be minimal. On HUP, no message loss occurs as rsyslog
is not actually stopped.

The default value for "expectedBootCompleteSeconds" is 90.

see also #5161
  • Loading branch information
rgerhards committed Nov 21, 2023
1 parent f4cfd55 commit efbe2ce
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 3 deletions.
21 changes: 20 additions & 1 deletion contrib/imkmsg/imkmsg.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,9 @@ static int bLegacyCnfModGlobalsPermitted;/* are legacy module-global config para

/* module-global parameters */
static struct cnfparamdescr modpdescr[] = {
{ "parsekerneltimestamp", eCmdHdlrGetWord, 0 }
{ "parsekerneltimestamp", eCmdHdlrGetWord, 0 },
{ "readmode", eCmdHdlrGetWord, 0 },
{ "expectedbootcompleteseconds", eCmdHdlrPositiveInt, 0 }
};
static struct cnfparamblk modpblk =
{ CNFPARAMBLK_VERSION,
Expand Down Expand Up @@ -193,6 +195,8 @@ CODESTARTbeginCnfLoad
/* init our settings */
pModConf->iFacilIntMsg = klogFacilIntMsg();
pModConf->parseKernelStamp = KMSG_PARSE_TS_STARTUP_ONLY;
pModConf->readMode = KMSG_READMODE_FULL_BOOT;
pModConf->expected_boot_complete_secs = 90;
loadModConf->configSetViaV2Method = 0;
bLegacyCnfModGlobalsPermitted = 1;
/* init legacy config vars */
Expand Down Expand Up @@ -233,6 +237,21 @@ CODESTARTsetModCnf
"parse mode '%s'", cstr);
free((void*)cstr);
}
} else if(!strcmp(modpblk.descr[i].name, "expectedbootcompleteseconds")) {
loadModConf->expected_boot_complete_secs = pvals[i].val.d.n;
} else if(!strcmp(modpblk.descr[i].name, "readmode")) {
if(!es_strconstcmp(pvals[i].val.d.estr, "full-boot")) {
loadModConf->readMode = KMSG_READMODE_FULL_BOOT;
} else if(!es_strconstcmp(pvals[i].val.d.estr, "full-always")) {
loadModConf->readMode = KMSG_READMODE_FULL_ALWAYS;
} else if(!es_strconstcmp(pvals[i].val.d.estr, "new-only")) {
loadModConf->readMode = KMSG_READMODE_NEW_ONLY;
} else {
const char *const cstr = es_str2cstr(pvals[i].val.d.estr, NULL);
LogError(0, RS_RET_PARAM_ERROR, "imkmsg: unknown "
"read mode '%s', keeping default setting", cstr);
free((void*)cstr);
}
} else {
LogMsg(0, RS_RET_INTERNAL_ERROR, LOG_WARNING,
"imkmsg: RSYSLOG BUG, non-handled param '%s' in "
Expand Down
9 changes: 8 additions & 1 deletion contrib/imkmsg/imkmsg.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,21 @@ typedef enum _kernel_ts_parse_mods {
KMSG_PARSE_TS_STARTUP_ONLY = 2
} t_kernel_ts_parse_mode;

typedef enum _kernel_readmode {
KMSG_READMODE_FULL_BOOT = 0,
KMSG_READMODE_FULL_ALWAYS = 1,
KMSG_READMODE_NEW_ONLY = 2
} t_kernel_readmode;

/* we need to have the modConf type present in all submodules */
struct modConfData_s {
rsconf_t *pConf;
int iFacilIntMsg;
uchar *pszPath;
int console_log_level;
int expected_boot_complete_secs;
t_kernel_ts_parse_mode parseKernelStamp;
sbool bFixKernelStamp;
t_kernel_readmode readMode;
sbool configSetViaV2Method;
};

Expand Down
25 changes: 24 additions & 1 deletion contrib/imkmsg/kmsg.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,8 +228,31 @@ static void
readkmsg(modConfData_t *const pModConf)
{
int i;
uchar pRcv[8192+1];
uchar pRcv[16*1024+1];
char errmsg[2048];
off_t seek_result = 0;

if(pModConf->readMode == KMSG_READMODE_FULL_BOOT) {
struct sysinfo info;
sysinfo(&info);
DBGPRINTF("imkmsg: system uptime is %lld, expected %d\n",
(long long) info.uptime, pModConf->expected_boot_complete_secs);
if(info.uptime > pModConf->expected_boot_complete_secs) {
seek_result = lseek(fklog, 0, SEEK_END);
}
} else if(pModConf->readMode == KMSG_READMODE_NEW_ONLY) {
seek_result = lseek(fklog, 0, SEEK_END);
} else if(pModConf->readMode != KMSG_READMODE_FULL_ALWAYS) {
imkmsgLogIntMsg(LOG_ERR, "imkmsg: internal program error, "
"unknown read mode %d, assuming 'full-always'",
pModConf->readMode);
}

if(seek_result == (off_t) -1) {
imkmsgLogIntMsg(LOG_WARNING,
"imkmsg: could not seek to requested klog entries - will"
"now potentially output all messages");
}

for (;;) {
dbgprintf("imkmsg waiting for kernel log line\n");
Expand Down

0 comments on commit efbe2ce

Please sign in to comment.