Update portage to create directories atomically.
authorDavid James <davidjames@google.com>
Fri, 13 Aug 2010 20:39:17 +0000 (13:39 -0700)
committerZac Medico <zmedico@gentoo.org>
Wed, 1 Sep 2010 00:48:21 +0000 (17:48 -0700)
Portage should use the ensure_dirs function instead of os.makedirs to create
directories, because this function ensures atomicity. It prevents failures
when more than one process tries to create the same directory.

This fixes a crash bug reported by msb:
[...]
  File "/usr/lib64/portage/pym/portage/dbapi/vartree.py", line 3258, in _merge
    self.vartree.dbapi._bump_mtime(self.mycpv)
  File "/usr/lib64/portage/pym/portage/dbapi/vartree.py", line 152, in _bump_mtime
    os.makedirs(catdir)
  File "/usr/lib64/portage/pym/portage/__init__.py", line 210, in __call__
    rval = self._func(*wrapped_args, **wrapped_kwargs)
  File "/usr/lib64/python2.6/os.py", line 157, in makedirs
    mkdir(name, mode)
OSError: [Errno 17] File exists: '/home/msb/trunk/src/build/images/x86-generic/0.8.63.2010_08_03_1844-a1/rootfs//var/db/pkg/x11-proto'

BUG=chromium-os:5366
TEST=build_packages && build_image

Review URL: http://codereview.chromium.org/3113014

pym/portage/dbapi/vartree.py

index bec7aa1b4f7b74bb8c4bd36df79dcb904addbb7a..923e96297ebe8081697bc066d216ab2a4b53eaf4 100644 (file)
@@ -179,7 +179,7 @@ class vardbapi(dbapi):
                        for x in (catdir, base):
                                os.utime(x, t)
                except OSError:
-                       os.makedirs(catdir)
+                       ensure_dirs(catdir)
 
        def cpv_exists(self, mykey):
                "Tells us whether an actual ebuild exists on disk (no masking)"
@@ -198,7 +198,7 @@ class vardbapi(dbapi):
 
        def cpv_inject(self, mycpv):
                "injects a real package into our on-disk database; assumes mycpv is valid and doesn't already exist"
-               os.makedirs(self.getpath(mycpv))
+               ensure_dirs(self.getpath(mycpv))
                counter = self.counter_tick(mycpv=mycpv)
                # write local package counter so that emerge clean does the right thing
                write_atomic(self.getpath(mycpv, filename="COUNTER"), str(counter))
@@ -239,7 +239,7 @@ class vardbapi(dbapi):
                        moves += 1
                        if not os.path.exists(self.getpath(mynewcat)):
                                #create the directory
-                               os.makedirs(self.getpath(mynewcat))
+                               ensure_dirs(self.getpath(mynewcat))
                        newpath = self.getpath(mynewcpv)
                        if os.path.exists(newpath):
                                #dest already exists; keep this puppy where it is.
@@ -2846,7 +2846,7 @@ class dblink(object):
                        self._eerror("preinst", lines)
 
                if not os.path.exists(self.dbcatdir):
-                       os.makedirs(self.dbcatdir)
+                       ensure_dirs(self.dbcatdir)
 
                otherversions = []
                for v in self.vartree.dbapi.cp_list(self.mysplit[0]):