Bug 859202

Summary: Yum incorrectly tries to update/install a package with the same nevra but different subarch
Product: [Fedora] Fedora Reporter: Brent Baude <bbaude>
Component: yumAssignee: Fedora Packaging Toolset Team <packaging-team>
Status: CLOSED CURRENTRELEASE QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: high Docs Contact:
Priority: unspecified    
Version: 18CC: ffesti, james.antill, maxamillion, packaging-team, pknirsch, tla, zpavlas
Target Milestone: ---Keywords: Reopened
Target Release: ---   
Hardware: ppc64   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2012-10-29 05:23:59 EDT Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Bug Depends On:    
Bug Blocks: 846990    

Description Brent Baude 2012-09-20 15:25:30 EDT
Description of problem:

Yum incorrectly tries to update/install a package with the same nevra but different subarch.  Description below.


Version-Release number of selected component (if applicable):
yum-3.4.3-42.fc18.noarch

How reproducible:


Steps to Reproduce:
1. Have an installed system with binutils-x.y.z.ppc64.rpm
2. Then issue yum groupinstall "Development Tools"
3. If a binutils-x.y.z-ppc64p7.rpm exists in the repo, it will try to install and fail due to package conflicts
  
Actual results:
  file /usr/bin/addr2line from install of binutils-2.23.51.0.1-3.fc18.ppc64p7 conflicts with file from package binutils-2.23.51.0.1-3.fc18.ppc64
  file /usr/bin/ar from install of binutils-2.23.51.0.1-3.fc18.ppc64p7 conflicts with file from package binutils-2.23.51.0.1-3.fc18.ppc64
  file /usr/bin/as from install of binutils-2.23.51.0.1-3.fc18.ppc64p7 conflicts with file from package binutils-2.23.51.0.1-3.fc18.ppc64
  file /usr/bin/c++filt from install of binutils-2.23.51.0.1-3.fc18.ppc64p7 conflicts with file from package binutils-2.23.51.0.1-3.fc18.ppc64
  file /usr/bin/elfedit from install of binutils-2.23.51.0.1-3.fc18.ppc64p7 conflicts with file from package binutils-2.23.51.0.1-3.fc18.ppc64
  file /usr/bin/gprof from install of binutils-2.23.51.0.1-3.fc18.ppc64p7 conflicts with file from package binutils-2.23.51.0.1-3.fc18.ppc64
  file /usr/bin/ld from install of binutils-2.23.51.0.1-3.fc18.ppc64p7 conflicts with file from package binutils-2.23.51.0.1-3.fc18.ppc64
  file /usr/bin/ld.bfd from install of binutils-2.23.51.0.1-3.fc18.ppc64p7 conflicts with file from package binutils-2.23.51.0.1-3.fc18.ppc64
  file /usr/bin/nm from install of binutils-2.23.51.0.1-3.fc18.ppc64p7 conflicts with file from package binutils-2.23.51.0.1-3.fc18.ppc64
  file /usr/bin/objcopy from install of binutils-2.23.51.0.1-3.fc18.ppc64p7 conflicts with file from package binutils-2.23.51.0.1-3.fc18.ppc64
  file /usr/bin/objdump from install of binutils-2.23.51.0.1-3.fc18.ppc64p7 conflicts with file from package binutils-2.23.51.0.1-3.fc18.ppc64
  file /usr/bin/ranlib from install of binutils-2.23.51.0.1-3.fc18.ppc64p7 conflicts with file from package binutils-2.23.51.0.1-3.fc18.ppc64
  file /usr/bin/readelf from install of binutils-2.23.51.0.1-3.fc18.ppc64p7 conflicts with file from package binutils-2.23.51.0.1-3.fc18.ppc64
  file /usr/bin/size from install of binutils-2.23.51.0.1-3.fc18.ppc64p7 conflicts with file from package binutils-2.23.51.0.1-3.fc18.ppc64
  file /usr/bin/strings from install of binutils-2.23.51.0.1-3.fc18.ppc64p7 conflicts with file from package binutils-2.23.51.0.1-3.fc18.ppc64
  file /usr/bin/strip from install of binutils-2.23.51.0.1-3.fc18.ppc64p7 conflicts with file from package binutils-2.23.51.0.1-3.fc18.ppc64
  file /usr/lib64/libbfd-2.23.51.0.1-3.fc18.so from install of binutils-2.23.51.0.1-3.fc18.ppc64p7 conflicts with file from package binutils-2.23.51.0.1-3.fc18.ppc64
  file /usr/lib64/libopcodes-2.23.51.0.1-3.fc18.so from install of binutils-2.23.51.0.1-3.fc18.ppc64p7 conflicts with file from package binutils-2.23.51.0.1-3.fc18.ppc64


Expected results:

I would expect the groupinstall to not install the binutils.ppc6p7 if the .ppc64 one is already installed.

Additional info:
Comment 1 Zdeněk Pavlas 2012-09-27 08:11:51 EDT
Ok, I think I know what's going on.  All of groupinstall, groupupdate, install, and localinstall commands are affected.  ppc64p7 is considered superior to ppc64, so when repo provides both, Yum picks ppc64p7.

The problem is caused by _install_is_upgrade() returning False, When the versions are equal, or the newer package is older than the already installed, it then does not check that arches can't be co-installed, so this must be an update.

I have no idea what the "verLE" check is there for, and what will break when this is removed.  Also, this particular case (equal versions) could be fixed by changing verLE to verLT.

yum/__init__.py:
     def _install_is_upgrade(self, po, ipkgs):
         ...
         for ipkg in ipkgs:
-            if po.verLE(ipkg):
-                continue
             if po.arch == ipkg.arch: # always fine.
                 return True
             if 'noarch' in (po.arch, ipkg.arch):
                 return True
             if not self.arch.multilib:
                 return True
             if canCoinstall(po.arch, ipkg.arch):
                 continue
             return True
         return False
Comment 2 Zdeněk Pavlas 2012-09-27 08:13:10 EDT
err
or the newer package is older => or the available package is older
Comment 3 James Antill 2012-09-28 11:17:03 EDT
 Zdeněk, the tests says "is the package we are looking at the same version or older" ... if it fails that then it can't be an upgrade, as an upgrade goes up.

 This test points to the problem, I think, but it can't be solved here. This test returns true or false, if true then the package will try to upgrade what is installed (which we also don't want).

 Looking through the install code it looks like we are missing a canCoinstall() test somewhere later on in the actual install() path, that should error out. My guess is that this same problem would happen with i686 and i386 but looking at f17 i386 it seems that we don't have any packages with the same NEVR where one is i386 and one i686 ... so this doesn't come up (chealpix/healpix seem the closest, but they are real upgrades too).

 The things to consider with the fix are that you don't get extra things on upgrade, Eg. 

installed pkgA-1.ppc64
available pkgA-2.ppc64
available pkgA-2.ppc64p7

...here we really want to have _just_ pkgA-2.ppc64 installed if the user types "yum install pkgA", and to also have "yum install pkgA.pppc64" either fail or (better, but maybe annoying) replace what is there.
Comment 4 Zdeněk Pavlas 2012-10-01 05:31:02 EDT

*** This bug has been marked as a duplicate of bug 854075 ***
Comment 5 Zdeněk Pavlas 2012-10-02 09:05:33 EDT
james> the tests says "is the package we are looking at the same version or older" ... if it fails that then it can't be an upgrade, as an upgrade goes up.

It depends.. Suppose binutils-2.23.51.0.1-3.fc18.ppc64 is installed, and:

1) binutils-2.23.51.0.1-4.fc18.ppc64p7 is available (that's GT).  Then all the IFs fail, _install_is_upgrade() returns True, and we handle it as upgrade- regardless of the arch change.  That's probably correct (I think).

2) binutils-2.23.51.0.1-3.fc18.ppc64p7 is available (EQ).  In this case, _install_is_upgrade() returns False (because versions are equal).  But compare_providers() thinks that the available package is superior, so it's not installed, and "newer/better" (kind of).  If 1) is upgrade, 2) should be probably as well.

james> Looking through the install code it looks like we are missing a canCoinstall() test somewhere later on in the actual install() path, that should error out.

Exactly.  But should it err?  We may also just filter all foo.arch1, when foo.arch2 is installed, arch1 != arch2 and canCoinstall(arch1, arch2)==False from the available list.  So, AIUI, options are:

a) handle it as update (should remove .ppc64 && install .ppc64p7).
b) fail with "cannot coinstall".
c) no new package available, nothing to do.
Comment 6 Phil Knirsch 2012-10-10 06:24:33 EDT
Just my $0.02 here as well:

I personally would prefer if we'd handle it as a) or c). Tough a) should only happen if exactarch==False. Or more concretely the whole situation should be treated as a) if exactarch==False and like c) if exactarch==True.

The reason being that "technically" a switch from ppc64 to ppc64p7 (or from i386 to i686) can be considered an upgrade, even if it's the same version as the higher architecture usually hints to more a more optimized version which imho can be considered an upgrade (it's faster/better).

Additionally yum already would perform an upgrade in case the repo would contain newer versions of the package, so the behavior for same versions suddenly failing then seems very counterintiutive, see the following example:

Example 1:

foo-1.ppc64 installed
foo-1.ppc64 and foo-1.ppc64p7 in repo

yum install foo will now fail as it'll try to coninstall the ppc64p7 package which it can't.

Example 2:

foo-1.ppc64 installed
foo-2.ppc64 and foo-2.ppc64p7

yum install foo will not fail now as yum will either upgrade to foo-2.ppc64 (if exactarch=True) or to foo-2.ppc64p7 (if exactarch=False).

So the first example is therefore just a very bad user experience and not something anyone would expect to happen.

Thanks & regards, Phil
Comment 7 Phil Knirsch 2012-10-29 05:23:59 EDT
Verified with latest yum from rawhide which fixed the issue. Current F18 package contains the same fix.

Closing as currentrelease therefore.

Thanks and regards, Phil