Use non-greedy findConsumers for bug #467896.
authorZac Medico <zmedico@gentoo.org>
Wed, 1 May 2013 04:00:52 +0000 (21:00 -0700)
committerZac Medico <zmedico@gentoo.org>
Wed, 1 May 2013 04:33:31 +0000 (21:33 -0700)
This fixes the preserve-libs display and @preserved-rebuild to omit
library consumers that are satisfied by alternative providers.

pym/portage/_sets/libs.py
pym/portage/util/_dyn_libs/LinkageMapELF.py
pym/portage/util/_dyn_libs/display_preserved_libs.py

index a6433e85568c667ee5521b53fd0b9cb87e6a5a8d..022e076f573d115767876c4185a6b1a302279725 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright 2007-2012 Gentoo Foundation
+# Copyright 2007-2013 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
 
 from __future__ import print_function
@@ -49,7 +49,8 @@ class LibraryFileConsumerSet(LibraryConsumerSet):
        def load(self):
                consumers = set()
                for lib in self.files:
-                       consumers.update(self.dbapi._linkmap.findConsumers(lib))
+                       consumers.update(
+                               self.dbapi._linkmap.findConsumers(lib, greedy=False))
 
                if not consumers:
                        return
@@ -77,10 +78,10 @@ class PreservedLibraryConsumerSet(LibraryConsumerSet):
                                for lib in libs:
                                        if self.debug:
                                                print(lib)
-                                               for x in sorted(self.dbapi._linkmap.findConsumers(lib)):
+                                               for x in sorted(self.dbapi._linkmap.findConsumers(lib, greedy=False)):
                                                        print("    ", x)
                                                print("-"*40)
-                                       consumers.update(self.dbapi._linkmap.findConsumers(lib))
+                                       consumers.update(self.dbapi._linkmap.findConsumers(lib, greedy=False))
                        # Don't rebuild packages just because they contain preserved
                        # libs that happen to be consumers of other preserved libs.
                        for libs in plib_dict.values():
index 8d0c09dec505a7ae04550d9be26515c86186f3e0..3920f9487f84df159f816351e1a3158041c51ad8 100644 (file)
@@ -678,7 +678,7 @@ class LinkageMapELF(object):
                                                rValue[soname].add(provider)
                return rValue
 
-       def findConsumers(self, obj, exclude_providers=None):
+       def findConsumers(self, obj, exclude_providers=None, greedy=True):
                """
                Find consumers of an object or object key.
 
@@ -715,6 +715,9 @@ class LinkageMapELF(object):
                        '/usr/lib/libssl.so.0.9.8'), and return True if the library is
                        owned by a provider which is planned for removal.
                @type exclude_providers: collection
+               @param greedy: If True, then include consumers that are satisfied
+               by alternative providers, otherwise omit them. Default is True.
+               @type greedy: Boolean
                @rtype: set of strings (example: set(['/bin/foo', '/usr/bin/bar']))
                @return: The return value is a soname -> set-of-library-paths, where
                set-of-library-paths satisfy soname.
@@ -769,16 +772,19 @@ class LinkageMapELF(object):
                defpath_keys = set(self._path_key(x) for x in self._defpath)
                satisfied_consumer_keys = set()
                if soname_node is not None:
-                       if exclude_providers is not None:
+                       if exclude_providers is not None or not greedy:
                                relevant_dir_keys = set()
                                for provider_key in soname_node.providers:
+                                       if not greedy and provider_key == obj_key:
+                                               continue
                                        provider_objs = self._obj_properties[provider_key].alt_paths
                                        for p in provider_objs:
                                                provider_excluded = False
-                                               for excluded_provider_isowner in exclude_providers:
-                                                       if excluded_provider_isowner(p):
-                                                               provider_excluded = True
-                                                               break
+                                               if exclude_providers is not None:
+                                                       for excluded_provider_isowner in exclude_providers:
+                                                               if excluded_provider_isowner(p):
+                                                                       provider_excluded = True
+                                                                       break
                                                if not provider_excluded:
                                                        # This provider is not excluded. It will
                                                        # satisfy a consumer of this soname if it
index 238274f2af6b7828f7d98f05bfe035480dfa7c5a..b16478d2b4b2edbb429cede11a5a5f98b27ccc07 100644 (file)
@@ -31,7 +31,7 @@ def display_preserved_libs(vardb):
                                if f in consumer_map:
                                        continue
                                consumers = []
-                               for c in linkmap.findConsumers(f):
+                               for c in linkmap.findConsumers(f, greedy=False):
                                        # Filter out any consumers that are also preserved libs
                                        # belonging to the same package as the provider.
                                        if linkmap._obj_key(c) not in internal_plib_keys: