michal-grzedzicki / rpms / rpm

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