[Rpm-maint] [PATCH v2 3/5] Add common Collection requirements

Steve Lawrence slawrence at tresys.com
Mon Jun 21 21:04:38 UTC 2010


This patch adds the install-time feature that if a package requires a package
in a collection, then it also requires all other packages in that collection.
This has the effect that collections will be roughly grouped together during a
transaction.

Although this is not absolutely necessary for the majority of collections, it
is required for the SELinux collection. This is because all SELinux policies
must be installed before the applications they secure to ensure correct labels.
This means we must ensure packages in the selinux collection are ordered
earlier in the transaction than all applications they protect. Adding this
implicit runtime requirements achieves this in a general manner, without major
modifications to dependency ordering.

To accomplish this, this patch splits the addRelation function into two parts:
one that determines which relations to add, and one that actually adds them.
After the usual relation is added between two packages, it then determines if
the required package contains any collections. If so, it finds all other
packages that are in the same collections and creates additional relations.
---
 lib/order.c |   87 ++++++++++++++++++++++++++++++++++++++--------------------
 lib/rpmal.c |   26 +++++++++++++++++
 lib/rpmal.h |   11 +++++++
 3 files changed, 94 insertions(+), 30 deletions(-)

diff --git a/lib/order.c b/lib/order.c
index e0b6924..7e77834 100644
--- a/lib/order.c
+++ b/lib/order.c
@@ -145,45 +145,24 @@ static void rpmTSIFree(tsortInfo tsi)
     }
 }
 
-/**
- * Record next "q <- p" relation (i.e. "p" requires "q").
- * @param ts		transaction set
- * @param p		predecessor (i.e. package that "Requires: q")
- * @param requires	relation
- * @return		0 always
- */
-static inline int addRelation(rpmts ts,
-			      rpmal al,
-			      rpmte p,
-			      rpmds requires)
+static inline int addSingleRelation(rpmte p,
+				    rpmte q,
+				    rpmsenseFlags dsflags)
 {
-    rpmte q;
-    struct tsortInfo_s * tsi_p, * tsi_q;
+    struct tsortInfo_s *tsi_p, *tsi_q;
     relation rel;
     rpmElementType teType = rpmteType(p);
-    rpmsenseFlags flags, dsflags;
-
-    dsflags = rpmdsFlags(requires);
-
-    /* Avoid dependendencies which are not relevant for ordering */
-    if (dsflags & (RPMSENSE_RPMLIB|RPMSENSE_CONFIG|RPMSENSE_PRETRANS))
-	return 0;
-
-    q = rpmalSatisfiesDepend(al, requires);
+    rpmsenseFlags flags;
 
     /* Avoid deps outside this transaction and self dependencies */
     if (q == NULL || q == p)
 	return 0;
 
-    /* Avoid certain dependency relations. */
-    if (ignoreDep(ts, p, q))
-	return 0;
-
     /* Erasures are reversed installs. */
     if (teType == TR_REMOVED) {
-        rpmte r = p;
-        p = q;
-        q = r;
+	rpmte r = p;
+	p = q;
+	q = r;
 	flags = isErasePreReq(dsflags);
     } else {
 	flags = isInstallPreReq(dsflags);
@@ -192,7 +171,7 @@ static inline int addRelation(rpmts ts,
     /* map legacy prereq to pre/preun as needed */
     if (isLegacyPreReq(dsflags)) {
 	flags |= (teType == TR_ADDED) ?
-		 RPMSENSE_SCRIPT_PRE : RPMSENSE_SCRIPT_PREUN;
+	    RPMSENSE_SCRIPT_PRE : RPMSENSE_SCRIPT_PREUN;
     }
 
     tsi_p = rpmteTSI(p);
@@ -233,6 +212,54 @@ static inline int addRelation(rpmts ts,
 }
 
 /**
+ * Record next "q <- p" relation (i.e. "p" requires "q").
+ * @param ts		transaction set
+ * @param p		predecessor (i.e. package that "Requires: q")
+ * @param requires	relation
+ * @return		0 always
+ */
+static inline int addRelation(rpmts ts,
+			      rpmal al,
+			      rpmte p,
+			      rpmds requires)
+{
+    rpmte q;
+    ARGV_const_t qcolls;
+    rpmsenseFlags dsflags;
+
+    dsflags = rpmdsFlags(requires);
+
+    /* Avoid dependendencies which are not relevant for ordering */
+    if (dsflags & (RPMSENSE_RPMLIB|RPMSENSE_CONFIG|RPMSENSE_PRETRANS))
+	return 0;
+
+    q = rpmalSatisfiesDepend(al, requires);
+
+    /* Avoid deps outside this transaction and self dependencies */
+    if (q == NULL || q == p)
+	return 0;
+
+    /* Avoid certain dependency relations. */
+    if (ignoreDep(ts, p, q))
+	return 0;
+
+    addSingleRelation(p, q, dsflags);
+
+    /* If q is a member of any collections, make sure p requires all packages
+     * that are also in those collections */
+    for (qcolls = rpmteCollections(q); qcolls && *qcolls; qcolls++) {
+	rpmte *te;
+	rpmte *tes = rpmalAllInCollection(al, *qcolls);
+	for (te = tes; te && *te; te++) {
+	    addSingleRelation(p, *te, RPMSENSE_SCRIPT_PRE);
+	}
+	_free(tes);
+    }
+
+    return 0;
+}
+
+/**
  * Add element to list sorting by tsi_qcnt.
  * @param p		new element
  * @retval qp		address of first element
diff --git a/lib/rpmal.c b/lib/rpmal.c
index abe44b3..7ad1e8c 100644
--- a/lib/rpmal.c
+++ b/lib/rpmal.c
@@ -11,6 +11,7 @@
 
 #include "lib/rpmal.h"
 #include "lib/misc.h"
+#include "lib/rpmte_internal.h"
 
 #include "debug.h"
 
@@ -393,3 +394,28 @@ rpmalSatisfiesDepend(const rpmal al, const rpmds ds)
     }
     return best;
 }
+
+rpmte *
+rpmalAllInCollection(const rpmal al, const char *collname)
+{
+    rpmte *ret = NULL;
+    int found = 0;
+    rpmalNum pkgNum;
+
+    if (!al || !al->list || !collname)
+	return NULL;
+
+    for (pkgNum = 0; pkgNum < al->size; pkgNum++) {
+	rpmte p = al->list[pkgNum].p;
+	if (rpmteHasCollection(p, collname)) {
+	    ret = xrealloc(ret, sizeof(*ret) * (found + 1 + 1));
+	    ret[found] = p;
+	    found++;
+	}
+    }
+    if (ret) {
+	ret[found] = NULL;
+    }
+
+    return ret;
+}
diff --git a/lib/rpmal.h b/lib/rpmal.h
index d389c74..9a0e640 100644
--- a/lib/rpmal.h
+++ b/lib/rpmal.h
@@ -57,6 +57,17 @@ void rpmalAdd(rpmal al, rpmte p);
 RPM_GNUC_INTERNAL
 rpmte rpmalSatisfiesDepend(const rpmal al, const rpmds ds);
 
+/**
+ * Get a list of transaction elements that are memebers of a collection in the
+ * available list
+ * @param al		available list
+ * @param collname	collection name to search for
+ * @return		NULL-terminated list of transaction elements that are
+ *			members of the specified collection
+ */
+RPM_GNUC_INTERNAL
+rpmte * rpmalAllInCollection(const rpmal al, const char * collname);
+
 #ifdef __cplusplus
 }
 #endif
-- 
1.6.2.5



More information about the Rpm-maint mailing list