Report package database damage and guard package caches during transactions - #3
Merged
Conversation
…ctions Add a package database integrity check to `status`. An entry whose `desc` file is missing or empty is reported as damaged, which is what an interrupted transaction or an unclean shutdown leaves behind: pacman then knows the package is installed but owns no files, and the next upgrade of it fails with file conflicts against its own files. `files` and `mtree` are legitimately empty for meta packages such as `base`, so only `desc` is treated as evidence of damage. Refuse package cache cleanup while a package transaction is running. A transaction installs archives straight out of `~/.cache/yay`, `~/.cache/paru`, and the system package cache, so emptying them mid upgrade can fail the upgrade and remove the archives needed to repair it afterwards. Presence of `/var/lib/pacman/db.lck` is the signal, since pacman creates it for the duration of a transaction and removes it after. The apt and dnf lock files are permanent and held with `flock`, so their existence is not used as a signal. Cleanups unrelated to package state still run during a transaction.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
An interrupted pacman transaction leaves entries in
/var/lib/pacman/localwithdesc,files, andmtreetruncated to zero bytes. Pacman still considers the package installed but believes it owns no files, so the next upgrade of that package fails with file conflicts against its own files:The state is silent until an upgrade hits it, and the error message points at the filesystem rather than at the database, which is the wrong place to look.
The second half of the problem is that emptying a package cache during a transaction is unsafe, and TuxCleaner offered exactly that. A transaction installs archives straight out of
~/.cache/yay,~/.cache/paru, and the system package cache. Cleaning them mid upgrade can fail the upgrade, and it also removes the archives needed to repair the damage afterwards.What changes
statusreports package database integrity.SystemStatusgains an optionalpackage_databasefield with the entry count, the damaged entry names, and whether a transaction is running. Onlydesccounts as evidence:filesandmtreeare legitimately empty for meta packages such asbaseandbase-devel, which own no files, so keying on those would report healthy systems as broken.Package cache cleanup is refused while a transaction runs. The signal is the presence of
/var/lib/pacman/db.lck, which pacman creates for the duration of a transaction and removes afterwards. The guard coverspaccache,pacman,apt-get, anddnfactions plus removal of the AUR helper build caches. Cleanups unrelated to package state still run normally.The apt and dnf lock files are deliberately not used: they are permanent files held with
flock, so their existence proves nothing about whether a transaction is in progress. Reporting for dpkg and rpm is left unimplemented rather than guessed at, since those databases are single files and need a different integrity check.Scope and conventions
src/distro.rs(package_database_path,package_transaction_lock_path).SystemStatusgains a field rather than renaming or removing one, so JSON output stays compatible.Executor::with_transaction_locksso the refusal cases are testable without touching the host.Tests
Nine new tests covering both the intended behavior and the refusal cases:
Full local validation passes:
Verified against a real system: the new output correctly reported a live
pacman -Syuholding the lock, and a clean database after repair.