The 'userland_*' flags have proven not good enough to determine
the availability of lock helpers. Fabian provided a nice portable
locking code instead.
Fixes:
https://bugs.gentoo.org/show_bug.cgi?id=466554
---
gx86/eclass/multibuild.eclass | 29 +++++++++++++++--------------
1 file changed, 15 insertions(+), 14 deletions(-)
diff --git a/gx86/eclass/multibuild.eclass b/gx86/eclass/multibuild.eclass
index acfdbbd..819c814 100644
--- a/gx86/eclass/multibuild.eclass
+++ b/gx86/eclass/multibuild.eclass
@@ -251,38 +251,39 @@ multibuild_merge_root() {
local src=${1}
local dest=${2}
- local lockfile=${T}/multibuild_merge_lock
+ local lockfile=${T}/.multibuild_merge_lock
+ local lockfile_l=${lockfile}.${$}
local ret
+ # Lock the install tree for merge. The touch+ln method ensures race
+ # condition-free locking with maximum portability.
+ touch "${lockfile_l}" || die
+ until ln "${lockfile_l}" "${lockfile}" &>/dev/null; do
+ sleep 1
+ done
+ rm "${lockfile_l}" || die
+
if use userland_BSD; then
- # Locking is done by 'lockf' which can wrap a command.
# 'cp -a -n' is broken:
#
http://www.freebsd.org/cgi/query-pr.cgi?pr=174489
# using tar instead which is universal but terribly slow.
tar -C "${src}" -f - -c . \
- | lockf "${lockfile}" tar -x -f - -C "${dest}"
+ | tar -x -f - -C "${dest}"
[[ ${PIPESTATUS[*]} == '0 0' ]]
ret=${?}
elif use userland_GNU; then
- # GNU has 'flock' which can't wrap commands but can lock
- # a fd which is good enough for us.
- # and cp works with '-a -n'.
-
- local lock_fd
- redirect_alloc_fd lock_fd "${lockfile}" '>>'
- flock ${lock_fd}
+ # cp works with '-a -n'.
cp -a -l -n "${src}"/. "${dest}"/
ret=${?}
-
- # Close the lock file when we are done with it.
- # Prevents deadlock if we aren't in a subshell.
- eval "exec ${lock_fd}>&-"
else
die "Unsupported userland (${USERLAND}), please report."
fi
+ # Remove the lock.
+ rm "${lockfile}" || die
+
if [[ ${ret} -ne 0 ]]; then
die "${MULTIBUILD_VARIANT:-(unknown)}: merging image failed."
fi
--
1.8.2.1