summaryrefslogtreecommitdiff
path: root/lib/order.c
diff options
context:
space:
mode:
authorPanu Matilainen <pmatilai@redhat.com>2010-10-25 15:03:56 +0300
committerPanu Matilainen <pmatilai@redhat.com>2010-10-25 15:40:24 +0300
commit0d4b7b8f3a0a2f0de7a30fd51c86be6849e54329 (patch)
tree5a93b560323142dbc8134b937a72763a9c7d1410 /lib/order.c
parent6281e4a215313f74244a6e3b027061d64d65895e (diff)
downloadlibrpm-tizen-0d4b7b8f3a0a2f0de7a30fd51c86be6849e54329.tar.gz
librpm-tizen-0d4b7b8f3a0a2f0de7a30fd51c86be6849e54329.tar.bz2
librpm-tizen-0d4b7b8f3a0a2f0de7a30fd51c86be6849e54329.zip
Create less draconian loops for grouped collections
- Instead of creating a completely unresolvable tangle of pre-requisites between all collection members and their requirements, just add a single relation loop of all the packages in a (grouped) collection, effectively turning it into a strongly connected component. The loop-cutting algorithm has slightly better chances of surviving this while still enforcing the collection members to be installed in one lump. Also only process each collection just once.
Diffstat (limited to 'lib/order.c')
-rw-r--r--lib/order.c33
1 files changed, 28 insertions, 5 deletions
diff --git a/lib/order.c b/lib/order.c
index e5b1c3efd..e794725aa 100644
--- a/lib/order.c
+++ b/lib/order.c
@@ -224,7 +224,6 @@ static inline int addRelation(rpmts ts,
rpmds requires)
{
rpmte q;
- ARGV_const_t qcolls;
rpmsenseFlags dsflags;
dsflags = rpmdsFlags(requires);
@@ -245,19 +244,38 @@ static inline int addRelation(rpmts ts,
addSingleRelation(p, q, dsflags);
- /* If q is a member of any grouped collections, make sure p requires
- * all packages that are also in those collections */
- for (qcolls = rpmteCollections(q); qcolls && *qcolls; qcolls++) {
+ return 0;
+}
+
+/*
+ * Collections might have special ordering requirements. Notably
+ * sepolicy collection requires having all the bits in the collection
+ * close to each other. We try to ensure this by creating a strongly
+ * connected component of such "grouped" collections, by introducing
+ * an artificial relation loop across the all its members.
+ */
+static int addCollRelations(rpmal al, rpmte p, ARGV_t *seenColls)
+{
+ ARGV_const_t qcolls;
+
+ for (qcolls = rpmteCollections(p); qcolls && *qcolls; qcolls++) {
char * flags;
+ if (argvSearch(*seenColls, *qcolls, NULL))
+ continue;
+
flags = rstrscat(NULL, "%{__collection_", *qcolls, "_flags}", NULL);
if (rpmExpandNumeric(flags) & 0x1) {
rpmte *tes = rpmalAllInCollection(al, *qcolls);
for (rpmte *te = tes; te && *te; te++) {
- addSingleRelation(p, *te, RPMSENSE_SCRIPT_PRE);
+ rpmte next = (*(te + 1) != NULL) ? *(te + 1) : *tes;
+ addSingleRelation(*te, next, RPMSENSE_ANY);
}
_free(tes);
}
free(flags);
+
+ argvAdd(seenColls, *qcolls);
+ argvSort(*seenColls, NULL);
}
return 0;
@@ -606,6 +624,7 @@ int rpmtsOrder(rpmts ts)
scc SCCs;
int nelem = rpmtsNElements(ts);
tsortInfo sortInfo = xcalloc(nelem, sizeof(struct tsortInfo_s));
+ ARGV_t seenColls = NULL;
(void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_ORDER), 0);
@@ -633,7 +652,11 @@ int rpmtsOrder(rpmts ts)
/* Record next "q <- p" relation (i.e. "p" requires "q"). */
(void) addRelation(ts, al, p, requires);
}
+
+ addCollRelations(al, p, &seenColls);
}
+
+ seenColls = argvFree(seenColls);
pi = rpmtsiFree(pi);
newOrder = xcalloc(tsmem->orderCount, sizeof(*newOrder));