On Sun, 17 Feb 2019 15:04:29 -0800
Zac Medico <zmed...@gentoo.org> wrote:

> Since hardlinks on sshfs do not have matching inode numbers, detect
> this behavior and use a simple stat call to detect if lock_path has
> been removed.
> 
> Bug: https://bugs.gentoo.org/678218
> Signed-off-by: Zac Medico <zmed...@gentoo.org>
> ---
>  lib/portage/locks.py | 27 +++++++++++++++++++++++++++
>  1 file changed, 27 insertions(+)
> 
> diff --git a/lib/portage/locks.py b/lib/portage/locks.py
> index 74c2c086a..510925da0 100644
> --- a/lib/portage/locks.py
> +++ b/lib/portage/locks.py
> @@ -340,6 +340,33 @@ def _lockfile_was_removed(lock_fd, lock_path):
>  
>               hardlink_stat = os.stat(hardlink_path)
>               if hardlink_stat.st_ino != fstat_st.st_ino or
> hardlink_stat.st_dev != fstat_st.st_dev:
> +                     # Create another hardlink in order to detect
> whether or not
> +                     # hardlink inode numbers are expected to
> match. For example,
> +                     # inode numbers are not expected to match
> for sshfs.
> +                     inode_test = hardlink_path + '-inode-test'
> +                     try:
> +                             os.unlink(inode_test)
> +                     except OSError as e:
> +                             if e.errno not in (errno.ENOENT,
> errno.ESTALE):
> +                                     _raise_exc(e)
> +                     try:
> +                             os.link(hardlink_path, inode_test)
> +                     except OSError as e:
> +                             if e.errno not in (errno.ENOENT,
> errno.ESTALE):
> +                                     _raise_exc(e)
> +                             return True
> +                     else:
> +                             if not
> os.path.samefile(hardlink_path, inode_test):
> +                                     # This implies that inode
> numbers are not expected
> +                                     # to match for this file
> system, so use a simple
> +                                     # stat call to detect if
> lock_path has been removed.
> +                                     return not
> os.path.exists(lock_path)
> +                     finally:
> +                             try:
> +                                     os.unlink(inode_test)
> +                             except OSError as e:
> +                                     if e.errno not in
> (errno.ENOENT, errno.ESTALE):
> +                                             _raise_exc(e)
>                       return True
>       finally:
>               try:

Looks fine to me

Reply via email to