When not being run directly on a PKGBUILD, repro runs a short script inside an ephemeral container based on the downloaded chroot. This script involves running pacman -S asp devtools --noconfirm to install tools required to download and validate the PKGBUILD file, which in turn will fail if pacman cannot take the lock on its database.
Early in it's run, repro will also try and update the chroot by running pacman -Syu --noconfirm inside it, which also takes the pacman database lock. In order to guard against this possibility, repro locks the file root.lock before doing this, and skips this step if it's already locked. However, the step above does not try and take this lock, so two instances of repro can try and run these two steps simultaneously.
The fact that the PKGBUILD step is run in an ephemeral container prevents it from damaging the update step, but not vice versa. If the snapshot used by the ephemeral container is taken while the update is in progress, it will include the lock file, and the PKGBUILD step will fail.
This can be seen by doing something like:
for i in {1..20}
do
CACHEDIR=/path/to/cache repro ./acl-2.2.53-3-x86_64.pkg.tar.zst 2>output-${i} >output-${i} &
sleep 1
done
Most of the spawned repro instances will fail due to this issue.
Taking a shared lock on root.lock for this step (lines 301-318 in repro.in) solves this issue, and will also prevent issues that may arise from operating in a chroot that is mid-upgrade. This should also be done for the other ephemeral containers used to set up the build chroot, though I haven't actually seen any issues from this yet, probably because chroot updates are relatively rare.
Also related to this lock, when setting up the chroot for the first time, repro attempts to take the lock, but doesn't check if this operation succeeds (line 215). Thus, multiple instances of repro can be trying to install the chroot at the same time. The correct order of operations should be:
if [ ! -d "$BUILDDIRECTORY"/root ]; then
# block on the lock file
nlock 9 "$BUILDDIRECTORY"/root.lock
if [ -d "$BUILDDIRECTORY"/root ]; then
# chroot was created by someone else, don't need to do anything
unlock 9
else
# set up chroot
fi
fi
When not being run directly on a PKGBUILD, repro runs a short script inside an ephemeral container based on the downloaded chroot. This script involves running
pacman -S asp devtools --noconfirmto install tools required to download and validate the PKGBUILD file, which in turn will fail if pacman cannot take the lock on its database.Early in it's run, repro will also try and update the chroot by running
pacman -Syu --noconfirminside it, which also takes the pacman database lock. In order to guard against this possibility, repro locks the fileroot.lockbefore doing this, and skips this step if it's already locked. However, the step above does not try and take this lock, so two instances of repro can try and run these two steps simultaneously.The fact that the PKGBUILD step is run in an ephemeral container prevents it from damaging the update step, but not vice versa. If the snapshot used by the ephemeral container is taken while the update is in progress, it will include the lock file, and the PKGBUILD step will fail.
This can be seen by doing something like:
Most of the spawned repro instances will fail due to this issue.
Taking a shared lock on
root.lockfor this step (lines 301-318 inrepro.in) solves this issue, and will also prevent issues that may arise from operating in a chroot that is mid-upgrade. This should also be done for the other ephemeral containers used to set up the build chroot, though I haven't actually seen any issues from this yet, probably because chroot updates are relatively rare.Also related to this lock, when setting up the chroot for the first time, repro attempts to take the lock, but doesn't check if this operation succeeds (line 215). Thus, multiple instances of repro can be trying to install the chroot at the same time. The correct order of operations should be: