Openembedded Core Discussions
 help / color / mirror / Atom feed
From: Richard Purdie <richard.purdie@linuxfoundation.org>
To: Peter Kjellerstedt <peter.kjellerstedt@axis.com>,
	openembedded-core@lists.openembedded.org
Subject: Re: [PATCH 1/1] fetch2: Create/replace symbolic links atomically
Date: Tue, 28 Mar 2017 13:44:03 +0100	[thread overview]
Message-ID: <1490705043.13980.277.camel@linuxfoundation.org> (raw)
In-Reply-To: <c03b3d4d91d37d2b620230fe29158478fe985afe.1490704144.git.pkj@axis.com>

On Tue, 2017-03-28 at 14:30 +0200, Peter Kjellerstedt wrote:
> Under rare circumstances, creating symbolic links could fail because
> the link already exists. At first glance the code seemed to protect
> against this, but there was a small window where two separate tasks
> could decide that a symbolic link needed to be created and then the
> first task would create it and the second task would fail.
> 
> Signed-off-by: Peter Kjellerstedt <peter.kjellerstedt@axis.com>
> ---
>  bitbake/lib/bb/fetch2/__init__.py | 20 +++++++++++++-------
>  1 file changed, 13 insertions(+), 7 deletions(-)

As Ross says, this needs to go to the bitbake list. I'm also curious
why not watch for the "AlreadyExists" exception (whatever it really is)
and then simply pass over the error assuming the symlink points to the
same place? That saves messing with temporary files.

I also worry a little about the locking? Why have you two fetch
processes which are changing the same files but not covered by the same
lock file? :/

Cheers,

Richard

> diff --git a/bitbake/lib/bb/fetch2/__init__.py
> b/bitbake/lib/bb/fetch2/__init__.py
> index 464e66b98a..f891e34eab 100644
> --- a/bitbake/lib/bb/fetch2/__init__.py
> +++ b/bitbake/lib/bb/fetch2/__init__.py
> @@ -25,7 +25,7 @@ BitBake build tools.
>  #
>  # Based on functions from the base bb module, Copyright 2003 Holger
> Schurig
>  
> -import os, re
> +import os, re, tempfile
>  import signal
>  import logging
>  import urllib.request, urllib.parse, urllib.error
> @@ -946,6 +946,16 @@ def rename_bad_checksum(ud, suffix):
>      bb.warn("Renaming %s to %s" % (ud.localpath, new_localpath))
>      bb.utils.movefile(ud.localpath, new_localpath)
>  
> +def atomic_symlink(src, dst):
> +    """Create/replace a symbolic link atomically."""
> +
> +    tmpname = tempfile.mktemp(prefix=dst)
> +    os.symlink(src, tmpname)
> +    try:
> +        os.rename(tmpname, dst)
> +    except OSError:
> +        os.remove(tmpname)
> +        raise
>  
>  def try_mirror_url(fetch, origud, ud, ld, check = False):
>      # Return of None or a value means we're finished
> @@ -983,7 +993,7 @@ def try_mirror_url(fetch, origud, ud, ld, check =
> False):
>                  open(ud.donestamp, 'w').close()
>              dest = os.path.join(dldir,
> os.path.basename(ud.localpath))
>              if not os.path.exists(dest):
> -                os.symlink(ud.localpath, dest)
> +                atomic_symlink(ud.localpath, dest)
>              if not verify_donestamp(origud, ld) or
> origud.method.need_update(origud, ld):
>                  origud.method.download(origud, ld)
>                  if hasattr(origud.method,"build_mirror_data"):
> @@ -991,11 +1001,7 @@ def try_mirror_url(fetch, origud, ud, ld, check
> = False):
>              return origud.localpath
>          # Otherwise the result is a local file:// and we symlink to
> it
>          if not os.path.exists(origud.localpath):
> -            if os.path.islink(origud.localpath):
> -                # Broken symbolic link
> -                os.unlink(origud.localpath)
> -
> -            os.symlink(ud.localpath, origud.localpath)
> +            atomic_symlink(ud.localpath, origud.localpath)
>          update_stamp(origud, ld)
>          return ud.localpath
>  
> -- 
> 2.12.0
> 


  parent reply	other threads:[~2017-03-28 12:44 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-03-28 12:30 [PATCH 0/1] Create symbolic links atomically in the fetcher Peter Kjellerstedt
2017-03-28 12:30 ` [PATCH 1/1] fetch2: Create/replace symbolic links atomically Peter Kjellerstedt
2017-03-28 12:37   ` Burton, Ross
2017-03-28 12:44   ` Richard Purdie [this message]
2017-03-28 12:32 ` ✗ patchtest: failure for Create symbolic links atomically in the fetcher Patchwork

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=1490705043.13980.277.camel@linuxfoundation.org \
    --to=richard.purdie@linuxfoundation.org \
    --cc=openembedded-core@lists.openembedded.org \
    --cc=peter.kjellerstedt@axis.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox