163 lines
7.0 KiB
Diff
163 lines
7.0 KiB
Diff
|
diff -up rsyslog-8.2102.0/plugins/imfile/imfile.c.state-file-leaking rsyslog-8.2102.0/plugins/imfile/imfile.c
|
||
|
--- rsyslog-8.2102.0/plugins/imfile/imfile.c.state-file-leaking 2021-01-18 11:21:14.000000000 +0100
|
||
|
+++ rsyslog-8.2102.0/plugins/imfile/imfile.c 2022-03-28 12:51:03.572554843 +0200
|
||
|
@@ -259,6 +259,7 @@ struct modConfData_s {
|
||
|
Must be manually reset to 0 if desired. Helper for
|
||
|
polling mode.
|
||
|
*/
|
||
|
+ sbool deleteStateOnFileMove;
|
||
|
};
|
||
|
static modConfData_t *loadModConf = NULL;/* modConf ptr to use for the current load process */
|
||
|
static modConfData_t *runModConf = NULL;/* modConf ptr to use for run process */
|
||
|
@@ -305,7 +306,8 @@ static struct cnfparamdescr modpdescr[]
|
||
|
{ "sortfiles", eCmdHdlrBinary, 0 },
|
||
|
{ "statefile.directory", eCmdHdlrString, 0 },
|
||
|
{ "normalizepath", eCmdHdlrBinary, 0 },
|
||
|
- { "mode", eCmdHdlrGetWord, 0 }
|
||
|
+ { "mode", eCmdHdlrGetWord, 0 },
|
||
|
+ { "deletestateonfilemove", eCmdHdlrBinary, 0 }
|
||
|
};
|
||
|
static struct cnfparamblk modpblk =
|
||
|
{ CNFPARAMBLK_VERSION,
|
||
|
@@ -545,11 +547,20 @@ static int
|
||
|
in_setupWatch(act_obj_t *const act, const int is_file)
|
||
|
{
|
||
|
int wd = -1;
|
||
|
+ int flags;
|
||
|
if(runModConf->opMode != OPMODE_INOTIFY)
|
||
|
goto done;
|
||
|
|
||
|
- wd = inotify_add_watch(ino_fd, act->name,
|
||
|
- (is_file) ? IN_MODIFY|IN_DONT_FOLLOW : IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO);
|
||
|
+ // wd = inotify_add_watch(ino_fd, act->name,
|
||
|
+ // (is_file) ? IN_MODIFY|IN_DONT_FOLLOW : IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO);
|
||
|
+ if(is_file)
|
||
|
+ flags = IN_MODIFY|IN_DONT_FOLLOW;
|
||
|
+ else if(runModConf->deleteStateOnFileMove)
|
||
|
+ flags = IN_CREATE|IN_DELETE|IN_MOVED_TO;
|
||
|
+ else
|
||
|
+ flags = IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO;
|
||
|
+ wd = inotify_add_watch(ino_fd, act->name, flags);
|
||
|
+
|
||
|
if(wd < 0) {
|
||
|
if (errno == EACCES) { /* There is high probability of selinux denial on top-level paths */
|
||
|
DBGPRINTF("imfile: permission denied when adding watch for '%s'\n", act->name);
|
||
|
@@ -713,7 +724,7 @@ act_obj_add(fs_edge_t *const edge, const
|
||
|
char basename[MAXFNAME];
|
||
|
DEFiRet;
|
||
|
int fd = -1;
|
||
|
-
|
||
|
+
|
||
|
DBGPRINTF("act_obj_add: edge %p, name '%s' (source '%s')\n", edge, name, source? source : "---");
|
||
|
for(act = edge->active ; act != NULL ; act = act->next) {
|
||
|
if(!strcmp(act->name, name)) {
|
||
|
@@ -977,9 +988,18 @@ act_obj_destroy(act_obj_t *const act, co
|
||
|
if(act == NULL)
|
||
|
return;
|
||
|
|
||
|
- DBGPRINTF("act_obj_destroy: act %p '%s' (source '%s'), wd %d, pStrm %p, is_deleted %d, in_move %d\n",
|
||
|
- act, act->name, act->source_name? act->source_name : "---", act->wd, act->pStrm, is_deleted,
|
||
|
- act->in_move);
|
||
|
+ // DBGPRINTF("act_obj_destroy: act %p '%s' (source '%s'), wd %d, pStrm %p, is_deleted %d, in_move %d\n",
|
||
|
+ // act, act->name, act->source_name? act->source_name : "---", act->wd, act->pStrm, is_deleted,
|
||
|
+ // act->in_move);
|
||
|
+ if (runModConf->deleteStateOnFileMove) {
|
||
|
+ DBGPRINTF("act_obj_destroy: act %p '%s' (source '%s'), wd %d, pStrm %p, is_deleted %d\n",
|
||
|
+ act, act->name, act->source_name? act->source_name : "---", act->wd, act->pStrm, is_deleted);
|
||
|
+ } else {
|
||
|
+ DBGPRINTF("act_obj_destroy: act %p '%s' (source '%s'), wd %d, pStrm %p, is_deleted %d, in_move %d\n",
|
||
|
+ act, act->name, act->source_name? act->source_name : "---", act->wd, act->pStrm,
|
||
|
+ is_deleted, act->in_move);
|
||
|
+ }
|
||
|
+
|
||
|
if(act->is_symlink && is_deleted) {
|
||
|
act_obj_t *target_act;
|
||
|
for(target_act = act->edge->active ; target_act != NULL ; target_act = target_act->next) {
|
||
|
@@ -996,13 +1016,15 @@ act_obj_destroy(act_obj_t *const act, co
|
||
|
pollFile(act); /* get any left-over data */
|
||
|
if(inst->bRMStateOnDel) {
|
||
|
statefn = getStateFileName(act, statefile, sizeof(statefile));
|
||
|
- getFullStateFileName(statefn, "", toDel, sizeof(toDel)); // TODO: check!
|
||
|
+ // getFullStateFileName(statefn, "", toDel, sizeof(toDel)); // TODO: check!
|
||
|
+ getFullStateFileName(statefn, act->file_id, toDel, sizeof(toDel)); // TODO: check!
|
||
|
statefn = toDel;
|
||
|
}
|
||
|
persistStrmState(act);
|
||
|
strm.Destruct(&act->pStrm);
|
||
|
/* we delete state file after destruct in case strm obj initiated a write */
|
||
|
- if(is_deleted && !act->in_move && inst->bRMStateOnDel) {
|
||
|
+ // if(is_deleted && !act->in_move && inst->bRMStateOnDel) {
|
||
|
+ if(is_deleted && inst->bRMStateOnDel && (runModConf->deleteStateOnFileMove || !act->in_move)) {
|
||
|
DBGPRINTF("act_obj_destroy: deleting state file %s\n", statefn);
|
||
|
unlink((char*)statefn);
|
||
|
}
|
||
|
@@ -1012,6 +1034,7 @@ act_obj_destroy(act_obj_t *const act, co
|
||
|
}
|
||
|
#ifdef HAVE_INOTIFY_INIT
|
||
|
if(act->wd != -1) {
|
||
|
+ inotify_rm_watch(ino_fd, act->wd);
|
||
|
wdmapDel(act->wd);
|
||
|
}
|
||
|
#endif
|
||
|
@@ -2026,6 +2049,7 @@ CODESTARTbeginCnfLoad
|
||
|
loadModConf->timeoutGranularity = 1000; /* default: 1 second */
|
||
|
loadModConf->haveReadTimeouts = 0; /* default: no timeout */
|
||
|
loadModConf->normalizePath = 1;
|
||
|
+ loadModConf->deleteStateOnFileMove = 0;
|
||
|
loadModConf->sortFiles = GLOB_NOSORT;
|
||
|
loadModConf->stateFileDirectory = NULL;
|
||
|
loadModConf->conf_tree = calloc(sizeof(fs_node_t), 1);
|
||
|
@@ -2085,6 +2109,8 @@ CODESTARTsetModCnf
|
||
|
loadModConf->stateFileDirectory = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
|
||
|
} else if(!strcmp(modpblk.descr[i].name, "normalizepath")) {
|
||
|
loadModConf->normalizePath = (sbool) pvals[i].val.d.n;
|
||
|
+ } else if(!strcmp(modpblk.descr[i].name, "deletestateonfilemove")) {
|
||
|
+ loadModConf->deleteStateOnFileMove = (sbool) pvals[i].val.d.n;
|
||
|
} else if(!strcmp(modpblk.descr[i].name, "mode")) {
|
||
|
if(!es_strconstcmp(pvals[i].val.d.estr, "polling"))
|
||
|
loadModConf->opMode = OPMODE_POLLING;
|
||
|
@@ -2388,16 +2414,35 @@ in_processEvent(struct inotify_event *ev
|
||
|
DBGPRINTF("in_processEvent process Event %x is_file %d, act->name '%s'\n",
|
||
|
ev->mask, etry->act->edge->is_file, etry->act->name);
|
||
|
|
||
|
- if((ev->mask & IN_MOVED_FROM)) {
|
||
|
- flag_in_move(etry->act->edge->node->edges, ev->name);
|
||
|
- }
|
||
|
- if(ev->mask & (IN_MOVED_FROM | IN_MOVED_TO)) {
|
||
|
- fs_node_walk(etry->act->edge->node, poll_tree);
|
||
|
- } else if(etry->act->edge->is_file && !(etry->act->is_symlink)) {
|
||
|
- in_handleFileEvent(ev, etry); // esentially poll_file()!
|
||
|
+ // if((ev->mask & IN_MOVED_FROM)) {
|
||
|
+ // flag_in_move(etry->act->edge->node->edges, ev->name);
|
||
|
+ // }
|
||
|
+ // if(ev->mask & (IN_MOVED_FROM | IN_MOVED_TO)) {
|
||
|
+ // fs_node_walk(etry->act->edge->node, poll_tree);
|
||
|
+ // } else if(etry->act->edge->is_file && !(etry->act->is_symlink)) {
|
||
|
+ // in_handleFileEvent(ev, etry); // esentially poll_file()!
|
||
|
+ // } else {
|
||
|
+ // fs_node_walk(etry->act->edge->node, poll_tree);
|
||
|
+ // }
|
||
|
+ if(!runModConf->deleteStateOnFileMove) {
|
||
|
+ if((ev->mask & IN_MOVED_FROM)) {
|
||
|
+ flag_in_move(etry->act->edge->node->edges, ev->name);
|
||
|
+ }
|
||
|
+ if(ev->mask & (IN_MOVED_FROM | IN_MOVED_TO)) {
|
||
|
+ fs_node_walk(etry->act->edge->node, poll_tree);
|
||
|
+ } else if(etry->act->edge->is_file && !(etry->act->is_symlink)) {
|
||
|
+ in_handleFileEvent(ev, etry); // esentially poll_file()!
|
||
|
+ } else {
|
||
|
+ fs_node_walk(etry->act->edge->node, poll_tree);
|
||
|
+ }
|
||
|
} else {
|
||
|
- fs_node_walk(etry->act->edge->node, poll_tree);
|
||
|
+ if((ev->mask & IN_MODIFY) && etry->act->edge->is_file && !(etry->act->is_symlink)) {
|
||
|
+ in_handleFileEvent(ev, etry); // esentially poll_file()!
|
||
|
+ } else {
|
||
|
+ fs_node_walk(etry->act->edge->node, poll_tree);
|
||
|
+ }
|
||
|
}
|
||
|
+
|
||
|
done: return;
|
||
|
}
|
||
|
|