Bug or feature ...

Scott Kitterman ubuntu at kitterman.com
Wed Apr 6 21:35:07 UTC 2011


There's recently been a ~long thread on amavis-users [1] about restart 
problems in Natty.  This is also an Ubuntu bug [2].  The conclusion of the 
thread is (from the amavis upstream):

> So what this means for restarting amavis: it means that on Ubuntu Natty
> a start of amavisd must not occur before all child processes of a
> previous incarnation have exited, thus fully releasing a socket.
>
> On other systems (Maverick, FreeBSD, ...) it suffices to wait for the
> main process to exit.
> 
> Can't tell if this is a feature of the new Linux kernel or a bug.

He offers this as a test case:

 #!/usr/bin/perl
use strict;
use Socket;

  socket(Server, PF_INET, SOCK_STREAM, getprotobyname('tcp'))
    or die "socket: $!";
  setsockopt(Server, SOL_SOCKET, SO_REUSEADDR, pack('l', 1))
    or die "setsockopt: $!";
  bind(Server, sockaddr_in(2222, inet_aton('127.0.0.1')))
    or die "bind: $!";
  listen(Server, SOMAXCONN)
    or die "listen: $!";

  my $pid = fork();
  if (!$pid) {  # child
    print "\nChild $$\n";
    sleep 10;
    exit;
  }

  # parent
  print "\nParent $$\n";
  shutdown(Server,2)  or die "shutdown: $!";


He also offers a patch for libnet-server-perl to respond to this change

--- Net/Server.pm~      2010-07-09 16:55:31.000000000 +0200
+++ Net/Server.pm       2011-04-05 21:47:18.318431988 +0200
@@ -32,4 +32,5 @@
 use Fcntl ();
 use FileHandle;
+use Errno qw(ESRCH);
 use Net::Server::Proto ();
 use Net::Server::Daemonize qw(check_pid_file create_pid_file
@@ -1098,14 +1099,38 @@
 
   foreach my $pid (keys %{ $prop->{children} }) {
-    ### if it is killable, kill it
-    if( ! defined($pid) || kill(15,$pid) || ! kill(0,$pid) ){
-      $self->delete_child( $pid );
-    }
-
+    kill(15,$pid) || $! == ESRCH
+      or $self->log(1, "Error sending SIGTERM to a child process [$pid]: 
$!");
   }
 
   ### need to wait off the children
-  ### eventually this should probably use &check_sigs
-  1 while waitpid(-1, POSIX::WNOHANG()) > 0;
+  my $process_group;
+  $process_group = $$  if $prop->{setsid};
+  if ($process_group) {
+    $self->log(3, "Close_children, waiting for %s procs in proc group [%s]",
+                  scalar keys %{ $prop->{children} }, $process_group);
+  } else {
+    $self->log(3, "Close_children, waiting for %s processes",
+                  scalar keys %{ $prop->{children} });
+  }
+  while (%{ $prop->{children} }) {
+    my($pid, $child_pid);
+    if ($process_group) {
+      $child_pid = waitpid(-$process_group, 0); # any child of a process 
group
+    } else {
+      $pid = (keys %{ $prop->{children} })[0];  # pick one explicitly
+      $child_pid = waitpid($pid,0);
+    }
+    my $child_status = $?;
+    if (!$child_pid || $child_pid == -1) {
+      $self->log(1, "Unable to obtain exit status of a child process 
[$pid]");
+      $child_pid = $pid;
+    } elsif (!$child_status) {
+      $self->log(3, "Child process [$child_pid] terminated with success");
+    } else {
+      $self->log(1, "Child process [%s] terminated with status %04x",
+                 $child_pid, $child_status);
+    }
+    $self->delete_child($child_pid)  if $child_pid;
+  }
 
 }

As the subject says, is this a bug or a new feature?  If it's a new feature, I 
can patch libnet-server-perl.  If it's a bug, it ought to be reassigned.  
Help.
[1] http://lists.amavis.org/pipermail/amavis-users/2011-March/000069.html
[2] https://bugs.launchpad.net/ubuntu/+source/amavisd-new/+bug/731878



More information about the ubuntu-devel mailing list