From: Zac Medico Date: Wed, 29 Oct 2008 00:07:34 +0000 (-0000) Subject: Fix interaction between LinkageMap.rebuild() and the package replacement X-Git-Tag: v2.2_rc13~43 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=035b0f03170765bdfe8ba0b93aabe3621970d49c;p=portage.git Fix interaction between LinkageMap.rebuild() and the package replacement process in order to avoid problems with stale or unaccounted NEEDED. This solves a LinkageMap corruption issue which caused findConsumers to return false positive inside dblink.unmerge(). svn path=/main/trunk/; revision=11742 --- diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py index 57dba00a1..9a77ce085 100644 --- a/pym/portage/dbapi/vartree.py +++ b/pym/portage/dbapi/vartree.py @@ -218,13 +218,15 @@ class LinkageMap(object): def __str__(self): return str(sorted(self.alt_paths)) - def rebuild(self, include_file=None): + def rebuild(self, exclude_pkgs=None, include_file=None): root = self._root libs = {} obj_key_cache = {} obj_properties = {} lines = [] for cpv in self._dbapi.cpv_all(): + if exclude_pkgs is not None and cpv in exclude_pkgs: + continue lines += self._dbapi.aux_get(cpv, ["NEEDED.ELF.2"])[0].split('\n') # Cache NEEDED.* files avoid doing excessive IO for every rebuild. self._dbapi.flush_cache() @@ -1938,8 +1940,12 @@ class dblink(object): if retval != os.EX_OK: writemsg("!!! FAILED postrm: %s\n" % retval, noiselevel=-1) - # regenerate reverse NEEDED map - self.vartree.dbapi.linkmap.rebuild() + # Skip this if another package in the same slot has just been + # merged on top of this package, since the other package has + # already called LinkageMap.rebuild() and passed it's NEEDED file + # in as an argument. + if not others_in_slot: + self.vartree.dbapi.linkmap.rebuild(exclude_pkgs=(self.mycpv,)) # remove preserved libraries that don't have any consumers left # Since preserved libraries can be consumers of other preserved @@ -1961,11 +1967,6 @@ class dblink(object): preserved_node.alt_paths.add(f) preserved_nodes.add(preserved_node) for c in self.vartree.dbapi.linkmap.findConsumers(f): - if self.isowner(c, root): - # TODO: Remove this case since it shouldn't be - # necessary. This seems to be a false positive - # returned from LinkageMap.findConsumers(). - continue consumer_node = LinkageMap._LibGraphNode(c, root) if not consumer_node.file_exists(): continue @@ -3126,6 +3127,10 @@ class dblink(object): gid=portage_gid, mode=02750, mask=02) writedict(cfgfiledict, conf_mem_file) + exclude_pkgs = set(dblnk.mycpv for dblnk in others_in_slot) + self.vartree.dbapi.linkmap.rebuild(exclude_pkgs=exclude_pkgs, + include_file=os.path.join(inforoot, "NEEDED.ELF.2")) + # These caches are populated during collision-protect and the data # they contain is now invalid. It's very important to invalidate # the contents_inodes cache so that FEATURES=unmerge-orphans