--- projects/cms/source/host/ihost-perl/ihost.pl 2001/03/15 09:46:18 1.31 +++ projects/cms/source/host/ihost-perl/ihost.pl 2001/11/14 16:41:30 1.36 @@ -5,12 +5,10 @@ # http://www.i-scream.org.uk # # An all-in-one script to act as an i-scream host on -# a typical Unix/Linux box. You may adapt the data-gathering -# methods as you see fit. -# - pjm2@ukc.ac.uk +# a typical Unix/Linux box. # -# $Author: pjm2 $ -# $Id: ihost.pl,v 1.31 2001/03/15 09:46:18 pjm2 Exp $ +# $Author: tdb $ +# $Id: ihost.pl,v 1.36 2001/11/14 16:41:30 tdb Exp $ #------------------------------------------------------------ $| = 1; @@ -35,6 +33,7 @@ use vars qw ( $fqdn $pidfile $retry_wait + @statgrab ); if (@ARGV != 2) { @@ -45,7 +44,7 @@ $filter_manager_addr = $ARGV[0]; $filter_manager_port = $ARGV[1]; $seq_no = 1; -$retry_wait = 600; +$retry_wait = 60; # write our PID to a file $pidfile = "/var/tmp/ihost.pid"; @@ -75,7 +74,7 @@ while (1) { else { $delay = $next_tcp; } - `sleep $delay`; + sleep $delay; } # we'll probably never get here... @@ -90,7 +89,7 @@ exit(0); #----------------------------------------------------------------------- sub wait_then_retry() { print "Will retry configuration with filter manager in $retry_wait seconds.\n"; - `sleep $retry_wait`; + sleep $retry_wait; } @@ -120,8 +119,8 @@ sub tcp_configure() { print $sock "STARTCONFIG\n"; $response = <$sock>; - if (!chop $response eq "OK") { - print "The i-scream server rejected the STARTCONFIG command. Terminated."; + if ($response && !($response eq "OK\n")) { + print "The i-scream server rejected the STARTCONFIG command.\n"; close($sock); wait_then_retry(); next; @@ -131,6 +130,12 @@ sub tcp_configure() { print $sock "LASTMODIFIED\n"; $response = <$sock>; + if (!$response) { + print "The i-scream server did not return anything for the LASTMODIFIED command.\n"; + close($sock); + wait_then_retry(); + next; + } chop $response; $last_modified = $response; @@ -138,6 +143,12 @@ sub tcp_configure() { print $sock "FILELIST\n"; $response = <$sock>; + if (!$response) { + print "The i-scream server did not provide a configuration file list.\n"; + close($sock); + wait_then_retry(); + next; + } chop $response; $file_list = $response; @@ -145,6 +156,12 @@ sub tcp_configure() { print $sock "FQDN\n"; $response = <$sock>; + if (!$response) { + print "The i-scream server did not tell us our FQDN.\n"; + close($sock); + wait_then_retry(); + next; + } chop $response; $fqdn = $response; @@ -152,11 +169,23 @@ sub tcp_configure() { print $sock "UDPUpdateTime\n"; $response = <$sock>; + if (!$response) { + print "The i-scream server did not give us a UDPUpdateTime.\n"; + close($sock); + wait_then_retry(); + next; + } chop $response; $udp_update_time = $response; print $sock "TCPUpdateTime\n"; $response = <$sock>; + if (!$response) { + print "The i-scream server did not give us a TCPUpdateTime.\n"; + close($sock); + wait_then_retry(); + next; + } chop $response; $tcp_update_time = $response; @@ -164,8 +193,7 @@ sub tcp_configure() { print $sock "ENDCONFIG\n"; $response = <$sock>; - chomp $response; - if (!$response eq "OK") { + if ($response && !($response eq "OK\n")) { print "ENDCONFIG command to server failed. Terminated.\n"; close($sock); wait_then_retry(); @@ -176,14 +204,14 @@ sub tcp_configure() { print $sock "FILTER\n"; $response = <$sock>; - unless (defined($response)) { + if (!$response) { print "Failed: Could not get a filter address from the filter manager.\n"; close($sock); wait_then_retry(); next; } chop $response; - $response =~ /(.*);(.*);(.*)/; + $response =~ /^(.*);(.*);(.*)/; if ($response eq "ERROR") { print "There are no active configured filters for your host.\n"; close($sock); @@ -202,12 +230,11 @@ sub tcp_configure() { print $sock "END\n"; $response = <$sock>; - chop $response; - if ($response eq "OK") { + if ($response && ($response eq "OK\n")) { print "Host successfully configured via TCP.\n" } else { - print "The server failed the host configuration on the END command."; + print "The server failed the host configuration on the END command.\n"; close($sock); wait_then_retry(); next; @@ -222,8 +249,6 @@ sub tcp_configure() { } - - #----------------------------------------------------------------------- # send_udp_packet # Sends a UDP packet to an i-scream filter. @@ -232,91 +257,29 @@ sub tcp_configure() { #----------------------------------------------------------------------- sub send_udp_packet() { - my(@statgrab) = `./statgrab.pl`; - my(%packet); - for (my($i) = 0; $i <= $#statgrab; $i++) { - $statgrab[$i] =~ /^([^\s]*) (.*)$/; - $packet{$1} = $2; - } + @statgrab = `./statgrab.pl`; + # get some extra data my($date) = time; + my($ip); + $ip = inet_ntoa(scalar(gethostbyname(hostname())) || 'localhost') or $ip = 'localhost'; - my($disk_info) = ""; - my($i) = 0; - while (defined $packet{"packet.disk.p$i.attributes.mount"}) { - $disk_info .= " - - $packet{"packet.load.load1"} - $packet{"packet.load.load5"} - $packet{"packet.load.load15"} - - - $packet{"packet.os.name"} - $packet{"packet.os.release"} - $packet{"packet.os.platform"} - $packet{"packet.os.sysname"} - $packet{"packet.os.version"} - $packet{"packet.os.uptime"} - - - $packet{"packet.users.count"} - $packet{"packet.users.list"} - - - $packet{"packet.processes.total"} - $packet{"packet.processes.sleeping"} - $packet{"packet.processes.zombie"} - $packet{"packet.processes.stopped"} - $packet{"packet.processes.cpu"} - - - $packet{"packet.cpu.idle"} - $packet{"packet.cpu.user"} - $packet{"packet.cpu.kernel"} - $packet{"packet.cpu.iowait"} - $packet{"packet.cpu.swap"} - - - $packet{"packet.memory.total"} - $packet{"packet.memory.free"} - - - $packet{"packet.swap.total"} - $packet{"packet.swap.free"} - - $disk_info - - -EOF - - # Make the packet smaller by stripping out newlines and leading spaces. - $xml =~ s/\n\s*//g; - + # turn the array into some nice XML + my($xml) = &make_xml("", ""); + my($sock) = new IO::Socket::INET ( PeerPort => $udp_port, PeerAddr => $filter_addr, Proto => 'udp' ) or die "Could not send UDP: $!\n"; - + print $sock $xml or die "Could not send UDP packet: $!\n"; close($sock); $seq_no++; @@ -326,15 +289,17 @@ EOF } - - #----------------------------------------------------------------------- # send_tcp_heartbeat # Establishes a TCP connection to an i-scream filter. # The heartbeat is used as a guaranteed "I'm alive" delivery mechanism. +# If we need to reconfigure, then we complete the heartbeat before +# doing so. #----------------------------------------------------------------------- sub send_tcp_heartbeat() { + my ($doReconfigure) = 0; + my($sock) = new IO::Socket::INET( PeerAddr => $filter_addr, PeerPort => $tcp_port, @@ -351,9 +316,7 @@ sub send_tcp_heartbeat() { print $sock "HEARTBEAT\n"; $response = <$sock>; - return if (!defined $response); - chop $response; - if (!$response eq "OK") { + if (!$response eq "OK\n") { close($sock); print "Server gave wrong response to HEARTBEAT: $response\n"; &tcp_configure(); @@ -362,9 +325,7 @@ sub send_tcp_heartbeat() { print $sock "CONFIG\n"; $response = <$sock>; - return if (!defined $response); - chop $response; - if (!$response eq "OK") { + if (!$response eq "OK\n") { close($sock); print "Server gave wrong response to CONFIG: $response\n"; &tcp_configure(); @@ -373,9 +334,7 @@ sub send_tcp_heartbeat() { print $sock "$file_list\n"; $response = <$sock>; - return if (!defined $response); - chop $response; - if (!$response eq "OK") { + if (!$response eq "OK\n") { close($sock); print "Server gave wrong response to file list: $response\n"; &tcp_configure(); @@ -384,15 +343,12 @@ sub send_tcp_heartbeat() { print $sock "$last_modified\n"; $response = <$sock>; - return if (!defined $response); - chop $response; - if ($response eq "ERROR") { + if ($response eq "ERROR\n") { close($sock); print "Server configuration changed. Reconfiguring with filter manager.\n"; - &tcp_configure(); - return; + $doReconfigure = 1; } - if (!$response eq "OK") { + if (!$response eq "OK\n") { close($sock); print "Server gave wrong response to HEARTBEAT: $response\n"; &tcp_configure(); @@ -401,9 +357,7 @@ sub send_tcp_heartbeat() { print $sock "ENDHEARTBEAT\n"; $response = <$sock>; - return if (!defined $response); - chop $response; - if (!$response eq "OK") { + if (!$response eq "OK\n") { close($sock); print "Server gave wrong response to ENDHEARTBEAT: $response\n"; &tcp_configure(); @@ -413,9 +367,12 @@ sub send_tcp_heartbeat() { close($sock); print "^"; + &tcp_configure() if $doReconfigure; + return; } + #----------------------------------------------------------------------- # write_pid # Writes the PID (process ID) of this instance to $pidfile. @@ -427,4 +384,37 @@ sub write_pid() { close PID; return; +} + +#----------------------------------------------------------------------- +# make_xml +# Turns an array of statgrab data into an XML string. +#----------------------------------------------------------------------- +sub make_xml() { + my($curlevel, $curline) = @_; + my($xmltemp) = ""; my($curtag) = ""; my($attributes) = ""; + while(true) { + $curline = shift(@statgrab) if $curline eq ""; chomp $curline; + if($curline =~ /^$curlevel([^\.\s]+\.)/) { + $curtag=$1; + } + if($curline =~ /^$curlevel$curtag([^\.\s]+)\s+(.*)$/) { + $xmltemp .= "<$1$attributes>$2"; + } + elsif($curline =~ /^$curlevel$curtag(attributes)\.([^\.=]+)=(.*)$/) { + $attributes .= " $2=\"$3\""; + } + else { + $xmltemp .= &make_xml("$curlevel$curtag", $curline); + } + my($nextline) = $statgrab[0]; chomp $nextline if defined $nextline; + $curtag =~ s/(.*)\./$1/; + if(defined $nextline && $nextline =~ /^$curlevel$curtag\./) { + $curline = ""; + } + else { + $xmltemp = "<$curtag$attributes>$xmltemp" unless $curtag eq ""; + return $xmltemp; + } + } }