Re: Bug#504880: Disambiguate "installed" for packages
I think at this point we really need someone from the dpkg team to tell us
what Policy needs to be saying here. This feels like one of those cases
where the best thing to do is just document what dpkg promises to do,
rather than trying to make dpkg match what Policy might be saying. I'd
like to hammer out in Policy not just what dpkg *does*, but what dpkg
*promises* to do going forward no matter what changes may be made in the
dependency handling (at least without another change to Policy).
I'm copying debian-dpkg towards that end. See the bottom of this message
after my analysis for my outstanding questions.
Kurt Roeckx <firstname.lastname@example.org> writes:
> On Sat, Feb 14, 2009 at 09:50:49PM +0100, Kurt Roeckx wrote:
>>> I think this is another aspect of the same point above? My
>>> understanding from the discussion and the clarified text that Raphael
>>> sent is that postrm can always rely on the depended-on package being
>>> unpacked and configured and prerm can always rely on it at least being
>>> unpacked, even in the case of circular dependencies.
>> As I understand it, the dependency is ignored so you can not rely on
>> anything you expect for a Depends in case of circular dependencies.
If that's the case, then certainly the wording should change back to
unpacked instead of configured.
> Policy says that the dependency can be broken at a packages not having a
> postinst script. Which seems to suggest that the other scripts can be
> run without problem. But as far as I know, that's only useful for the
> case of installing new packages.
The current wording does cover the cases of the other scripts. What my
current proposed wording says, summarized, is:
preinst (all functions):
Only essential packages or pre-dependencies may be relied on.
Pre-dependencies will either be configured or will be unpacked or
half-configured but previously had been configured and was never
postinst (all functions):
All dependencies will be unpacked. All dependencies will be
configured provided that there are no dependency cycles.
prerm (all functions):
All dependencies will be unpacked. They may or may not be
postrm (all functions except purge):
All dependencies will be configured. (Given that prerm doesn't
require that they be configured, this is odd -- Raphael, can you
confirm this is really what you intended?)
Only essential packages may be relied on.
Walking through the possible ways that the scripts are called:
The normal cases, for which the wording above should be fine.
This is called when a package is being upgraded, the old postrm fails
an upgrade action, and the new postrm also fails a failed-upgrade
action. The wording above should still be fine at this point. The
package is unpacked, but that doesn't imply that dependencies will be
The normal case, for which the above wording should be fine.
Called for the currently installed package when the old prerm upgrade
script fails and the new prerm failed-upgrade script also fails, or
when the preinst of the new package fails (in which case it's called
first in the new package and then in the old package). This is done
before unpacking the new package. It can also be called after
unpacking the new package if postrm upgrade fails, I believe after
unwinding the attempted package installation. I think this is a case
where dependencies may not be satisfied in the case that the new
version of the package and the old version of the package have
Called when the prerm script for a package fails. I think the above
language should be correct for this, since even if the package is
being removed due to conflicts, I would expect that to happen in
advance of the new packages being unpacked. But I'm not sure.
Called only when prerm deconfigure fails, which in turn is called only
when packages are removed due to Breaks or because they depended on a
conflicting package that's being removed. As with abort-remove, I'm
not sure if such work is always done in advance of unpacking packages
that may break dependencies.
The normal case. The above language should be fine.
This is the first thing that's called during the unpack of an upgrade,
before anything else. As with abort-remove and abort-deconfigure,
whether one can rely on dependencies being unpacked depends on whether
this is done before unpacking all the possible dependencies.
This is a special case: it's an error handler for a prerm upgrade
failure in the previous version of the package. If dependencies would
be unpacked for prerm upgrade, they wouldn't be unpacked for prerm
failed-upgrade, and vice versa. So we definitely don't guarantee that
all dependencies are unpacked for all prerm functions.
Called when packages are removed due to Breaks or because they
depended on a conflicting package that's being removed. As above,
depends on the ordering during an upgrade.
The regular removal case, for which the above language should be
Only essential packages are guaranteed, as discussed.
Called after the new package is unpacked, so fairly definitely can't
rely on its dependencies being unpacked if they conflict with the
dependencies of the new version.
As with prerm failed-upgrade, this is a special case error handler for
a failed postrm upgrade in the previous version. In this case, it's
called after the package is unpacked but before it's configured, so
probably can't rely on its dependencies being configured.
Called if preinst install fails. This can probably only rely on
having the same things that preinst has.
Called during the nastiest error handling case, where the old postrm
upgrade and the new postrm failed-upgrade both fail after the unpack.
It's called in the new package after the old preinst abort-upgrade
succeeds. I'm not sure what the package can rely on at this point.
Called if all of your files have gone away after unpacking a new
package. I'm fairly sure that the above language is correct for this
and you can rely on all dependencies being present, since otherwise it
would hit one of the other cases of removal due to conflicts.
So... what does that all mean we should say? Unfortunately, it looks like
a mess, and not just for the circular dependency case. Even without
circular dependencies, we can end up with weird conditions if the
dependencies of a new package are mutually incompatible with the
dependencies of the old version of the package. We also don't know
whether one can rely on all of one's dependencies being unpacked when
postinst configure is called, or if they might not even be unpacked.
What I'd like at this point are answers from the dpkg developers about
dpkg's behavior in the following areas:
1. Are all package dependencies guaranteed to at least be unpacked at the
time that postinst configure is called, even if there are circular
2. Is a package guaranteed that its dependencies will still at least be
unpacked when its prerm upgrade is called, even if the new package
we're in the process of installing has dependencies that cannot be
satisfied at the same time as the dependencies of the currently
3. The same question as (2) for prerm deconfigure.
If the answer to all of the above questions is yes, then I think we can
say that package dependencies are always at least unpacked when postinst
configure, prerm remove, and prerm deconfigure are called, and package
dependencies are always configured when postrm remove and postrm disappear
are called. Package dependencies are also always configured when postinst
configure is called unless there are circular dependencies. Then I would
just say that there are no guarantees for the other postinst, prerm, and
Russ Allbery (email@example.com) <http://www.eyrie.org/~eagle/>