alter shutdown behaviour to send a term signal to all processes and then go through again to send a KILL if neccessary. This eliminates unneccesary sleeping.

This commit is contained in:
Isaac Connor 2015-05-21 15:37:08 -04:00
parent d509861f9e
commit 47192156cd
1 changed files with 69 additions and 44 deletions

View File

@ -219,7 +219,7 @@ package ZMServer;
use strict;
use bytes;
@EXTRA_PERL_LIB@
use lib '/usr/share/perl/5.20.2'; # Include custom perl install path
use ZoneMinder;
use POSIX;
use Socket;
@ -414,8 +414,7 @@ sub start
my $daemon = shift;
my @args = @_;
my $command = $daemon;
$command .= ' '.join( ' ', ( @args ) ) if ( @args );
my $command = join(' ', $daemon, @args );
my $process = $cmd_hash{$command};
if ( !$process )
@ -506,22 +505,12 @@ sub start
}
}
sub _stop
{
my $final = shift;
my $daemon = shift;
my @args = @_;
# Sends the stop signal, without waiting around to see if the process died.
sub send_stop {
my ( $final, $process ) = @_;
my $command = $daemon;
$command .= ' '.join( ' ', ( @args ) ) if ( @args );
my $process = $cmd_hash{$command};
if ( !$process )
{
dPrint( ZoneMinder::Logger::WARNING, "Can't find process with command of '$command'\n" );
return();
}
elsif ( $process->{pending} )
{
my $command = $process->{command};
if ( $process->{pending} ) {
delete( $cmd_hash{$command} );
dPrint( ZoneMinder::Logger::INFO, "Command '$command' removed from pending list at "
.strftime( '%y/%m/%d %H:%M:%S', localtime() )
@ -530,37 +519,63 @@ sub _stop
return();
}
my $cpid = $process->{pid};
if ( !$pid_hash{$cpid} )
my $pid = $process->{pid};
if ( !$pid_hash{$pid} )
{
dPrint( ZoneMinder::Logger::ERROR, "No process with command of '$command' is running\n" );
dPrint( ZoneMinder::Logger::ERROR, "No process with command of '$command' pid $pid is running\n" );
return();
}
dPrint( ZoneMinder::Logger::INFO, "'$daemon ".join( ' ', @args )
."' stopping at "
dPrint( ZoneMinder::Logger::INFO, "'$command' sending stop to pid $pid at "
.strftime( '%y/%m/%d %H:%M:%S', localtime() )
."\n"
);
$process->{keepalive} = !$final;
kill( 'TERM', $cpid );
delete( $cmd_hash{$command} );
kill( 'TERM', $pid );
return $pid;
} # end sub send_stop
sub kill_until_dead {
my ( $process ) = @_;
# Now check it has actually gone away, if not kill -9 it
my $count = 0;
while( $cpid && kill( 0, $cpid ) )
while( $process and $$process{pid} and kill( 0, $$process{pid} ) )
{
if ( $count++ > 5 )
{
kill( 'KILL', $cpid );
dPrint( ZoneMinder::Logger::WARNING, "'$$process{command}' has not stopped at "
.strftime( '%y/%m/%d %H:%M:%S', localtime() )
.". Sending KILL to pid $$process{pid}\n"
);
kill( 'KILL', $$process{pid} );
}
sleep( 1 );
}
}
sub _stop {
my ($final, $process ) = @_;
my $pid = send_stop( $final, $process );
return if ! $pid;
kill_until_dead( $process );
delete( $cmd_hash{$$process{command}} );
}
sub stop
{
_stop( 1, @_ );
my ( $daemon, @args ) = @_;
my $command = join(' ', $daemon, @args );
my $process = $cmd_hash{$command};
if ( !$process )
{
dPrint( ZoneMinder::Logger::WARNING, "Can't find process with command of '$command'\n" );
return();
}
_stop( 1, $process );
}
sub restart
@ -578,7 +593,7 @@ sub restart
my $cpid = $process->{pid};
if ( defined($pid_hash{$cpid}) )
{
_stop( 0, $daemon, @args );
_stop( 0, $process );
return;
}
}
@ -718,9 +733,20 @@ sub restartPending
sub shutdownAll
{
foreach my $process ( values( %pid_hash ) )
{
stop( $process->{daemon}, @{$process->{args}} );
foreach my $pid ( keys %pid_hash ) {
# This is a quick fix because a SIGCHLD can happen and alter pid_hash while we are in here.
next if ! $pid_hash{$pid};
send_stop( 1, $pid_hash{$pid} );
}
foreach my $pid ( keys %pid_hash ) {
# This is a quick fix because a SIGCHLD can happen and alter pid_hash while we are in here.
next if ! $pid_hash{$pid};
my $process = $pid_hash{$pid};
kill_until_dead( $process );
delete( $cmd_hash{$$process{command}} );
delete( $pid_hash{$pid} );
}
killAll( 5 );
dPrint( ZoneMinder::Logger::INFO, "Server shutdown at "
@ -830,21 +856,20 @@ sub killAll
{
my $delay = shift;
sleep( $delay );
my $killall;
if ( '@HOST_OS@' eq 'BSD' )
{
$killall = 'killall -';
} elsif ( '@HOST_OS@' eq 'solaris' ) {
my $killall;
if ( 'linux' eq 'BSD' )
{
$killall = 'killall -';
} elsif ( 'linux' eq 'solaris' ) {
$killall = 'pkill -';
} else {
$killall = 'killall -q -s ';
}
} else {
$killall = 'killall -q -s ';
}
foreach my $daemon ( @daemons )
{
my $cmd = $killall ."TERM $daemon";
Debug( $cmd );
qx( $cmd );
my $cmd = $killall ."TERM $daemon";
Debug( $cmd );
qx( $cmd );
}
sleep( $delay );
foreach my $daemon ( @daemons )