expand pacman whitelist and fix locked db

This commit is contained in:
Krzysztof kuhy Rudnicki 2025-10-24 23:30:01 +02:00
parent 60b7ccbf0f
commit 8d5e0ce1ba
2 changed files with 185 additions and 1 deletions

View File

@ -99,4 +99,74 @@ python-dateutil
python-kiwisolver
python-pyparsing
python-platformdirs
python-pycparser
python-pycparser
python-dbus-next
python-parse
python-pyvips
python-systemd
python-colorlog
python-injector
python-peewee
python-py3nvml
python-reactivex
python-pyusb
python-hidapi
python-crcmod
gst-python
python-beautifulsoup4
python-certifi
python-evdev
python-moddb
python-aioquic
python-argon2-cffi
python-asgiref
python-flask
python-h11
python-h2
python-hyperframe
python-kaitaistruct
python-ldap3
python-mitmproxy-rs
python-msgpack
python-passlib
python-publicsuffix2
python-pyperclip
python-ruamel-yaml
python-sortedcontainers
python-tornado
python-urwid
python-wsproto
python-zstandard
python-bcrypt
python-aaf2
python-vdf
python-inputs
python-pyaml
python-steam
python-readme-renderer
python-requests-toolbelt
python-importlib-metadata
python-keyring
python-rfc3986
python-rich
python-id
python-pylsqpack
python-argon2-cffi-bindings
python-soupsieve
python-blinker
python-itsdangerous
python-werkzeug
python-hpack
python-zipp
python-jaraco.classes
python-secretstorage
python-pkgconfig
python-docutils
python-nh3
python-markdown-it-py
python-ruamel.yaml.clib
python-cachetools
python-pycryptodomex
python-wcwidth
python-mdurl
python-jeepney

View File

@ -204,6 +204,115 @@ function has_noconfirm_flag() {
return 1
}
# Handle stale pacman database lock if present and no package managers are running
check_and_handle_db_lock() {
local lock_file="/var/lib/pacman/db.lck"
# Quick exit if no lock
if [[ ! -e "$lock_file" ]]; then
return 0
fi
# Determine which processes actually have the lock open
local -a holders=()
if command -v fuser >/dev/null 2>&1; then
mapfile -t holders < <(fuser "$lock_file" 2>/dev/null | tr ' ' '\n' | grep -E '^[0-9]+$' || true)
elif command -v lsof >/dev/null 2>&1; then
mapfile -t holders < <(lsof -t "$lock_file" 2>/dev/null | grep -E '^[0-9]+$' || true)
else
holders=()
fi
# Filter out our own PID if it somehow appears
if [[ ${#holders[@]} -gt 0 ]]; then
local -a filtered=()
for pid in "${holders[@]}"; do
[[ "$pid" -eq "$$" ]] && continue
filtered+=("$pid")
done
holders=("${filtered[@]}")
fi
if [[ ${#holders[@]} -gt 0 ]]; then
local pac_holder=0
local gui_holder=0
for pid in "${holders[@]}"; do
local comm args lower
comm=$(ps -p "$pid" -o comm= 2>/dev/null || true)
args=$(ps -p "$pid" -o args= 2>/dev/null || true)
lower="${comm,,} ${args,,}"
if [[ "$lower" == *" pacman"* || "$lower" == pacman* || "$lower" == *"/pacman "* || "$lower" == *" pamac"* ]]; then
pac_holder=1
elif [[ "$lower" == *packagekit* || "$lower" == *gnome-software* || "$lower" == *discover* ]]; then
gui_holder=1
fi
done
if [[ $pac_holder -eq 1 ]]; then
echo -e "${RED}Another pacman/pamac transaction is holding the database lock. Try again later.${NC}" >&2
return 1
fi
if [[ $gui_holder -eq 1 ]]; then
echo -e "${YELLOW}A background software updater is holding the pacman lock. Attempting to stop it...${NC}" >&2
if command -v systemctl >/dev/null 2>&1; then
systemctl --quiet stop packagekit.service 2>/dev/null || true
systemctl --quiet stop packagekit 2>/dev/null || true
fi
pkill -x packagekitd 2>/dev/null || true
pkill -f gnome-software 2>/dev/null || true
pkill -f discover 2>/dev/null || true
sleep 1
# Re-check holders
holders=()
if command -v fuser >/dev/null 2>&1; then
mapfile -t holders < <(fuser "$lock_file" 2>/dev/null | tr ' ' '\n' | grep -E '^[0-9]+$' || true)
elif command -v lsof >/dev/null 2>&1; then
mapfile -t holders < <(lsof -t "$lock_file" 2>/dev/null | grep -E '^[0-9]+$' || true)
fi
if [[ ${#holders[@]} -gt 0 ]]; then
echo -e "${RED}Cannot free the pacman lock; another process still holds it. Try again later.${NC}" >&2
return 1
fi
fi
fi
# Decide whether to remove the lock
local now epoch age
if epoch=$(stat -c %Y "$lock_file" 2>/dev/null); then
now=$(date +%s)
age=$(( now - epoch ))
else
age=999999
fi
# Auto-remove in non-interactive mode (--noconfirm) or if the lock is older than 10 minutes
if has_noconfirm_flag "$@" || [[ $age -ge 600 ]]; then
echo -e "${YELLOW}Stale pacman lock detected (age: ${age}s). Removing it automatically...${NC}" >&2
if [[ $EUID -ne 0 ]]; then
sudo rm -f "$lock_file" || return 1
else
rm -f "$lock_file" || return 1
fi
return 0
fi
# Interactive prompt (15s timeout)
echo -e "${YELLOW}A pacman lock exists but no active pacman is running.${NC}" >&2
echo -e "${CYAN}Lock path:${NC} $lock_file (age: ${age}s)" >&2
read -r -t 15 -p $'Remove stale lock and continue? [y/N]: ' reply || reply="n"
if [[ "${reply,,}" == "y" || "${reply,,}" == "yes" ]]; then
if [[ $EUID -ne 0 ]]; then
sudo rm -f "$lock_file" || return 1
else
rm -f "$lock_file" || return 1
fi
return 0
fi
echo -e "${RED}Aborting due to existing pacman lock. Close other updaters and retry, or run with --noconfirm to auto-clear stale locks.${NC}" >&2
return 1
}
# Cleanup: remove any installed blocked packages (in addition to the queued operation)
function remove_installed_blocked_packages() {
# args not used; kept for future policy extension
@ -586,6 +695,11 @@ if needs_unlock "$@"; then
pre_unlock_hosts
fi
# Handle a possible stale DB lock before executing
if ! check_and_handle_db_lock "$@"; then
exit 1
fi
"$PACMAN_BIN" "$@"
exit_code=$?