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");
 }

Reply via email to