* [gentoo-commits] proj/portage:master commit in: pym/portage/dbapi/, pym/portage/util/_dyn_libs/
@ 2011-05-07 3:03 Zac Medico
0 siblings, 0 replies; 3+ messages in thread
From: Zac Medico @ 2011-05-07 3:03 UTC (permalink / raw
To: gentoo-commits
commit: f4ef24e29e2968bd581425198220dce7d6a28bc3
Author: Zac Medico <zmedico <AT> gentoo <DOT> org>
AuthorDate: Sat May 7 03:02:50 2011 +0000
Commit: Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Sat May 7 03:02:50 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=f4ef24e2
preserve-libs: fix linkmap logic for new plibs
Together with commit f36b9fa38b5268c2a5579db62acec026625f84a9,
hopefully this solves bug #366061.
---
pym/portage/dbapi/vartree.py | 18 ++++++++++----
pym/portage/util/_dyn_libs/LinkageMapELF.py | 33 ++++++++++++++++++++++-----
2 files changed, 40 insertions(+), 11 deletions(-)
diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py
index 4170d3d..d8fe7b5 100644
--- a/pym/portage/dbapi/vartree.py
+++ b/pym/portage/dbapi/vartree.py
@@ -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:
diff --git a/pym/portage/util/_dyn_libs/LinkageMapELF.py b/pym/portage/util/_dyn_libs/LinkageMapELF.py
index bbfce88..9e79bd8 100644
--- a/pym/portage/util/_dyn_libs/LinkageMapELF.py
+++ b/pym/portage/util/_dyn_libs/LinkageMapELF.py
@@ -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:
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [gentoo-commits] proj/portage:master commit in: pym/portage/dbapi/, pym/portage/util/_dyn_libs/
@ 2011-05-15 1:57 Zac Medico
0 siblings, 0 replies; 3+ messages in thread
From: Zac Medico @ 2011-05-15 1:57 UTC (permalink / raw
To: gentoo-commits
commit: dc36d802cc1eba7c3d818cebb77e947e930ec2ce
Author: Zac Medico <zmedico <AT> gentoo <DOT> org>
AuthorDate: Sun May 15 01:56:39 2011 +0000
Commit: Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Sun May 15 01:56:39 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=dc36d802
_LibGraphNode: re-use the _key attribute
This allows us to avoid repeating any previous stat calls, which helps
to avoid potential race conditions due to inconsistent stat results
when the file system is being modified concurrently.
---
pym/portage/dbapi/vartree.py | 6 +++---
pym/portage/util/_dyn_libs/LinkageMapELF.py | 13 ++++++++++---
2 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py
index 802253a..d190566 100644
--- a/pym/portage/dbapi/vartree.py
+++ b/pym/portage/dbapi/vartree.py
@@ -2344,7 +2344,7 @@ class dblink(object):
def path_to_node(path):
node = path_node_map.get(path)
if node is None:
- node = LinkageMap._LibGraphNode(path, root)
+ node = LinkageMap._LibGraphNode(linkmap._obj_key(path))
alt_path_node = lib_graph.get(node)
if alt_path_node is not None:
node = alt_path_node
@@ -2499,6 +2499,7 @@ class dblink(object):
# Since preserved libraries can be consumers of other preserved
# libraries, use a graph to track consumer relationships.
plib_dict = self.vartree.dbapi._plib_registry.getPreservedLibs()
+ linkmap = self.vartree.dbapi._linkmap
lib_graph = digraph()
preserved_nodes = set()
preserved_paths = set()
@@ -2509,7 +2510,7 @@ class dblink(object):
def path_to_node(path):
node = path_node_map.get(path)
if node is None:
- node = LinkageMap._LibGraphNode(path, root)
+ node = LinkageMap._LibGraphNode(linkmap._obj_key(path))
alt_path_node = lib_graph.get(node)
if alt_path_node is not None:
node = alt_path_node
@@ -2517,7 +2518,6 @@ class dblink(object):
path_node_map[path] = node
return node
- linkmap = self.vartree.dbapi._linkmap
for cpv, plibs in plib_dict.items():
for f in plibs:
path_cpv_map[f] = cpv
diff --git a/pym/portage/util/_dyn_libs/LinkageMapELF.py b/pym/portage/util/_dyn_libs/LinkageMapELF.py
index fe86a7a..fef75b6 100644
--- a/pym/portage/util/_dyn_libs/LinkageMapELF.py
+++ b/pym/portage/util/_dyn_libs/LinkageMapELF.py
@@ -60,7 +60,7 @@ class LinkageMapELF(object):
"""Helper class used as _obj_properties keys for objects."""
- __slots__ = ("__weakref__", "_key")
+ __slots__ = ("_key",)
def __init__(self, obj, root):
"""
@@ -135,8 +135,15 @@ class LinkageMapELF(object):
class _LibGraphNode(_ObjectKey):
__slots__ = ("alt_paths",)
- def __init__(self, obj, root):
- LinkageMapELF._ObjectKey.__init__(self, obj, root)
+ def __init__(self, key):
+ """
+ Create a _LibGraphNode from an existing _ObjectKey.
+ This re-uses the _key attribute in order to avoid repeating
+ any previous stat calls, which helps to avoid potential race
+ conditions due to inconsistent stat results when the
+ file system is being modified concurrently.
+ """
+ self._key = key._key
self.alt_paths = set()
def __str__(self):
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [gentoo-commits] proj/portage:master commit in: pym/portage/dbapi/, pym/portage/util/_dyn_libs/
@ 2011-07-18 5:30 Zac Medico
0 siblings, 0 replies; 3+ messages in thread
From: Zac Medico @ 2011-07-18 5:30 UTC (permalink / raw
To: gentoo-commits
commit: 296fc63fee262600811520fccf4692f47a39ffba
Author: Zac Medico <zmedico <AT> gentoo <DOT> org>
AuthorDate: Mon Jul 18 05:30:54 2011 +0000
Commit: Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Mon Jul 18 05:30:54 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=296fc63f
preserve-libs: search for alt providers of soname
This will fix bug #289180 by making LinkageMapELF.findconsumers()
exclude consumers from the results in cases when they are satisfied by
an alternative provider of the required soname.
---
pym/portage/dbapi/vartree.py | 3 +-
pym/portage/util/_dyn_libs/LinkageMapELF.py | 58 +++++++++++++++++++++++----
2 files changed, 52 insertions(+), 9 deletions(-)
diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py
index 9efc47f..d61f739 100644
--- a/pym/portage/dbapi/vartree.py
+++ b/pym/portage/dbapi/vartree.py
@@ -2422,7 +2422,8 @@ class dblink(object):
# so we don't try to preserve the old copy.
continue
try:
- consumers = linkmap.findConsumers(f)
+ consumers = linkmap.findConsumers(f,
+ exclude_providers=(installed_instance.isowner,))
except KeyError:
continue
if not consumers:
diff --git a/pym/portage/util/_dyn_libs/LinkageMapELF.py b/pym/portage/util/_dyn_libs/LinkageMapELF.py
index c55d6d6..c8e9acf 100644
--- a/pym/portage/util/_dyn_libs/LinkageMapELF.py
+++ b/pym/portage/util/_dyn_libs/LinkageMapELF.py
@@ -603,7 +603,7 @@ class LinkageMapELF(object):
rValue[soname].add(provider)
return rValue
- def findConsumers(self, obj):
+ def findConsumers(self, obj, exclude_providers=None):
"""
Find consumers of an object or object key.
@@ -626,8 +626,20 @@ class LinkageMapELF(object):
corresponding libtool archive (*.la) files to detect such consumers
(revdep-rebuild is able to detect them).
+ The exclude_providers argument is useful for determining whether
+ removal of one or more packages will create unsatisfied consumers. When
+ this option is given, consumers are excluded from the results if there
+ is an alternative provider (which is not excluded) of the required
+ soname such that the consumers will remain satisfied if the files
+ owned by exclude_providers are removed.
+
@param obj: absolute path to an object or a key from _obj_properties
@type obj: string (example: '/usr/bin/bar') or _ObjectKey
+ @param exclude_providers: A collection of callables that each take a
+ single argument referring to the path of a library (example:
+ '/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
@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.
@@ -636,8 +648,6 @@ class LinkageMapELF(object):
os = _os_merge
- rValue = set()
-
if not self._libs:
self.rebuild()
@@ -672,15 +682,47 @@ class LinkageMapELF(object):
(soname_st.st_dev, soname_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)
+ arch, _needed, _path, soname, _objs = self._obj_properties[obj_key]
+
+ soname_node = None
+ arch_map = self._libs.get(arch)
+ if arch_map is not None:
+ soname_node = arch_map.get(soname)
+
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:
+ relevant_dir_keys = set()
+ for provider_key in soname_node.providers:
+ provider_objs = self._obj_properties[provider_key][4]
+ for p in provider_objs:
+ for excluded in exclude_providers:
+ if not excluded(p):
+ # This provider is not excluded. It will
+ # satisfy a consumer of this soname if it
+ # is in the default ld.so path or the
+ # consumer's runpath.
+ relevant_dir_keys.add(
+ self._path_key(os.path.dirname(p)))
+
+ for consumer_key in soname_node.consumers:
+ _arch, _needed, path, _soname, _consumer_objs = \
+ self._obj_properties[consumer_key]
+ path_keys = defpath_keys.copy()
+ path_keys.update(self._path_key(x) for x in path)
+ if relevant_dir_keys.intersection(path_keys):
+ satisfied_consumer_keys.add(consumer_key)
- arch, _needed, _path, soname, _objs = self._obj_properties[obj_key]
- if arch in self._libs and soname in self._libs[arch]:
+ rValue = set()
+ if soname_node is not None:
# For each potential consumer, add it to rValue if an object from the
# arguments resides in the consumer's runpath.
- for consumer_key in self._libs[arch][soname].consumers:
+ objs_dir_keys = set(self._path_key(os.path.dirname(x))
+ for x in objs)
+ for consumer_key in soname_node.consumers:
+ if consumer_key in satisfied_consumer_keys:
+ continue
_arch, _needed, path, _soname, consumer_objs = \
self._obj_properties[consumer_key]
path_keys = defpath_keys.union(self._path_key(x) for x in path)
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2011-07-18 5:31 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-05-07 3:03 [gentoo-commits] proj/portage:master commit in: pym/portage/dbapi/, pym/portage/util/_dyn_libs/ Zac Medico
-- strict thread matches above, loose matches on Subject: below --
2011-05-15 1:57 Zac Medico
2011-07-18 5:30 Zac Medico
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox