Gentoo Archives: gentoo-dev

From: "Michał Górny" <mgorny@g.o>
To: gentoo-dev@l.g.o
Cc: python@g.o, grobian@g.o, "Michał Górny" <mgorny@g.o>
Subject: [gentoo-dev] [PATCH multibuild.eclass] Use portable locking code from Fabian Groffen.
Date: Wed, 15 May 2013 19:28:01
Message-Id: 1368645741-1406-1-git-send-email-mgorny@gentoo.org
1 The 'userland_*' flags have proven not good enough to determine
2 the availability of lock helpers. Fabian provided a nice portable
3 locking code instead.
4
5 Fixes: https://bugs.gentoo.org/show_bug.cgi?id=466554
6 ---
7 gx86/eclass/multibuild.eclass | 29 +++++++++++++++--------------
8 1 file changed, 15 insertions(+), 14 deletions(-)
9
10 diff --git a/gx86/eclass/multibuild.eclass b/gx86/eclass/multibuild.eclass
11 index acfdbbd..819c814 100644
12 --- a/gx86/eclass/multibuild.eclass
13 +++ b/gx86/eclass/multibuild.eclass
14 @@ -251,38 +251,39 @@ multibuild_merge_root() {
15 local src=${1}
16 local dest=${2}
17
18 - local lockfile=${T}/multibuild_merge_lock
19 + local lockfile=${T}/.multibuild_merge_lock
20 + local lockfile_l=${lockfile}.${$}
21 local ret
22
23 + # Lock the install tree for merge. The touch+ln method ensures race
24 + # condition-free locking with maximum portability.
25 + touch "${lockfile_l}" || die
26 + until ln "${lockfile_l}" "${lockfile}" &>/dev/null; do
27 + sleep 1
28 + done
29 + rm "${lockfile_l}" || die
30 +
31 if use userland_BSD; then
32 - # Locking is done by 'lockf' which can wrap a command.
33 # 'cp -a -n' is broken:
34 # http://www.freebsd.org/cgi/query-pr.cgi?pr=174489
35 # using tar instead which is universal but terribly slow.
36
37 tar -C "${src}" -f - -c . \
38 - | lockf "${lockfile}" tar -x -f - -C "${dest}"
39 + | tar -x -f - -C "${dest}"
40 [[ ${PIPESTATUS[*]} == '0 0' ]]
41 ret=${?}
42 elif use userland_GNU; then
43 - # GNU has 'flock' which can't wrap commands but can lock
44 - # a fd which is good enough for us.
45 - # and cp works with '-a -n'.
46 -
47 - local lock_fd
48 - redirect_alloc_fd lock_fd "${lockfile}" '>>'
49 - flock ${lock_fd}
50 + # cp works with '-a -n'.
51
52 cp -a -l -n "${src}"/. "${dest}"/
53 ret=${?}
54 -
55 - # Close the lock file when we are done with it.
56 - # Prevents deadlock if we aren't in a subshell.
57 - eval "exec ${lock_fd}>&-"
58 else
59 die "Unsupported userland (${USERLAND}), please report."
60 fi
61
62 + # Remove the lock.
63 + rm "${lockfile}" || die
64 +
65 if [[ ${ret} -ne 0 ]]; then
66 die "${MULTIBUILD_VARIANT:-(unknown)}: merging image failed."
67 fi
68 --
69 1.8.2.1

Replies