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