Gentoo Archives: gentoo-portage-dev

From: Brian Dolbec <dolsen@g.o>
To: gentoo-portage-dev@l.g.o
Subject: Re: [gentoo-portage-dev] [PATCH] locks: handle sshfs hardlink inode numbers (bug 678218)
Date: Mon, 18 Feb 2019 16:57:32
Message-Id: 20190218085730.6fe4a2d9@professor-x
In Reply to: [gentoo-portage-dev] [PATCH] locks: handle sshfs hardlink inode numbers (bug 678218) by Zac Medico
1 On Sun, 17 Feb 2019 15:04:29 -0800
2 Zac Medico <zmedico@g.o> wrote:
3
4 > Since hardlinks on sshfs do not have matching inode numbers, detect
5 > this behavior and use a simple stat call to detect if lock_path has
6 > been removed.
7 >
8 > Bug: https://bugs.gentoo.org/678218
9 > Signed-off-by: Zac Medico <zmedico@g.o>
10 > ---
11 > lib/portage/locks.py | 27 +++++++++++++++++++++++++++
12 > 1 file changed, 27 insertions(+)
13 >
14 > diff --git a/lib/portage/locks.py b/lib/portage/locks.py
15 > index 74c2c086a..510925da0 100644
16 > --- a/lib/portage/locks.py
17 > +++ b/lib/portage/locks.py
18 > @@ -340,6 +340,33 @@ def _lockfile_was_removed(lock_fd, lock_path):
19 >
20 > hardlink_stat = os.stat(hardlink_path)
21 > if hardlink_stat.st_ino != fstat_st.st_ino or
22 > hardlink_stat.st_dev != fstat_st.st_dev:
23 > + # Create another hardlink in order to detect
24 > whether or not
25 > + # hardlink inode numbers are expected to
26 > match. For example,
27 > + # inode numbers are not expected to match
28 > for sshfs.
29 > + inode_test = hardlink_path + '-inode-test'
30 > + try:
31 > + os.unlink(inode_test)
32 > + except OSError as e:
33 > + if e.errno not in (errno.ENOENT,
34 > errno.ESTALE):
35 > + _raise_exc(e)
36 > + try:
37 > + os.link(hardlink_path, inode_test)
38 > + except OSError as e:
39 > + if e.errno not in (errno.ENOENT,
40 > errno.ESTALE):
41 > + _raise_exc(e)
42 > + return True
43 > + else:
44 > + if not
45 > os.path.samefile(hardlink_path, inode_test):
46 > + # This implies that inode
47 > numbers are not expected
48 > + # to match for this file
49 > system, so use a simple
50 > + # stat call to detect if
51 > lock_path has been removed.
52 > + return not
53 > os.path.exists(lock_path)
54 > + finally:
55 > + try:
56 > + os.unlink(inode_test)
57 > + except OSError as e:
58 > + if e.errno not in
59 > (errno.ENOENT, errno.ESTALE):
60 > + _raise_exc(e)
61 > return True
62 > finally:
63 > try:
64
65 Looks fine to me

Replies