Re: understanding dpkg trigger cycles
On Wed, 2014-12-10 at 22:35:01 +0100, Johannes Schauer wrote:
> I figured out that I must have a misunderstanding with respect to trigger
> cycles. Let me express my current understanding so that you can point out where
> I got it wrong. Lets limit this to file triggers and exclude noawait triggers.
> A package can be interested in a certain path through the "triggers" file in
> its control archive. When another package shipping a file under that path gets
> installed, then the package being interested in the path gets triggered.
(We say the trigger gets activated, which seems less confusing, but yes.)
> The triggering package (the one providing the file) gets put into the
> triggers-awaited state and the package that was interested in that path gets
> put into the triggers-pending state.
(Just for completeness, a package already in triggers-pending can also be
placed in triggers-awaited, or a package with pending triggers can also
already be in triggers-awaited, both will end up with recording the
pending triggers they need to process. Otherwise also yes.)
> Packages that are in the triggers-awaited state do not satisfy dependencies.
> So if the interested package in the triggers-pending state directly or
> indirectly depends on the package that triggered it (the one currently in
> triggers-awaited state), then that package cannot get configured because:
s/can/might/, remember that dpkg only looks at the immediate
dependencies, so if there's an element in the chain that is properly
installed then it will not see any problem. But if everything in the
chain is not yet fully installed, then all the dependencies will need
to be satisfied, which will not be able to.
> - to configure the package in triggers-awaited state, the trigger has to be
> resolved by the package in triggers-pending state
> - to configure the package in triggers-pending state, its dependency on the
> package in triggers-awaited state has to be resolved which cannot happen as
> long as it is in triggers-awaited state
> And this creates a cycle.
This creates one type of cycle. I'll go in more depth below.
> This is illustrated by the test case t-triggers-depcycle in the dpkg-tests
> In that particular example, the package "pkg-trigger" gets into
> triggers-pending state because it is interested in /test/trigger which is
> provided by the package "pkg-files" which is put into triggers-awaited state
> because of that. But because of that, the package "pkg-files" cannot satisfy
> dependencies. But "pkg-files" depends on "pkg-trigger" which depends on
> "pkg-files". So "pkg-files" cannot be installed because its transitive
> dependency on itself cannot be satisfied.
> Is this the correct explanation?
> If so, I wonder why the error message says:
> dpkg: cycle found while processing triggers:
> chain of packages whose triggers are or may be responsible:
> pkg-trigger -> pkg-trigger
> packages' pending triggers which are or may be unresolvable:
> pkg-trigger: /test/trigger
> The package "pkg-files" is the one that fails to configure but it does not
> appear in the error message?
Oh, that's because triggers are processed sometimes “out-of-band” and
in preference to other operations like configuration, so if there's
pending triggers then they will processed. In this case the processing
queue has tried to process the triggers several times but failed and
the trigger cycle detection has detected that there's a loop and no
> Given that the above was more or less correct, I do not understand the test
> case in t-triggers-depfarcycle.
> In this scenario, the package "pkg-files" gets installed. The package ships the
> file "/test/trigger/test-file" which triggers the package "pkg-trigger" which
> is interested in "/test/trigger". The package "pkg-files" will be put into
> triggers-awaited state while "pkg-trigger" gets into triggers-pending state.
> Thus the package "pkg-files" cannot satisfy dependencies. The package
> "pkg-files" depends on "pkg-depends-b" depends on "pkg-trigger" depends on
> "pkg-depends-a" depends on "pkg-files". So how does the test case manage to
> install the package "pkg-files" if it transitively depends on itself but should
> not be able to satisfy that dependency because it is in triggers-awaited state.
Ah, sorry, I see the test is pretty misleading, I'll be fixing or
renaming it. Here the test succeeds because the immediate dependencies
are satisfiable, I'll be adding another test case with the whole chain
not fully installed.
> Lastly, the examples in the dpkg-tests repository show situations in which a
> fully dependency cycle of binary packages is created. But can a trigger cycle
> not also occur without a full dependency cycle? Is it not enough if a package
> "foo" (which is interested in path A) directly or indirectly depends on a
> package "bar" (which provides something under the path A)? Why, in the test
> suite, does "bar" also always depend on "foo"? Coincidence?
I've been adding functional tests for regressions in dpkg, or
situations I wanted to stress, most of those involved both a trigger
and a dependency cycle. But it's correct that it should not need
There should be cases with pure trigger cycles coming from either
dynamically activated triggers in maintscripts or packages activating
each other from paths for example; others with half cycles, half from
dependencies and the other half from triggers. I'll try to add cases
for most of those.
Thanks for taking a look! And hope the above clarifies things.