[Rpm-maint] ignoring %preun faillure (like for %post & %postun)

Panu Matilainen pmatilai at laiskiainen.org
Wed Aug 5 07:17:34 UTC 2015

On 08/04/2015 01:31 PM, Thierry Vignaud wrote:
> Hi
> Since commit a1377fcc7544acba04e67f40f5a2307ab04694ff &
> 71c6b06b3f240021f2ece46f9cf7aa891f716710, only %pre, %preun &
> %pretrans can fail a transaction depending on their return value,
> other scriptlet failures result in a warning

Fail the operation, not the entire transaction (except in the special 
case of transaction being just that one op)

> See http://rpm.org/gitweb?p=rpm.git;a=blob;f=lib/transaction.c#l1420
> However I would like to reconsider %preun case.
> Allowing it to fail is the same as when we previously allowed %post or
> %postun to fail:
> Eg when updating foo-1 to foo-2,
> - if %post of foo-2 fails,
> - or if %preun of foo-1 fails,
> - or if %postun of foo-1 fails,
> foo-1 was not removed, so we ended up with both packages in rpmdb
> This was fixed for %post & %postun.
> But allowing %preun to result in having 2 packages in rpmdb is bogus IMHO.
> I think that rpm should ignore the error in the %preun cases too.
> Obviously, there's 2 POV:
> - failing uninstalling a package:
>    should we allow %preun to abort it:
> - updating a package:
>    we should definitively not allow to end with both old & new packages in rpmdb
> But unless we pass the info this is un update, I think the 2nd point
> is more important than the first.
> Having the same semantics for all %pre* scriptlets didn't take the
> impact of duplicate packages in rpmdb in consideration. %pretrans &
> %pre cannot result in this whereas %preun can...

Just to provide a bit of historical context on this: the reason %preun 
fails the operation is for erasure. People learned over the years that 
you can make a package uninstallable by having its %preun exit non-zero, 
and this is being (ab)used in the wild. Of course its a bad way to do 
it, the correct answer is "use dependencies" but for 3rd party packages 
it's not necessary easy or even possible. My favorite practical example 
on this would be a certain commercial disk encryption software, which of 
course nothing on distros depended on so it could all too easily be 
wiped out. So the package had something in the spirit of

if [ $1 -eq 0 ]; then
    echo "Package is uninstallable"
    exit 1

...and for that particular case I thought it was a quite reasonable 
thing to do. Lots of other 3rd party / company internal things / etc use 
it as well for similar (if less dramatic) reasons. Note how the example 
above does allow for upgrading but not erasing.

Bailing out of upgrade on %preun is of course way too late to save it 
since the files from the new package have already been laid down, mostly 
on top of the old package. So following the "no dupes in rpmdb and files 
laid down already anyway" reasoning, indeed failing the install due to 
non-zero exit %preun *on upgrade* makes no sense at all, for erasure its 
a bit different. Whether having it behave differently for different 
cases is sane either is another question.

P.S. Turned out there were people using %post etc exit status for "did 
package install successfully" status, and they did not like the "make 
scriptlet failures just warn" changes a single bit, but by that time it 
was way too late revert such changes (even if we had wanted to).

P.P.S. My "grand idea" for fixing these (ab)use-cases was to add a few 
admin (and probably package) controllable policy bits which can be 
toggled on and off to prevent eg upgrades and erasures of given packages 
outside of dependencies and unreliable scriptlet hacks. What to do with 
the scriptlet exit statuses I didn't and still dont know :)

	- Panu -

More information about the Rpm-maint mailing list