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