# Automatically added by dh_installdebconf
if [ "$1" = purge -a -e /usr/share/debconf/confmodule ]; then
. /usr/share/debconf/confmodule
db_purge
fi
# End automatically added section
However, there may be a package, that provides additional features to other
daemons. Said package may deregister itself during postrm, and restart the
other service/daemon. Because the above block doesn't call db_stop, there is
the potential for the fd problem.
Additionally, it could be argued that there should be no communication with
debconf after db_purge is called. However, one may still need to fetch shared
values, so that's a difficult one to deside.
I haven't actually seen a problem in the real world, but it's possible that
one could arise.
Adam Heath wrote: Uh huh. <bap>
dh_installdebconf inserts code into the postrm which calls db_purge (unprotected, but a debconf protocol dump shows that PURGE returns status 0). It fails to call db_stop, as warned by #133029. This leaves our postinst will all stdout output redirected into confmodule, which seems to cause the mess. Editing /var/lib/dpkg/info/amavisd-new.postrm first line to #!/bin/sh -x shows that, as expected, calling confmodule in the middle of the script is an extremely dumb thing to do, as it runs part of the script twice... Instead of moving #DEBHELPER# to the top of the script, or trying to second-guess what kind of mess we could get into yet again, I am disabling debhelper-included dh_installdebconf scripts, and doing it by ourselves. Report cc'ed to #133029 so that Joey can be reminded of that report, and that it does cause issues on real world packages (note that I am not blaming the bug on debhelper, it is just that our usage is not compatible with the script it produces). Just for the kick of it, here's the full dump, with debconf protocol debug enabled. (steps to reproduce): login in a sarge chroot (pbuilder, new debootstrap one) apt-get install amavisd-new sed -i s/sarge/testing/g /etc/apt/sources.list apt-get update ; apt-get install amavisd-new (amavisd-new will be upgraded correctly) export DEBCONF_DEBUG=developer sed -i '1 s@#!.*@#!/bin/sh -x@' /var/lib/dpkg/info/amavisd-new.postrm dpkg -P amavisd-new [output of dpkg -P amavisd-new] (Reading database ... 12164 files and directories currently installed.) Removing amavisd-new ... + set -e + '[' remove = purge ']' + '[' remove = purge ']' + exit 0 Purging configuration files for amavisd-new ... + set -e + dpkg-statoverride --remove /var/lib/amavis + dpkg-statoverride --remove /var/lib/amavis/db + dpkg-statoverride --remove /var/lib/amavis/tmp + dpkg-statoverride --remove /var/lib/amavis/virusmails + dpkg-statoverride --remove /var/run/amavis + getent passwd amavis + deluser amavis Removing user `amavis'... done. + getent group amavis + echo 'Removing amavis files and directories...' Removing amavis files and directories... + '[' -d /var/lib/amavis ']' + rm -fr /var/lib/amavis + '[' -d /etc/amavis ']' + rm -fr /etc/amavis + '[' purge = purge ']' + '[' -e /usr/share/debconf/confmodule ']' + . /usr/share/debconf/confmodule ++ '[' '!' '' ']' ++ PERL_DL_NONLAZY=1 ++ export PERL_DL_NONLAZY ++ exec /usr/share/debconf/frontend /var/lib/dpkg/info/amavisd-new.postrm purge debconf (developer): frontend started debconf (developer): frontend running, package name is amavisd-new debconf (developer): starting /var/lib/dpkg/info/amavisd-new.postrm purge + set -e + dpkg-statoverride --remove /var/lib/amavis No override present. + true + dpkg-statoverride --remove /var/lib/amavis/db No override present. + true + dpkg-statoverride --remove /var/lib/amavis/tmp No override present. + true + dpkg-statoverride --remove /var/lib/amavis/virusmails No override present. + true + dpkg-statoverride --remove /var/run/amavis No override present. + true + getent passwd amavis + getent group amavis + echo 'Removing amavis files and directories...' debconf (developer): <-- Removing amavis files and directories... + '[' -d /var/lib/amavis ']' + '[' -d /etc/amavis ']' + '[' purge = purge ']' + '[' -e /usr/share/debconf/confmodule ']' + . /usr/share/debconf/confmodule ++ '[' '!' 1 ']' ++ '[' -z '' ']' ++ exec ++ DEBCONF_REDIR=1 ++ export DEBCONF_REDIR + db_purge + _db_cmd 'PURGE ' + echo 'PURGE ' debconf (developer): <-- PURGE + local 'IFS= ' + local _LINE + read -r _LINE + RET=20 Unsupported command "removing" (full line was "Removing amavis files an d directories...") received from confmodule. + return 20 debconf (developer): --> 0 dpkg: error processing amavisd-new (--purge): subprocess post-removal script returned error exit status 128 Errors were encountered while processing: amavisd-new
Henrique> This leaves our postinst will all stdout output
Henrique> redirected into confmodule, which seems to cause the
Henrique> mess.
I don't particularly like the debconf standard of using stdout for its
command stream. Too many programs use stdout to write anything they
desire. Not only that, but the error generated is very obscure (unless
you have debugging turned on and are competent enough to understand
it). I don't think it was even obvious that the error was being
generated from debconf. It would be better to redirect stdout -->
/dev/null IMHO, and use some other hard coded file handle for debconf.
In this case it would appear that the problem is caused by echo
statements in our script (do we really need them?). Like the
following:
Henrique> + echo 'Removing amavis files and directories...'
Henrique> Removing amavis files and directories...
However all you need is for one of the many utility programs we use,
eg:
Henrique> + deluser amavis
Henrique> Removing user `amavis'...
Henrique> done.
to output the status information to stdout instead of stderr (I assume
it is currently using stderr as this line didn't seem to upset
debconf) for some obscure/untested condition, and our scripts starts
outputting to stdout again. In fact, I would argue that deluser should
be outputting this to stdout, the status information shown above is
hardly an error condition.
I don't disagree, but you can fix it pretty easily by doing exec 1>&2; right? Justin
Justin> I don't disagree, but you can fix it pretty easily by doing
Justin> exec 1>&2;
Justin> right?
Won't this break debconf commands?
Meh, I don't know, what I mean is, you can use exec to avoid lots of echo >&3 foo if you have a large chunk of not-debconf stuff.
Hello,
Adam Heath, 2002-02-08 17:17-0600:
This is just an update to point out that it has been seen in the real
world, as I just ran into that issue while packaging pluxml (#630467).
pluxml is a blog engine, so upcoming my package installs some
configuration for apache2 or lighttpd and then reloads these daemons. No
problem in postinst, where at the end of the script:
1. I call db_stop;
2. dh_installdebconf adds nothing;
3 the script exists fine.
But in postrm, things happen differently. I remove the configuration
from apache2 or lighttpd, reload these daemons, and at the end of the
script:
1. I call db_stop;
2. dh_installdebconf inserts some code that sources
/usr/share/debconf/confmodule again, which starts debconf (I do not
know the dirty details) and calls db_purge;
3. the script stalls, or rather, exists, but stays defunct with a
debconf wrapper waiting for nothing, as it seems.
I solved that problem by moving my call to db_stop after the #DEBHELPER#
placeholder.
Would there be a problem in adding a call to db_stop after db_purge, in
the code added to postrm by dh_installdebconf? Otherwise, that problem
could be mitigated by adding a notice in dh_installdebconf(1) and
probably in debconf-devel(7) too, telling people to put their call to
db_stop after the debhelper placeholder, as I did.
Librement,