preserve-libs: fix linkmap logic for new plibs
authorZac Medico <zmedico@gentoo.org>
Sat, 7 May 2011 03:02:50 +0000 (20:02 -0700)
committerZac Medico <zmedico@gentoo.org>
Sat, 7 May 2011 03:02:50 +0000 (20:02 -0700)
Together with commit f36b9fa38b5268c2a5579db62acec026625f84a9,
hopefully this solves bug #366061.

pym/portage/dbapi/vartree.py
pym/portage/util/_dyn_libs/LinkageMapELF.py

index 4170d3dfdd6f97af82a474b5dd14e8854d918071..d8fe7b51888513abf2cd3bc34386f3d6d7acb8a9 100644 (file)
@@ -1434,7 +1434,7 @@ class dblink(object):
                return pkgfiles
 
        def _prune_plib_registry(self, unmerge=False, others_in_slot=[],
-               needed=None):
+               needed=None, preserve_paths=None):
                # remove preserved libraries that don't have any consumers left
                plib_registry = self.vartree.dbapi._plib_registry
                if plib_registry:
@@ -1450,7 +1450,7 @@ class dblink(object):
                                        exclude_pkgs = None
 
                                self._linkmap_rebuild(exclude_pkgs=exclude_pkgs,
-                                       include_file=needed)
+                                       include_file=needed, preserve_paths=preserve_paths)
 
                                cpv_lib_map = self._find_unused_preserved_libs()
                                if cpv_lib_map:
@@ -1476,7 +1476,8 @@ class dblink(object):
                                plib_registry.unlock()
 
        def unmerge(self, pkgfiles=None, trimworld=None, cleanup=True,
-               ldpath_mtimes=None, others_in_slot=None, needed=None):
+               ldpath_mtimes=None, others_in_slot=None, needed=None,
+               preserve_paths=None):
                """
                Calls prerm
                Unmerges a given package (CPV)
@@ -1496,6 +1497,11 @@ class dblink(object):
                @type others_in_slot: list
                @param needed: Filename containing libraries needed after unmerge.
                @type needed: String
+               @param preserve_paths: Libraries preserved by a package instance that
+                       is currently being merged. They need to be explicitly passed to the
+                       LinkageMap, since they are not registered in the
+                       PreservedLibsRegistry yet.
+               @type preserve_paths: set
                @rtype: Integer
                @returns:
                1. os.EX_OK if everything went well.
@@ -1629,7 +1635,8 @@ class dblink(object):
                                                level=logging.ERROR, noiselevel=-1)
 
                        self._prune_plib_registry(unmerge=True,
-                               others_in_slot=others_in_slot, needed=needed)
+                               others_in_slot=others_in_slot, needed=needed,
+                               preserve_paths=preserve_paths)
                finally:
                        self.vartree.dbapi._bump_mtime(self.mycpv)
                        if builddir_lock:
@@ -3321,7 +3328,8 @@ class dblink(object):
                        dblnk.settings["REPLACED_BY_VERSION"] = portage.versions.cpv_getversion(self.mycpv)
                        dblnk.settings.backup_changes("REPLACED_BY_VERSION")
                        unmerge_rval = dblnk.unmerge(ldpath_mtimes=prev_mtimes,
-                               others_in_slot=others_in_slot, needed=needed)
+                               others_in_slot=others_in_slot, needed=needed,
+                               preserve_paths=preserve_paths)
                        dblnk.settings.pop("REPLACED_BY_VERSION", None)
 
                        if unmerge_rval == os.EX_OK:
index bbfce8880a88e81e1aef826264aa494b1e83adf8..9e79bd888e65135bdfde44f581c3f9a5193b6eed 100644 (file)
@@ -142,10 +142,26 @@ class LinkageMapELF(object):
                def __str__(self):
                        return str(sorted(self.alt_paths))
 
-       def rebuild(self, exclude_pkgs=None, include_file=None):
+       def rebuild(self, exclude_pkgs=None, include_file=None,
+               preserve_paths=None):
                """
                Raises CommandNotFound if there are preserved libs
                and the scanelf binary is not available.
+
+               @param exclude_pkgs: A set of packages that should be excluded from
+                       the LinkageMap, since they are being unmerged and their NEEDED
+                       entries are therefore irrelevant and would only serve to corrupt
+                       the LinkageMap.
+               @type exclude_pkgs: set
+               @param include_file: The path of a file containing NEEDED entries for
+                       a package which does not exist in the vardbapi yet because it is
+                       currently being merged.
+               @type include_file: String
+               @param preserve_paths: Libraries preserved by a package instance that
+                       is currently being merged. They need to be explicitly passed to the
+                       LinkageMap, since they are not registered in the
+                       PreservedLibsRegistry yet.
+               @type preserve_paths: set
                """
 
                os = _os_merge
@@ -178,12 +194,17 @@ class LinkageMapELF(object):
                # have to call scanelf for preserved libs here as they aren't 
                # registered in NEEDED.ELF.2 files
                plibs = set()
-               if self._dbapi._plib_registry and self._dbapi._plib_registry.getPreservedLibs():
-                       args = ["/usr/bin/scanelf", "-qF", "%a;%F;%S;%r;%n"]
-                       for items in self._dbapi._plib_registry.getPreservedLibs().values():
+               if preserve_paths is not None:
+                       plibs.update(preserve_paths)
+               if self._dbapi._plib_registry and \
+                       self._dbapi._plib_registry.hasEntries():
+                       for items in \
+                               self._dbapi._plib_registry.getPreservedLibs().values():
                                plibs.update(items)
-                               args.extend(os.path.join(root, x.lstrip("." + os.sep)) \
-                                       for x in items)
+               if plibs:
+                       args = ["/usr/bin/scanelf", "-qF", "%a;%F;%S;%r;%n"]
+                       args.extend(os.path.join(root, x.lstrip("." + os.sep)) \
+                               for x in plibs)
                        try:
                                proc = subprocess.Popen(args, stdout=subprocess.PIPE)
                        except EnvironmentError as e: