commit:     9f6967dbc38ea55c0de5fbf5ad663ca676c54743
Author:     Zac Medico <zmedico <AT> gentoo <DOT> org>
AuthorDate: Thu Nov 13 19:35:48 2014 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Fri Nov 14 17:30:31 2014 +0000
URL:        
http://sources.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=9f6967db

fs_template._ensure_dirs: handle EEXIST (529120)

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
Acked-by: Alexander Berntsen <bernalex <AT> gentoo.org>

---
 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 = []

Reply via email to