1
0
mirror of https://github.com/moparisthebest/pacman synced 2025-01-10 13:28:12 -05:00

repo-add : new locking system

Weird things could happen if several repo-add were run concurrently on the
same database. The introduced locking system will prevent this to happen.

Signed-off-by: Xavier Chantry <shiningxc@gmail.com>
This commit is contained in:
Xavier Chantry 2009-03-03 17:05:14 +01:00
parent a556bc57fc
commit 59b4725bbb

View File

@ -28,7 +28,10 @@ myver='@PACKAGE_VERSION@'
confdir='@sysconfdir@' confdir='@sysconfdir@'
QUIET=0 QUIET=0
REPO_DB_FILE="" REPO_DB_FILE=
LOCKFILE=
CLEAN_LOCK=0
startdir="$PWD"
# ensure we have a sane umask set # ensure we have a sane umask set
umask 0022 umask 0022
@ -219,7 +222,7 @@ db_write_entry()
return 1 return 1
fi fi
pushd "$gstmpdir" 2>&1 >/dev/null cd "$gstmpdir"
if [ -d "$pkgname-$pkgver" ]; then if [ -d "$pkgname-$pkgver" ]; then
warning "$(gettext "An entry for '%s' already existed")" "$pkgname-$pkgver" warning "$(gettext "An entry for '%s' already existed")" "$pkgname-$pkgver"
@ -264,7 +267,7 @@ db_write_entry()
write_list_entry "PROVIDES" "$_provides" "depends" write_list_entry "PROVIDES" "$_provides" "depends"
write_list_entry "OPTDEPENDS" "$_optdepends" "depends" write_list_entry "OPTDEPENDS" "$_optdepends" "depends"
popd 2>&1 >/dev/null cd "$startdir"
# preserve the modification time # preserve the modification time
# Xav : what for? # Xav : what for?
@ -295,6 +298,15 @@ db_remove_entry() {
check_repo_db() check_repo_db()
{ {
# check lock file
if ( set -o noclobber; echo "$$" > "$LOCKFILE") 2> /dev/null; then
CLEAN_LOCK=1
else
error "$(gettext "Failed to acquire lockfile: %s.")" "$LOCKFILE"
[ -f "$LOCKFILE" ] && error "$(gettext "Held by %s")" "$(cat $LOCKFILE)"
exit 1
fi
if [ -f "$REPO_DB_FILE" ]; then if [ -f "$REPO_DB_FILE" ]; then
if ! (bsdtar -tf "$REPO_DB_FILE" | grep -q "/desc"); then if ! (bsdtar -tf "$REPO_DB_FILE" | grep -q "/desc"); then
error "$(gettext "Repository file '%s' is not a proper pacman database.")" "$REPO_DB_FILE" error "$(gettext "Repository file '%s' is not a proper pacman database.")" "$REPO_DB_FILE"
@ -367,6 +379,23 @@ remove()
fi fi
} }
trap_exit()
{
echo
error "$@"
exit 1
}
clean_up() {
local exit_code=$?
cd "$startdir"
[ -d "$gstmpdir" ] && rm -rf "$gstmpdir"
[ $CLEAN_LOCK -eq 1 -a -f "$LOCKFILE" ] && rm -f "$LOCKFILE"
exit $exit_code
}
# PROGRAM START # PROGRAM START
# determine whether we have gettext; make it a no-op if we do not # determine whether we have gettext; make it a no-op if we do not
@ -387,11 +416,6 @@ if [ $# -lt 2 ]; then
exit 1 exit 1
fi fi
# main routine
gstmpdir=$(mktemp -d /tmp/repo-tools.XXXXXXXXXX) || (\
error "$(gettext "Cannot create temp directory for database building.")"; \
exit 1)
# figure out what program we are # figure out what program we are
cmd="$(basename $0)" cmd="$(basename $0)"
if [ "$cmd" != "repo-add" -a "$cmd" != "repo-remove" ]; then if [ "$cmd" != "repo-add" -a "$cmd" != "repo-remove" ]; then
@ -399,6 +423,15 @@ if [ "$cmd" != "repo-add" -a "$cmd" != "repo-remove" ]; then
exit 1 exit 1
fi fi
gstmpdir=$(mktemp -d /tmp/repo-tools.XXXXXXXXXX) || (\
error "$(gettext "Cannot create temp directory for database building.")"; \
exit 1)
trap 'clean_up' EXIT
trap 'trap_exit "$(gettext "TERM signal caught. Exiting...")"' TERM HUP QUIT
trap 'trap_exit "$(gettext "Aborted by user! Exiting...")"' INT
trap 'trap_exit "$(gettext "An unknown error has occured. Exiting...")"' ERR
success=0 success=0
# parse arguments # parse arguments
for arg in "$@"; do for arg in "$@"; do
@ -413,6 +446,7 @@ for arg in "$@"; do
*) *)
if [ -z "$REPO_DB_FILE" ]; then if [ -z "$REPO_DB_FILE" ]; then
REPO_DB_FILE="$arg" REPO_DB_FILE="$arg"
LOCKFILE="$REPO_DB_FILE.lck"
check_repo_db check_repo_db
else else
case "$cmd" in case "$cmd" in
@ -437,14 +471,14 @@ if [ $success -eq 1 ]; then
filename=$(basename "$REPO_DB_FILE") filename=$(basename "$REPO_DB_FILE")
pushd "$gstmpdir" 2>&1 >/dev/null cd "$gstmpdir"
if [ -n "$(ls)" ]; then if [ -n "$(ls)" ]; then
bsdtar -c${TAR_OPT}f "$filename" * bsdtar -c${TAR_OPT}f "$filename" *
else else
# the database will be moved to .old below, and there will be no new one to replace it # the database will be moved to .old below, and there will be no new one to replace it
error "$(gettext "All packages have been removed from the database. Deleting '%s'.")" "$REPO_DB_FILE" error "$(gettext "All packages have been removed from the database. Deleting '%s'.")" "$REPO_DB_FILE"
fi fi
popd 2>&1 >/dev/null cd "$startdir"
[ -f "$REPO_DB_FILE" ] && mv -f "$REPO_DB_FILE" "${REPO_DB_FILE}.old" [ -f "$REPO_DB_FILE" ] && mv -f "$REPO_DB_FILE" "${REPO_DB_FILE}.old"
[ -f "$gstmpdir/$filename" ] && mv "$gstmpdir/$filename" "$REPO_DB_FILE" [ -f "$gstmpdir/$filename" ] && mv "$gstmpdir/$filename" "$REPO_DB_FILE"
@ -452,7 +486,5 @@ else
msg "$(gettext "No packages modified, nothing to do.")" msg "$(gettext "No packages modified, nothing to do.")"
fi fi
# remove the temp directory used to unzip exit 0
[ -d "$gstmpdir" ] && rm -rf "$gstmpdir"
# vim: set ts=2 sw=2 noet: # vim: set ts=2 sw=2 noet: