Cover V04, I05
Article
Listing 1
Listing 2

sep95.tar


Listing 2: pcnfsdcheck.pl

#!/usr/local/bin/perl
#
;#
;# a perl conversion of John Jarocki's pcnfsbabysit shell code
;# with some new items as needed
;# Author - Bruce Altmann
;#
;# rev AMD 1.0
;# Copyright Advanced Micro Devices, Inc. 1995
;#This script is distributed AS IS -- no warranties are stated or implied.

require 'getopts.pl';

;# zero is off
$SILENT = 0;
;# LOCAL CUSTOMIZE SECTION -------------------------
;#
;# ..............rpc info call
;# SunOS 4.1.3.X
;# HPUX 9.01
$RPCINFOCALL = '/usr/etc/rpcinfo';

;# SunOS 5.4
;# $RPCINFOCALL = '/usr/bin/rpcinfo';

;# ........how to start rpc.pcnfsd
;#      change this for your install
;#      ADD ANY FLAGS or ARGS YOU USE..!!
;# SunOS 4.1.3.X
$RPCPCNFSDCALL = '/usr/local/etc/rpc.pcnfsd';
;# SunOS 5.4
;#$RPCPCNFSDCALL = "/etc/init.d/pcnfs start";
;# HPUX 9.X OS default
;# $RPCPCNFSDCALL = '/etc/pcnfsd';

;# ........what to search for in the PS search for a PID if needed
$PSPCNFSD = 'rpc.pcnfsd';
;# HPUX is a little strange about this

;# $PSPCNFSD = 'pcnfsd';
;# LOCAL CUSTOMIZE SECTION -------------------------

$FIXITFLAG = 0;
undef($RPCSERVER);

$Usage = 'pcnfsdcheck.pl -n node_to_check -s -l -f'
;# if no -h check the localhost
;# -s is silent for return monitoring stuff, and cron calls
;# -l is log to syslog, best with the -s and -f
;# -f try to ps for the PID and kill and restart rpc.pcnfsd (localhost only)

;# I expect people to run this via cron, so I output on
;# error even with -s
;# so they will get mail at root if this fails

;# return codes to identify what is down
;# will only return the code of the first rpc port
;# found to be down, not all of them
$Returncode = 0;  # everything ok

;# 10 ver 1 UDP not working
;# 20 ver 2 UDP not working
;# 11 ver 1 TCP not working
;# 21 ver 2 TCP not working
;# 99 - can't fix (-f)
;# 1 - some program error

;# start MAIN
;#---------------------------------------------------
;# parse the options
undef ($opt_n);

&Getopts('n:slfh');

if ($opt_s) {
$SILENT = 1;
}

if ($opt_n) {
$RPCSERVER = "$opt_n";
if (!$SILENT) {
print "checking rpcinfo on server $RPCSERVER\n";
}
} else {
$RPCSERVER = `uname -n` || `hostname` || 'localhostX';
chop($RPCSERVER);
if (!$SILENT) {
print "checking rpcinfo on server $RPCSERVER\n";
}
}

if ($opt_l) {
require "syslog.pl";
&openlog("$PSPCNFSD", 'cons,pid','daemon');
$SYSLOGIT = 1;
}

if ($opt_f) {
$FIXITFLAG = 1;
}

if ($opt_h) {
print "$Usage\n";
print "if no -n <node> check the localhost\n";
print "-s is silent mode, although errors will write to STDOUT\n";
print "-l is log to syslog, best with the -s\n";
print "-f try to ps for the PID and kill and restart rpc.pcnfsd (localhost)\n";
exit(1);
}

;# ---------------------------------------------------
;# UDP check ver 1 and 2
$UDP1 = 0;
$UDP2 = 0;

if (!$SILENT) {
print "\n.........Checking PCNFSD UDP ver 1 on $RPCSERVER\n";
}

if (!$SILENT) {
system("$RPCINFOCALL -u $RPCSERVER pcnfsd 1");
} else {
system("$RPCINFOCALL -u $RPCSERVER pcnfsd 1 >/dev/null 2>&1");
}

;# get the return stat
;# zero for ok, other non zero is a problem
$UDP1 = ($? >> 8);

if ($UDP1) {
print "PCNFSD UDP ver 1 not running\n";
$Returncode = 10;
}

if (!$SILENT) {
print "\n........Checking PCNFSD UDP ver 2 on $RPCSERVER\n";
}

if (!$SILENT) {
system("$RPCINFOCALL -u $RPCSERVER pcnfsd 2");
} else {
system("$RPCINFOCALL -u $RPCSERVER pcnfsd 2 >/dev/null 2>&1");
}

;# get the return stat (nothing between this and the system call)
;# zero for ok, other non zero is a problem
$UDP2 = ($? >> 8);

if ($UDP2) {
print "PCNFSD UDP ver 2 not running\n";
$Returncode = 20;
}
;# ---------------------------------------------------
;# TCP check ver 1 and 2
$TCP1 = 0;
$TCP2 = 0;

if (!$SILENT) {
print "\n........Checking PCNFSD TCP ver 1 on $RPCSERVER\n";
}

if (!$SILENT) {
system("$RPCINFOCALL -t $RPCSERVER pcnfsd 1");
} else {
system("$RPCINFOCALL -t $RPCSERVER pcnfsd 1 >/dev/null 2>&1");
}

;# get the return stat
;# zero for ok, other non zero is a problem
$TCP1 = ($? >> 8);

if ($TCP1) {
print "PCNFSD TCP ver 1 not running\n";
$Returncode = 11;
}

if (!$SILENT) {
print "\n........Checking PCNFSD TCP ver 2 on $RPCSERVER\n";
}

if (!$SILENT) {
system("$RPCINFOCALL -t $RPCSERVER pcnfsd 2");
} else {
system("$RPCINFOCALL -t $RPCSERVER pcnfsd 2 >/dev/null 2>&1");
}

;# get the return stat
;# zero for ok, other non zero is a problem
$TCP2 = ($? >> 8);

if ($TCP2) {
print "PCNFSD TCP ver 2 not running\n";
$Returncode = 21;
}

;# ok we know what is down, check fix flag, and fix if possible
;# local or remote
;#  for HPUX 9.X use:
;#if ($UDP1) {

if ($UDP1 || $UDP2 || $TCP1 || $TCP2) {
if ($SYSLOGIT) {
&syslog('warning', "PCNFSD via pcnfsdcheck reported an error $UDP1, $UDP2, $TCP1,
$TCP2");
}
if ($FIXITFLAG) {
if (!$SILENT) {
print "Trying to restart $PSPCNFSD\n";
}
;# get PID
;# ps calls differ by OS
$OS_is = `uname`;
$OS_rev = `uname -r`;
chop($OS_is);
chop($OS_rev);
if ($OS_is eq "HP-UX") {
$pscmd = "/bin/ps -ef";
}
if ($OS_is eq "SunOS") {
if($OS_rev =~ /^5/) {
$pscmd = "/usr/bin/ps -ef";
} else {
$pscmd = "/usr/bin/ps -auxw";
}

}

open(PSTAG, "$pscmd|") || warn "can't run $pscmd: $!";
$PStitle = <PS>; # read the title line
$found  = 0;
;# this getpid code came from the Perl Camel book; 1992 march ed. p329
;# Reprinted with permission from Programming Perl, copyright 1992,
;# O'Reilly & Associates, Inc.  For orders and information
;# call 800-998-9938.

while ($PSline = <PS>) {
chop($PSline);
($PSuser, $PSPID) = split(' ', $PSline);
next if $PSPID == $$;
$found = 1 if $PSline =~ /\b$PSPCNFSD\b/;
if($found) {
$PCNFSDPID = $PSPID;
last;
}
} ;# end of PS while search
close(PSTAG);

$Result = 0;

if ($found) {
if (!$SILENT) {
print "$PSPCNFSD PID is $PCNFSDPID\n";
}
kill('SIGKILL', $PCNFSDPID) || warn "could not kill pcnfsd PID $PCNFSDPID\n";
;# may not have been killed, but start a new one anyway
system("$RPCPCNFSDCALL >/dev/null 2>&1");
$Result = ($? >> 8);
} else {
system("$RPCPCNFSDCALL >/dev/null 2>&1");
$Result = ($? >> 8);
}

if ($Result != 0) {
;# check to make sure it is running as errors may just
;# be library warnings or some minor stuff
;# hmm , here is this getpid code again, I smell a subroutine
;# maybe in the next rev
open(PSTAG, "$pscmd|") || warn "can't run $pscmd: $!";
$PStitle = <PS>; # read the title line
$found  = 0;
;# this getpid code came from the Perl Camel book; 1992 march ed. p329
;# Reprinted with permission from Programming Perl, copyright 1992,
;# O'Reilly & Associates, Inc.  For orders and information
;# call 800-998-9938.

while ($PSline = <PS>) {
chop($PSline);
($PSuser, $PSPID) = split(' ', $PSline);
next if $PSPID == $$;
$found = 1 if $PSline =~ /\b$PSPCNFSD\b/;
if($found) {
$PCNFSDPID = $PSPID;
last;
}
} ;# end of PS while search
close(PSTAG);

if (!$found) {
print "\n\n Could NOT start/restart $PSPCNFSD\n";
if ($SYSLOGIT) {
&syslog('warning', "pcnfsdcheck was NOT able to restart PCNFSD");
}
$Returncode = 99;
}


};# end Result check section

if($Result == 0 || $found == 1) {
print "$PSPCNFSD restarted\n";
if ($SYSLOGIT) {
&syslog('warning', "pcnfsdcheck restarted PCNFSD");
}
}

} ;# end of the FIXITFLAG section
};# end of UDP TCP section

if ($SYSLOGIT) {
&closelog();
}

;# return the code
exit($Returncode);