RPM Community Forums

Mailing List Message of <rpm-devel>

Re: %post-script prerequisites

From: Jeff Johnson <n3npq@mac.com>
Date: Thu 25 Sep 2008 - 15:49:16 CEST
Message-id: <A7AC7B3A-7463-4D5A-A08E-894211396751@mac.com>

On Sep 25, 2008, at 8:37 AM, Pixel wrote:

> Michael Schroeder <mls@suse.de> writes:
>
>> So A requires B and B has a requires(post) to A? This isn't  
>> installable
>> at all, thus it's a packaging bug.
>
> i don't agree.
>
> not knowing exactly what rpmlib does, here is how i understand the pb:
>
> "Requires" is same as "Requires(postrans)", ie if A requires B, it
> doesn't mean B must be installed before A.
>
> (1) the typical example:
>   B requires A
>   C requires(post) B
> becomes after graph closure
>   C requires(post) B
>   C requires(post) A
> ie
>   C requires(post) B requires A
> becomes
>   C requires(post) A
> (the strongest require is kept [*])
>
> (2) Alexey's example:
>   A requires(post) B
>   B requires A
> becomes
>   A requires(post) B
>   A requires(post) A
>
> "A requires(post) A", is it a tautology? i would say yes,
> whereas "A requires(pre) A" is always false. Otherwise, what's the use
> having a distinction between pre and post!
>

There is no distinction between "(pre)" and "(post)" in rpmlib.

The context marker bits are
     RPMSENSE_SCRIPT_PRE = (1 << 9),     /*!< %pre dependency. */
     RPMSENSE_SCRIPT_POST = (1 << 10),   /*!< %post dependency. */

The bits are bundled into a test as

     #define _notpre(_x)             ((_x) & ~RPMSENSE_PREREQ)
     #define _INSTALL_ONLY_MASK \
         _notpre(RPMSENSE_SCRIPT_PRE|RPMSENSE_SCRIPT_POST| 
RPMSENSE_RPMLIB|RPMSENSE_KEYRING)

     ...

     #define isInstallPreReq(_x)     ((_x) & _INSTALL_ONLY_MASK)

The test is used 2 places in rpmtsOrder like
             switch (rpmteType(p)) {
             case TR_REMOVED:
                 /* Skip if not %preun/%postun requires. */
                 if (!isErasePreReq(Flags))
                     /*@innercontinue@*/ continue;
                 /*@switchbreak@*/ break;
             case TR_ADDED:
                 /* Skip if not %pre/%post requires. */
                 if (!isInstallPreReq(Flags))
                     /*@innercontinue@*/ continue;
                 /*@switchbreak@*/ break;
             }

So the only distinction between the 2 bits is that the bits are
different. The rpmlib implementation always tests both bits together,
so all of
	Requires(pre):
	Requires(post):
	Requires(pre,post):
are collapsed and treated identically in the first usage in rpmtsOrder,
while the second usage also queues tsort relations
	Requires:
but slightly later.

>
> "A requires(pre) B"  means "install B files before doing A %pre"
> "A requires(post) B" means "install B files before doing A %post"
>
> so example (1) says "install C after A and B"
>    example (2) says "install A after B"
>
> (3) another example
>   A requires(post) B
>   B requires(post) A
> is the same after closure, and so says "install A after B" and
> "install B after A", which is not possible, and must be an error
> (rpm correctly makes an "rpmtsOrder failed" error)
>
> (4) Alexey's example with pre
>   A requires(pre) B
>   B requires A
> becomes
>   A requires(pre) B
>   A requires(pre) A
> which is impossible and must be an error
> (rpm currently accepts this and install B first)
>
> WYT?
>

One can imagine many possible semantic uses for context markers.

All that is actually implemented in rpmlib is described above, and
the end result is that __ALL__ dependency relations are used for the  
topological
sort, the only affect is permuting the order in which the relations
are queued for "partial ordering" sorting.

>
> [*] ordering used: pre > post > posttrans.
>     so for example "A requires(post) B requires (pre) C requires D"
>     becomes "A requires(pre) D"
>
> nb: erasure can be handled quite the same

Erasure __IS__ handled the same way, the only difference in
erasure ordering is that arrow on the dependency edge between
package nodes is reversed from install ordering (reversal symmetry):

     /* Erasures are reversed installs. */
     if (teType == TR_REMOVED) {
         rpmte r = p;
         p = q;
         q = r;
     }

73 de Jeff
Received on Thu Sep 25 15:50:07 2008
Driven by Jeff Johnson and the RPM project team.
Hosted by OpenPKG and Ralf S. Engelschall.
Powered by FreeBSD and OpenPKG.