Gentoo Archives: gentoo-commits

From: "Fabian Groffen (grobian)" <grobian@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] portage r11754 - in main/branches/prefix: bin pym/_emerge pym/portage/dbapi
Date: Thu, 30 Oct 2008 21:13:39
Message-Id: E1KvepY-0005KR-3H@stork.gentoo.org
1 Author: grobian
2 Date: 2008-10-30 21:13:23 +0000 (Thu, 30 Oct 2008)
3 New Revision: 11754
4
5 Modified:
6 main/branches/prefix/bin/repoman
7 main/branches/prefix/pym/_emerge/__init__.py
8 main/branches/prefix/pym/portage/dbapi/vartree.py
9 Log:
10 Merged from trunk -r11745:11753
11
12 | 11746 | Bug #225429 - In dblink.unmerge(), eliminate consumers |
13 | zmedico | having providers with the same soname as an installed |
14 | | library that is not preserved. This eliminates libraries |
15 | | that are erroneously preserved due to a move from one |
16 | | directory to another. |
17
18 | 11747 | In dblink.unmerge(), update the CONTENTS entries when |
19 | zmedico | preserved libs are removed. |
20
21 | 11748 | Bug # 225429 - Try to remove unneeded preserved libs just |
22 | zmedico | before returning from dblink.treewalk(), after the library |
23 | | path has been updated. This is intended to remove unneeded |
24 | | preserved libs after a gcc upgrade. TODO: Figure out why |
25 | | libgomp.so.1 still isn't properly removed. |
26
27 | 11749 | Bug #225429 - Inside LinkageMap.rebuild(), update |
28 | zmedico | self._defpath since it can change during a gcc upgrade. |
29
30 | 11751 | define myunadded such that repoman doesn't crash when being |
31 | zmedico | run in a non-{cvs,svn} dir (branches/prefix r11750) |
32
33 | 11752 | Avoid unnecessary aux_get calls inside Scheduler._pkg() by |
34 | zmedico | getting the existing Package instance from the digraph. |
35
36 | 11753 | Make sure mychanged and mynew are always defined even if |
37 | zmedico | there is no vcs because commit mode is allowed without a vcs |
38 | | in pretend mode. |
39
40
41 Modified: main/branches/prefix/bin/repoman
42 ===================================================================
43 --- main/branches/prefix/bin/repoman 2008-10-30 20:33:57 UTC (rev 11753)
44 +++ main/branches/prefix/bin/repoman 2008-10-30 21:13:23 UTC (rev 11754)
45 @@ -748,6 +748,8 @@
46
47 new_ebuilds = set()
48 modified_changelogs = set()
49 +mychanged = []
50 +mynew = []
51 if vcs == "cvs":
52 mycvstree = cvstree.getentries("./", recursive=1)
53 mychanged = cvstree.findchanged(mycvstree, recursive=1, basedir="./")
54
55 Modified: main/branches/prefix/pym/_emerge/__init__.py
56 ===================================================================
57 --- main/branches/prefix/pym/_emerge/__init__.py 2008-10-30 20:33:57 UTC (rev 11753)
58 +++ main/branches/prefix/pym/_emerge/__init__.py 2008-10-30 21:13:23 UTC (rev 11754)
59 @@ -10387,6 +10387,13 @@
60 if installed:
61 operation = "nomerge"
62
63 + if self._digraph is not None:
64 + # Reuse existing instance when available.
65 + pkg = self._digraph.get(
66 + (type_name, root_config.root, cpv, operation))
67 + if pkg is not None:
68 + return pkg
69 +
70 tree_type = depgraph.pkg_tree_map[type_name]
71 db = root_config.trees[tree_type].dbapi
72 db_keys = list(self.trees[root_config.root][
73 @@ -10399,10 +10406,6 @@
74 settings.setcpv(pkg)
75 pkg.metadata["USE"] = settings["PORTAGE_USE"]
76
77 - if self._digraph is not None:
78 - # Reuse existing instance when available.
79 - pkg = self._digraph.get(pkg, pkg)
80 -
81 return pkg
82
83 class MetadataRegen(PollScheduler):
84
85 Modified: main/branches/prefix/pym/portage/dbapi/vartree.py
86 ===================================================================
87 --- main/branches/prefix/pym/portage/dbapi/vartree.py 2008-10-30 20:33:57 UTC (rev 11753)
88 +++ main/branches/prefix/pym/portage/dbapi/vartree.py 2008-10-30 21:13:23 UTC (rev 11754)
89 @@ -220,6 +220,7 @@
90
91 def rebuild(self, exclude_pkgs=None, include_file=None):
92 root = self._root
93 + self._defpath = set(getlibpaths(root))
94 libs = {}
95 obj_key_cache = {}
96 obj_properties = {}
97 @@ -480,6 +481,11 @@
98 """
99 if not self._libs:
100 self.rebuild()
101 + if isinstance(obj, self._ObjectKey):
102 + obj_key = obj
103 + if obj_key not in self._obj_properties:
104 + raise KeyError("%s not in object list" % obj_key)
105 + return self._obj_properties[obj_key][3]
106 if obj not in self._obj_key_cache:
107 raise KeyError("%s not in object list" % obj)
108 return self._obj_properties[self._obj_key_cache[obj]][3]
109 @@ -930,6 +936,11 @@
110 """
111 if not self._libs:
112 self.rebuild()
113 + if isinstance(obj, self._ObjectKey):
114 + obj_key = obj
115 + if obj_key not in self._obj_properties:
116 + raise KeyError("%s not in object list" % obj_key)
117 + return self._obj_properties[obj_key][2]
118 if obj not in self._obj_key_cache:
119 raise KeyError("%s not in object list" % obj)
120 return self._obj_properties[self._obj_key_cache[obj]][2]
121 @@ -2393,61 +2404,21 @@
122 self.vartree.dbapi.linkmap.rebuild(exclude_pkgs=(self.mycpv,))
123
124 # remove preserved libraries that don't have any consumers left
125 - # Since preserved libraries can be consumers of other preserved
126 - # libraries, use a graph to track consumer relationships.
127 - plib_dict = plib_registry.getPreservedLibs()
128 - lib_graph = digraph()
129 - preserved_nodes = set()
130 - root = self.myroot
131 - for plibs in plib_dict.itervalues():
132 - for f in plibs:
133 - preserved_node = LinkageMap._LibGraphNode(f, root)
134 - if not preserved_node.file_exists():
135 + cpv_lib_map = self._find_unused_preserved_libs()
136 + if cpv_lib_map:
137 + self._remove_preserved_libs(cpv_lib_map)
138 + for cpv, removed in cpv_lib_map.iteritems():
139 + if not self.vartree.dbapi.cpv_exists(cpv):
140 + for dblnk in others_in_slot:
141 + if dblnk.mycpv == cpv:
142 + # This one just got merged so it doesn't
143 + # register with cpv_exists() yet.
144 + self.vartree.dbapi.removeFromContents(
145 + dblnk, removed)
146 + break
147 continue
148 - existing_node = lib_graph.get(preserved_node)
149 - if existing_node is not None:
150 - preserved_node = existing_node
151 - else:
152 - lib_graph.add(preserved_node, None)
153 - preserved_node.alt_paths.add(f)
154 - preserved_nodes.add(preserved_node)
155 - for c in self.vartree.dbapi.linkmap.findConsumers(f):
156 - consumer_node = LinkageMap._LibGraphNode(c, root)
157 - if not consumer_node.file_exists():
158 - continue
159 - # Note that consumers may also be providers.
160 - existing_node = lib_graph.get(consumer_node)
161 - if existing_node is not None:
162 - consumer_node = existing_node
163 - consumer_node.alt_paths.add(c)
164 - lib_graph.add(preserved_node, consumer_node)
165 + self.vartree.dbapi.removeFromContents(cpv, removed)
166
167 - while not lib_graph.empty():
168 - root_nodes = preserved_nodes.intersection(lib_graph.root_nodes())
169 - if not root_nodes:
170 - break
171 - lib_graph.difference_update(root_nodes)
172 - unlink_list = set()
173 - for node in root_nodes:
174 - unlink_list.update(node.alt_paths)
175 - unlink_list = sorted(unlink_list)
176 - for obj in unlink_list:
177 - obj = os.path.join(root, obj.lstrip(os.sep))
178 - if os.path.islink(obj):
179 - obj_type = "sym"
180 - else:
181 - obj_type = "obj"
182 - try:
183 - os.unlink(obj)
184 - except OSError, e:
185 - if e.errno != errno.ENOENT:
186 - raise
187 - del e
188 - else:
189 - showMessage("<<< !needed %s %s\n" % (obj_type, obj))
190 -
191 - plib_registry.pruneNonExisting()
192 -
193 finally:
194 if builddir_lock:
195 try:
196 @@ -3023,8 +2994,143 @@
197 # keep track of the libs we preserved
198 self.vartree.dbapi.plib_registry.register(self.mycpv, self.settings["SLOT"], counter, preserve_paths)
199
200 - del preserve_paths
201 -
202 + def _find_unused_preserved_libs(self):
203 + """
204 + Find preserved libraries that don't have any consumers left.
205 + """
206 +
207 + # Since preserved libraries can be consumers of other preserved
208 + # libraries, use a graph to track consumer relationships.
209 + plib_dict = self.vartree.dbapi.plib_registry.getPreservedLibs()
210 + lib_graph = digraph()
211 + preserved_nodes = set()
212 + preserved_paths = set()
213 + path_cpv_map = {}
214 + path_node_map = {}
215 + root = self.myroot
216 +
217 + def path_to_node(path):
218 + node = path_node_map.get(path)
219 + if node is None:
220 + node = LinkageMap._LibGraphNode(path, root)
221 + alt_path_node = lib_graph.get(node)
222 + if alt_path_node is not None:
223 + node = alt_path_node
224 + node.alt_paths.add(path)
225 + path_node_map[path] = node
226 + return node
227 +
228 + linkmap = self.vartree.dbapi.linkmap
229 + for cpv, plibs in plib_dict.iteritems():
230 + for f in plibs:
231 + path_cpv_map[f] = cpv
232 + preserved_node = path_to_node(f)
233 + if not preserved_node.file_exists():
234 + continue
235 + lib_graph.add(preserved_node, None)
236 + preserved_paths.add(f)
237 + preserved_nodes.add(preserved_node)
238 + for c in self.vartree.dbapi.linkmap.findConsumers(f):
239 + consumer_node = path_to_node(c)
240 + if not consumer_node.file_exists():
241 + continue
242 + # Note that consumers may also be providers.
243 + lib_graph.add(preserved_node, consumer_node)
244 +
245 + # Eliminate consumers having providers with the same soname as an
246 + # installed library that is not preserved. This eliminates
247 + # libraries that are erroneously preserved due to a move from one
248 + # directory to another.
249 + provider_cache = {}
250 + for preserved_node in preserved_nodes:
251 + soname = linkmap.getSoname(preserved_node)
252 + for consumer_node in lib_graph.parent_nodes(preserved_node):
253 + if consumer_node in preserved_nodes:
254 + continue
255 + providers = provider_cache.get(consumer_node)
256 + if providers is None:
257 + providers = linkmap.findProviders(consumer_node)
258 + provider_cache[consumer_node] = providers
259 + providers = providers.get(soname)
260 + if providers is None:
261 + continue
262 + for provider in providers:
263 + if provider in preserved_paths:
264 + continue
265 + provider_node = path_to_node(provider)
266 + if not provider_node.file_exists():
267 + continue
268 + if provider_node in preserved_nodes:
269 + continue
270 + # An alternative provider seems to be
271 + # installed, so drop this edge.
272 + lib_graph.remove_edge(preserved_node, consumer_node)
273 + break
274 +
275 + cpv_lib_map = {}
276 + while not lib_graph.empty():
277 + root_nodes = preserved_nodes.intersection(lib_graph.root_nodes())
278 + if not root_nodes:
279 + break
280 + lib_graph.difference_update(root_nodes)
281 + unlink_list = set()
282 + for node in root_nodes:
283 + unlink_list.update(node.alt_paths)
284 + unlink_list = sorted(unlink_list)
285 + for obj in unlink_list:
286 + cpv = path_cpv_map[obj]
287 + removed = cpv_lib_map.get(cpv)
288 + if removed is None:
289 + removed = set()
290 + cpv_lib_map[cpv] = removed
291 + removed.add(obj)
292 +
293 + return cpv_lib_map
294 +
295 + def _remove_preserved_libs(self, cpv_lib_map):
296 + """
297 + Remove files returned from _find_unused_preserved_libs().
298 + """
299 +
300 + files_to_remove = set()
301 + for files in cpv_lib_map.itervalues():
302 + files_to_remove.update(files)
303 + files_to_remove = sorted(files_to_remove)
304 + showMessage = self._display_merge
305 + root = self.myroot
306 +
307 + parent_dirs = set()
308 + for obj in files_to_remove:
309 + obj = os.path.join(root, obj.lstrip(os.sep))
310 + parent_dirs.add(os.path.dirname(obj))
311 + if os.path.islink(obj):
312 + obj_type = "sym"
313 + else:
314 + obj_type = "obj"
315 + try:
316 + os.unlink(obj)
317 + except OSError, e:
318 + if e.errno != errno.ENOENT:
319 + raise
320 + del e
321 + else:
322 + showMessage("<<< !needed %s %s\n" % (obj_type, obj))
323 +
324 + # Remove empty parent directories if possible.
325 + while parent_dirs:
326 + x = parent_dirs.pop()
327 + while True:
328 + try:
329 + os.rmdir(x)
330 + except OSError:
331 + break
332 + prev = x
333 + x = os.path.dirname(x)
334 + if x == prev:
335 + break
336 +
337 + self.vartree.dbapi.plib_registry.pruneNonExisting()
338 +
339 def _collision_protect(self, srcroot, destroot, mypkglist, mycontents):
340 collision_ignore = set([normalize_path(myignore) for myignore in \
341 shlex.split(self.settings.get("COLLISION_IGNORE", ""))])
342 @@ -3680,6 +3786,17 @@
343 contents=contents, env=self.settings.environ(),
344 writemsg_level=self._display_merge)
345
346 + # For gcc upgrades, preserved libs have to be removed after the
347 + # the library path has been updated.
348 + self.vartree.dbapi.linkmap.rebuild()
349 + cpv_lib_map = self._find_unused_preserved_libs()
350 + if cpv_lib_map:
351 + self._remove_preserved_libs(cpv_lib_map)
352 + for cpv, removed in cpv_lib_map.iteritems():
353 + if not self.vartree.dbapi.cpv_exists(cpv):
354 + continue
355 + self.vartree.dbapi.removeFromContents(cpv, removed)
356 +
357 return os.EX_OK
358
359 def mergeme(self, srcroot, destroot, outfile, secondhand, stufftomerge, cfgfiledict, thismtime):