Skip to content
Haiku OSDeep Dive Published Updated 5 min readViews unavailable

Haiku pkgman cleanup: Reclaim Space Without Erasing Recent Rollback States

Understand R1/beta6 package activation states, pkgman cleanup's age and count safeguards, and the difference between system and home cleanup.

Package upgrades can leave more disk use than the downloaded packages alone suggest. Haiku preserves previous package activation states so a user can return to an earlier state from the boot loader if a new package set proves unusable. This is a recovery feature, not ordinary temporary cache. Haiku’s R1/beta6 release notes explain the packagefs union model and why historical states can accumulate. They also introduce automatic SoftwareUpdater cleanup and a pkgman cleanup command for old states.

The narrow operational question is when to run that command and what it actually targets. pkgman cleanup in the R1/beta6 source is not a general “remove unused packages” solver. Its help text says it cleans old states and transactions in the administrative directory. It defaults to the system installation location; -H selects the user’s home installation location. The implementation itself is release-tagged command_cleanup.cpp. The details below are specifically for R1/beta6, not an assertion that future Haiku releases will preserve the same thresholds.

Read the result before reclaiming anything

After a package transaction, R1/beta6 may print a message similar to the one shown in its release notes: an old activation state was backed up as state_..., cleanup ran, and some old states remain eligible for pkgman cleanup. That message is an invitation to inspect the situation, not evidence that the newest state should be removed. If an update has just caused a boot, driver, or application regression, preserve its rollback path until recovery is complete.

The first command is deliberately non-destructive:

pkgman cleanup --help

Then run the interactive form only when you are ready to evaluate the proposed removal:

pkgman cleanup

The R1/beta6 command source constructs an interactive decision provider by default. Its -y option is non-interactive and automatically confirms changes while still failing on problems. That flag is appropriate only for an already reviewed policy in a controlled environment; it is a poor first diagnostic action. Do not wrap pkgman cleanup -y into every update script simply because a transaction reported reclaimable space.

There are two installation locations, and the command deliberately separates them. Without -H, it asks BPackageRoster for the system installation location. With -H (or --home), it asks for the home location. Run a distinct interactive check if you intend to clean user-scope state:

pkgman cleanup -H

This separation matters on a workstation where system packages and user packages have different operational owners. A successful system cleanup does not prove home history was examined, and -H is not an option for “more aggressive system cleanup.” Both invocations use the same command logic but a different package administrative directory, as the source’s location selection shows.

Know the retention logic, not just the prompt

R1/beta6 defines two thresholds in pkgman.h: keep days is 30 and minimum states to keep is 10. command_cleanup.cpp computes a time boundary from the current clock, then passes both values to CleanUpAdminDirectoryRequest. These are implementation constants for this release, not settings exposed by the shown pkgman cleanup options. Do not paraphrase them as a promise to delete every state older than 30 days.

The cleanup job implementation scans the package administrative directory and considers directories beginning state_ or transaction-. For a transaction directory, it skips entries whose modification time is newer than the cutoff. For a state directory, it also avoids states at or after the active state name and counts newer states toward the minimum retained number. It sorts the older eligible state names and removes enough from the candidate list to retain the minimum. In other words, age, active-state ordering, and count work together; a directory’s age alone does not decide its fate.

That code is also a useful boundary on what the command does not promise. It operates on these administrative directories, not arbitrary files in ~/config, downloaded repositories, the current package set, or general filesystem snapshots. It checks status while removing entries and returns an error when removal fails. A command that reports failure should prompt investigation of permissions, disk health, and package state; treating it as a successful partial cleanup would hide an unresolved storage condition.

Choose the right recovery moment

The release notes say SoftwareUpdater now removes older states after some time and provides a setting to disable that behavior. This is a separate automatic path from manually invoking pkgman cleanup. If rollback history is unusually important on a test machine, review the updater setting before relying on the mere presence of older states. Conversely, if a small system volume is filling after many update cycles, use the interactive command to reclaim eligible history after confirming the current activation works.

A sensible maintenance sequence is: finish the update, reboot if the update requires it, verify the applications and hardware affected by that update, check available space, read pkgman cleanup --help, then run the interactive system or home command as appropriate. The verification steps are operational policy, not a claim that pkgman itself performs application health checks. In a lab, record the release version and the command’s proposed count and size before confirming, so a later operator can tell which rollback capacity was deliberately traded for space.

Do not manually remove state_... or transaction-... directories because their names look old. The R1/beta6 job has selection logic tied to the active package state and its retention constants; bypassing it discards those checks. Likewise, do not promise a particular number of reclaimed bytes from the release-note example: its “3 old states (166.27 MiB)” is illustrative output from Haiku’s own update scenario, not a measured result on the reader’s machine.

The core distinction is between package activation history and disposable cache. pkgman cleanup is a bounded administrative cleanup with an interactive decision by default. Use it after a known-good update, with system and home scopes chosen explicitly, and treat its R1/beta6 retention rules as source-inspected behavior rather than a universal guarantee.

Related:

Sources:

Comments