Blame SOURCES/rsyslog-8.2102.0-rhbz1909639-statefiles-fix.patch

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