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 \


     #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
are collapsed and treated identically in the first usage in rpmtsOrder,
while the second usage also queues tsort relations
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  
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.