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

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