1 |
On Sun, 26 Apr 2015 21:30:28 -0700 |
2 |
Zac Medico <zmedico@g.o> wrote: |
3 |
|
4 |
> The ro_checker code added in commit |
5 |
> 47ef9a0969474f963dc8e52bfbbb8bc075e8d73c incorrectly asserts that all |
6 |
> parent directories be writable. Fix it to only assert that the nearest |
7 |
> parent directory be writable. |
8 |
> |
9 |
> Fixes 47ef9a096947: ("Test for read-only filesystems, fixes bug |
10 |
> 378869") X-Gentoo-Bug: 547390 |
11 |
> X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=547390 |
12 |
> --- |
13 |
> [PATCH v3] fixes writeable_check to return paths from mountinfo |
14 |
> |
15 |
> pym/portage/dbapi/vartree.py | 44 |
16 |
> +++++++++++++++++++++---------------- |
17 |
> pym/portage/util/writeable_check.py | 24 ++++++++++++++++++-- 2 files |
18 |
> changed, 47 insertions(+), 21 deletions(-) |
19 |
> |
20 |
> diff --git a/pym/portage/dbapi/vartree.py |
21 |
> b/pym/portage/dbapi/vartree.py index 1c0deab..c59d778 100644 |
22 |
> --- a/pym/portage/dbapi/vartree.py |
23 |
> +++ b/pym/portage/dbapi/vartree.py |
24 |
> @@ -33,7 +33,7 @@ portage.proxy.lazyimport.lazyimport(globals(), |
25 |
> 'portage.util.env_update:env_update', |
26 |
> 'portage.util.listdir:dircache,listdir', |
27 |
> 'portage.util.movefile:movefile', |
28 |
> - 'portage.util.path:first_existing', |
29 |
> + 'portage.util.path:first_existing,iter_parents', |
30 |
> 'portage.util.writeable_check:get_ro_checker', |
31 |
> 'portage.util._dyn_libs.PreservedLibsRegistry:PreservedLibsRegistry', |
32 |
> 'portage.util._dyn_libs.LinkageMapELF:LinkageMapELF@LinkageMap', |
33 |
> @@ -3325,6 +3325,8 @@ class dblink(object): |
34 |
> showMessage = self._display_merge |
35 |
> stopmerge = False |
36 |
> collisions = [] |
37 |
> + dirs = set() |
38 |
> + dirs_ro = set() |
39 |
> symlink_collisions = [] |
40 |
> destroot = self.settings['ROOT'] |
41 |
> showMessage(_(" %s checking %d files for |
42 |
> package collisions\n") % \ @@ -3337,6 +3339,18 @@ class |
43 |
> dblink(object): |
44 |
> dest_path = normalize_path( |
45 |
> os.path.join(destroot, |
46 |
> f.lstrip(os.path.sep))) + |
47 |
> + parent = os.path.dirname(dest_path) |
48 |
> + if parent not in dirs: |
49 |
> + for x in |
50 |
> iter_parents(parent): |
51 |
> + if x in dirs: |
52 |
> + break |
53 |
> + dirs.add(x) |
54 |
> + if os.path.isdir(x): |
55 |
> + if not |
56 |
> os.access(x, os.W_OK): |
57 |
> + |
58 |
> dirs_ro.add(x) |
59 |
> + break |
60 |
> + |
61 |
> try: |
62 |
> dest_lstat = |
63 |
> os.lstat(dest_path) except EnvironmentError as e: |
64 |
> @@ -3410,7 +3424,7 @@ class dblink(object): |
65 |
> break |
66 |
> if stopmerge: |
67 |
> collisions.append(f) |
68 |
> - return collisions, symlink_collisions, |
69 |
> plib_collisions |
70 |
> + return collisions, dirs_ro, |
71 |
> symlink_collisions, plib_collisions |
72 |
> def _lstat_inode_map(self, path_iter): |
73 |
> """ |
74 |
> @@ -3759,7 +3773,6 @@ class dblink(object): |
75 |
> eagain_error = False |
76 |
> |
77 |
> filelist = [] |
78 |
> - dirlist = [] |
79 |
> linklist = [] |
80 |
> paths_with_newlines = [] |
81 |
> def onerror(e): |
82 |
> @@ -3792,13 +3805,6 @@ class dblink(object): |
83 |
> unicode_errors.append(new_parent[ed_len:]) |
84 |
> break |
85 |
> |
86 |
> - relative_path = parent[srcroot_len:] |
87 |
> - if len(relative_path) >= eprefix_len: |
88 |
> - # Files are never installed |
89 |
> outside of the prefix, |
90 |
> - # therefore we skip the |
91 |
> readonly filesystem check for |
92 |
> - # parent directories of the |
93 |
> prefix (see bug 544624). |
94 |
> - |
95 |
> dirlist.append(os.path.join(destroot, relative_path)) - |
96 |
> for fname in files: |
97 |
> try: |
98 |
> fname = |
99 |
> _unicode_decode(fname, @@ -3911,9 +3917,17 @@ class dblink(object): |
100 |
> for other in others_in_slot]) |
101 |
> prepare_build_dirs(settings=self.settings, |
102 |
> cleanup=cleanup) |
103 |
> + # check for package collisions |
104 |
> + blockers = self._blockers |
105 |
> + if blockers is None: |
106 |
> + blockers = [] |
107 |
> + collisions, dirs_ro, symlink_collisions, |
108 |
> plib_collisions = \ |
109 |
> + self._collision_protect(srcroot, destroot, |
110 |
> + others_in_slot + blockers, filelist, |
111 |
> linklist) + |
112 |
> # Check for read-only filesystems. |
113 |
> ro_checker = get_ro_checker() |
114 |
> - rofilesystems = ro_checker(dirlist) |
115 |
> + rofilesystems = ro_checker(dirs_ro) |
116 |
> |
117 |
> if rofilesystems: |
118 |
> msg = _("One or more files installed to this |
119 |
> package are " @@ -3935,14 +3949,6 @@ class dblink(object): |
120 |
> eerror(msg) |
121 |
> return 1 |
122 |
> |
123 |
> - # check for package collisions |
124 |
> - blockers = self._blockers |
125 |
> - if blockers is None: |
126 |
> - blockers = [] |
127 |
> - collisions, symlink_collisions, plib_collisions = \ |
128 |
> - self._collision_protect(srcroot, destroot, |
129 |
> - others_in_slot + blockers, filelist, |
130 |
> linklist) - |
131 |
> if symlink_collisions: |
132 |
> # Symlink collisions need to be |
133 |
> distinguished from other types # of collisions, in order to avoid |
134 |
> confusion (see bug #409359). diff --git |
135 |
> a/pym/portage/util/writeable_check.py |
136 |
> b/pym/portage/util/writeable_check.py index 445b2c2..ac6c039 100644 |
137 |
> --- a/pym/portage/util/writeable_check.py +++ |
138 |
> b/pym/portage/util/writeable_check.py @@ -1,5 +1,5 @@ |
139 |
> #-*- coding:utf-8 -*- |
140 |
> -# Copyright 2014 Gentoo Foundation |
141 |
> +# Copyright 2014-2015 Gentoo Foundation |
142 |
> # Distributed under the terms of the GNU General Public License v2 |
143 |
> """ |
144 |
> Methods to check whether Portage is going to write to read-only |
145 |
> filesystems. @@ -13,6 +13,7 @@ from __future__ import unicode_literals |
146 |
> |
147 |
> import io |
148 |
> import logging |
149 |
> +import os |
150 |
> |
151 |
> from portage import _encodings |
152 |
> from portage.util import writemsg_level |
153 |
> @@ -68,7 +69,26 @@ def linux_ro_checker(dir_list): |
154 |
> level=logging.WARNING, noiselevel=-1) |
155 |
> return [] |
156 |
> |
157 |
> - return set.intersection(ro_filesystems, set(dir_list)) |
158 |
> + ro_devs = {} |
159 |
> + for x in ro_filesystems: |
160 |
> + try: |
161 |
> + ro_devs[os.stat(x).st_dev] = x |
162 |
> + except OSError: |
163 |
> + pass |
164 |
> + |
165 |
> + ro_filesystems.clear() |
166 |
> + for x in set(dir_list): |
167 |
> + try: |
168 |
> + dev = os.stat(x).st_dev |
169 |
> + except OSError: |
170 |
> + pass |
171 |
> + else: |
172 |
> + try: |
173 |
> + ro_filesystems.add(ro_devs[dev]) |
174 |
> + except KeyError: |
175 |
> + pass |
176 |
> + |
177 |
> + return ro_filesystems |
178 |
> |
179 |
> |
180 |
> def empty_ro_checker(dir_list): |
181 |
|
182 |
looks fine |
183 |
|
184 |
-- |
185 |
Brian Dolbec <dolsen> |