[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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 <kurt@roeckx.be> 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
    removed.

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
    configured.

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?)

postrm purge:
    Only essential packages may be relied on.

Walking through the possible ways that the scripts are called:

preinst install
preinst upgrade
    The normal cases, for which the wording above should be fine.

preinst abort-upgrade
    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
    available.

postinst configure
    The normal case, for which the above wording should be fine.

postinst abort-upgrade
    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
    contradictory dependencies.

postinst abort-remove
    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.

postinst abort-deconfigure
    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.

prerm remove
    The normal case.  The above language should be fine.

prerm upgrade
    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.

prerm failed-upgrade
    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.

prerm deconfigure
    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.

postrm remove
    The regular removal case, for which the above language should be
    correct.

postrm purge
    Only essential packages are guaranteed, as discussed.

postrm upgrade
    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.

postrm failed-upgrade
    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.

postrm abort-install
    Called if preinst install fails.  This can probably only rely on
    having the same things that preinst has.

postrm abort-upgrade
    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.

postrm disappear
    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
   dependencies?

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
   installed package?

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
postrm actions.

-- 
Russ Allbery (rra@debian.org)               <http://www.eyrie.org/~eagle/>



Reply to: