Blame SOURCES/rpm-4.14.3-fix-spurious-transfiletriggerpostun-execution.patch

63d136
From f17aa638649fb8de730fecdbc906dc869b626ba5 Mon Sep 17 00:00:00 2001
63d136
From: Panu Matilainen <pmatilai@redhat.com>
63d136
Date: Tue, 16 Nov 2021 11:49:18 +0200
63d136
Subject: [PATCH 1/2] Fix spurious %transfiletriggerpostun execution
63d136
 (RhBug:2023311)
63d136
63d136
If a package has multiple %transfiletriggerpostun triggers, any one
63d136
of them matching would cause all of them to run, due to disconnect
63d136
in the intel gathering stage: we'd gather all the headers with matching
63d136
files into a lump, and then add any postun triggers found in them,
63d136
but this loses the triggering file information and causes all postuns
63d136
to run.
63d136
63d136
The triggers need to be added while looping over the file matches,
63d136
like runFileTriggers() does. Doing so actually simplifies the code.
63d136
These should really be unified to use the same code, but leaving
63d136
that exercise to another rainy day.
63d136
---
63d136
 lib/rpmtriggers.c | 64 +++++++++++++++++++++++------------------------
63d136
 1 file changed, 31 insertions(+), 33 deletions(-)
63d136
63d136
diff --git a/lib/rpmtriggers.c b/lib/rpmtriggers.c
63d136
index 0827af0c2..dc457f7cc 100644
63d136
--- a/lib/rpmtriggers.c
63d136
+++ b/lib/rpmtriggers.c
63d136
@@ -97,19 +97,37 @@ static void rpmtriggersSortAndUniq(rpmtriggers trigs)
63d136
     }
63d136
 }
63d136
 
63d136
+static void addTriggers(rpmts ts, Header trigH, rpmsenseFlags filter)
63d136
+{
63d136
+    int tix = 0;
63d136
+    rpmds ds;
63d136
+    rpmds triggers = rpmdsNew(trigH, RPMTAG_TRANSFILETRIGGERNAME, 0);
63d136
+
63d136
+    while ((ds = rpmdsFilterTi(triggers, tix))) {
63d136
+	if ((rpmdsNext(ds) >= 0) && (rpmdsFlags(ds) & filter)) {
63d136
+	    struct rpmtd_s priorities;
63d136
+
63d136
+	    if (headerGet(trigH, RPMTAG_TRANSFILETRIGGERPRIORITIES,
63d136
+			&priorities, HEADERGET_MINMEM)) {
63d136
+		rpmtdSetIndex(&priorities, tix);
63d136
+		rpmtriggersAdd(ts->trigs2run, headerGetInstance(trigH),
63d136
+				tix, *rpmtdGetUint32(&priorities));
63d136
+	    }
63d136
+	}
63d136
+	rpmdsFree(ds);
63d136
+	tix++;
63d136
+    }
63d136
+    rpmdsFree(triggers);
63d136
+}
63d136
+
63d136
 void rpmtriggersPrepPostUnTransFileTrigs(rpmts ts, rpmte te)
63d136
 {
63d136
-    rpmdbMatchIterator mi;
63d136
     rpmdbIndexIterator ii;
63d136
-    Header trigH;
63d136
     const void *key;
63d136
     size_t keylen;
63d136
     rpmfiles files;
63d136
-    rpmds rpmdsTriggers;
63d136
-    rpmds rpmdsTrigger;
63d136
 
63d136
     ii = rpmdbIndexIteratorInit(rpmtsGetRdb(ts), RPMDBI_TRANSFILETRIGGERNAME);
63d136
-    mi = rpmdbNewIterator(rpmtsGetRdb(ts), RPMDBI_PACKAGES);
63d136
     files = rpmteFiles(te);
63d136
 
63d136
     /* Iterate over file triggers in rpmdb */
63d136
@@ -121,39 +139,19 @@ void rpmtriggersPrepPostUnTransFileTrigs(rpmts ts, rpmte te)
63d136
 	rpmfi fi = rpmfilesFindPrefix(files, pfx);
63d136
 	while (rpmfiNext(fi) >= 0) {
63d136
 	    if (RPMFILE_IS_INSTALLED(rpmfiFState(fi))) {
63d136
-		/* If yes then store it */
63d136
-		rpmdbAppendIterator(mi, rpmdbIndexIteratorPkgOffsets(ii),
63d136
-				rpmdbIndexIteratorNumPkgs(ii));
63d136
-		break;
63d136
+		unsigned int npkg = rpmdbIndexIteratorNumPkgs(ii);
63d136
+		const unsigned int *offs = rpmdbIndexIteratorPkgOffsets(ii);
63d136
+		/* Save any matching postun triggers */
63d136
+		for (int i = 0; i < npkg; i++) {
63d136
+		    Header h = rpmdbGetHeaderAt(rpmtsGetRdb(ts), offs[i]);
63d136
+		    addTriggers(ts, h, RPMSENSE_TRIGGERPOSTUN);
63d136
+		    headerFree(h);
63d136
+		}
63d136
 	    }
63d136
 	}
63d136
 	rpmfiFree(fi);
63d136
     }
63d136
     rpmdbIndexIteratorFree(ii);
63d136
-
63d136
-    if (rpmdbGetIteratorCount(mi)) {
63d136
-	/* Filter triggers and save only trans postun triggers into ts */
63d136
-	while ((trigH = rpmdbNextIterator(mi)) != NULL) {
63d136
-	    int tix = 0;
63d136
-	    rpmdsTriggers = rpmdsNew(trigH, RPMTAG_TRANSFILETRIGGERNAME, 0);
63d136
-	    while ((rpmdsTrigger = rpmdsFilterTi(rpmdsTriggers, tix))) {
63d136
-		if ((rpmdsNext(rpmdsTrigger) >= 0) &&
63d136
-		    (rpmdsFlags(rpmdsTrigger) & RPMSENSE_TRIGGERPOSTUN)) {
63d136
-		    struct rpmtd_s priorities;
63d136
-
63d136
-		    headerGet(trigH, RPMTAG_TRANSFILETRIGGERPRIORITIES,
63d136
-				&priorities, HEADERGET_MINMEM);
63d136
-		    rpmtdSetIndex(&priorities, tix);
63d136
-		    rpmtriggersAdd(ts->trigs2run, rpmdbGetIteratorOffset(mi),
63d136
-				    tix, *rpmtdGetUint32(&priorities));
63d136
-		}
63d136
-		rpmdsFree(rpmdsTrigger);
63d136
-		tix++;
63d136
-	    }
63d136
-	    rpmdsFree(rpmdsTriggers);
63d136
-	}
63d136
-    }
63d136
-    rpmdbFreeIterator(mi);
63d136
     rpmfilesFree(files);
63d136
 }
63d136
 
63d136
-- 
63d136
2.35.1
63d136
63d136
From e617e7c550d3523998707c55f96b37ede2c48c78 Mon Sep 17 00:00:00 2001
63d136
From: Panu Matilainen <pmatilai@redhat.com>
63d136
Date: Wed, 2 Feb 2022 13:46:23 +0200
63d136
Subject: [PATCH 2/2] Really fix spurious %transfiletriggerpostun execution
63d136
 (RhBug:2023311)
63d136
63d136
Commit b3d672a5523dfec033160e5cc866432a0e808649 got the base reasoning
63d136
in the ballpark but the code all wrong, introducing a severe performance
63d136
regression without actually fixing what it claimed to.
63d136
63d136
The missing incredient is actually comparing the current prefix with the
63d136
triggers in matched package (trying to describe this makes my head
63d136
spin): a package may have multiple triggers on multiple prefixes and
63d136
we need to make sure we only execute triggers of this type, from this
63d136
prefix.
63d136
63d136
This stuff really needs more and better testcases.
63d136
63d136
Fixes: b3d672a5523dfec033160e5cc866432a0e808649
63d136
---
63d136
 lib/rpmtriggers.c | 11 +++++++----
63d136
 1 file changed, 7 insertions(+), 4 deletions(-)
63d136
63d136
diff --git a/lib/rpmtriggers.c b/lib/rpmtriggers.c
63d136
index dc457f7cc..c652981be 100644
63d136
--- a/lib/rpmtriggers.c
63d136
+++ b/lib/rpmtriggers.c
63d136
@@ -97,14 +97,16 @@ static void rpmtriggersSortAndUniq(rpmtriggers trigs)
63d136
     }
63d136
 }
63d136
 
63d136
-static void addTriggers(rpmts ts, Header trigH, rpmsenseFlags filter)
63d136
+static void addTriggers(rpmts ts, Header trigH, rpmsenseFlags filter,
63d136
+			const char *prefix)
63d136
 {
63d136
     int tix = 0;
63d136
     rpmds ds;
63d136
     rpmds triggers = rpmdsNew(trigH, RPMTAG_TRANSFILETRIGGERNAME, 0);
63d136
 
63d136
     while ((ds = rpmdsFilterTi(triggers, tix))) {
63d136
-	if ((rpmdsNext(ds) >= 0) && (rpmdsFlags(ds) & filter)) {
63d136
+	if ((rpmdsNext(ds) >= 0) && (rpmdsFlags(ds) & filter) &&
63d136
+		strcmp(prefix, rpmdsN(ds)) == 0) {
63d136
 	    struct rpmtd_s priorities;
63d136
 
63d136
 	    if (headerGet(trigH, RPMTAG_TRANSFILETRIGGERPRIORITIES,
63d136
@@ -141,12 +143,13 @@ void rpmtriggersPrepPostUnTransFileTrigs(rpmts ts, rpmte te)
63d136
 	    if (RPMFILE_IS_INSTALLED(rpmfiFState(fi))) {
63d136
 		unsigned int npkg = rpmdbIndexIteratorNumPkgs(ii);
63d136
 		const unsigned int *offs = rpmdbIndexIteratorPkgOffsets(ii);
63d136
-		/* Save any matching postun triggers */
63d136
+		/* Save any postun triggers matching this prefix */
63d136
 		for (int i = 0; i < npkg; i++) {
63d136
 		    Header h = rpmdbGetHeaderAt(rpmtsGetRdb(ts), offs[i]);
63d136
-		    addTriggers(ts, h, RPMSENSE_TRIGGERPOSTUN);
63d136
+		    addTriggers(ts, h, RPMSENSE_TRIGGERPOSTUN, pfx);
63d136
 		    headerFree(h);
63d136
 		}
63d136
+		break;
63d136
 	    }
63d136
 	}
63d136
 	rpmfiFree(fi);
63d136
-- 
63d136
2.35.1
63d136