public inbox for gentoo-portage-dev@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-portage-dev] [PATCH] locks: handle sshfs hardlink inode numbers (bug 678218)
@ 2019-02-17 23:04 Zac Medico
  2019-02-18 16:57 ` Brian Dolbec
  0 siblings, 1 reply; 3+ messages in thread
From: Zac Medico @ 2019-02-17 23:04 UTC (permalink / raw
  To: gentoo-portage-dev; +Cc: Zac Medico

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 <zmedico@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:
-- 
2.18.1



^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [gentoo-portage-dev] [PATCH] locks: handle sshfs hardlink inode numbers (bug 678218)
  2019-02-17 23:04 [gentoo-portage-dev] [PATCH] locks: handle sshfs hardlink inode numbers (bug 678218) Zac Medico
@ 2019-02-18 16:57 ` Brian Dolbec
  2019-02-18 20:41   ` Zac Medico
  0 siblings, 1 reply; 3+ messages in thread
From: Brian Dolbec @ 2019-02-18 16:57 UTC (permalink / raw
  To: gentoo-portage-dev

On Sun, 17 Feb 2019 15:04:29 -0800
Zac Medico <zmedico@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 <zmedico@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


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [gentoo-portage-dev] [PATCH] locks: handle sshfs hardlink inode numbers (bug 678218)
  2019-02-18 16:57 ` Brian Dolbec
@ 2019-02-18 20:41   ` Zac Medico
  0 siblings, 0 replies; 3+ messages in thread
From: Zac Medico @ 2019-02-18 20:41 UTC (permalink / raw
  To: gentoo-portage-dev, Brian Dolbec


[-- Attachment #1.1: Type: text/plain, Size: 2201 bytes --]

On 2/18/19 8:57 AM, Brian Dolbec wrote:
> On Sun, 17 Feb 2019 15:04:29 -0800
> Zac Medico <zmedico@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 <zmedico@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

Thanks, merged:

https://gitweb.gentoo.org/proj/portage.git/commit/?id=34532af167cff457c3cccda4ea4249a0bc26481a

-- 
Thanks,
Zac


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 981 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2019-02-18 20:41 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-02-17 23:04 [gentoo-portage-dev] [PATCH] locks: handle sshfs hardlink inode numbers (bug 678218) Zac Medico
2019-02-18 16:57 ` Brian Dolbec
2019-02-18 20:41   ` Zac Medico

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox