From: Stephen L Johnson Date: Wed, 5 Jan 2000 15:26:33 +0000 (+0000) Subject: Changed child process management to make it easier to scale. Update processes X-Git-Tag: spong-2_7-alpha5~120 X-Git-Url: http://git.etc.gen.nz/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3841f39409f3de0f9f67c5a9aad24a2ebe65be4d;p=spong.git Changed child process management to make it easier to scale. Update processes can now be selectively enabled. --- diff --git a/src/spong-server.pl b/src/spong-server.pl index f8f6b11..1c043cd 100755 --- a/src/spong-server.pl +++ b/src/spong-server.pl @@ -47,14 +47,26 @@ $HOST =~ tr/A-Z/a-z/; &load_data_funcs(); &debug("Done loading data plugins"); -$upd_pid = 0; -$bb_pid = 0; +%PROCS = (); # All of the procs that we will be monitoring in the main process + $shutdown = 0; &load_config_files(); # Loads the user specified configuration information Spong::Daemon::Daemonize() unless ($debug || $restart || $kill) ; &handle_signals(); # Set up handlers, and signal the current server if asked +# Determine all of the update processes that will need to be running +$PROCS{'query'} = { func => \&listen_for_queries, pid => undef }; + +if ( defined $SPONG_BB_UPDATE_PORT ) { + $PROCS{'bb-update'} = { func => \&listen_for_bb_updates, pid => undef }; +} + +if (defined $SPONG_UPDATE_PORT ) { + $PROCS{'spong-update'} = { func => \&listen_for_updates, pid => undef }; +} + + # Establish a list of all the services that we monitor so that we can be # consistant in the output that we display regardless of the group that we # are showing. @@ -64,31 +76,37 @@ Spong::Daemon::Daemonize() unless ($debug || $restart || $kill) ; foreach $host ( Spong::HostList->new( "all" )->hosts() ) { foreach $service ( $host->service_names() ) { $main::SERVICES{$service}=1;}} -# Split into two processes, one process listens at port 1970 for update -# messages, and the other process listens at port 1960 and responds to query -# messages. Both processes are "single-threaded", they don't fork off +# Split into lots of processes, the main process is the master process spawns +# off the rest of the processes as children and restarted them when they die. +# One mandatory processes listens at port 1999 for query messages. The rest +# of the processes are that listen for update messages via various different +# protocols +# All child processes are "single-threaded", they don't fork off # additional subprocesses, they just deal with the message setting at their # queue, and then process the next message as it comes in. $SIG{'CHLD'} = \&chld_handler; -if( $upd_pid = fork() ) { - if( $bb_pid = fork() ) { - &listen_for_queries(); - } elsif( defined $bb_pid ) { - &listen_for_bb_updates(); +while ( my($name,$proc) = each %PROCS ) { + my $pid = fork(); + if (! defined $pid ) { + die "Error: Could not fork for $name process: $!"; + } elsif ($pid) { + # I'm the parent, save the child's pid. + $proc->{'pid'} = $pid; } else { - die "Can't bb fork: $!"; + # I'm the child, call function I'm assigned + $0 = "spong-server ($name)"; + &{$proc->{'func'}}(); } -} elsif( defined $upd_pid ) { - &listen_for_updates(); -} else { - die "Can't update fork: $!"; } -# We should not get here, if we do then something is wrong... +$0 = "spong-server (main)"; -die "Error: Exiting spong-server!\n"; +# At this point we just sleep, and handle dead children +while ( 1 ) { + sleep 30; +} # This procedure listens for connections at port 1970 (the update port), and @@ -101,10 +119,10 @@ sub listen_for_updates { # Set up the socket to listen to $SIG{'PIPE'} = 'IGNORE'; - $SIG{'QUIT'} = sub {&debug('spong updates caught QUIT signal, exiting'); - close SERVER; exit;}; - $SIG{'HUP'} = sub {&debug('spong updates caught HUP signal, exiting'); - close SERVER; exit;}; + $SIG{'TERM'} = $SIG{'HUP'} = $SIG{'QUIT'} = sub { + &debug('spong updates caught QUIT signal, exiting'); + close SERVER; exit; + }; my $proto = getprotobyname( 'tcp' ); @@ -155,8 +173,10 @@ sub listen_for_bb_updates { # Set up the socket to listen to $SIG{'PIPE'} = 'IGNORE'; - $SIG{'QUIT'} = sub {&debug('bb updates caught QUIT signal, exiting'); - close SERVER; exit;}; + $SIG{'TERM'} = $SIG{'HUP'} = $SIG{'QUIT'} = sub { + &debug('spong updates caught QUIT signal, exiting'); + close SERVER; exit; + }; $SIG{'HUP'} = sub {&debug('bb updates caught HUP signal, exiting'); close SERVER; exit;}; @@ -210,6 +230,10 @@ sub listen_for_queries { # Set up the socket to listen to $SIG{'PIPE'} = 'IGNORE'; + $SIG{'TERM'} = $SIG{'HUP'} = $SIG{'QUIT'} = sub { + &debug('spong updates caught QUIT signal, exiting'); + close SERVER; exit; + }; my $proto = getprotobyname( 'tcp' ); my $p = pack( "l", 1 ); @@ -864,7 +888,10 @@ sub fmt_error { sub exit_handler { &debug( "caught QUIT signal, exiting..." ); $shutdown = 1; - kill QUIT,$upd_pid,$bb_pid; + while ( my($name,$proc) = (each %PROCS) ) { + kill QUIT,$proc->{'pid'}; + } +# kill QUIT,$upd_pid,$bb_pid; unlink "$SPONGTMP/spong-server.pid" if -f "$SPONGTMP/spong-server.pid"; exit(0); } @@ -873,8 +900,11 @@ sub hup_handler { &debug( "caught HUP signal, restarting..." ); $shutdown = 1; $SIG{CHLD} = 'DEFAULT'; - kill QUIT,$upd_pid; waitpid($upd_pid,0); - kill QUIT,$bb_pid; waitpid($bb_pid,0); + while ( my($name,$proc) = (each %PROCS) ) { + kill QUIT,$proc->{'pid'}; waitpid($proc->{'pid'},0); + } +# kill QUIT,$upd_pid; waitpid($upd_pid,0); +# kill QUIT,$bb_pid; waitpid($bb_pid,0); unlink "$SPONGTMP/spong-server.pid" if -f "$SPONGTMP/spong-server.pid"; close( SERVER ); if( $debug ) { exec $me, "--debug"; } else { exec $me; } @@ -891,23 +921,21 @@ sub chld_handler { } &debug( "caught CHLD signal, restarting child..." ); - if ($pid == $upd_pid) { - if( $upd_pid = fork() ) { - return; - } elsif( defined $upd_pid ) { - &listen_for_updates(); - } else { - die "Can't fork: $!"; - } - } elsif ($pid == $bb_pid ) { - if( $bb_pid = fork() ) { - return; - } elsif( defined $bb_pid ) { - &listen_for_bb_updates(); - } else { - die "Can't fork: $!"; + while( my($name,$proc) = each %PROCS ) { + if ( $pid == $proc->{'pid'} ) { + my $pid = fork(); + if (! defined $pid ) { + die "Error: Cannot fork for $name process: $!"; + } elsif ($pid) { + # I'm the parent, save the new child pid + $proc->{'pid'} = $pid; + } else { + # I'm the parent, call the function I'm assigned + &{$proc->{'func'}}(); + } } } + } # ---------------------------------------------------------------------------