Mailing List Archive

svn commit: r440066 - in /spamassassin/trunk: lib/Mail/SpamAssassin/SpamdForkScaling.pm spamd/spamd.raw t/spamd_hup.t
Author: jm
Date: Mon Sep 4 06:18:46 2006
New Revision: 440066

URL: http://svn.apache.org/viewvc?view=rev&rev=440066
Log:
bug 5081: sometimes, SIGHUPing spamd would leave one child process still alive due to a race in the SIGHUP handler and the preforking code. fixed

Modified:
spamassassin/trunk/lib/Mail/SpamAssassin/SpamdForkScaling.pm
spamassassin/trunk/spamd/spamd.raw
spamassassin/trunk/t/spamd_hup.t

Modified: spamassassin/trunk/lib/Mail/SpamAssassin/SpamdForkScaling.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/SpamdForkScaling.pm?view=diff&rev=440066&r1=440065&r2=440066
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/SpamdForkScaling.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/SpamdForkScaling.pm Mon Sep 4 06:18:46 2006
@@ -122,6 +122,15 @@
$self->compute_lowest_child_pid();
}

+# this is called by SIGTERM and SIGHUP handlers, to ensure that new
+# kids aren't added while the main code is killing the old ones
+# and planning to exit.
+#
+sub set_exiting_flag {
+ my ($self) = @_;
+ $self->{am_exiting} = 1;
+}
+
sub child_error_kill {
my ($self, $pid, $sock) = @_;

@@ -651,6 +660,9 @@

sub adapt_num_children {
my ($self) = @_;
+
+ # don't start up new kids while main is working at killing the old ones
+ return if $self->{am_exiting};

my $kids = $self->{kids};
my $statestr = '';

Modified: spamassassin/trunk/spamd/spamd.raw
URL: http://svn.apache.org/viewvc/spamassassin/trunk/spamd/spamd.raw?view=diff&rev=440066&r1=440065&r2=440066
==============================================================================
--- spamassassin/trunk/spamd/spamd.raw (original)
+++ spamassassin/trunk/spamd/spamd.raw Mon Sep 4 06:18:46 2006
@@ -673,12 +673,12 @@
my $gid = -1;
if ($owner) {
my ($login,$pass,$puid,$pgid) = getpwnam($owner)
- or die "spamd: $owner not in passwd database\n";
+ or die "spamd: $owner not in passwd database\n";
$uid = $puid;
}
if ($group) {
my ($name,$pass,$ggid,$members) = getgrnam($group)
- or die "spamd: $group not in group database\n";
+ or die "spamd: $group not in group database\n";
$gid = $ggid;
}
if (!chown $uid, $gid, $path) {
@@ -704,7 +704,7 @@
);
dbg("spamd: creating SSL socket:\n" . join("\n", map { " $_: " . (defined $socket{$_} ? $socket{$_} : "(undef)") } sort keys %socket));
$server = new IO::Socket::SSL(%socket)
- || die "spamd: could not create SSL socket on $addr:$port: $!\n";
+ || die "spamd: could not create SSL socket on $addr:$port: $!\n";
}
else {
my %socket = (
@@ -717,7 +717,7 @@
);
dbg("spamd: creating INET socket:\n" . join("\n", map { " $_: " . (defined $socket{$_} ? $socket{$_} : "(undef)") } sort keys %socket));
$server = new_io_socket_inetx(%socket)
- || die "spamd: could not create INET socket on $addr:$port: $!\n";
+ || die "spamd: could not create INET socket on $addr:$port: $!\n";
}

if ( defined $opt{'pidfile'} ) {
@@ -2033,6 +2033,9 @@
}

$SIG{CHLD} = 'DEFAULT'; # we're going to kill our children
+ if ($scaling) {
+ $scaling->set_exiting_flag(); # don't start new ones
+ }
kill 'INT' => keys %children;
exit 0;
}
@@ -2075,6 +2078,10 @@
info("spamd: server hit by SIG$sig, restarting");

$SIG{CHLD} = 'DEFAULT'; # we're going to kill our children
+ if ($scaling) {
+ $scaling->set_exiting_flag(); # don't start new ones
+ }
+
foreach (keys %children) {
kill 'INT' => $_;
my $pid = waitpid($_, 0);

Modified: spamassassin/trunk/t/spamd_hup.t
URL: http://svn.apache.org/viewvc/spamassassin/trunk/t/spamd_hup.t?view=diff&rev=440066&r1=440065&r2=440066
==============================================================================
--- spamassassin/trunk/t/spamd_hup.t (original)
+++ spamassassin/trunk/t/spamd_hup.t Mon Sep 4 06:18:46 2006
@@ -69,7 +69,7 @@
chomp $npid;
close(PID);
} else {
- print "Could not open pid file ${pid_file}: $!\n";
+ die "Could not open pid file ${pid_file}: $!\n";
}
#} until ($npid != $opid or $timeout == 0);
return $npid;