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


Reply via email to