Package: debconf
Version: 1.5.14
(Mostly cloned from #425397 at the request of Joey Hess. I've been
running puppet in the d-i/late-command part of the install to get these
problems, if it helps I'll try and trim it down (I suspect a preseeded
postfix install might be sufficient))
I'm using puppet at the end of a preseeded install and some packages
keep hanging (sysstat and postfix namely). I suspect it's the
preseeding that's causing the problem.
What I see is dpkg-preconfigure running /tmp/postfix.config.12345
(sometimes with a zombie'd process in the middle). dpkg-preconfigure
is reading from FD8 (which is FD1 from the postfix.config), the
postfix-config in turn is reading from FD0 (which is FD7 from the
dpkg-preconfigure). Deadlock ensues :-(
I've been trying to do some debugging but it's a bit tricky as I'm not
sure exactly which frontends etc end up being run. puppet is calling
apt which is set to run dpkg-preconfigure, overall therefore, the
config file thus gets run once by dpkg-preconfigure and once normally.
When postfix.config runs /usr/share/debconf/confmodules, at line 45 it
complains that FD3 is a bad file descriptor. Listing /proc/$$/fd
shows that FD3 doesn't exist. FD2 points to the overall stderr, FD1
is a pipe back to FD8 of dpkg-preconfigure. FD0 is FD7 from
dpkg-preconfigure.
FD3 exists and DEBCONF_REDIR is set when ConfModule::startup() is
called, however it looks like FD3 does not persist into the open2()
call.
It appears
that when kicked off through a preseed install, DEBCONF_REDIR and file
descriptor 3 (hereafter FD3) are set.
These are set all the way down the stack upto and including apt-get.
However when apt-get runs dpkg-preconfigure, FD3 is no where to be
seen. I put a "sleep" right at the top of dpkg-preconfigure and I
still couldn't see it - so I'm fairly sure that apt-get is not passing
FD3 though.
(It looks like apt-get is closing the FDs in ExecFork which does look
at an APT::Keep-Fds option but I've not looked any further.)
As a gross hack workaround (which might break god knows what else)
I've edited /usr/share/debconf/confmodule to unset DEBCONF_REDIR if
/proc/$$/fd/3 does not exist.
I now no longer get the confmodule line 42: 3: Bad file descriptor
error messages :-)
However, I still get some hangs (one I've seen before). In this case,
dpkg-preconfigure is sat in a waitpid(pidof /tmp/postfix.config...)
whilst postfix.config is sat reading STDIN (which is FD#8 from the
dpkg-preconfigure. There is a dpkg-preconfigure zombie process
between these two.
Well after several days of pouring over "ls -l /proc/$$/fd" output etc
(and with very little actually understanding of how the
DEBIAN_FRONTEND, DEBIAN_HAS_FRONTEND, DEBCONF_REDIR is supposed to
be being used!), I have some workarounds which let me use puppet with
a debian preseed to make a fully automated install.
I've attached the three patches I'm using (on top of your debconf
patch) which allow this to work. Mostly they involve checking if file
descriptor #3 is actually open - if it's not then unset DEBCONF_REDIR
(and possibly DEBIAN_HAS_FRONTEND - I only just saw that there is also
DEBIAN_FRONTEND :-( ). BTW ClientConfModule.pm is the
"Client/ConfModule.pm" file.
Adrian
--- debconf/usr/share/perl5/Debconf/Client/ConfModule.pm 2007-07-25 14:59:58.000000000 +0100
+++ /tmp/ClientConfModule.pm 2007-08-22 08:53:13.000000000 +0100
@@ -86,7 +86,9 @@
# /usr/share/debconf/confmodule is loaded, and then this
# perl module is used. In that case, this module needs to write
# to fd #3, rather than stdout. See changelog 0.3.74.
# apt-get is closing the FD without unsetting the ENV
- if (exists $ENV{DEBCONF_REDIR} && $ENV{DEBCONF_REDIR}) {
+ if (exists $ENV{DEBCONF_REDIR} && $ENV{DEBCONF_REDIR}
+ && -e "/proc/$$/fd/3") {
open(STDOUT,">&3");
}
}
7a8,15
> # apt-get is closing the FDs without unsetting the ENV
> if [ "$DEBCONF_REDIR" ]; then
> if ! [ -e /proc/$$/fd/3 ]; then
> unset DEBCONF_REDIR
> unset DEBIAN_HAS_FRONTEND
> fi
> fi
>
--- debconf/usr/sbin/dpkg-preconfigure 2007-07-25 14:59:59.000000000 +0100
+++ /tmp/dpkg-preconfigure 2007-08-22 08:51:34.000000000 +0100
@@ -35,6 +35,16 @@
@ARGV=();
my $have_tty=1;
+ # apt-get is closing the FD without unset the ENV
+ if ($ENV{DEBCONF_REDIR}) {
+ local (*TMP);
+ if (! open(TMP,"<&3")) {
+ delete $ENV{DEBCONF_REDIR};
+ delete $ENV{DEBIAN_HAS_FRONTEND};
+ } else {
+ close TMP;
+ }
+ }
if ($apt) {
while (<>) {
@@ -100,6 +109,7 @@
exit;
}
my @buffer=<INFO>;
+close INFO;
if ($apt && @buffer) {
print gettext("Preconfiguring packages ...\n");
}