Subject: On sensors and burning up the CPU CHIP
To: None <netbsd-users@netbsd.org>
From: Todd Gruhn <tgruhn2@mail.com>
List: netbsd-users
Date: 09/30/2003 10:18:26
I got the kernel working with APC. Got daemon code
implemented properly. Built rc.d script.
Anyone want to suggest how I can further secure this
daemon? How I can speed it up?
#!/bin/sh
# $NetBSD: snmpd.sh,v 1.3 2001/01/26 02:02:35 hubertf Exp $
#NOTES: This script causes snmpd to put a pid file in /var/run/snmpd
# I can now start/stop/restart snmpd
# I modified it to use my config files (come with UCD-SNMP
# REQUIRE: DAEMON
# PROVIDE: stingerd
# BEFORE: LOGIN
# PID file:
PF=/var/run/stingerd.pid
case $1 in
start)
if [ -x /usr/local/sbin/stingerd ]
then
echo -n ' stingerd'
/usr/local/sbin/stingerd
fi
;;
stop)
if [ -f ${PF} ]; then
num=`cat ${PF}`
pidr=`expr $num + 1`
#The REAL PID...
kill $pidr
# kill `cat ${PF}`
rm -f ${PF}
else
echo "$0: stingerd not running or PID not recorded!" 1>&2
fi
;;
restart)
sh $0 stop
sh $0 start
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
esac
#! /usr/local/bin/perl -w
## MY SECOND attempt at writing daemon...
## Watch the CPU temp and FAN rpms lest I get stung by another
## burnt chip... Notify root via email, and shutdown system...
die ("Must be root to execute this script") if ($< && $>);
eval 'exec /usr/local/bin/perl -w -S $0 ${1+"$@"}'
if 0; # not running under some shell
$ENV{SHELL} = ""; # I set perlman PATH and SHELL for safety reasons
$ENV{PATH} = "/etc:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin";
use Log::Logger;
use Mail::Mailer;
use strict; #restrict unsafe programming; see CAMEL book p. 500
#use Proc::PID::File qw( :all ); #qw(:all);
use POSIX qw( setsid ) ;
use vars qw($ppid $pid); #DECLARE the global vars! SEE CAMEL Book, p. 516
&become_daemonic();
# Your code here
if (-e "/var/run/stingerd.pid")
{unlink "/var/run/stingerd.pid"}; # GET RID of old pid file
# pid_file_set( dir => "/var/run", name => "stingerd.pid" );
# die "Already running!" if pid_file_alive();
# die "Already running!" if Proc::PID::File->running();
open(PIDFILE,"+>/var/run/stingerd.pid");
print PIDFILE $ppid; #was $pid_target; ## ESTAB. a new PIDFILE
close PIDFILE;
my $its_time_to_die = 0;
&mv_old_log(); #MOVE the logfile stingerd.log to stingerd.?.gz -- where ? is a number
#now it wont get run over
###############################################################
my $lh = new Log::Logger;
$lh ->open ("/var/log/stingerd.log");
$lh ->log("CPU and FAN readings\n"); #INITIALIZE the log...
$lh ->log("\n");
###############################################################
my $count = 0;
while (1) #GENERATE the inf. loop condition
{
$count++; #increment $count
my (@ENV_vars, $nums, @numbers, $ts, @ts, $ts2 );
@ENV_vars = `/usr/sbin/envstat`; ## This is called "BACKTICKING";
## see CAMEL book, p. 342
$nums = $ENV_vars[2];
# print "\$nums=: $nums\n"; #DIAGNOSTIC CODE
@numbers = split(/\s+ /,$nums); # MUST BE \s+ !!
#print "\@numbers=: @numbers\n";
if ( 0 == ($count % 360 ) ) # IF 0 == ( remainder of $count / 898 ) then ...
# 898 gives me 1805s between samples/log entries (30min is 1800s) @ sleep = 2
{
$ts = localtime; # ADDED a time stamp here...
@ts = split /\s+/, $ts;
shift @ts;
# @ts2 = @ts[1,2,3,4];
$ts2 = join(" ",@ts);
$lh -> log("$ts2" . " " . "$numbers[1]" . " " . "$numbers[4]"); ## $ENV_vars[1] is ' ' (leads with a space)
}
# write data to file...
#MUST GRAB first set of nums and analyse IMMEDIATELY!
if ( ($numbers[1] gt 49 ) || ($numbers[4] lt 1700 ) )
{$its_time_to_die = 1; } # reset the flag -- makes the code test able...
&run_shutdown if ($its_time_to_die); # if 1 ...
sleep 10; # Looks right -- cuts CPU load. IF YOU MAKE sleep() too long, 3600s for
# instance, and CPU temp goes too high, then it can easily overheat
# without ever being detected -- WHAT GOOD WAS THAT!?
} # close while {}
sub run_shutdown
{
use Term::ANSIColor;
print "\n";
print color ("bold");
print color ("red"), "**** CPU hit 49 deg. Centgrade: OVERHEAT CONDITION \n";
print color ("red"), " shutting down system... ****",color("reset");
print color ("reset");
my $mailer = Mail::Mailer ->new("sendmail");
$mailer -> open ({ To=> 'root@localhost',
Subject=>"System Shutdown",
}) or die "Cant open: $!";
print $mailer "Stingerd has noticed a rise in CPU core temp\n";
print $mailer "or a drop below minimum FAN velocity\n";
print $mailer "\n";
print $mailer "I have taken the liberty of shutting down the system\n";
print $mailer "before any damage accurs. PLEASE FIX ME\n";
$mailer -> close();
$lh -> close(); #close logfile
sleep 5; # GIVE the mail a chance to get there...
system "/sbin/shutdown -p now";
}
sub mv_old_log
{
# print "YOUR RUNNING mv_old_log...\n";
chdir "/var/log";
my (@fields, $foo, $last_ele, $last_index, $length, @ls_said, $this_index );
if ( (-e "/var/log/stingerd.log" ) && (!-e "/var/log/stingerd.0.gz") )
{
rename "/var/log/stingerd.log" , "/var/log/stingerd.0";
system "/usr/bin/gzip stingerd.0"; #gets us to stingerd.0.gz
}
elsif ( (-e "/var/log/stingerd.log" ) && (-e "/var/log/stingerd.0.gz") )
{
# chdir "/var/log"; # were already in /var/log stupid...
open (PROC, "ls stingerd*gz |"); #ISN'T that the truth???
@ls_said = <PROC>;
close PROC;
$length = (@ls_said);
$last_ele = $ls_said[$length - 1];
$last_ele =~ s/[.]/ /g; #convert . to ' ' RIGHT?
@fields = split /\s+/, $last_ele;
#print "\@fields =: @fields\n";
$last_index = $fields[1];
#print "\$last_index =: $last_index\n";
$this_index = $last_index + 1;
$foo = "/var/log/stingerd." . $this_index;
# print "\$foo=: $foo\n";
rename "/var/log/stingerd.log" , $foo;
system ("/usr/bin/gzip " . $foo);
unlink $foo; # a safety thing
}
} ## close sub mv_old_log
sub become_daemonic
{
# /usr/local/bin/perl -w -d does not catch this code with debugger and complain!
# bother it as little as possible!
# by Zaxo (see perlmonks.org)
# based on W. Richard Stevens' rules; see Advanced Programming in the UNIX Environment
my $debug = 1;
my $logfile = q(.testlog);
# Season to taste
my @fh_unused = (\*STDIN, \*STDOUT);
open \*STDERR, ">> $ENV{'HOME'}/$logfile";
select((select(\*STDERR), $| = 1)[0]);
{
# Daemon Rule 1) Fork and exit the parent.
$ppid = $$; # Another way to get at PID
sleep 1;
$pid = fork and exit 0;
! defined $pid and die "No Fork: ", $!;
while (kill 0, $ppid) {
select undef, undef, undef, .001;
};
}
# Daemon Rule 2) become session leader, pg leader, no term
my $session_id = POSIX::setsid();
# Daemon Rule 3) cd to /
chdir '/' or die "Could not cd to rootfs", $!;
# Daemon Rule 4) set file creation mask to 0
my $oldmask = umask 00;
# Daemon Rule 5) Close unneeded file handles
close $_ or die $! for @fh_unused;
}# close subroutine
--
__________________________________________________________
Sign-up for your own personalized E-mail at Mail.com
http://www.mail.com/?sr=signup
CareerBuilder.com has over 400,000 jobs. Be smarter about your job search
http://corp.mail.com/careers