apt cancels holds on uninstalled packages

Bug #1904195 reported by Harald van Dijk
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
dpkg (Ubuntu)
Triaged
Low
Unassigned

Bug Description

When a package is not installed and apt dist-upgrade offers to install it, if this is not desired, it is possible to hold the package using multiple tools, which puts it in a state documented in dpkg.1 as:

       hold
           A package marked to be on hold is kept on the same version, that
           is, no automatic new installs, upgrades or removals will be
           performed on them, unless these actions are requested explicitly,
           or are permitted to be done automatically with the --force-hold
           option.

Note the "no automatic new installs", suggesting that this is a correct and valid use for packages that are not installed. I use "apt-mark hold" to put packages in this state.

This is respected by apt when choosing what to install, but any installation causes this state to be lost for uninstalled packages, even installations of completely unrelated packages.

Steps to reproduce:

- Add a repository to sources.list that adds new essential packages, and run `apt update`.
- Observe that `apt dist-upgrade` will want to install new packages.
- Put the packages on hold, using `apt-mark hold <package>`.
- Observe that `apt dist-upgrade` will no longer want to install new packages.
- Install an unrelated package.
- Observe that `apt dist-upgrade` will again want to install new packages.

Seen on Ubuntu 20.10, apt 2.1.10.

Revision history for this message
Julian Andres Klode (juliank) wrote :

This is not a bug in apt. dpkg cleans up its database and removes hold states for non-installed packages following an operation.

Changed in apt (Ubuntu):
status: New → Invalid
Revision history for this message
Harald van Dijk (hvdijk) wrote :

Whether it's a bug in apt or in something used by apt doesn't really make a difference from an end user perspective. Can this bug be reopened as a dpkg bug, then, or should I report that as a new bug?

Revision history for this message
Harald van Dijk (hvdijk) wrote :

You're right btw that it's a dpkg bug, but it's a bit more subtle. The cleanup that dpkg performs after installation is meant to preserve the hold state for non-installed packages. This is handled by the pkg_is_informative function, which classifies everything with "pkg->want != PKG_WANT_UNKNOWN" as informative, so would actually preserve hold for non-installed packages. However, pkg_parse_verify contains logic to fix up state left by older dpkg versions, without taking into account that this also includes valid state by current dpkg versions:

  /* XXX: Mark not-installed leftover packages for automatic removal on
   * next database dump. This code can be removed after dpkg 1.16.x, when
   * there's guarantee that no leftover is found on the status file on
   * major distributions. */
  if (!(ps->flags & pdb_recordavailable) &&
      pkg->status == PKG_STAT_NOTINSTALLED &&
      pkg->eflag == PKG_EFLAG_OK &&
      (pkg->want == PKG_WANT_PURGE ||
       pkg->want == PKG_WANT_DEINSTALL ||
       pkg->want == PKG_WANT_HOLD)) {
    pkg_set_want(pkg, PKG_WANT_UNKNOWN);
  }

We are now at dpkg 1.20.x, well after 1.16.x. If this block of code is removed (or at least the pkg->want == PKG_WANT_HOLD condition), direct installation by dpkg works as expected, and presumably installation using apt will work as expected as well.

Revision history for this message
Julian Andres Klode (juliank) wrote :

Yes, but that's really something for dpkg upstream to look at, and not something we should patch out downstream.

no longer affects: apt (Ubuntu)
Changed in dpkg (Ubuntu):
importance: Undecided → Low
status: New → Triaged
Revision history for this message
Julian Andres Klode (juliank) wrote :

I didn't remember the discussions with the dpkg maintainer about this, but I did find them now, and he basically pointed at the same thing.

Anyway, this is not a common use case, so there's no point adding an extra delta here. Use pinning in apt instead.

Revision history for this message
Harald van Dijk (hvdijk) wrote :

My understanding of pinning is that that can be used to specify which version to use, which is what I use it for already, but not to force no version to be used. Agreed that this is not a common use case, so low prio and not patching it till it's fixed upstream makes sense, but since it's something I don't have a good alternative for, I have locally just built a modified dpkg to get this working properly.

Revision history for this message
Julian Andres Klode (juliank) wrote :

Sure you can keep versions away with pinning, you pin them to negative values, e.g.

Package: idontlike
Pin: version *
Pin-Priority: -1

Revision history for this message
Harald van Dijk (hvdijk) wrote :

Huh, so you can, thanks. Confirming that this works too, and agreed that that looks like it should cover all cases.

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.