There was a race inside fs_template._ensure_dirs which could cause it to
raise EEXIST if a concurrent process created the directory after
os.path.exists returned False. Fix it by using the util.ensure_dirs
function, which already handles EEXIST.

X-Gentoo-Bug: 529120
X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=529120
---
 pym/portage/cache/fs_template.py | 25 ++++++++++---------------
 1 file changed, 10 insertions(+), 15 deletions(-)

diff --git a/pym/portage/cache/fs_template.py b/pym/portage/cache/fs_template.py
index de4fe4b..fa44abc 100644
--- a/pym/portage/cache/fs_template.py
+++ b/pym/portage/cache/fs_template.py
@@ -10,7 +10,7 @@ from portage import os
 from portage.proxy.lazyimport import lazyimport
 lazyimport(globals(),
        'portage.exception:PortageException',
-       'portage.util:apply_permissions',
+       'portage.util:apply_permissions,ensure_dirs',
 )
 del lazyimport
 
@@ -61,20 +61,15 @@ class FsBased(template.database):
 
                for dir in 
path.lstrip(os.path.sep).rstrip(os.path.sep).split(os.path.sep):
                        base = os.path.join(base,dir)
-                       if not os.path.exists(base):
-                               if self._perms != -1:
-                                       um = os.umask(0)
-                               try:
-                                       perms = self._perms
-                                       if perms == -1:
-                                               perms = 0
-                                       perms |= 0o755
-                                       os.mkdir(base, perms)
-                                       if self._gid != -1:
-                                               os.chown(base, -1, self._gid)
-                               finally:
-                                       if self._perms != -1:
-                                               os.umask(um)
+                       if ensure_dirs(base):
+                               # We only call apply_permissions if ensure_dirs 
created
+                               # a new directory, so as not to interfere with
+                               # permissions of existing directories.
+                               mode = self._perms
+                               if mode == -1:
+                                       mode = 0
+                               mode |= 0o755
+                               apply_permissions(base, mode=mode, 
gid=self._gid)
 
        def _prune_empty_dirs(self):
                all_dirs = []
-- 
2.0.4


Reply via email to