[Rpm-maint] [PATCH 10/19] Add new policy requires tag to spec file format

Steve Lawrence slawrence at tresys.com
Tue Feb 2 20:25:13 UTC 2010


The PolicyRequires tag is used to specify which versions of packages are
required by policies installed in the module. The PolicyRequires tag has
the same syntax as the Requires tag.

Assume libselinux-1.2 is installed on the system. Package foo-1.0 has a
policy module that 'Requires: libselinux >= 1.3'. Running the command:

rpm -Uvh foo-1.0.rpm libselinux-1.3.rpm

would meet all normal dependencies. However, the policy installation
would still fail because a policy module in foo requires a newer version
of libselinux than is on the system at the time of policy installation
(at the beginning of the transaction). The solution would be to install
the packages in two separate transactions:

rpm -Uvh libselinux-1.3.rpm
rpm -Uvh foo-1.0.rpm

However, this is unintuitive and not always possible.

The new PolicyRequires directive solves this problem. The directive is
simply a list of dependencies, in the same format as the Requires tag,
that specifies what packages must already be installed at the start of
a transaction for policy modules to be successfully installed. This will
most commonly be packages like libselinux or checkpolicy.
---
 build/parsePreamble.c |    8 ++++++++
 build/parseReqs.c     |    4 ++++
 build/reqprov.c       |    5 +++++
 build/rpmfc.c         |    3 +++
 lib/rpmds.h           |    4 +++-
 lib/rpmtag.h          |    4 ++++
 tests/rpmgeneral.at   |    4 ++++
 7 files changed, 31 insertions(+), 1 deletions(-)

diff --git a/build/parsePreamble.c b/build/parsePreamble.c
index e31af74..5251adf 100644
--- a/build/parsePreamble.c
+++ b/build/parsePreamble.c
@@ -643,6 +643,13 @@ static int handlePreambleTag(rpmSpec spec, Package pkg, rpmTag tag,
 	if ((rc = parseRCPOT(spec, pkg, field, tag, 0, tagflags)))
 	    return rc;
 	break;
+    case RPMTAG_POLICYREQUIREFLAGS:
+#if WITH_SELINUX
+	tagflags = RPMSENSE_ANY;
+	if ((rc = parseRCPOT(spec, pkg, field, tag, 0, tagflags)))
+	    return rc;
+#endif
+	break;
     case RPMTAG_BUILDCONFLICTS:
     case RPMTAG_CONFLICTFLAGS:
     case RPMTAG_OBSOLETEFLAGS:
@@ -750,6 +757,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_POLICYREQUIREFLAGS,	0, 0, LEN_AND_STR("policyrequires")},
     {0, 0, 0, 0}
 };
 
diff --git a/build/parseReqs.c b/build/parseReqs.c
index 92e6ace..b031875 100644
--- a/build/parseReqs.c
+++ b/build/parseReqs.c
@@ -81,6 +81,10 @@ rpmRC parseRCPOT(rpmSpec spec, Package pkg, const char *field, rpmTag tagN,
 	tagflags |= RPMSENSE_TRIGGERUN;
 	h = pkg->header;
 	break;
+    case RPMTAG_POLICYREQUIREFLAGS:
+	tagflags |= RPMSENSE_POLICY;
+	h = pkg->header;
+	break;
     case RPMTAG_BUILDPREREQ:
     case RPMTAG_BUILDREQUIRES:
 	tagflags |= RPMSENSE_ANY;
diff --git a/build/reqprov.c b/build/reqprov.c
index 9c48b11..1559db2 100644
--- a/build/reqprov.c
+++ b/build/reqprov.c
@@ -75,6 +75,11 @@ int addReqProv(rpmSpec spec, Header h, rpmTag tagN,
 	flagtag = RPMTAG_TRIGGERFLAGS;
 	indextag = RPMTAG_TRIGGERINDEX;
 	extra = Flags & RPMSENSE_TRIGGER;
+    } else if (Flags & RPMSENSE_POLICY) {
+	nametag = RPMTAG_POLICYREQUIRENAME;
+	versiontag = RPMTAG_POLICYREQUIREVERSION;
+	flagtag = RPMTAG_POLICYREQUIREFLAGS;
+	extra = Flags & RPMSENSE_POLICY;
     } else {
 	nametag = RPMTAG_REQUIRENAME;
 	versiontag = RPMTAG_REQUIREVERSION;
diff --git a/build/rpmfc.c b/build/rpmfc.c
index 2c98e11..7fa8973 100644
--- a/build/rpmfc.c
+++ b/build/rpmfc.c
@@ -1382,6 +1382,9 @@ static struct DepMsg_s depMsgs[] = {
   { "Requires",		{ "%{?__find_requires}", NULL, NULL, NULL },
 	-1, -1, RPMTAG_REQUIREFLAGS,	/* XXX inherit name/version arrays */
 	RPMSENSE_FIND_REQUIRES|RPMSENSE_TRIGGERIN|RPMSENSE_TRIGGERUN|RPMSENSE_TRIGGERPOSTUN|RPMSENSE_TRIGGERPREIN, 0 },
+  { "PolicyRequires",	{ NULL, "policy", NULL, NULL },
+	RPMTAG_POLICYREQUIRENAME, RPMTAG_POLICYREQUIREVERSION, RPMTAG_POLICYREQUIREFLAGS,
+	0, -1 },
   { "Conflicts",	{ "%{?__find_conflicts}", NULL, NULL, NULL },
 	RPMTAG_CONFLICTNAME, RPMTAG_CONFLICTVERSION, RPMTAG_CONFLICTFLAGS,
 	0, -1 },
diff --git a/lib/rpmds.h b/lib/rpmds.h
index e8b2a33..08fbac4 100644
--- a/lib/rpmds.h
+++ b/lib/rpmds.h
@@ -56,7 +56,8 @@ typedef	enum rpmsenseFlags_e {
     RPMSENSE_TRIGGERPREIN = (1 << 25),	/*!< %triggerprein dependency. */
     RPMSENSE_KEYRING	= (1 << 26),
     RPMSENSE_PATCHES	= (1 << 27),
-    RPMSENSE_CONFIG	= (1 << 28)
+    RPMSENSE_CONFIG	= (1 << 28),
+    RPMSENSE_POLICY	= (1 << 29)	/*!< PolicyRequires dependency */
 } rpmsenseFlags;
 
 #define	RPMSENSE_SENSEMASK	15	 /* Mask to get senses, ie serial, */
@@ -79,6 +80,7 @@ typedef	enum rpmsenseFlags_e {
     RPMSENSE_SCRIPT_CLEAN | \
     RPMSENSE_RPMLIB | \
     RPMSENSE_KEYRING | \
+    RPMSENSE_POLICY | \
     RPMSENSE_PREREQ)
 
 #define	_notpre(_x)		((_x) & ~RPMSENSE_PREREQ)
diff --git a/lib/rpmtag.h b/lib/rpmtag.h
index a2ee6d9..95fa8a7 100644
--- a/lib/rpmtag.h
+++ b/lib/rpmtag.h
@@ -272,6 +272,10 @@ typedef enum rpmTag_e {
     RPMTAG_BUILDOBSOLETES	= 1194, /* internal */
     RPMTAG_DBINSTANCE		= 1195, /* i extension */
     RPMTAG_NVRA			= 1196, /* s extension */
+    RPMTAG_POLICYREQUIREFLAGS		= 2097,	/* i[] */
+    RPMTAG_POLICYREQUIRENAME		= 2098,	/* s[] */
+#define	RPMTAG_POLICYREQUIRES RPMTAG_POLICYREQUIRENAME	/* s[] */
+    RPMTAG_POLICYREQUIREVERSION	= 2099,	/* s[] */
     RPMTAG_POLICYNAMES		= 2100,	/* s[] */
     RPMTAG_POLICYTYPES		= 2101,	/* s[] */
     RPMTAG_POLICYTYPESINDEXES		= 2102,	/* i[] */
diff --git a/tests/rpmgeneral.at b/tests/rpmgeneral.at
index b994797..5a930cf 100644
--- a/tests/rpmgeneral.at
+++ b/tests/rpmgeneral.at
@@ -184,6 +184,10 @@ POLICYFLAGS
 POLICYNAMES
 POLICYOBSOLETES
 POLICYOBSOLETESBY
+POLICYREQUIREFLAGS
+POLICYREQUIRENAME
+POLICYREQUIRES
+POLICYREQUIREVERSION
 POLICYTYPES
 POLICYTYPESINDEXES
 POSTIN
-- 
1.6.2.5



More information about the Rpm-maint mailing list