[Rpm-maint] RPM Obsoletes unversioned Provides too eagerly

Fernando Nasser fnasser at redhat.com
Fri Feb 23 15:25:09 UTC 2007


Description of problem:

When processing a versioned Obsoletes like:

Obsoletes:   xml-commons-apis  <=  0:1.3.02

RPM also removes any package that provides an unversioned 
'xml-commons-apis'.  Although it is an awfully bad practice to have 
unversioned virtual provides, some third part entities do it, like Sun 
in their JDK RPM.

So any attempt to remove the real, deprecated, xml-commons-apis package 
on the package that replaces it, causes RPM to attempt to remove the JDK 
RPM, which is a basic package and cannot be removed.  RPM fails to 
install the new package.

See Expected Results for my suggested behavior and Additional Info for a 
suggested pseudo-code.

Version-Release number of selected component (if applicable):

Any rpm 4.4.x version.


How reproducible:

Always

Steps to Reproduce:
1. Install the Sun JDK RPM, like  jdk-1.5.0_08-fcs.i586
2. Try and install a package like xml-commons that tries and Obsoletes 
xml-commons-apis with a <= version with:
rpm -i -vv xml-commons
3. Note the message:
D:   Obsoletes: xml-commons-apis = 0:1.3.02-2jpp                erases 
jdk-1.5.0_08-fcs.i586

Actual results:

Installation fails

Expected results:

Only a xml-commons-apis package (or provider) with a specified version 
that was >= than the one specified would be removed.  Or, if >= must be 
kept removing unversioned provides, at least do not match for a '=' 
version specification.

Additional info:

This policy is enforced in lib/rpmds.c, in the function rpmdsCompare

  /* If either EVR is non-existent or empty, always overlap. */
  if (!(A->EVR[A->i] && *A->EVR[A->i] && B->EVR[B->i] && *B->EVR[B->i])) {
    result = 1;
    goto exit;
  }

What should be done is:

If the Obsoletes is unversioned, Then do indeed remove the same name package

Else (Obsoletes is versioned)
   If Obsoletes version _not_ with '=', Then remove other package

   Else (Obsoletes version with '='), continue to next loop iteration 
(i.e., leave the unversioned provides package alone)

With this change, Obsoletes with '>=' would still keep the old behavior 
for backward compatibility (if that is indeed deemed necessary  -- 
perhaps it is necessary as a way to remove package with unversioned 
provides with something less powerful than a unversioned Obsoletes?).

On the other hand, one at least have a way to remove deprecated packages 
with one (or more) Obsoletes with '='.  Not ideal (one needs to require 
an updated system, consider packages coming from other sources etc., but 
at least it is a way out.

Of course, if '>=' can be made to ignore unversioned provides altogether 
that would be much preferable.




More information about the Rpm-maint mailing list