RPM Community Forums

Mailing List Message of <rpm-users>

Re: trigger ordering

From: Jeff Johnson <n3npq@mac.com>
Date: Fri 12 Nov 2010 - 03:12:51 CET
Message-id: <00795FA3-ECA2-430B-B789-5EA5543A558E@mac.com>

On Nov 10, 2010, at 10:58 PM, Bela Lubkin wrote:

> [ This was originally composed as mail directly to Jeff Johnson, then I
> came to my senses and decided a mailing list is more appropriate.  So
> "you" that I am speaking to is Jeff or suitable proxy ;-} ]
> 
> I have a question and I'm 99.5% sure I have the right answer.  I'm
> writing you because although I have the right answer, I feel the RPM
> docs are quite unclear about this and should be fixed.  [ Below I find
> the necessary doc; however *this* doc is still unclear and should be
> improved... ]
> 
> Refer to the discussion <http://rpm5.org/community/rpm-users/0416.html>
> and the referenced doc <http://rpm5.org/docs/api/triggers.html>.  This
> section is what is unclear to me:
> 
>  any-%triggerin (%triggerin from other packages set off by new install)
>  new-%triggerin
>  old-%triggerun
>  any-%triggerun (%triggerun from other packages set off by old uninstall)
> 

(aside)
Hehe, ya gotta remember that I wrote this document on May 2nd, 1998,
my 2nd day working at Red Hat. Alan Cox's 2nd day too ... but I digress ...

Basically what I attempted to capture with "new-%triggerin" and "old-%triggerun"
is the concept of "this package" as opposed to "every pother package".

There's the other complexity, of "new" vs "old" instances of "this package"
there too.

> That is: the first and last lines are adequately clear, and I don't have
> any real issues with "old-%triggerun", but "new-%triggerin" could be
> taken in at least two radically different ways (maybe more, but these
> are the ones that get me).  I'm sure this seems perfectly clear to you,
> who have been steeped in the sequencing of RPM installs for who knows
> how many years, but for those of us who just occasionally use this
> stuff, it's a bit boggling.
> 
> The two interpretations are:
> 
>  new-%triggerin might mean:
> 
>     1. "fire any %triggerin scripts of new' which pertain to packages
>         BEING INSTALLED RIGHT NOW BY THE SAME  COMMAND INVOCATION"
> 
> Like I said, I'm 99.5% certain that I know the right answer (1), but I'm
> still worried about the 0.5% chance it's (2).  And more to the point, I
> definitely understand why other people might have the same doubt, but
> not have the grounding to (fairly) firmly believe it's (1).
> 

This is the sense: a trigger from the incoming "new" package is fired at
that point in time.

> Please change the doc to read:
> 
>  any-%triggerin (%triggerin from other packages set off by new install)
>  new-%triggerin (set off by packages already installed + being installed now)

At least to my dialect of English, that's the wrong way to express.

The actual implemented semantics are most easily (imho) read directly
from the code (typically in lib/psm.c).

At the point triggers are fired "this" (aka the "new" package) is examined
for a %triggerin script. If it exists, the trigger (i.e. the %triggerin) script
is run.

What doesn't fit into what I tried to describe (and the code is quite clear if/when you
find it), is only "this" (aka the "new" header) is queried for a %triggerin script which
(if found) is run. The problem I have with your suggested wording change is the "already installed"
portion. The "already installed" is (at least in what I tried to write) already covered by the set implied
by
	any-triggerin
as in the complement of "this" package, aka "already installed" packages.

I hope that is clear.


>  old-%triggerun
>  any-%triggerun (%triggerun from other packages set off by old uninstall)
> 
> Actually, wait a sec.  Why would old-%triggerun be fired at all?  I
> suppose it *could* list a trigger for *itself* being uninstalled, but if
> so, I would consider that merely a case of "any-%triggerun".  Likewise,
> if multiple packages are being removed at once, this package's
> "old-%triggerun" might fire in response to some other package also
> exiting the building, but again, that's an instance of "any-%triggerun".
> So I *think* that line of the doc is just wrong.

Again the concepts are quite difficult to describe in words. Examine
lib/psm.c (PSM == Package State Machine, simple linear state machine of


	%init -> %pre -> %process -> %post -> %fini
with the added "new" vs. "old" (and "install" vs. "erase") steps merged.

> 
> It also begs a further clarification.  Suppose that packages "foo" and
> "bar" are both already installed on the system, and foo has:
> 
>  %triggerun -- bar
> 
> Obviously if you run , foo's trigger will run.
> 

There isn't so much "obvious" as what is actually implemented in RPM.

> What if you run ?  Will foo's trigger run because bar is
> being removed, even though foo will also be gone by the end of the whole
> transaction?
> 

The easiest (and most objective imho) is to try-and-see.

@rpm5.org carries around some toy test packages to exercise triggers.

See tests/trigger-N-1.0-1.src.rpm for "classical" trigger behavior. (there's
other packages that exercise pattern matching on file paths and glob patterns, mere details,
on the same basic state machine)

When run by "make check", there's an echo that is added to display $1 and $2 as
well as the order and the conditions for firing are implicit in the actual package,
and the context of "make check".

If you look at triggers-N.spec (its a toy package, won't hurt you a bit) you can see
what testing is being attempted: not much.

Here's the displayed output for the "make check" install if triggers-N*.rpm
(cut and pasted from an actual install here

    http://buildbot.rpm5.org:8010/builders/MDV1x_rpm_release/builds/11/steps/compile_5/logs/stdio

--> N:
--- triggerprein(b) -- triggers-N-a <= 1.0	arg 1 0 ...
--- triggerprein(a) -- triggers-N-b <= 1.0	arg 0 0 ...
--- triggerin(b) -- triggers-N-a <= 1.0	arg 1 0 ...
--- triggerin(a) -- triggers-N-b <= 1.0	arg 0 0 ...
--- triggerun(b) -- triggers-N-a <= 1.0	arg 0 0 ...
--- triggerun(a) -- triggers-N-b <= 1.0	arg 1 0 ...
--- triggerpostun(a) -- triggers-N-b <= 1.0	arg 1 0 ...
--- triggerpostun(b) -- triggers-N-a <= 1.0	arg 0 0 ...


That should pin down _EXACTLY_ what is happening with trigger firings as well
as the argument values passed to trigger scripts.

Again its rather hard to express what the code does precisely in words; but what the code _ACTUALLY_
does (when insturmented with echo) is absolutely/objectively clear
given a test case like triggers-N being installed.

> Does order matter; i.e., will  behave differently?
> 

The order is de facto: no one (certainly not me) has ever tried to pin
down precise semantics for the order in which triggers are run. The context
is quite tricky; but the order will be deterministic and de facto dependent
on the order in which Berkeley DB (and the match iterator) return header objects
containing trigger scriptlets to be run.

> Same for %triggerpostun.
> 
> Fully expanding the question, I'm asking what happens in these 8 cases +
> 2 meta questions:
> 
>  scenario 1: foo & bar both already installed, foo has "%triggerun --
>              bar"
> 
>  Q1a:            A1a: foo's trigger runs
>  Q1b:        A1b: ??
>  Q1c:        A1c: ??
>  Q1d: if A1b & A1c are the same, is this because of the underlying
>       principle or because of same emergent outcomes of different
>       internal processing?   A1d: ??
>  Q1e:            A1e: foo's trigger doesn't run (irrelevant
>                                   -- person asking this question is
>                                      confused about subject/object)
> 
>  scenario 2: foo & bar both already installed, foo has "%triggerpostun
>              -- bar"
> 
>  Q2a:            A2a: foo's trigger runs
>  Q2b:        A2b: ??
>  Q2c:        A2c: ??
>  Q2d:  same as Q1d           A2d: same as A1d?
>  Q2e:            A2e: foo's trigger doesn't run (irrelevant)
> 
> That page also mentions "triggerprein" but doesn't spread it out fully
> -- I see in more recent emails you're talking like it exists, so it's
> not an incompletely removed aborted idea but an incompletely added idea?
> 

AFAIK %triggerprein is completely functional and documented for quite some
(like >5) years now. As originally implemented, there was a missing
trigger condition/firing, i.e. %triggerprein wasn't implemented.

All that was done to implemet %triggerprein was to complete the state machine
(based on obvious symmetry principles).

If you want precise answers, then examine the toy tests/trigger*.src.rpm packages.
I can try to answer precisely, but I'm just as likely to confuse further.

I cannot discuss accurately/precisely in words: what the code does (and what
the toy trigger packages attempt) is precise even if I am imprecise in my vocabulary
and usage.

But I'll be happy to attempt an explanation for any specifc reproducer.
Just the vocabulary is quite hard to be _ABSOLUTELY_ precise expressing
in words.

> Ah, just found <http://rpm5.org/docs/rpm-guide.html> "Setting Triggers"
> which brings my certainty up to 100%, but still leaves many of the side
> questions open.
> 
> For instance these sentences: "The %triggerpostun script is run after
> the target package has been removed.  It is not run if your package is
> removed.":
> 
> The 2nd sentence could be meant as a simple reminder of the
> subject/object roles ("removing YOUR package is not what fires this
> trigger");
> 

(aside)
Note that %triggerpostun changed semantic behavior because of a bug report
from Owen Taylor (@redhat.com) back around 2004.

The issue (from memory) was largely a lack of symmetry in the start machine
revolving around the question

	Should a %triggerpostun from a just erased package be run?

From a pragmatic (and what was originally implemented in RPM circa rpm-2.4.x) the answer was
	No: The package was just removed, why bother running a scriptlet from
	a package that isn't presently installed?!?

From a symmetry POV, one arrives at the rather different answer:
	Yes: %triggerpostun (from a just erased package) should be run because
	that's a symmetric (i.e. invertible etc) state machine.

Please note that, in the "real world, it simply doesn't matter what RPM does or doesn't do
running %triggerpostun:
	the no. of packages that have needed (or used) %triggerpostun is vanishingly small.

> -- or as specific info ("if YOUR package has a %triggerpostun for
> package OTHER, and both are removed at the same time, the fact that
> YOUR package is being removed in the same transaction means that it
> loses the opportunity it would normally have had to fire its
> %triggerpostun regarding OTHER").
> 

If you show me an actual reproducer, I can likely understand (and justify)
any trigger behavior in RPM precisely. I hesitate to attempt the analysis
a priori; its as likely that I misunderstood what was being asked as it is that I
will have expressed something imperfectly. Words (imho) are difficult, code and
examples are perfect, for expressing subtleties like the context/ordering
of trigger execution in RPM.

73 de Jeff
Received on Fri Nov 12 03:13:43 2010
Driven by Jeff Johnson and the RPM project team.
Hosted by OpenPKG and Ralf S. Engelschall.
Powered by FreeBSD and OpenPKG.