Merge pull request #1455 from alorbach/imfile-wildcardfix

imfile: Fixed an issue monitoring wrong files when using multiple imf…
This commit is contained in:
Rainer Gerhards 2017-03-09 12:25:01 +01:00 committed by GitHub
commit 74f47a0908
3 changed files with 83 additions and 48 deletions

View File

@ -84,6 +84,15 @@ static int bLegacyCnfModGlobalsPermitted;/* are legacy module-global config para
#define ADD_METADATA_UNSPECIFIED -1 #define ADD_METADATA_UNSPECIFIED -1
/*
* Helpers for wildcard in directory detection
*/
#define DIR_CONFIGURED 0
#define DIR_DYNAMIC 1
/* If set to 1, fileTableDisplay will be compiled and used for debugging */
#define ULTRA_DEBUG 0
/* this structure is used in pure polling mode as well one of the support /* this structure is used in pure polling mode as well one of the support
* structures for inotify. * structures for inotify.
*/ */
@ -217,6 +226,7 @@ typedef struct fileTable_s fileTable_t;
*/ */
struct dirInfo_s { struct dirInfo_s {
uchar *dirName; uchar *dirName;
int bDirType; /* Configured or dynamic */
fileTable_t active; /* associated active files */ fileTable_t active; /* associated active files */
fileTable_t configured; /* associated configured files */ fileTable_t configured; /* associated configured files */
}; };
@ -224,11 +234,11 @@ typedef struct dirInfo_s dirInfo_t;
static dirInfo_t *dirs = NULL; static dirInfo_t *dirs = NULL;
static int allocMaxDirs; static int allocMaxDirs;
static int currMaxDirs; static int currMaxDirs;
/* the following two macros are used to select the correct file table */ /* the following two macros are used to select the correct file table */
#define ACTIVE_FILE 1 #define ACTIVE_FILE 1
#define CONFIGURED_FILE 0 #define CONFIGURED_FILE 0
/* We need to map watch descriptors to our actual objects. Unfortunately, the /* We need to map watch descriptors to our actual objects. Unfortunately, the
* inotify API does not provide us with any cookie, so a simple O(1) algorithm * inotify API does not provide us with any cookie, so a simple O(1) algorithm
* cannot be done (what a shame...). We assume that maintaining the array is much * cannot be done (what a shame...). We assume that maintaining the array is much
@ -826,7 +836,7 @@ checkInstance(instanceConf_t *inst)
*/ */
if(inst->pszFileName == NULL) if(inst->pszFileName == NULL)
ABORT_FINALIZE(RS_RET_INTERNAL_ERROR); ABORT_FINALIZE(RS_RET_INTERNAL_ERROR);
i = getBasename(basen, inst->pszFileName); i = getBasename(basen, inst->pszFileName);
if (i == -1) { if (i == -1) {
errmsg.LogError(0, RS_RET_CONFIG_ERROR, "imfile: file path '%s' does not include a basename component", errmsg.LogError(0, RS_RET_CONFIG_ERROR, "imfile: file path '%s' does not include a basename component",
@ -1392,26 +1402,30 @@ fileTableInit(fileTable_t *const __restrict__ tab, const int nelem)
finalize_it: finalize_it:
RETiRet; RETiRet;
} }
/* uncomment if needed
#if ULTRA_DEBUG == 1
static void static void
fileTableDisplay(fileTable_t *tab) fileTableDisplay(fileTable_t *tab)
{ {
int f; int f;
uchar *baseName; uchar *baseName;
DBGPRINTF("imfile: dirs.currMaxfiles %d\n", tab->currMax); DBGPRINTF("imfile: fileTableDisplay = dirs.currMaxfiles %d\n", tab->currMax);
for(f = 0 ; f < tab->currMax ; ++f) { for(f = 0 ; f < tab->currMax ; ++f) {
baseName = tab->listeners[f].pLstn->pszBaseName; baseName = tab->listeners[f].pLstn->pszBaseName;
DBGPRINTF("imfile: TABLE %p CONTENTS, %d->%p:'%s'\n", tab, f, tab->listeners[f].pLstn, (char*)baseName); DBGPRINTF("imfile: fileTableDisplay = TABLE %p CONTENTS, %d->%p:'%s'\n",
tab, f, tab->listeners[f].pLstn, (char*)baseName);
} }
} }
*/ #endif
static int static int
fileTableSearch(fileTable_t *const __restrict__ tab, uchar *const __restrict__ fn) fileTableSearch(fileTable_t *const __restrict__ tab, uchar *const __restrict__ fn)
{ {
int f; int f;
uchar *baseName = NULL; uchar *baseName = NULL;
/* UNCOMMENT FOR DEBUG fileTableDisplay(tab); */ #if ULTRA_DEBUG == 1
fileTableDisplay(tab);
#endif
for(f = 0 ; f < tab->currMax ; ++f) { for(f = 0 ; f < tab->currMax ; ++f) {
baseName = tab->listeners[f].pLstn->pszBaseName; baseName = tab->listeners[f].pLstn->pszBaseName;
if(!fnmatch((char*)baseName, (char*)fn, FNM_PATHNAME | FNM_PERIOD)) if(!fnmatch((char*)baseName, (char*)fn, FNM_PATHNAME | FNM_PERIOD))
@ -1524,7 +1538,7 @@ dirsAdd(uchar *dirName, int* piIndex)
break; break;
} }
} }
/* Save Index for higher functions */ /* Save Index for higher functions */
if (piIndex != NULL ) if (piIndex != NULL )
*piIndex = newindex; *piIndex = newindex;
@ -1546,6 +1560,7 @@ dirsAdd(uchar *dirName, int* piIndex)
/* if we reach this point, there is space in the file table for the new entry */ /* if we reach this point, there is space in the file table for the new entry */
dirs[newindex].dirName = (uchar*)strdup((char*)dirName); /* Get a copy of the string !*/ dirs[newindex].dirName = (uchar*)strdup((char*)dirName); /* Get a copy of the string !*/
dirs[newindex].bDirType = DIR_CONFIGURED; /* Default to configured! */
CHKiRet(fileTableInit(&dirs[newindex].active, INIT_FILE_IN_DIR_TAB_SIZE)); CHKiRet(fileTableInit(&dirs[newindex].active, INIT_FILE_IN_DIR_TAB_SIZE));
CHKiRet(fileTableInit(&dirs[newindex].configured, INIT_FILE_IN_DIR_TAB_SIZE)); CHKiRet(fileTableInit(&dirs[newindex].configured, INIT_FILE_IN_DIR_TAB_SIZE));
@ -1681,8 +1696,8 @@ in_setupDirWatch(const int dirIdx)
} }
} }
wdmapAdd(wd, dirIdx, NULL); wdmapAdd(wd, dirIdx, NULL);
DBGPRINTF("imfile: in_setupDirWatch: watch %d added for dir %s\n", wd, DBGPRINTF("imfile: in_setupDirWatch: watch %d added for dir %s(Idx=%d)\n", wd,
(dirnamelen == 0) ? (char*) dirs[dirIdx].dirName : (char*) dirnametrunc); (dirnamelen == 0) ? (char*) dirs[dirIdx].dirName : (char*) dirnametrunc, dirIdx);
done: return; done: return;
} }
@ -1728,7 +1743,7 @@ lstnDup(lstn_t **ppExisting, uchar *const __restrict__ newname, uchar *const __r
lstn_t *const existing = *ppExisting; lstn_t *const existing = *ppExisting;
lstn_t *pThis; lstn_t *pThis;
CHKiRet(lstnAdd(&pThis)); CHKiRet(lstnAdd(&pThis));
/* Use dynamic dirname if newdirname is set! */ /* Use dynamic dirname if newdirname is set! */
if (newdirname == NULL) { if (newdirname == NULL) {
pThis->pszDirName = existing->pszDirName; /* read-only */ pThis->pszDirName = existing->pszDirName; /* read-only */
@ -2028,6 +2043,7 @@ in_handleDirEventDirCREATE(struct inotify_event *ev, const int dirIdx)
/* Add dir to table and create watch */ /* Add dir to table and create watch */
DBGPRINTF("imfile: Adding new dir '%s' to dirs table \n", fulldn); DBGPRINTF("imfile: Adding new dir '%s' to dirs table \n", fulldn);
dirsAdd((uchar*)fulldn, &newdiridx); dirsAdd((uchar*)fulldn, &newdiridx);
dirs[newdiridx].bDirType = DIR_DYNAMIC; /* Set to DYNAMIC directory! */
in_setupDirWatch(newdiridx); in_setupDirWatch(newdiridx);
} else { } else {
DBGPRINTF("imfile: dir '%s' already exists in dirs table (Idx %d)\n", fulldn, newdiridx); DBGPRINTF("imfile: dir '%s' already exists in dirs table (Idx %d)\n", fulldn, newdiridx);
@ -2038,7 +2054,7 @@ static void
in_handleDirEventFileCREATE(struct inotify_event *ev, const int dirIdx) in_handleDirEventFileCREATE(struct inotify_event *ev, const int dirIdx)
{ {
int i; int i;
lstn_t *pLstn; lstn_t *pLstn = NULL;
int ftIdx; int ftIdx;
char fullfn[MAXFNAME]; char fullfn[MAXFNAME];
uchar* pszDir = NULL; uchar* pszDir = NULL;
@ -2047,48 +2063,59 @@ in_handleDirEventFileCREATE(struct inotify_event *ev, const int dirIdx)
if(ftIdx >= 0) { if(ftIdx >= 0) {
pLstn = dirs[dirIdxFinal].active.listeners[ftIdx].pLstn; pLstn = dirs[dirIdxFinal].active.listeners[ftIdx].pLstn;
} else { } else {
DBGPRINTF("imfile: in_handleDirEventFileCREATE '%s' not associated with dir '%s' (CurMax:%d)\n", DBGPRINTF("imfile: in_handleDirEventFileCREATE '%s' not associated with dir '%s' "
ev->name, dirs[dirIdxFinal].dirName, dirs[dirIdxFinal].active.currMax); "(CurMax:%d, DirIdx:%d, DirType:%s)\n", ev->name, dirs[dirIdxFinal].dirName,
dirs[dirIdxFinal].active.currMax, dirIdxFinal,
(dirs[dirIdxFinal].bDirType == DIR_CONFIGURED ? "configured" : "dynamic") );
ftIdx = fileTableSearch(&dirs[dirIdxFinal].configured, (uchar*)ev->name); ftIdx = fileTableSearch(&dirs[dirIdxFinal].configured, (uchar*)ev->name);
if(ftIdx == -1) { if(ftIdx == -1) {
/* Search all other configured directories for proper index! */ if (dirs[dirIdxFinal].bDirType == DIR_DYNAMIC) {
if (currMaxDirs > 0) { /* Search all other configured directories for proper index! */
/* Store Dirname as we need to overwrite it in in_setupFileWatchDynamic */ if (currMaxDirs > 0) {
pszDir = dirs[dirIdxFinal].dirName; /* Store Dirname as we need to overwrite it in in_setupFileWatchDynamic */
pszDir = dirs[dirIdxFinal].dirName;
/* Combine directory and filename */ /* Combine directory and filename */
snprintf(fullfn, MAXFNAME, "%s/%s", pszDir, (uchar*)ev->name); snprintf(fullfn, MAXFNAME, "%s/%s", pszDir, (uchar*)ev->name);
for(i = 0 ; i < currMaxDirs ; ++i) { for(i = 0 ; i < currMaxDirs ; ++i) {
ftIdx = fileTableSearch(&dirs[i].configured, (uchar*)ev->name); ftIdx = fileTableSearch(&dirs[i].configured, (uchar*)ev->name);
if(ftIdx != -1) { if(ftIdx != -1) {
/* Found matching directory! */ /* Found matching directory! */
dirIdxFinal = i; /* Have to correct directory index for listnr dupl dirIdxFinal = i; /* Have to correct directory index for listnr dupl
in in_setupFileWatchDynamic */ in in_setupFileWatchDynamic */
break;
DBGPRINTF("imfile: Found matching directory for file '%s' in dir '%s' (Idx=%d)\n",
ev->name, dirs[dirIdxFinal].dirName, dirIdxFinal);
break;
}
} }
} /* Found Listener to se */
pLstn = dirs[dirIdxFinal].configured.listeners[ftIdx].pLstn;
if(ftIdx == -1) { if(ftIdx == -1) {
DBGPRINTF("imfile: file '%s' not associated with dir '%s' and also no " DBGPRINTF("imfile: file '%s' not associated with dir '%s' and also no "
"matching wildcard directory found\n", ev->name, dirs[dirIdxFinal].dirName); "matching wildcard directory found\n", ev->name, dirs[dirIdxFinal].dirName);
goto done;
}
else {
DBGPRINTF("imfile: file '%s' not associated with dir '%s', using dirIndex %d instead\n",
ev->name, (pszDir == NULL) ? dirs[dirIdxFinal].dirName : pszDir, dirIdxFinal);
}
} else {
DBGPRINTF("imfile: file '%s' not associated with dir '%s'\n",
ev->name, dirs[dirIdxFinal].dirName);
goto done; goto done;
} }
else {
DBGPRINTF("imfile: file '%s' not associated with dir '%s', using dirIndex %d instead\n",
ev->name, (pszDir == NULL) ? dirs[dirIdxFinal].dirName : pszDir, dirIdxFinal);
}
} else {
DBGPRINTF("imfile: file '%s' not associated with dir '%s'\n",
ev->name, dirs[dirIdxFinal].dirName);
goto done;
} }
} } else
pLstn = dirs[dirIdxFinal].configured.listeners[ftIdx].pLstn; pLstn = dirs[dirIdxFinal].configured.listeners[ftIdx].pLstn;
}
if (pLstn != NULL) {
DBGPRINTF("imfile: file '%s' associated with dir '%s' (Idx=%d)\n",
ev->name, (pszDir == NULL) ? dirs[dirIdxFinal].dirName : pszDir, dirIdxFinal);
in_setupFileWatchDynamic(pLstn, (uchar*)ev->name, (pszDir == NULL) ? NULL : (uchar*)fullfn);
} }
DBGPRINTF("imfile: file '%s' associated with dir '%s'\n",
ev->name, (pszDir == NULL) ? dirs[dirIdxFinal].dirName : pszDir);
in_setupFileWatchDynamic(pLstn, (uchar*)ev->name, (pszDir == NULL) ? NULL : (uchar*)fullfn);
done: return; done: return;
} }

View File

@ -8,7 +8,7 @@ export IMFILEINPUTFILES="10"
# generate input files first. Note that rsyslog processes it as # generate input files first. Note that rsyslog processes it as
# soon as it start up (so the file should exist at that point). # soon as it start up (so the file should exist at that point).
imfilebefore="rsyslog.input.1" imfilebefore="rsyslog.input.1.log"
./inputfilegen -m 1 > $imfilebefore ./inputfilegen -m 1 > $imfilebefore
# Start rsyslog now before adding more files # Start rsyslog now before adding more files
@ -18,8 +18,8 @@ sleep 1
for i in `seq 2 $IMFILEINPUTFILES`; for i in `seq 2 $IMFILEINPUTFILES`;
do do
cp $imfilebefore rsyslog.input.$i cp $imfilebefore rsyslog.input.$i.log
imfilebefore="rsyslog.input.$i" imfilebefore="rsyslog.input.$i.log"
done done
ls -l rsyslog.input.* ls -l rsyslog.input.*

View File

@ -6,12 +6,20 @@ module( load="../plugins/imfile/.libs/imfile"
PollingInterval="1") PollingInterval="1")
input(type="imfile" input(type="imfile"
File="./rsyslog.input.*" File="./rsyslog.input.*.log"
Tag="file:" Tag="file:"
Severity="error" Severity="error"
Facility="local7" Facility="local7"
addMetadata="on" addMetadata="on"
) )
input(type="imfile"
File="/does/not/exist/*.log"
Tag="file:"
Severity="error"
Facility="local7"
addMetadata="on"
)
template(name="outfmt" type="list") { template(name="outfmt" type="list") {
constant(value="HEADER ") constant(value="HEADER ")