Fix LinkageMap.findConsumers() to check whether the master link for a lib
authorZac Medico <zmedico@gentoo.org>
Sat, 26 Jul 2008 11:33:18 +0000 (11:33 -0000)
committerZac Medico <zmedico@gentoo.org>
Sat, 26 Jul 2008 11:33:18 +0000 (11:33 -0000)
providing a given soname actually points to that lib. If there is another
version of this lib with the same soname and the master link points to
that other version, this lib will be shadowed and won't have any consumers.
By eliminating false, positives this way, we avoid the following state
after upgrade from media-libs/mesa-7.0.3 to media-libs/mesa-7.1_rc3:

# scanelf -S /usr/lib64/libGLU.so*
 TYPE   SONAME FILE
ET_DYN libGLU.so.1 /usr/lib64/libGLU.so
ET_DYN libGLU.so.1 /usr/lib64/libGLU.so.1
ET_DYN libGLU.so.1 /usr/lib64/libGLU.so.1.3
ET_DYN libGLU.so.1 /usr/lib64/libGLU.so.1.3.070003
ET_DYN libGLU.so.1 /usr/lib64/libGLU.so.1.3.070100 <- shadowed lib

Thanks to Diego "Flameeyes" Pettenò for reporting this issue.

svn path=/main/trunk/; revision=11200

pym/portage/dbapi/vartree.py

index 61d08f83c7ec41003e3664fed0d33cc6f1d4f49e..8e51a1591a133ac39e4bc9d8123ce0f96c809548 100644 (file)
@@ -264,6 +264,24 @@ class LinkageMap(object):
                        obj = realpath(obj)
                        if obj not in self._obj_properties:
                                raise KeyError("%s not in object list" % obj)
+
+               # If there is another version of this lib with the
+               # same soname and the master link points to that
+               # other version, this lib will be shadowed and won't
+               # have any consumers.
+               arch, needed, path, soname = self._obj_properties[obj]
+               obj_dir = os.path.dirname(obj)
+               master_link = os.path.join(obj_dir, soname)
+               try:
+                       master_st = os.stat(master_link)
+                       obj_st = os.stat(obj)
+               except OSError:
+                       pass
+               else:
+                       if (obj_st.st_dev, obj_st.st_ino) != \
+                               (master_st.st_dev, master_st.st_ino):
+                               return set()
+
                rValue = set()
                for soname in self._libs:
                        for arch in self._libs[soname]:
@@ -273,7 +291,7 @@ class LinkageMap(object):
                                                path = [realpath(y) for y in path+self._defpath]
                                                if soname[0] == os.sep and realpath(soname) == realpath(obj):
                                                        rValue.add(x)
-                                               elif realpath(os.path.dirname(obj)) in path:
+                                               elif realpath(obj_dir) in path:
                                                        rValue.add(x)
                return rValue