summaryrefslogtreecommitdiffstats
path: root/pym
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2008-11-04 07:40:34 +0000
committerZac Medico <zmedico@gentoo.org>2008-11-04 07:40:34 +0000
commit6dc2a3ef1ffac9eab3728d37a3f6e133ac34ab27 (patch)
tree2df30291ed2aeb0a7002950b611dc24452e08ee5 /pym
parent5a0e91c290dad87f14feb1bb0d67557944634953 (diff)
downloadportage-6dc2a3ef1ffac9eab3728d37a3f6e133ac34ab27.tar.gz
portage-6dc2a3ef1ffac9eab3728d37a3f6e133ac34ab27.tar.bz2
portage-6dc2a3ef1ffac9eab3728d37a3f6e133ac34ab27.zip
Bug #245362 - Use tuples of (device, inode) for all path comparisons inside
LinkageMap, so that they work regardless of path differences due to symlinked directories. TODO: Fix other preserve-libs code, such as dblink._preserve_libs(), to use this approach for path comparisons. svn path=/main/trunk/; revision=11806
Diffstat (limited to 'pym')
-rw-r--r--pym/portage/dbapi/vartree.py51
-rw-r--r--pym/portage/util.py6
2 files changed, 32 insertions, 25 deletions
diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py
index 0361bb3d9..f88431ee0 100644
--- a/pym/portage/dbapi/vartree.py
+++ b/pym/portage/dbapi/vartree.py
@@ -149,8 +149,23 @@ class LinkageMap(object):
self._root = self._dbapi.root
self._libs = {}
self._obj_properties = {}
- self._defpath = set(getlibpaths(self._root))
self._obj_key_cache = {}
+ self._defpath = set()
+ self._path_key_cache = {}
+
+ def _clear_cache(self):
+ self._libs.clear()
+ self._obj_properties.clear()
+ self._obj_key_cache.clear()
+ self._defpath.clear()
+ self._path_key_cache.clear()
+
+ def _path_key(self, path):
+ key = self._path_key_cache.get(path)
+ if key is None:
+ key = self._ObjectKey(path, self._root)
+ self._path_key_cache[path] = key
+ return key
class _ObjectKey(object):
@@ -222,10 +237,12 @@ class LinkageMap(object):
def rebuild(self, exclude_pkgs=None, include_file=None):
root = self._root
- self._defpath = set(getlibpaths(root))
- libs = {}
- obj_key_cache = {}
- obj_properties = {}
+ self._clear_cache()
+ self._defpath.update(getlibpaths(self._root))
+ libs = self._libs
+ obj_key_cache = self._obj_key_cache
+ obj_properties = self._obj_properties
+
lines = []
for cpv in self._dbapi.cpv_all():
if exclude_pkgs is not None and cpv in exclude_pkgs:
@@ -259,8 +276,7 @@ class LinkageMap(object):
obj = fields[1]
obj_key = self._ObjectKey(obj, root)
soname = fields[2]
- path = set([
- normalize_path(os.path.join(self._root, x.lstrip(os.path.sep)))
+ path = set([normalize_path(x) \
for x in filter(None, fields[3].replace(
"${ORIGIN}", os.path.dirname(obj)).replace(
"$ORIGIN", os.path.dirname(obj)).split(":"))])
@@ -281,10 +297,6 @@ class LinkageMap(object):
obj_properties.setdefault(obj_key, \
(arch, needed, path, soname, set()))[4].add(obj)
- self._libs = libs
- self._obj_properties = obj_properties
- self._obj_key_cache = obj_key_cache
-
def listBrokenBinaries(self, debug=False):
"""
Find binaries and their needed sonames, which have no providers.
@@ -530,7 +542,7 @@ class LinkageMap(object):
raise KeyError("%s (%s) not in object list" % (obj_key, obj))
arch, needed, path, _, _ = self._obj_properties[obj_key]
- path = path.union(self._defpath)
+ path_keys = set(self._path_key(x) for x in path.union(self._defpath))
for soname in needed:
rValue[soname] = set()
if soname not in self._libs or arch not in self._libs[soname]:
@@ -540,8 +552,7 @@ class LinkageMap(object):
for provider_key in self._libs[soname][arch]["providers"]:
providers = self._obj_properties[provider_key][4]
for provider in providers:
- if os.path.join(self._root,
- os.path.dirname(provider).lstrip(os.path.sep)) in path:
+ if self._path_key(os.path.dirname(provider)) in path_keys:
rValue[soname].add(provider)
return rValue
@@ -584,10 +595,6 @@ class LinkageMap(object):
if obj_key not in self._obj_properties:
raise KeyError("%s (%s) not in object list" % (obj_key, obj))
- # Determine the directory(ies) from the set of objects.
- objs_dirs = set(os.path.join(self._root,
- os.path.dirname(x).lstrip(os.sep)) for x in objs)
-
# 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
@@ -606,6 +613,10 @@ class LinkageMap(object):
(master_st.st_dev, master_st.st_ino):
return set()
+ # Determine the directory(ies) from the set of objects.
+ objs_dir_keys = set(self._path_key(os.path.dirname(x)) for x in objs)
+ defpath_keys = set(self._path_key(x) for x in self._defpath)
+
arch, _, _, soname, _ = self._obj_properties[obj_key]
if soname in self._libs and arch in self._libs[soname]:
# For each potential consumer, add it to rValue if an object from the
@@ -613,8 +624,8 @@ class LinkageMap(object):
for consumer_key in self._libs[soname][arch]["consumers"]:
_, _, path, _, consumer_objs = \
self._obj_properties[consumer_key]
- path = path.union(self._defpath)
- if objs_dirs.intersection(path):
+ path_keys = defpath_keys.union(self._path_key(x) for x in path)
+ if objs_dir_keys.intersection(path_keys):
rValue.update(consumer_objs)
return rValue
diff --git a/pym/portage/util.py b/pym/portage/util.py
index 481c15bbc..ab7214070 100644
--- a/pym/portage/util.py
+++ b/pym/portage/util.py
@@ -1208,8 +1208,4 @@ def getlibpaths(root):
rval.append("/usr/lib")
rval.append("/lib")
- rval = [normalize_path(os.path.join(root, x.lstrip(os.path.sep))) \
- for x in rval if x]
-
- return rval
-
+ return [normalize_path(x) for x in rval if x]