[Techtalk] kpackage/rpm help?

Almut Behrens almut_behrens at yahoo.com
Thu Nov 1 16:10:15 EST 2001


On Wed, Oct 31, 2001 at 01:15:07PM -0700, Ruth Kneale wrote:
> 
> Two problems:  one small and one large.  Small first:  I usually use
> kpackage to administer and manage my RPM installations, but now it
> won't run - I get:
> 
> kpackage: error in loading shared libraries:
> /usr/lib/librpmbuild.so.0: undefined symbol: rpmGlobalMacroContext

I suspect that you've somehow managed to mix up incompatible versions
of kpackage and the RPM libraries it relies upon :)  A little poking
around for the symbol in question revealed the following:

With an older set of RPM libs:

$ objdump -T /usr/lib/librpm*.so.0 | grep 'Global\|librpm'
/usr/lib/librpm.so.0:     file format elf32-i386
0004bfa4 g    DO .bss   0000000c  Base        rpmGlobalMacroContext
/usr/lib/librpmbuild.so.0:     file format elf32-i386
00000000      D  *UND*  00000000              rpmGlobalMacroContext


With the current libs (belonging to the rpm-4.0.2 package):

$ objdump -T ./librpm*.so.0 | grep 'Global\|librpm'
./librpm.so.0:     file format elf32-i386
./librpmbuild.so.0:     file format elf32-i386
00000000      D  *UND*  00000000              rpmGlobalMacroContext
./librpmio.so.0:     file format elf32-i386
0001b898 g    DO .bss   0000000c  Base        rpmGlobalMacroContext

This shows in which related libraries the symbol is being mentioned
and where it is actually located. (BTW, 'nm' provides similar output.)

The "*UND*" (referring to librpmbuild.so) indicates that the symbol is
not defined within that particular library, but rather is just a
reference to a library-external entity that needs to be resolved before
the program can run. (Well, this is simplified somewhat. With lazy/late
binding in effect, the program might start at first, but would crash
later on, as soon as some functionality tries to access the symbol...)

So, as we can see, the real location of the symbol is in librpm.so,
with the older libs.  With current versions of the RPM libraries,
however, things have changed, and rpmGlobalMacroContext is no longer
in librpm.so, but rather in librpmio.so (note the 'io').

As you can probably guess, an older kpackage binary does not know
about this change and therefore doesn't make any attempt to load
the relevant library, which in turn causes the symbol to not be found
when it is supposed to be resolved upon request of librpmbuild.so.

You can verify this, and indirectly check what kind of version you have
with ldd:

With an older kpackage you would probably get:

$ ldd /usr/sbin/kpackage | grep librpm
        librpmbuild.so.0 => /usr/lib/librpmbuild.so.0 (0x40b99000)
        librpm.so.0 => /usr/lib/librpm.so.0 (0x40bbe000)

whereas, running it on a more recent kpackage will output:

$ ldd ./kpackage | grep librpm
        librpm.so.0 => /usr/lib/librpm.so.0 (0x404c5000)
        librpmbuild.so.0 => /usr/lib/librpmbuild.so.0 (0x40511000)
        librpmio.so.0 => not found

(the "not found" is specific to the system I ran this on -- it only had
the old rpm libs in the standard places...)

Either way around (old kpackage and new rpm libs, or new kpackage and
old libs), things will not work...
Also, the set of the three rpm libs themselves might not be coherent --
although I'm not quite sure how this might have happened without manual
intervention.  Anyway, you'll need matching versions of everything
involved.

For .rpms of the RPM package (which also contains the libs), visit the
following site:

ftp://ftp.rpm.org/pub/rpm/dist/

There you'll find any version your heart desires... For different
versions of kpackage I would try something like:

http://rpmfind.net/linux/rpm2html/search.php?query=kpackage


*Theoretically*, you could force kpackage to pull in the corresponding
lib versions it needs, making use of the LD_PRELOAD environment
variable, which the dynamic linker checks at link time, to pull in any
libs given as the value of it (colon-seperated list of .so-files).
So, you could in principle write a little wrapper for kpackage doing
just that:

#!/bin/bash
libpath=/path/to/the/correct/version/of/the/libs
export LD_PRELOAD=$libpath/librpmio.so.0:$libpath/librpm.so.0[:...]
exec /usr/sbin/kpackage

This is merely to illustrate the technique, though  (in case someone
might need it some time in a different context).  I wouldn't really
recommend that you actually do this.  Mixing different RPM versions on
one system might trash your package database -- at least, I've heard
rumours along these lines...  However, I'm not an RPM expert, so take
the latter statement with a grain of salt.

Good luck,

- Almut

PS: does anyone know of a way to extract *individual* files from RPMs,
without having to install the whole shebang? Let's say I wanted to get
hold of the above mentioned librmpio.so.0.  Any way to do that with the
native RPM tools?  I usually use mc's (midnight commander) virtual RPM
file system (+ cpio) to do this.  Works fine, but I've always been
wondering whether there is some combination of commandline options that
you give to rpm to achieve the same effects.  Always curious, you know,
but in this particular case just too lazy to fully read the manuals ;)





More information about the Techtalk mailing list