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

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