Skip to contentSkip to conversation

image.py: avoid mkdir race when building multiple images

PATCH New Mike Crowe 1 participant 1 message Nov 19, 2015

lore
Share & tools
lore

Mike Crowe

author
#0 lore raw

PATCH v2 1/1 image.py: avoid mkdir race when building multiple images

If multiple images are being built simultaneously against the same sysroot then the call to os.makedirs in Image._write_wic_env can fail with:

File: '.../meta/lib/oe/image.py', lineno: 341, function: _write_wic_env

     0337:        """
     0338:        stdir = self.d.getVar('STAGING_DIR_TARGET', True)
     0339:        outdir = os.path.join(stdir, 'imgdata')
     0340:        if not os.path.exists(outdir):

*** 0341: os.makedirs(outdir)
0342: basename = self.d.getVar('IMAGE_BASENAME', True)
0343: with open(os.path.join(outdir, basename) + '.env', 'w') as envf:
0344: for var in self.d.getVar('WICVARS', True).split():
0345: value = self.d.getVar(var, True)
File: '/usr/lib/python2.7/os.py', lineno: 157, function: makedirs

     0153:            if e.errno != errno.EEXIST:
     0154:                raise
     0155:        if tail == curdir:           # xxx/newdir/. exists if xxx/newdir exists
     0156:            return
 *** 0157:    mkdir(name, mode)
     0158:
     0159:def removedirs(name):
     0160:    """removedirs(path)
     0161:

Exception: OSError: [Errno 17] File exists: '.../tmp-glibc/sysroots/cheetah/imgdata'

Using bb.utils.mkdirhier() protects against this.

There's also little point in checking to see if the directory already exists - we might as well just try and create it regardless.

Once the directory has been created, there's no race on the actual file since the filename contains IMAGE_BASENAME.

---
 meta/lib/oe/image.py | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
meta/lib/oe/image.py +1 -2
index b9eb3de..17b096d 100644
@@ -337,8 +337,7 @@ class Image(ImageDepGraph):
         """
         stdir = self.d.getVar('STAGING_DIR_TARGET', True)
         outdir = os.path.join(stdir, 'imgdata')
-        if not os.path.exists(outdir):
-            os.makedirs(outdir)
+        bb.utils.mkdirhier(outdir)
         basename = self.d.getVar('IMAGE_BASENAME', True)
         with open(os.path.join(outdir, basename) + '.env', 'w') as envf:
             for var in self.d.getVar('WICVARS', True).split():
Signature · 1 line
2.1.4