From Bugzilla Helper: User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.0.1) Gecko/20021003 Description of problem: There seems to be some inconsistancy in the way RPM is handling version comparison wrt promoting the epoch of install and build dependancies, vs when it is checking for conflicts on install or dependancies on package removal. For the former case, the epoch is not promoted, and in the latter case, it is. My understanding is that in rpm 4.1, if there is no epoch on the dependency, then it is assumed to be == 0 (no epoch promotion). However, install dependencies and build prereqs still promote the epoch. The following spec file demonstrates this for a build dependancy: <snip> Summary: Test for epoch comparison. Name: foo Version: 1.0 Release: 0 Epoch: 0 BuildArch: noarch License: Whaever you damn well want. Group: Useless Stuff Packager: Joe Mama, Inc. BuildRoot: /var/tmp/foo-tmp BuildPrereq: make > 3.79.1-14 %description This RPM is useless. Do not use it. Just walk away. %install rm -rf $RPM_BUILD_ROOT mkdir -p $RPM_BUILD_ROOT/tmp touch $RPM_BUILD_ROOT/tmp/sadlfkj.txt %files /tmp/sadlfkj.txt </snip> run the following command (which will fail the BuildPrereq check): rpmbuild -vv -bs foo.spec and notice the following in the output: D: rpmdsCompare: makeD: The "B" dependency needs an epoch (assuming same epoch as "A") A = "make = 1:3.79.1-14" B = "make > 3.79.1-14" The nopromote member of the "B" rpmds structure is not set to 1, so the epoch is promoted. It seems that when the add/remove elements are added to the transaction set, addTE is called (through a few other functions) to do the dirty work of assembling the element based on the bits of information in the header. In this function, rpmdsNew is called a bunch of times starting around line 115 to build dep sets for the requires, conflicts, etc.. rpmdsNew creates the dep set with nopromote == 0. addTE makes no attempt to call rpmdsSetNoPromote() on the newly created set. More on that in a second. Later on in the chain of events of an install, remove, or a build (which seems to be taken as a special case of install for the purpose of BuildPrereq checking), rpmtsCheck() is called against the fully assembled transaction. As it iterates through the elements, it behaves differently based on whether it is an add or remove. For removes, a call to checkDependentPackages() is made, which in turn calls checkPackageSet(). For conflict checking on install, a call to checkDependentConflicts() is made which also calls checkPackageSet(). checkPackageSet() calls rpmdsSetNoPromote() before calling checkPackageDeps() - sort of, see below. For _dependancy_ checking on install (or build prereq), it goes directly to checkPackageDeps() and given the paragraph above, there is never a chance to set the nopromote flag on the requires dep set before falling through to rpmdsCompare (through another function or two). I say checkPackageSet() sort of sets the flag because of this code in depends.c, line 697 - 700: requires = rpmdsNew(h, RPMTAG_REQUIRENAME, scareMem); (void) rpmdsSetNoPromote(requires, _rpmds_nopromote); conflicts = rpmdsNew(h, RPMTAG_CONFLICTNAME, scareMem); (void) rpmdsSetNoPromote(requires, _rpmds_nopromote); Seems to be a copy/paste error, the requires dep set has its flag set twice. Is this context-sensitive behavior intentional? Version-Release number of selected component (if applicable): How reproducible: Always Steps to Reproduce: See above description. Additional info:
I just finished figuring out all these details for myself. Because of this inconsistency, a number of packages crept into Red Hat 9 with missing epochs in requirements (as I mentioned on rpm-list: gnome-libs, ORBit-devel, esound-devel, probably others). Here is a reproduction recipe which illustrates the problem: 1. Prepare an RPM which "Provides: gnome-libs". Call it "bozo". 2. Install gnome-libs and gnome-libs-devel from Red Hat 9. Here, we go through the rpmtsCheck -> checkPackageDeps code path, which does not set nopromote. The install succeeds. 3. Install bozo. 4. Try to remove bozo. Here, we go through the rpmtsCheck -> checkPackageSet code path, which does set nopromote. We get a dependency failure for gnome-libs-devel.
FWIW, there's a large number of dependencies that have a missing Epoich:. See the complete set by doing rpm -Vav --nofiles Hmmm, yes, there's a cut and paste error for conflicts. Yes, you get different answers fro missing dependencies. While adding, a missing Epoch: in EVR comparison is treated as same as specified Epoch: (i.e. Epoch: comparison is skipped), while after install missing Epoch: is treated as Epoch: 0. Presumably this is the cause of your test case failure. In all cases, the best fix is to supply an explict value for Epoch:, as some value needs to be guessed for a missing Epoch: in order to do the most significant elment of an epoch-version-release comparison.
Yup, gnome-libs-* has an Epoch:, so what is needed in bozo is (at least) Provides: gnome-libs = 1: (Note: this provides all possible version/release combos for Epoch: 1)
You appear to misunderstand. bozo isn't supposed to satisfy the gnome-libs-devel dependency; gnome-libs is supposed to. The only role bozo has in the test case is to trigger a checkPackageSet() call on gnome-libs-devel. Making bozo provide gnome-libs=1: wouldn't change anything. I agree that life would be better if every requires line specified an epoch when appropriate, but I have no control over Red Hat 9. As things stand, rpm is dangerously inconsistent; it allows mismatched epochs on the way in and then complains about them once they're there. (If the epoch promotion actually went into the database, and didn't merely affect the result of the comparison, then things would be better.)
If gnome-libs-devel has Requires: gnome-libs = V-R (i.e. w/o an Epoch: specified), then this problem is a packaging, not rpm, error. There's is simply no way to guess what Epoch: is intended if not specified. Please open a bug against gnome-libs.
I can file bug reports against the individual packages, but that doesn't make rpm any less at fault for encouraging the situation. Either rpm should be lax about missing epochs in all cases, or it should be strict about them in all cases. (Or, I suppose, it would be okay to be strict about them on the way in but lax if they're already there; that would be reasonable transition behavior.) Being lax on the way in and strict once they're there is just insane.
Encouraging? Heh ... rpm is transiting from loose to strict, changing to what should have been implemented originally A missing Epoch: is equivalent to Epoch: 0. All delays on that pathway, even if insane, are due to attempts to accomodate legacy behavior and lots of already deployed broken packaging. The rate limiting step is exactly Broken packages.
rpm-4.2.1 has Missing Epoch: is exactly the same as Epoch: 0, everywhere and always. Use --promoteepoch if you need/want the traditional behavior.