Bug 915975

Summary: libjpeg-turbo missing libjpeg.so.62 provides?
Product: Red Hat Enterprise Linux 6 Reporter: Jeffrey Ness <jeffrey.ness>
Component: libjpegAssignee: Tom Lane <tgl>
Status: CLOSED NOTABUG QA Contact: BaseOS QE - Apps <qe-baseos-apps>
Severity: medium Docs Contact:
Priority: unspecified    
Version: 6.4CC: hhorak
Target Milestone: rc   
Target Release: ---   
Hardware: Unspecified   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2013-02-27 16:37:59 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Jeffrey Ness 2013-02-26 21:34:20 UTC
Description of problem:

It seems libjpeg-turbo has been added as of Enterprise Linux 6.4.

This package appears to be the replacement to libjpeg, and tries to meet backwards compatibly. However, it appears this package is missing the provides
of libjpeg.so.62 (the one found in previous versions of libjpeg)

  $ rpm -qp libjpeg-6b-46.el6.i686.rpm --provides
  libjpeg.so.62  
  libjpeg = 6b-46.el6
  libjpeg(x86-32) = 6b-46.el6


  $ rpm -qp libjpeg-turbo-1.2.1-1.el6.x86_64.rpm --provides
  libjpeg = 6b-47.el6
  libjpeg(x86-64) = 6b-47.el6
  libjpeg.so.62()(64bit)  
  libjpeg.so.62(LIBJPEGTURBO_6.2)(64bit)  
  libjpeg.so.62(LIBJPEG_6.2)(64bit)  
  libjpeg-turbo = 1.2.1-1.el6
  libjpeg-turbo(x86-64) = 1.2.1-1.el6

We are seeing issues with BuildRequires: libjpeg-devel,
with these BR libjpeg-turbo-devel are being pulled it and auto dependencies resolutions is linking against "libjpeg.so.62(LIBJPEG_6.2)(64bit)"

   Error: Package: php53u-gd-5.3.22-1.ius.el6.x86_64 (ius-testing)
              Requires: libjpeg.so.62(LIBJPEG_6.2)(64bit)

This will cause issues for our EUS customers on 6.1.z, 6.2.z, and 6.3.z where
libjpeg-turbo is not present and "libjpeg.so.62(LIBJPEG_6.2)(64bit)" can't be meet.


Thanks for your help.

Expected results:

Being libjpeg-turbo provides "libjpeg = 6b-47.el6" (same as libjpeg) I would
assume it should also provides "libjpeg.so.62".

Comment 2 Tom Lane 2013-02-26 21:52:14 UTC
I don't exactly see the problem.  You should be building RPMs for, say, 6.3.z against 6.3 packages not 6.4 packages.

BTW, what's going on is not that it's "missing" any provides, it's that it's added new ones.

Comment 3 Jeffrey Ness 2013-02-26 22:13:03 UTC
Hello Tom,

Thanks for your quick response.

Yeah, building specifically for each point release would be ideal,
I guess with the current model we use for IUS Community (build off of base only) I can foresee users with non updated, or EUS subscriptions having dependency issues.

You are right, there has been added provides, but I guess I'm not sure as to why both packages don't provide "libjpeg.so.62", libjpeg-turbo provides "libjpeg.so.62()(64bit)" using the %{?_isa}. To meet backwards compatibility shouldn't it also provide "libjpeg.so.62" in addition to the libjpeg.so.62()(64bit)?

I'm going to dig around a bit more and see why our build on 6.4 (base) are pulling in libjpeg-turbo-devel when a explicit BuildRequires: libjpeg-devel is written.

Thanks for all and any help

Jeffrey-

Comment 4 Tom Lane 2013-02-26 23:07:13 UTC
(In reply to comment #3)
> You are right, there has been added provides, but I guess I'm not sure as to
> why both packages don't provide "libjpeg.so.62", libjpeg-turbo provides
> "libjpeg.so.62()(64bit)" using the %{?_isa}. To meet backwards compatibility
> shouldn't it also provide "libjpeg.so.62" in addition to the
> libjpeg.so.62()(64bit)?

No, it shouldn't.  The reason that looks different is you're comparing 32-bit and 64-bit RPMs, which *should* offer different Provides: in this respect.

> I'm going to dig around a bit more and see why our build on 6.4 (base) are
> pulling in libjpeg-turbo-devel when a explicit BuildRequires: libjpeg-devel
> is written.

The reason for that is we've replaced libjpeg with libjpeg-turbo as of 6.4.  libjpeg-turbo is now the only provider of "libjpeg-devel".

Comment 5 Jeffrey Ness 2013-02-26 23:14:23 UTC
(In reply to comment #4)
> (In reply to comment #3)
> > You are right, there has been added provides, but I guess I'm not sure as to
> > why both packages don't provide "libjpeg.so.62", libjpeg-turbo provides
> > "libjpeg.so.62()(64bit)" using the %{?_isa}. To meet backwards compatibility
> > shouldn't it also provide "libjpeg.so.62" in addition to the
> > libjpeg.so.62()(64bit)?
> 
> No, it shouldn't.  The reason that looks different is you're comparing
> 32-bit and 64-bit RPMs, which *should* offer different Provides: in this
> respect.

Shoot! I feel silly for doing that..

You are right, the provides are there:

  $ rpm -qp libjpeg-6b-46.el6.x86_64.rpm --provides
  libjpeg.so.62()(64bit)  
  libjpeg = 6b-46.el6
  libjpeg(x86-64) = 6b-46.el6

  $ rpm -qp libjpeg-turbo-1.2.1-1.el6.x86_64.rpm --provides
  libjpeg = 6b-47.el6
  libjpeg(x86-64) = 6b-47.el6
  libjpeg.so.62()(64bit)  
  libjpeg.so.62(LIBJPEGTURBO_6.2)(64bit)  
  libjpeg.so.62(LIBJPEG_6.2)(64bit)  
  libjpeg-turbo = 1.2.1-1.el6
  libjpeg-turbo(x86-64) = 1.2.1-1.el6

> 
> > I'm going to dig around a bit more and see why our build on 6.4 (base) are
> > pulling in libjpeg-turbo-devel when a explicit BuildRequires: libjpeg-devel
> > is written.
> 
> The reason for that is we've replaced libjpeg with libjpeg-turbo as of 6.4. 
> libjpeg-turbo is now the only provider of "libjpeg-devel".

This clears things up. Thank you.

Comment 6 Jeffrey Ness 2013-02-27 15:05:25 UTC
Hello Again Tom,

Maybe you can help me shed some light on what I'm seeing here.

On a RHEL 6.4 Server, I can show libjpeg-turbo provides the following:

  # cat /etc/redhat-release 
  Red Hat Enterprise Linux Server release 6.4 (Santiago)

  # rpm -q libjpeg-turbo
  libjpeg-turbo-1.2.1-1.el6.x86_64

  # rpm -q libjpeg-turbo --provides
  libjpeg = 6b-47.el6
  libjpeg(x86-64) = 6b-47.el6
  libjpeg.so.62()(64bit)  
  libjpeg.so.62(LIBJPEGTURBO_6.2)(64bit)  
  libjpeg.so.62(LIBJPEG_6.2)(64bit)  
  libjpeg-turbo = 1.2.1-1.el6
  libjpeg-turbo(x86-64) = 1.2.1-1.el6

  # rpm -q libjpeg-turbo -l
  /usr/bin/cjpeg
  /usr/bin/djpeg
  /usr/bin/jpegtran
  /usr/bin/rdjpgcom
  /usr/bin/wrjpgcom
  /usr/lib64/libjpeg.so.62
  /usr/lib64/libjpeg.so.62.0.0
  /usr/share/doc/libjpeg-turbo-1.2.1
  /usr/share/doc/libjpeg-turbo-1.2.1/ChangeLog.txt
  /usr/share/doc/libjpeg-turbo-1.2.1/README
  /usr/share/doc/libjpeg-turbo-1.2.1/README-turbo.txt
  /usr/share/doc/libjpeg-turbo-1.2.1/change.log
  /usr/share/doc/libjpeg-turbo-1.2.1/usage.txt
  /usr/share/doc/libjpeg-turbo-1.2.1/wizard.txt
  /usr/share/man/man1/cjpeg.1.gz
  /usr/share/man/man1/djpeg.1.gz
  /usr/share/man/man1/jpegtran.1.gz
  /usr/share/man/man1/rdjpgcom.1.gz
  /usr/share/man/man1/wrjpgcom.1.gz

According to find-requires libjpeg.so.62()(64bit) is a requirement of these blob of binaries:

  # /usr/lib/rpm/find-requires <<EOF
  > /usr/bin/cjpeg
  > /usr/bin/djpeg
  > /usr/bin/jpegtran
  > /usr/bin/rdjpgcom
  > /usr/bin/wrjpgcom
  > EOF
  libc.so.6()(64bit)
  libc.so.6(GLIBC_2.2.5)(64bit)
  libc.so.6(GLIBC_2.3.4)(64bit)
  libc.so.6(GLIBC_2.3)(64bit)
  libc.so.6(GLIBC_2.4)(64bit)
  libc.so.6(GLIBC_2.7)(64bit)
  libjpeg.so.62()(64bit)

So far this is exactly what I would expect, and frankly what I want to see.

--

My issue is in Mock:

  $ rpm -q mock
  mock-1.1.21-1.fc15.noarch

  $ mock -r ius-6-x86_64 --clean
  $ mock -r ius-6-x86_64 --init

  $ mock -r ius-6-x86_64 --install libjpeg-turbo
  INFO: mock.py version 1.1.21 starting...
  State Changed: init plugins
  INFO: selinux enabled
  State Changed: start
  Mock Version: 1.1.21
  INFO: Mock Version: 1.1.21
  State Changed: lock buildroot
  INFO: installing package(s): libjpeg-turbo
  INFO: Ignored option -c (probably due to merging -yc != -y -c)
  
  ================================================================================
   Package               Arch           Version                Repository    Size
  ================================================================================
  Installing:
   libjpeg-turbo         x86_64         1.2.1-1.el6            base         174 k  

  Transaction Summary
  ================================================================================

 
  $ mock -r ius-6-x86_64 --no-clean --shell

  <mock-chroot># cat /etc/redhat-release 
  Red Hat Enterprise Linux Server release 6.4 (Santiago)

  <mock-chroot># rpm --eval "%__find_requires"
  /usr/lib/rpm/redhat/find-requires

  <mock-chroot># /usr/lib/rpm/redhat/find-requires <<EOF
  > /usr/bin/cjpeg
  > /usr/bin/djpeg
  > /usr/bin/jpegtran
  > /usr/bin/rdjpgcom
  > /usr/bin/wrjpgcom
  > EOF
  libc.so.6()(64bit)
  libc.so.6(GLIBC_2.2.5)(64bit)
  libc.so.6(GLIBC_2.3.4)(64bit)
  libc.so.6(GLIBC_2.3)(64bit)
  libc.so.6(GLIBC_2.4)(64bit)
  libc.so.6(GLIBC_2.7)(64bit)
  libjpeg.so.62()(64bit)
  libjpeg.so.62(LIBJPEG_6.2)(64bit)

Notice the addition of "libjpeg.so.62(LIBJPEG_6.2)(64bit)" being added to the Requires chain.

Why is this additional Requires being found in the Mock environment and not the EL6 environment?

Possibly due to an older Mock version (under Fedora 15)?

Thanks again for any guidance.

Jeffrey-

Comment 7 Tom Lane 2013-02-27 16:04:46 UTC
(In reply to comment #6)
> Notice the addition of "libjpeg.so.62(LIBJPEG_6.2)(64bit)" being added to
> the Requires chain.
> 
> Why is this additional Requires being found in the Mock environment and not
> the EL6 environment?

Hm ... it sure looks like you have the same libjpeg-turbo version installed in the mock chroot as you do on your RHEL6.4 box.  So my guess is this is a difference in find-requires or whatever tools it uses (looks like objdump is probably the one for this).  I'm afraid I don't know enough about those tools to say more, but you could start by comparing package versions for rpm and binutils.

The bigger picture, though, is that it's not terribly surprising if a program built against the newer library acquires a dependency on "libjpeg.so.62(LIBJPEG_6.2)"; that's a consequence of symbol versioning having been added to the newer package.  This would then stop that program from being executed with an older library, even if it weren't using any of the newer functions added by libjpeg-turbo.  So the binary compatibility here is one-way: you can go forward but not backward.  That's as much as we promise, so this is really NOTABUG as far as I'm concerned, even if it's a bit unfortunate for your use-case.  As I said earlier, you need to build against the oldest RHEL branch you intend to support.

Comment 8 Jeffrey Ness 2013-02-27 16:12:53 UTC
I agree, this is not a bug with the libjpeg-turbo package.

It does appear to be a difference in the find-requires script:

 -- base system with 6.4 --

  # cat /etc/redhat-release 
  Red Hat Enterprise Linux Server release 6.4 (Santiago)
  
  # md5sum /usr/lib/rpm/find-requires
  eaf8ff86e41e2e60e62b0460bf2114e8  /usr/lib/rpm/find-requires

  # ls -ld /usr/lib/rpm/find-requires
  -rwxr-xr-x 1 root root 3505 Nov 15 08:22 /usr/lib/rpm/find-requires

 -- mock env with 6.4 --

  <mock-chroot># cat /etc/redhat-release 
  Red Hat Enterprise Linux Server release 6.4 (Santiago)

  <mock-chroot># md5sum /usr/lib/rpm/find-requires
  eaf8ff86e41e2e60e62b0460bf2114e8  /usr/lib/rpm/find-requires
 
  <mock-chroot># ls -ld /usr/lib/rpm/find-requires 
  -rwxr-xr-x. 1 root root 3505 Nov 15 08:22 /usr/lib/rpm/find-requires

 --

Please feel free to close this bug, I can't seem to set the Status to 'NOTABUG' or 'CLOSED'.

Thanks
Jeffrey-

Comment 9 Jeffrey Ness 2013-02-27 16:14:14 UTC
(In reply to comment #8)
> It does appear to be a difference in the find-requires script:
> 

Should read "does not appear to be a difference"

Comment 10 Tom Lane 2013-02-27 16:37:59 UTC
(In reply to comment #9)
> Should read "does not appear to be a difference"

Yeah, so it must be a change in the called tools?  Seems a bit weird though.

Anyway, I don't see anything to change about libjpeg-turbo, so I'll close this bug.

Comment 11 Jeffrey Ness 2013-02-27 18:30:15 UTC
This Bug is closed, but I wanted to put my findings here for future reference,
and maybe to help other users.

Turns out a Mock environment has two *find-requires* files:

  $ find /var/lib/mock/el6.x86_64/root/usr/lib -name find-requires
  /var/lib/mock/el6.x86_64/root/usr/lib/rpm/find-requires
  /var/lib/mock/el6.x86_64/root/usr/lib/rpm/redhat/find-requires

These two files are different:

  <mock-chroot># md5sum /usr/lib/rpm/find-requires
  eaf8ff86e41e2e60e62b0460bf2114e8  /usr/lib/rpm/find-requires

  <mock-chroot># md5sum /usr/lib/rpm/redhat/find-requires
  aa7ad830f652edad47f11dc6468da7f4  /usr/lib/rpm/redhat/find-requires

They even provide differnt output, you will notice the one under *redhat* provides
the Requires I was unsure about "libjpeg.so.62(LIBJPEG_6.2)(64bit)":

  <mock-chroot># /usr/lib/rpm/find-requires <<EOF
  > /usr/bin/cjpeg
  > /usr/bin/djpeg
  > /usr/bin/jpegtran
  > /usr/bin/rdjpgcom
  > /usr/bin/wrjpgcom
  > EOF
  libc.so.6()(64bit)
  libc.so.6(GLIBC_2.2.5)(64bit)
  libc.so.6(GLIBC_2.3.4)(64bit)
  libc.so.6(GLIBC_2.3)(64bit)
  libc.so.6(GLIBC_2.4)(64bit)
  libc.so.6(GLIBC_2.7)(64bit)
  libjpeg.so.62()(64bit)

  <mock-chroot># /usr/lib/rpm/redhat/find-requires <<EOF
  > /usr/bin/cjpeg
  > /usr/bin/djpeg
  > /usr/bin/jpegtran
  > /usr/bin/rdjpgcom
  > /usr/bin/wrjpgcom
  > EOF
  libc.so.6()(64bit)
  libc.so.6(GLIBC_2.2.5)(64bit)
  libc.so.6(GLIBC_2.3.4)(64bit)
  libc.so.6(GLIBC_2.3)(64bit)
  libc.so.6(GLIBC_2.4)(64bit)
  libc.so.6(GLIBC_2.7)(64bit)
  libjpeg.so.62()(64bit)
  libjpeg.so.62(LIBJPEG_6.2)(64bit)

Comment 12 Jeffrey Ness 2013-02-27 20:14:54 UTC
Additional research:

Here is the script found in /usr/lib/rpm/find-requires (package rpm-build)
that is responsible for creating the requirements:

# objdump -p /usr/bin/cjpeg | awk 'BEGIN { START=0; LIBNAME=""; needed='$needed'; }
        /^$/ { START=0; }
        /^Dynamic Section:$/ { START=1; }
        (START==1) && /NEEDED/ {
            if (needed) {
                if ("'$lib64'" != "") {
                    sub(/$/, "()'$lib64'", $2) ;
                }
                print $2 ;
            }
        }
        (START==2) && /^[A-Za-z]/ { START=3; }
        /^Version References:$/ { START=2; }
        (START==2) && /required from/ {
            sub(/:/, "", $3);
            LIBNAME=$3;
        }
        (START==2) && (LIBNAME!="") && ($4!="") && (($4~/^GLIBC_*/) || ($4~/^GCC_*/)) {
            print LIBNAME "(" $4 ")'$lib64'";
        }
    '

libjpeg.so.62
libc.so.6
libc.so.6(GLIBC_2.4)
libc.so.6(GLIBC_2.3)
libc.so.6(GLIBC_2.2.5)
libc.so.6(GLIBC_2.7)
libc.so.6(GLIBC_2.3.4)

==
==

And here is the script found in /usr/lib/rpm/redhat/find-requires (package redhat-rpm-config):

# objdump -p /usr/bin/cjpeg | awk 'BEGIN { START=0; LIBNAME=""; needed='$needed'; }
        /^$/ { START=0; }
        /^Dynamic Section:$/ { START=1; }
        (START==1) && /NEEDED/ {
            if (needed) {
                if ("'$lib64'" != "") {
                    sub(/$/, "()'$lib64'", $2) ;
                }
                print $2 ;
            }
        }
        (START==2) && /^[A-Za-z]/ { START=3; }
        /^Version References:$/ { START=2; }
        (START==2) && /required from/ {
            sub(/:/, "", $3);
            LIBNAME=$3;
        }
        (START==2) && (LIBNAME!="") && ($4!="") {
            print LIBNAME "(" $4 ")'$lib64'";
        }
    '
libjpeg.so.62
libc.so.6
libjpeg.so.62(LIBJPEG_6.2)
libc.so.6(GLIBC_2.4)
libc.so.6(GLIBC_2.3)
libc.so.6(GLIBC_2.2.5)
libc.so.6(GLIBC_2.7)
libc.so.6(GLIBC_2.3.4)

==
==

The line in question that differs these scripts is 

rpm-build:
  (START==2) && (LIBNAME!="") && ($4!="") && (($4~/^GLIBC_*/) || ($4~/^GCC_*/)) {

redhat-rpm-config:
  (START==2) && (LIBNAME!="") && ($4!="") {

==
==

We have the full objdump:

# objdump -p /usr/bin/cjpeg

/usr/bin/cjpeg:     file format elf64-x86-64

Program Header:
    PHDR off    0x0000000000000040 vaddr 0x0000000000400040 paddr 0x0000000000400040 align 2**3
         filesz 0x00000000000001c0 memsz 0x00000000000001c0 flags r-x
  INTERP off    0x0000000000000200 vaddr 0x0000000000400200 paddr 0x0000000000400200 align 2**0
         filesz 0x000000000000001c memsz 0x000000000000001c flags r--
    LOAD off    0x0000000000000000 vaddr 0x0000000000400000 paddr 0x0000000000400000 align 2**21
         filesz 0x0000000000006574 memsz 0x0000000000006574 flags r-x
    LOAD off    0x0000000000006578 vaddr 0x0000000000606578 paddr 0x0000000000606578 align 2**21
         filesz 0x00000000000002e8 memsz 0x0000000000000328 flags rw-
 DYNAMIC off    0x00000000000065a0 vaddr 0x00000000006065a0 paddr 0x00000000006065a0 align 2**3
         filesz 0x00000000000001a0 memsz 0x00000000000001a0 flags rw-
    NOTE off    0x000000000000021c vaddr 0x000000000040021c paddr 0x000000000040021c align 2**2
         filesz 0x0000000000000044 memsz 0x0000000000000044 flags r--
EH_FRAME off    0x0000000000005a00 vaddr 0x0000000000405a00 paddr 0x0000000000405a00 align 2**2
         filesz 0x0000000000000194 memsz 0x0000000000000194 flags r--
   STACK off    0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**3
         filesz 0x0000000000000000 memsz 0x0000000000000000 flags rw-

Dynamic Section:
  NEEDED               libjpeg.so.62
  NEEDED               libc.so.6
  INIT                 0x0000000000400c80
  FINI                 0x00000000004047a8
  GNU_HASH             0x0000000000400260
  STRTAB               0x0000000000400650
  SYMTAB               0x00000000004002a8
  STRSZ                0x0000000000000260
  SYMENT               0x0000000000000018
  DEBUG                0x0000000000000000
  PLTGOT               0x0000000000606748
  PLTRELSZ             0x00000000000002a0
  PLTREL               0x0000000000000007
  JMPREL               0x00000000004009e0
  RELA                 0x0000000000400980
  RELASZ               0x0000000000000060
  RELAENT              0x0000000000000018
  VERNEED              0x0000000000400900
  VERNEEDNUM           0x0000000000000002
  VERSYM               0x00000000004008b0

Version References:
  required from libjpeg.so.62:
    0x04cdffe2 0x00 05 LIBJPEG_6.2
  required from libc.so.6:
    0x0d696914 0x00 07 GLIBC_2.4
    0x0d696913 0x00 06 GLIBC_2.3
    0x09691a75 0x00 04 GLIBC_2.2.5
    0x0d696917 0x00 03 GLIBC_2.7
    0x09691974 0x00 02 GLIBC_2.3.4

==
==

And the place LIBJPEG_6.2 is being pulled in is:

  Version References:
    required from libjpeg.so.62:
      0x04cdffe2 0x00 05 LIBJPEG_6.2