All of lore.kernel.org
 help / color / mirror / Atom feed
From: Richard Purdie <richard.purdie@linuxfoundation.org>
To: Mike Crowe <mac@mcrowe.com>
Cc: openembedded-core@lists.openembedded.org
Subject: Re: [PATCH 1/2] image.py: avoid mkdir race when building multiple images
Date: Thu, 19 Nov 2015 11:23:47 +0000	[thread overview]
Message-ID: <1447932227.12500.121.camel@linuxfoundation.org> (raw)
In-Reply-To: <1447932037-29676-1-git-send-email-mac@mcrowe.com>

On Thu, 2015-11-19 at 11:20 +0000, Mike Crowe wrote:
> 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'
> 
> os.makedirs protects against racing on parent directories but not on the
> final part.
> 
> The sysroot directory will already exist so let's just try and make the
> imgdata directory and cope with the exception thrown if it already
> exists. This stops the race being fatal.
> 
> Once the directory has been created, there's no race on the actual file
> since the filename contains IMAGE_BASENAME.
> 
> Signed-off-by: Mike Crowe <mac@mcrowe.com>
> ---
>  meta/lib/oe/image.py | 13 +++++++++++--
>  1 file changed, 11 insertions(+), 2 deletions(-)
> 
> diff --git a/meta/lib/oe/image.py b/meta/lib/oe/image.py
> index b9eb3de..8c797ec 100644
> --- a/meta/lib/oe/image.py
> +++ b/meta/lib/oe/image.py
> @@ -1,5 +1,6 @@
>  from oe.utils import execute_pre_post_process
>  import os
> +import errno
>  import subprocess
>  import multiprocessing
>  
> @@ -337,8 +338,16 @@ 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)
> +        try:
> +            # This may race against another image being created, so
> +            # let's just try and create the directory and just ignore
> +            # the error if it already exists. The parent directory
> +            # will already exist so there's no benefit to using
> +            # os.makedirs (which is also subject to the race.)
> +            os.mkdir(outdir)
> +        except OSError as e:
> +            if e.errno != errno.EEXIST:
> +                raise
>          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():

How about using bb.utils.mkdirhier() which already does this?

Cheers,

Richard




  reply	other threads:[~2015-11-19 11:24 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-11-19 11:20 [PATCH 1/2] image.py: avoid mkdir race when building multiple images Mike Crowe
2015-11-19 11:23 ` Richard Purdie [this message]
2015-11-19 11:50   ` Mike Crowe

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1447932227.12500.121.camel@linuxfoundation.org \
    --to=richard.purdie@linuxfoundation.org \
    --cc=mac@mcrowe.com \
    --cc=openembedded-core@lists.openembedded.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.