buildsystem: use an update lock when updating image and sysroot

cp (and potentially mkdir -p) are not atomic, and we have seen situations where two packages
concurrently copying the same file (eg. the udev rule for xf86-video-nvidia and
xf86-video-nvidia-legacy) will succeed for one package but the other package fails with
a "file exists" error (as the file didn't exist when it checked, but does exist when it
actually copies the file). Not even cp -f will avoid this issue.

There are several workarounds, but the most practical (and general) solution is to ensure
sequential updates of the image and shared sysroot directories.
This commit is contained in:
MilhouseVH 2020-01-14 18:15:23 +00:00
parent e30bcd93b2
commit fe1dd1e8ac
3 changed files with 30 additions and 0 deletions

View File

@ -1371,6 +1371,13 @@ enable_service() {
### MULTI-THREADED FUNCTION HELPERS ###
# flocks: 94 (pkg_lock_status)
# 95 (scripts/pkgbuild)
# 96 (acquire_exclusive_lock)
# 97 (acquire_update_lock)
# 98 (pkg_lock)
# 99 (scripts/get)
# Test build type so that these functions are a no-op during non-multithreaded builds.
# Prevent concurrent modifications to a package during certain activities.
@ -1540,6 +1547,20 @@ exec_thread_safe() {
return ${result}
}
# A lightweight target specific lock (eg. image, sysroot)
acquire_update_lock() {
is_sequential_build && return 0
exec 97>"${THREAD_CONTROL}/locks/.update.${1}"
flock --exclusive 97
}
release_update_lock() {
is_sequential_build && return 0
flock --unlock 97 2>/dev/null
}
# Use distribution functions if any
if [ -f "distributions/$DISTRO/config/functions" ]; then
. distributions/$DISTRO/config/functions

View File

@ -444,8 +444,13 @@ for i in $(find "${SYSROOT_PREFIX}" -type l 2>/dev/null); do
done
# Transfer the new sysroot content to the shared sysroot
acquire_update_lock sysroot
mkdir -p "${PKG_ORIG_SYSROOT_PREFIX}"
cp -PRf "${SYSROOT_PREFIX}"/* "${PKG_ORIG_SYSROOT_PREFIX}"
release_update_lock
rm -rf "${SYSROOT_PREFIX}"
export SYSROOT_PREFIX="${PKG_ORIG_SYSROOT_PREFIX}"

View File

@ -64,6 +64,8 @@ pkg_lock_status "ACTIVE" "${PKG_NAME}:${TARGET}" "install"
build_msg "CLR_INSTALL" "INSTALL" "${PKG_NAME} $(print_color CLR_TARGET "(${TARGET})")" "indent"
acquire_update_lock image
mkdir -p ${INSTALL}
if [ "${TARGET}" = "target" ] ; then
@ -169,6 +171,8 @@ if [ "${TARGET}" = "target" ] ; then
pkg_call_exists post_install && pkg_call post_install
fi
release_update_lock
touch ${STAMP}
pkg_lock_status "UNLOCK" "${PKG_NAME}:${TARGET}" "install" "installed"