summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Steffens <jan.steffens@gmail.com>2011-03-13 19:06:27 +0100
committerJan Steffens <jan.steffens@gmail.com>2011-03-22 19:47:32 +0100
commit174ff59dba8c24f544e354cd43f3b68aea91d265 (patch)
tree08eec872ad89cdb98850082347566a975067f377
parent5434d3991cd51873f987bde49d55948341c09f3e (diff)
downloaddevtools-174ff59dba8c24f544e354cd43f3b68aea91d265.tar.gz
devtools-174ff59dba8c24f544e354cd43f3b68aea91d265.tar.xz
Add flock-based locking to chroots
This prevents accidents when chroots are shared between multiple users.
-rwxr-xr-xarchbuild13
-rwxr-xr-xmakechrootpkg23
-rwxr-xr-xmkarchroot16
3 files changed, 52 insertions, 0 deletions
diff --git a/archbuild b/archbuild
index 7e8c456..9dd4888 100755
--- a/archbuild
+++ b/archbuild
@@ -36,6 +36,19 @@ fi
if ${clean_first} || [ ! -d "${chroots}/${repo}-${arch}" ]; then
echo "Creating chroot for [${repo}] (${arch})..."
+
+ for copy in ${chroots}/${repo}-${arch}/*; do
+ [[ -d $copy ]] || continue
+ echo "Deleting chroot copy '$(basename "${copy}")'..."
+
+ # Lock the copy
+ exec 9>${copy}.lock
+ flock 9
+
+ rm -rf ${copy}
+ done
+ exec 9>&-
+
rm -rf ${chroots}/${repo}-${arch}
mkdir -p ${chroots}/${repo}-${arch}
setarch ${arch} mkarchroot \
diff --git a/makechrootpkg b/makechrootpkg
index a38a740..1f6f20a 100755
--- a/makechrootpkg
+++ b/makechrootpkg
@@ -105,11 +105,34 @@ if [ ! -d "$chrootdir/root" ]; then
fi
umask 0022
+
+# Lock the chroot we want to use. We'll keep this lock until we exit.
+# Note this is the same FD number as in mkarchroot
+exec 9>"$copydir.lock"
+if ! flock -n 9; then
+ echo -n "locking chroot copy '$copy'..."
+ flock 9
+ echo "done"
+fi
+
if [ ! -d "$copydir" -o "$clean_first" -eq "1" ]; then
+ # Get a read lock on the root chroot to make
+ # sure we don't clone a half-updated chroot
+ exec 8>"$chrootdir/root.lock"
+
+ if ! flock -sn 8; then
+ echo -n "locking clean chroot..."
+ flock -s 8
+ echo "done"
+ fi
+
echo -n 'creating clean working copy...'
mkdir -p "$copydir"
rsync -a --delete -q -W -x "$chrootdir/root/" "$copydir"
echo 'done'
+
+ # Drop the read lock again
+ exec 8>&-
fi
if [ -n "$install_pkg" ]; then
diff --git a/mkarchroot b/mkarchroot
index 254841e..5c6548e 100755
--- a/mkarchroot
+++ b/mkarchroot
@@ -141,6 +141,20 @@ chroot_umount () {
umount "${working_dir}/${cache_dir}"
[ -n "${host_mirror_path}" ] && umount "${working_dir}/${host_mirror_path}"
}
+
+chroot_lock () {
+ # Only reopen the FD if it wasn't handed to us
+ if [ "$(readlink -f /dev/fd/9)" != "${working_dir}.lock" ]; then
+ exec 9>"${working_dir}.lock"
+ fi
+
+ # Lock the chroot. Take note of the FD number.
+ if ! flock -n 9; then
+ echo -n "locking chroot..."
+ flock 9
+ echo "done"
+ fi
+}
# }}}
umask 0022
@@ -153,6 +167,7 @@ if [ "$RUN" != "" ]; then
exit 1
fi
+ chroot_lock
chroot_mount
copy_hostconf
@@ -169,6 +184,7 @@ else
mkdir -p "${working_dir}/var/lib/pacman/sync"
mkdir -p "${working_dir}/etc/"
+ chroot_lock
chroot_mount
pacargs="--noconfirm --root=${working_dir} --cachedir=${cache_dir}"