197 lines
6.6 KiB
Diff
197 lines
6.6 KiB
Diff
From 14ed1ff025dbe7897791ec11d6bafe29dfc6b866 Mon Sep 17 00:00:00 2001
|
|
From: Panu Matilainen <pmatilai@redhat.com>
|
|
Date: Mon, 13 Dec 2010 12:03:18 +0200
|
|
Subject: [PATCH] Implement transaction ordering hinting - Add support for new
|
|
"OrderWithRequires: foo" spec syntax which has "if and only if foo is
|
|
present in transaction, order the transaction as if this package required
|
|
foo" semantics. While it looks, and in some ways is, a soft dependency,
|
|
this is not the same as recommends/suggests etc: those have unknown
|
|
depsolver policy dependent semantics attached to them, whereas ordering
|
|
hints have a clear definition and is only relevant for rpm itself,
|
|
depsolvers should not even look at the data. - This allows packages to
|
|
express correct ordering for optional functionality, such as
|
|
|
|
%post
|
|
if [ -x %{_bindir}/register-component ]; then
|
|
%{_bindir}/register-component %{name}
|
|
fi
|
|
|
|
If the package containing %{_bindir}/register-component is included
|
|
in the same transaction, it makes sense to have it installed before the
|
|
package(s) that use it. But as it is fully optional, Requires would
|
|
not be appropriate. Using OrderWithRequires allows this to be expressed
|
|
without dragging in extraneous dependencies for optional functionality.
|
|
(cherry picked from commit 5c43095e1d78b3befe93c746fd182746c3b96c92)
|
|
|
|
Conflicts:
|
|
build/parsePreamble.c
|
|
build/reqprov.c
|
|
lib/order.c
|
|
lib/rpmtag.h
|
|
lib/rpmte.c
|
|
---
|
|
build/parsePreamble.c | 2 ++
|
|
build/parseReqs.c | 1 +
|
|
build/reqprov.c | 6 ++++++
|
|
lib/order.c | 6 ++++++
|
|
lib/rpmds.c | 4 ++++
|
|
lib/rpmtag.h | 3 +++
|
|
lib/rpmte.c | 5 +++++
|
|
tests/rpmgeneral.at | 3 +++
|
|
8 files changed, 30 insertions(+)
|
|
|
|
diff --git a/build/parsePreamble.c b/build/parsePreamble.c
|
|
index b5f1780..2bb0512 100644
|
|
--- a/build/parsePreamble.c
|
|
+++ b/build/parsePreamble.c
|
|
@@ -630,6 +630,7 @@ static int handlePreambleTag(rpmSpec spec, Package pkg, rpmTag tag,
|
|
if ((rc = parseRCPOT(spec, pkg, field, tag, 0, tagflags)))
|
|
return rc;
|
|
break;
|
|
+ case RPMTAG_ORDERFLAGS:
|
|
case RPMTAG_REQUIREFLAGS:
|
|
case RPMTAG_PREREQ:
|
|
if ((rc = parseBits(lang, installScriptBits, &tagflags))) {
|
|
@@ -748,6 +749,7 @@ static struct PreambleRec_s const preambleList[] = {
|
|
{RPMTAG_DOCDIR, 0, 0, LEN_AND_STR("docdir")},
|
|
{RPMTAG_DISTTAG, 0, 0, LEN_AND_STR("disttag")},
|
|
{RPMTAG_BUGURL, 0, 0, LEN_AND_STR("bugurl")},
|
|
+ {RPMTAG_ORDERFLAGS, 2, 0, LEN_AND_STR("orderwithrequires")},
|
|
{0, 0, 0, 0}
|
|
};
|
|
|
|
diff --git a/build/parseReqs.c b/build/parseReqs.c
|
|
index d12aca3..161e9a8 100644
|
|
--- a/build/parseReqs.c
|
|
+++ b/build/parseReqs.c
|
|
@@ -86,6 +86,7 @@ rpmRC parseRCPOT(rpmSpec spec, Package pkg, const char *field, rpmTag tagN,
|
|
h = spec->buildRestrictions;
|
|
break;
|
|
default:
|
|
+ case RPMTAG_ORDERFLAGS:
|
|
case RPMTAG_REQUIREFLAGS:
|
|
tagflags |= RPMSENSE_ANY;
|
|
h = pkg->header;
|
|
diff --git a/build/reqprov.c b/build/reqprov.c
|
|
index 9c48b11..5c6b377 100644
|
|
--- a/build/reqprov.c
|
|
+++ b/build/reqprov.c
|
|
@@ -75,6 +75,12 @@ int addReqProv(rpmSpec spec, Header h, rpmTag tagN,
|
|
flagtag = RPMTAG_TRIGGERFLAGS;
|
|
indextag = RPMTAG_TRIGGERINDEX;
|
|
extra = Flags & RPMSENSE_TRIGGER;
|
|
+ /* use tagN as there is no RPMSENSE flag for ORDER */
|
|
+ } else if (tagN == RPMTAG_ORDERFLAGS) {
|
|
+ nametag = RPMTAG_ORDERNAME;
|
|
+ versiontag = RPMTAG_ORDERVERSION;
|
|
+ flagtag = RPMTAG_ORDERFLAGS;
|
|
+ extra = Flags & _ALL_REQUIRES_MASK;
|
|
} else {
|
|
nametag = RPMTAG_REQUIRENAME;
|
|
versiontag = RPMTAG_REQUIREVERSION;
|
|
diff --git a/lib/order.c b/lib/order.c
|
|
index 8b4725d..8ff770b 100644
|
|
--- a/lib/order.c
|
|
+++ b/lib/order.c
|
|
@@ -593,11 +593,17 @@ int rpmtsOrder(rpmts ts)
|
|
rpmal al = (rpmteType(p) == TR_REMOVED) ?
|
|
erasedPackages : ts->addedPackages;
|
|
rpmds requires = rpmdsInit(rpmteDS(p, RPMTAG_REQUIRENAME));
|
|
+ rpmds order = rpmdsInit(rpmteDS(p, RPMTAG_ORDERNAME));
|
|
|
|
while (rpmdsNext(requires) >= 0) {
|
|
/* Record next "q <- p" relation (i.e. "p" requires "q"). */
|
|
(void) addRelation(ts, al, p, requires);
|
|
}
|
|
+
|
|
+ while (rpmdsNext(order) >= 0) {
|
|
+ /* Record next "q <- p" ordering request */
|
|
+ (void) addRelation(ts, al, p, order);
|
|
+ }
|
|
}
|
|
pi = rpmtsiFree(pi);
|
|
|
|
diff --git a/lib/rpmds.c b/lib/rpmds.c
|
|
index 3f92ab8..d047d04 100644
|
|
--- a/lib/rpmds.c
|
|
+++ b/lib/rpmds.c
|
|
@@ -62,6 +62,10 @@ static int dsType(rpmTag tag,
|
|
t = "Obsoletes";
|
|
evr = RPMTAG_OBSOLETEVERSION;
|
|
f = RPMTAG_OBSOLETEFLAGS;
|
|
+ } else if (tag == RPMTAG_ORDERNAME) {
|
|
+ t = "Order";
|
|
+ evr = RPMTAG_ORDERVERSION;
|
|
+ f = RPMTAG_ORDERFLAGS;
|
|
} else if (tag == RPMTAG_TRIGGERNAME) {
|
|
t = "Trigger";
|
|
evr = RPMTAG_TRIGGERVERSION;
|
|
diff --git a/lib/rpmtag.h b/lib/rpmtag.h
|
|
index eb3b1ad..b1de107 100644
|
|
--- a/lib/rpmtag.h
|
|
+++ b/lib/rpmtag.h
|
|
@@ -292,6 +292,9 @@ typedef enum rpmTag_e {
|
|
RPMTAG_HEADERCOLOR = 5017, /* i extension */
|
|
RPMTAG_VERBOSE = 5018, /* i extension */
|
|
RPMTAG_EPOCHNUM = 5019, /* i extension */
|
|
+ RPMTAG_ORDERNAME = 5035, /* s[] */
|
|
+ RPMTAG_ORDERVERSION = 5036, /* s[] */
|
|
+ RPMTAG_ORDERFLAGS = 5037, /* i[] */
|
|
|
|
RPMTAG_FIRSTFREE_TAG /*!< internal */
|
|
} rpmTag;
|
|
diff --git a/lib/rpmte.c b/lib/rpmte.c
|
|
index f25af12..f9ff666 100644
|
|
--- a/lib/rpmte.c
|
|
+++ b/lib/rpmte.c
|
|
@@ -51,6 +51,7 @@ struct rpmte_s {
|
|
rpmds requires; /*!< Requires: dependencies. */
|
|
rpmds conflicts; /*!< Conflicts: dependencies. */
|
|
rpmds obsoletes; /*!< Obsoletes: dependencies. */
|
|
+ rpmds order; /*!< Order: dependencies. */
|
|
rpmfi fi; /*!< File information. */
|
|
rpmps probs; /*!< Problems (relocations) */
|
|
|
|
@@ -78,6 +79,7 @@ void rpmteCleanDS(rpmte te)
|
|
te->requires = rpmdsFree(te->requires);
|
|
te->conflicts = rpmdsFree(te->conflicts);
|
|
te->obsoletes = rpmdsFree(te->obsoletes);
|
|
+ te->order = rpmdsFree(te->order);
|
|
}
|
|
|
|
/**
|
|
@@ -266,6 +268,7 @@ static void addTE(rpmts ts, rpmte p, Header h,
|
|
p->requires = rpmdsNew(h, RPMTAG_REQUIRENAME, 0);
|
|
p->conflicts = rpmdsNew(h, RPMTAG_CONFLICTNAME, 0);
|
|
p->obsoletes = rpmdsNew(h, RPMTAG_OBSOLETENAME, 0);
|
|
+ p->order = rpmdsNew(h, RPMTAG_ORDERNAME, 0);
|
|
|
|
{
|
|
// get number of files by hand as rpmfiNew needs p->fs
|
|
@@ -606,6 +609,8 @@ rpmds rpmteDS(rpmte te, rpmTag tag)
|
|
else
|
|
if (tag == RPMTAG_OBSOLETENAME)
|
|
return te->obsoletes;
|
|
+ if (tag == RPMTAG_ORDERNAME)
|
|
+ return te->order;
|
|
else
|
|
return NULL;
|
|
}
|
|
diff --git a/tests/rpmgeneral.at b/tests/rpmgeneral.at
|
|
index 98f86d5..7f2ad8e 100644
|
|
--- a/tests/rpmgeneral.at
|
|
+++ b/tests/rpmgeneral.at
|
|
@@ -163,6 +163,9 @@ OBSOLETES
|
|
OBSOLETEVERSION
|
|
OLDFILENAMES
|
|
OPTFLAGS
|
|
+ORDERFLAGS
|
|
+ORDERNAME
|
|
+ORDERVERSION
|
|
ORIGBASENAMES
|
|
ORIGDIRINDEXES
|
|
ORIGDIRNAMES
|
|
--
|
|
2.1.0
|
|
|