From e9836b6b2afa70f22d305509593b375543b20ba6 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Sun, 25 Nov 2012 20:05:09 -0500 Subject: Use common functions to handle file locking * lib/common.sh: implement - lock_open_write() - lock_open_read() - lock_close() * archbuild.in, makechrootpkg.in, mkarchroot.in: use said functions This has two benefits: 1. All programs using these methods gain the ability to inherit locks, something that only mkarchroot could do before. This allows the commands to be more compos-able. 2. It is more readable. File locking isn't obvious. --- archbuild.in | 9 ++------- lib/common.sh | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ makechrootpkg.in | 17 +++-------------- mkarchroot.in | 12 +----------- 4 files changed, 55 insertions(+), 32 deletions(-) diff --git a/archbuild.in b/archbuild.in index 7220391..9476415 100644 --- a/archbuild.in +++ b/archbuild.in @@ -43,17 +43,12 @@ if ${clean_first} || [[ ! -d "${chroots}/${repo}-${arch}" ]]; then [[ -d $copy ]] || continue msg2 "Deleting chroot copy '$(basename "${copy}")'..." - exec 9>"$copy.lock" - if ! flock -n 9; then - stat_busy "Locking chroot copy '$copy'" - flock 9 - stat_done - fi + lock_open_write 9 "$copy.lock" "Locking chroot copy '$copy'" { type -P btrfs && btrfs subvolume delete "${copy}"; } &>/dev/null rm -rf --one-file-system "${copy}" done - exec 9>&- + lock_close 9 rm -rf --one-file-system "${chroots}/${repo}-${arch}" mkdir -p "${chroots}/${repo}-${arch}" diff --git a/lib/common.sh b/lib/common.sh index b39bbbc..5204091 100644 --- a/lib/common.sh +++ b/lib/common.sh @@ -103,6 +103,55 @@ in_array() { return 1 # Not Found } +## +# usage : lock_open_write( $fd, $path, $wait_message ) +## +lock_open_write() { + local fd=$1 + local path=$2 + local msg=$3 + + # Only reopen the FD if it wasn't handed to us + if [[ $(readlink -f /dev/fd/$fd) != "${path}.lock" ]]; then + eval "exec $fd>${path}.lock" + fi + + if ! flock -n $fd; then + stat_busy "$msg" + flock $fd + stat_done + fi +} + +## +# usage : lock_open_read( $fd, $path, $wait_message ) +## +lock_open_read() { + local fd=$1 + local path=$2 + local msg=$3 + + # Only reopen the FD if it wasn't handed to us + if [[ $(readlink -f /dev/fd/$fd) != "${path}.lock" ]]; then + eval "exec $fd>${path}.lock" + fi + + if ! flock -sn $fd; then + stat_busy "$msg" + flock -s $fd + stat_done + fi +} + + +## +# usage : lock_close( $fd ) +## +lock_close() { + local fd=$1 + eval "exec $fd>&-" +} + ## # usage : get_full_version( [$pkgname] ) # return : full version spec, including epoch (if necessary), pkgver, pkgrel diff --git a/makechrootpkg.in b/makechrootpkg.in index 6c0b013..f3333ca 100644 --- a/makechrootpkg.in +++ b/makechrootpkg.in @@ -114,23 +114,12 @@ 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 - stat_busy "Locking chroot copy '$copy'" - flock 9 - stat_done -fi +lock_open_write 9 "$copydir.lock" "Locking chroot copy '$copy'" if [[ ! -d $copydir ]] || $clean_first; 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 - stat_busy "Locking clean chroot" - flock -s 8 - stat_done - fi + lock_open_read 8 "$chrootdir/root.lock" "Locking clean chroot" stat_busy 'Creating clean working copy' use_rsync=false @@ -149,7 +138,7 @@ if [[ ! -d $copydir ]] || $clean_first; then stat_done # Drop the read lock again - exec 8>&- + lock_close 8 fi if [[ -n $install_pkg ]]; then diff --git a/mkarchroot.in b/mkarchroot.in index 76ad840..022943e 100644 --- a/mkarchroot.in +++ b/mkarchroot.in @@ -183,17 +183,7 @@ trap_chroot_umount () { } 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 - stat_busy "Locking chroot" - flock 9 - stat_done - fi + lock_open_write 9 "${working_dir}.lock" "Locking chroot"u } chroot_run() { -- cgit v1.2.3