Gentoo Archives: gentoo-commits

From: "Zac Medico (zmedico)" <zmedico@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] portage r11766 - main/trunk/pym/portage/dbapi
Date: Fri, 31 Oct 2008 20:21:56
Message-Id: E1Kw0VF-0007Nu-Ha@stork.gentoo.org
1 Author: zmedico
2 Date: 2008-10-31 20:21:53 +0000 (Fri, 31 Oct 2008)
3 New Revision: 11766
4
5 Modified:
6 main/trunk/pym/portage/dbapi/vartree.py
7 Log:
8 Bug #243178 - Handle file collisions with preserved libs by allowing the
9 current package to assume ownership and unregistering the preserved libraries.
10
11
12 Modified: main/trunk/pym/portage/dbapi/vartree.py
13 ===================================================================
14 --- main/trunk/pym/portage/dbapi/vartree.py 2008-10-31 18:49:10 UTC (rev 11765)
15 +++ main/trunk/pym/portage/dbapi/vartree.py 2008-10-31 20:21:53 UTC (rev 11766)
16 @@ -2681,6 +2681,18 @@
17 collision_ignore = set([normalize_path(myignore) for myignore in \
18 shlex.split(self.settings.get("COLLISION_IGNORE", ""))])
19
20 + # For collisions with preserved libraries, the current package
21 + # will assume ownership and the libraries will be unregistered.
22 + plib_dict = self.vartree.dbapi.plib_registry.getPreservedLibs()
23 + plib_cpv_map = {}
24 + plib_paths = set()
25 + for cpv, paths in plib_dict.iteritems():
26 + plib_paths.update(paths)
27 + for f in paths:
28 + plib_cpv_map[f] = cpv
29 + plib_inodes = self._lstat_inode_map(plib_paths)
30 + plib_collisions = {}
31 +
32 showMessage = self._display_merge
33 scheduler = self._scheduler
34 stopmerge = False
35 @@ -2732,6 +2744,21 @@
36 raise
37 if f[0] != "/":
38 f="/"+f
39 +
40 + plibs = plib_inodes.get((dest_lstat.st_dev, dest_lstat.st_ino))
41 + if plibs:
42 + for path in plibs:
43 + cpv = plib_cpv_map[path]
44 + paths = plib_collisions.get(cpv)
45 + if paths is None:
46 + paths = set()
47 + plib_collisions[cpv] = paths
48 + paths.add(path)
49 + # The current package will assume ownership and the
50 + # libraries will be unregistered, so exclude this
51 + # path from the normal collisions.
52 + continue
53 +
54 isowned = False
55 full_path = os.path.join(destroot, f.lstrip(os.path.sep))
56 for ver in mypkglist:
57 @@ -2752,8 +2779,34 @@
58 break
59 if stopmerge:
60 collisions.append(f)
61 - return collisions
62 + return collisions, plib_collisions
63
64 + def _lstat_inode_map(self, path_iter):
65 + """
66 + Use lstat to create a map of the form:
67 + {(st_dev, st_ino) : set([path1, path2, ...])}
68 + Multiple paths may reference the same inode due to hardlinks.
69 + All lstat() calls are relative to self.myroot.
70 + """
71 + root = self.myroot
72 + inode_map = {}
73 + for f in path_iter:
74 + path = os.path.join(root, f.lstrip(os.sep))
75 + try:
76 + st = os.lstat(path)
77 + except OSError, e:
78 + if e.errno not in (errno.ENOENT, errno.ENOTDIR):
79 + raise
80 + del e
81 + continue
82 + key = (st.st_dev, st.st_ino)
83 + paths = inode_map.get(key)
84 + if paths is None:
85 + paths = set()
86 + inode_map[key] = paths
87 + paths.add(f)
88 + return inode_map
89 +
90 def _security_check(self, installed_instances):
91 if not installed_instances:
92 return 0
93 @@ -3011,7 +3064,8 @@
94 blockers = self._blockers()
95 if blockers is None:
96 blockers = []
97 - collisions = self._collision_protect(srcroot, destroot,
98 + collisions, plib_collisions = \
99 + self._collision_protect(srcroot, destroot,
100 others_in_slot + blockers, myfilelist + mylinklist)
101
102 # Make sure the ebuild environment is initialized and that ${T}/elog
103 @@ -3289,6 +3343,24 @@
104 self.vartree.dbapi.removeFromContents(blocker, iter(contents),
105 relative_paths=False)
106
107 + # Unregister any preserved libs that this package has overwritten
108 + # and update the contents of the packages that owned them.
109 + plib_registry = self.vartree.dbapi.plib_registry
110 + plib_dict = plib_registry.getPreservedLibs()
111 + for cpv, paths in plib_collisions.iteritems():
112 + if cpv not in plib_dict:
113 + continue
114 + if cpv == self.mycpv:
115 + continue
116 + try:
117 + slot, counter = self.vartree.dbapi.aux_get(
118 + cpv, ["SLOT", "COUNTER"])
119 + except KeyError:
120 + continue
121 + remaining = [f for f in plib_dict[cpv] if f not in paths]
122 + plib_registry.register(cpv, slot, counter, remaining)
123 + self.vartree.dbapi.removeFromContents(cpv, paths)
124 +
125 self.vartree.dbapi._add(self)
126 contents = self.getcontents()