Gentoo Archives: gentoo-commits

From: Zac Medico <zmedico@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/portage:master commit in: lib/portage/
Date: Mon, 18 Feb 2019 01:01:41
Message-Id: 1550444568.34532af167cff457c3cccda4ea4249a0bc26481a.zmedico@gentoo
1 commit: 34532af167cff457c3cccda4ea4249a0bc26481a
2 Author: Zac Medico <zmedico <AT> gentoo <DOT> org>
3 AuthorDate: Sun Feb 17 22:44:29 2019 +0000
4 Commit: Zac Medico <zmedico <AT> gentoo <DOT> org>
5 CommitDate: Sun Feb 17 23:02:48 2019 +0000
6 URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=34532af1
7
8 locks: handle sshfs hardlink inode numbers (bug 678218)
9
10 Since hardlinks on sshfs do not have matching inode numbers, detect
11 this behavior and use a simple stat call to detect if lock_path has
12 been removed.
13
14 Bug: https://bugs.gentoo.org/678218
15 Signed-off-by: Zac Medico <zmedico <AT> gentoo.org>
16
17 lib/portage/locks.py | 27 +++++++++++++++++++++++++++
18 1 file changed, 27 insertions(+)
19
20 diff --git a/lib/portage/locks.py b/lib/portage/locks.py
21 index 74c2c086a..510925da0 100644
22 --- a/lib/portage/locks.py
23 +++ b/lib/portage/locks.py
24 @@ -340,6 +340,33 @@ def _lockfile_was_removed(lock_fd, lock_path):
25
26 hardlink_stat = os.stat(hardlink_path)
27 if hardlink_stat.st_ino != fstat_st.st_ino or hardlink_stat.st_dev != fstat_st.st_dev:
28 + # Create another hardlink in order to detect whether or not
29 + # hardlink inode numbers are expected to match. For example,
30 + # inode numbers are not expected to match for sshfs.
31 + inode_test = hardlink_path + '-inode-test'
32 + try:
33 + os.unlink(inode_test)
34 + except OSError as e:
35 + if e.errno not in (errno.ENOENT, errno.ESTALE):
36 + _raise_exc(e)
37 + try:
38 + os.link(hardlink_path, inode_test)
39 + except OSError as e:
40 + if e.errno not in (errno.ENOENT, errno.ESTALE):
41 + _raise_exc(e)
42 + return True
43 + else:
44 + if not os.path.samefile(hardlink_path, inode_test):
45 + # This implies that inode numbers are not expected
46 + # to match for this file system, so use a simple
47 + # stat call to detect if lock_path has been removed.
48 + return not os.path.exists(lock_path)
49 + finally:
50 + try:
51 + os.unlink(inode_test)
52 + except OSError as e:
53 + if e.errno not in (errno.ENOENT, errno.ESTALE):
54 + _raise_exc(e)
55 return True
56 finally:
57 try: