jablonka.czprosek.czf

hotsanic

Subversion Repositories:
[/] [trunk/] [lib/] [HotSaNICmod.pm] - Blame information for rev 36

 

Line No. Rev Author Line
11simandl#
2# $Id: HotSaNICmod.pm,v 1.21 2004/02/27 09:21:47 bernisys Exp $
3#
4 
5package HotSaNICmod;
6 
7use HotSaNICparser;
8use RRDs;
9 
10my $MODNAME;
11my %MODARGS;
12 
13($VERSION = '$Revision: 1.21 $') =~ s/.*(\d+\.\d+).*/$1/;
14 
15######################################################################
16#
17# control function to make sure that a module is running only once
18#
19# Usage:
20# dupe_control($what,$module-name,$message);
21#
22# $what:
23# start -> call this method at the head of a module to touch the
24# dupe-detection checkfile.
25# stop -> remove checkfile and exit normally.
26# warn -> print $message as warning and continue execution.
27# die -> remove checkfile and stop process with error.
28#
29# The given message will be preceded with a timestamp (in seconds
30# since 1970) and the module-name:
31#
32# <time> MODULE:message\n
33#
34sub dupe_control {
35 my ($what,$mod,$message)=@_;
36 if (!defined $mod) { $mod="(unknown module)"; }
37 if (!defined $message) { $message="(unknown reason)"; }
38 my $pid=0;
39 my $delta=0;
40 my $line;
41 
42 if ( ($what eq "check") || ($what eq "start") ) { $pid=HotSaNICparser::get_pid($MODARGS{DEBUGLEVEL}); }
43 
44 if ($what eq "start") {
45 if ($pid > 0) { die time." $mod: process already running on PID $pid for $delta seconds.\n"; }
46 open FILE,">running.pid";
47 print FILE $$;
48 close FILE;
49 }
50 elsif ($what eq "stop") {
51 if (-e "running.pid") { unlink "running.pid"; }
52 exit 0;
53 }
54 elsif ($what eq "die") {
55 if (-e "running.pid") { unlink "running.pid"; }
56 die time." $mod: $message\n";
57 }
58 elsif ($what eq "warn") {
59 print time," $mod warn: $message\n";
60 }
61 elsif ($what eq "check") {
62 if (!defined $pid) { $pid=0; }
63 if (($pid > 0) && (-e "/proc/$pid/stat")) {
64 open FILE,"/proc/$pid/stat";
65 @fileds=split / /,<FILE>;
66 close FILE;
67 $starttime=$fileds[21]/100;
68 open FILE,"/proc/uptime";
69 $line=<FILE>;
70 close FILE;
71 ($uptime)=split / /,$line;
72 $delta=int(($uptime-$starttime)*100)/100;
73 }
74 if (($pid > 0) && ($^O =~ /bsd/)) {
75 open FILE,"/proc/$pid/status";
76 @fileds=split / /,<FILE>;
77 close FILE;
78 ($starttime, $msec)= split /,/, $fileds[7];
79 $delta=int((time-$starttime)*100)/100;
80 }
81 if (!defined $delta) { $delta=0; }
82 return ($pid,$delta);
83 }
84 else { print time," $mod: method \"$what\" not supported.\n"; }
85 }
86 
87 
88######################################################################
89#
90# check cmdline arguments
91#
92sub init {
93 $args=shift || "";
94 $MODNAME=HotSaNICparser::get_module_name()."";
95 
96 my $found=0;
97 my @possible_args=("start","stop","status","configure","sample","update","version","help","showargs");
98 foreach (@possible_args) {
99 if ($args eq $_) { $found++; }
100 }
101 if ($found == 0) { $args=""; }
102 
103# import common functions
104#
105 my $COM_LIB="./platform/common.pm";
106 if ( -e $COM_LIB ) {
107 eval { require $COM_LIB; };
108 if ($@) { HotSaNICmod::dupe_control("die",$MODNAME,"Error importing common library: $COM_LIB.\n\t$!\n$@\n"); }
109 }
110 else { HotSaNICmod::dupe_control("die",$MODNAME,"Error importing common library: $COM_LIB.\n\tfile not found.\n"); }
111 
112 configure();
113 
114# import OS-specific functions
115#
116 my $fallback=0;
117 my $OS_LIB="./platform/$^O.pm";
118 if ( -e $OS_LIB ) {
119 eval { require $OS_LIB; };
120 if ($@) { print "Error importing library: $OS_LIB\n\t$!\n$@\n"; $fallback=1; }
121 }
122 else { print "$MODNAME: Operating system \"$^O\" not supported!\n"; $fallback=1; }
123 
124# OS-lib not found -> try to load default lib
125#
126 if ($fallback == 1) {
127 print "$MODNAME: Falling back to \"default\"\n";
128 eval { require "./platform/default.pm"; };
129 if ($@) { HotSaNICmod::dupe_control("die",$MODNAME,"Error importing default module.\n$@\n"); }
130 }
131 
132 if ( $args eq "" ) {
133 print "arguments missing!\n";
134 print "usage: $0 [start/stop/status/configure/sample/update/version/help/showargs]\n";
135 print "\n";
136 }
137 
138 if ( $args =~ /help/) {
139 print "usage: $0 [start/stop/status/configure/sample/update/version/help/showargs]\n";
140 print "\n";
141 print "alternative usage: send a signal to <module PID>\n";
142 print "\n";
143 print "argument signal function\n";
144 print "--------- ------- --------------------------------------------------\n";
145 print "start start module daemon\n";
146 print "stop SIGTERM terminate module daemon\n";
147 print "status show status of module daemon\n";
148 print "configure SIGHUP daemon re-reads its config file\n";
149 print "sample SIGUSR1 sample now\n";
150 print "update SIGUSR2 (not implemented yet)\n";
151 print "version show version of OS-dependant module used\n";
152 print "showargs show settings hash\n";
153 print "\n";
154 }
155 
156 if ( ($args =~ /version/) or ($MODARGS{DEBUGLEVEL} > 0) ) {
157 push my @VERSIONS,HotSaNICmod::OSdep::version() if defined &HotSaNICmod::OSdep::version;
158 push @VERSIONS,HotSaNICmod::common::version() if defined &HotSaNICmod::common::version;
159 push @VERSIONS,syssnmp::version() if defined &syssnmp::version;
160 print "$MODNAME: using libs: ",join(" / ",@VERSIONS),"\n";
161 }
162 
163 if ( $args =~ /start/) {
164 my ($pid,$uptime)=HotSaNICmod::dupe_control("check",$MODNAME,"");
165 if ($pid > 0) { print "$MODNAME: module already running on PID $pid\n"; }
166 else {
167 HotSaNICmod::daemonize();
168 HotSaNICmod::dupe_control("start",$MODNAME,"");
169 while (1 == 1) { sleep; }
170 }
171 }
172 
173 if ( $args =~ /status/) {
174 my ($pid,$uptime)=HotSaNICmod::dupe_control("check",$MODNAME,"");
175 if ($pid > 0) {
176 print "$MODNAME: module running on PID $pid for $uptime sec.\n";
177 }
178 else { print "$MODNAME: no process running.\n"; }
179 my @DBs=HotSaNICmod::get_DBs();
180 my ($min,$max)=HotSaNICmod::get_last_DB_changes();
181 if ($min>=0) {
182 print "last DB update: $min";
183 if ($max != $min) { print " (max: $max)"; }
184 print " seconds ago\n";
185 print "DBs found: ",join("\n ",@DBs),"\n";
186 }
187 }
188 
189 if ( $args =~ /sample/) {
190 my ($pid,$uptime)=HotSaNICmod::dupe_control("check",$MODNAME,"");
191 if ($pid > 0) { kill "SIGUSR1",$pid; }
192 else { print "$MODNAME: no process running.\n"; }
193 }
194 
195 if ( $args =~ /stop/) {
196 my ($pid,$uptime)=HotSaNICmod::dupe_control("check",$MODNAME,"");
197 if ($pid > 0) { kill "SIGTERM",$pid; }
198 else { print "$MODNAME: no process running.\n"; }
199 }
200 
201 if ( $args =~ /configure/) {
202 my ($pid,$uptime)=HotSaNICmod::dupe_control("check",$MODNAME,"");
203 if ($pid > 0) { kill "SIGHUP",$pid; }
204 else { print "$MODNAME: no process running.\n"; }
205 }
206 
207 if ( $args =~ /update/) {
208 my ($pid,$uptime)=HotSaNICmod::dupe_control("check",$MODNAME,"");
209 if ($pid > 0) { kill "SIGUSR2",$pid; }
210 else { print "$MODNAME: no process running.\n"; }
211 }
212 
213 if ( $args =~ /showargs/) {
214 for (sort keys %MODARGS) { print "$_ = ".$MODARGS{$_}."\n"; }
215 }
216 }
217 
218 
219######################################################################
220#
221# fork into background
222#
223sub daemonize {
224# set signal handlers and create background childprocess
225#
226 $SIG{TERM} = \&terminate;
227 $SIG{HUP} = \&configure;
228 $SIG{USR1} = \&sample;
229 $SIG{USR2} = \&update;
230 fork && exit 0;
231 }
232 
233######################################################################
234#
235# terminate module daemon
236#
237sub terminate {
238 HotSaNICmod::dupe_control("stop",$MODNAME,"");
239 }
240 
241######################################################################
242#
243# interface to OS-dependent functions
244#
245sub sample {
246 HotSaNICmod::OSdep::sample(%MODARGS);
247 }
248 
249sub update {
250 HotSaNICmod::OSdep::update;
251 }
252 
253######################################################################
254#
255# configure
256# - parse main settings
257# - parse module settings
258# - set module-specific configuration
259sub configure {
260 my @CONFmod=HotSaNICparser::read_settings(".",$MODNAME);
261 my %CONFglob=HotSaNICparser::get_config("../..",$MODNAME);
262 if (scalar(@CONFmod) == 0) { HotSaNICmod::dupe_control("die",$MODNAME,"missing settings file"); }
263 if (scalar(keys(%CONFglob)) == 0) { HotSaNICmod::dupe_control("die",$MODNAME,"missing settings file"); }
264 if (! -d $CONFglob{VARDIR}."/modules/system") { mkdir $CONFglob{VARDIR}."/modules/system",0755; }
265 
266# configure module-specific settings
267#
268 %MODARGS=HotSaNICmod::common::configure(@CONFmod);
269 
270# configure common module settings
271#
272 foreach (@CONFmod) {
273 ($var,$value)=HotSaNICparser::parse_line($_);
274 if ($var eq "DEBUGLEVEL") { $MODARGS{DEBUGLEVEL}=$value; }
275 }
276 
277# add global settings
278#
279 $MODARGS{MODNAME}=$MODNAME;
280 $MODARGS{VARDIR}=$CONFglob{VARDIR}."/modules/system";
281 $MODARGS{SNMPWALK}=$CONFglob{SNMPWALK};
282 $MODARGS{SNMPGET}=$CONFglob{SNMPGET};
283 if ( (!defined $MODARGS{DEBUGLEVEL}) || ($CONFglob{DEBUGLEVEL} > $MODARGS{DEBUGLEVEL}) ) { $MODARGS{DEBUGLEVEL}=$CONFglob{DEBUGLEVEL}; }
284 if (!defined $MODARGS{DEBUGLEVEL}) { $MODARGS{DEBUGLEVEL}=-1; }
285 
286 }
287 
288######################################################################
289#
290# returns an array containing all "*.rrd" files in the current module's "rrd" directory
291#
292sub get_DBs {
293 opendir(DIR,"rrd") || HotSaNICmod::dupe_control("die",$MODARGS{"MODNAME"},"error opening database dir - $!");
294 my @DBs=grep(/\.rrd/,readdir(DIR));
295 closedir(DIR);
296 return @DBs;
297 }
298 
299 
300######################################################################
301#
302# returns an array containing the min and max seconds since last DB changes
303#
304# if no DBs are found, (-1,-1) will be returned.
305#
306sub get_last_DB_changes {
307 
308 my @DBs=get_DBs();
309 
310 if (!@DBs) { return (-1,-1); }
311 
312 my ($min,$max)=(999999999999,0);
313 foreach $test (@DBs) {
314 (undef,undef,undef,undef,undef,undef,undef,undef,undef,$mtime,undef,undef,undef)=stat("rrd/".$test);
315 $mtime=time-$mtime;
316 if ($mtime<$min) { $min=$mtime; }
317 if ($mtime>$max) { $max=$mtime; }
318 }
319 
320 return ($min,$max);
321 }
322 
323 
324######################################################################
325#
326# updates a database, creates a new one if necessary
327#
328# USAGE:
329#
330# do_rrd($database,$maxvalue,$sampletime,@values);
331#
332# $database name of the database (without ".rrd" suffix)
333#
334# $maxvalue the maximum value to be expected on this datasource
335# (needed for DB creation)
336#
337# $sampletime timestamp of the current sample
338#
339# @values array of all values for this timestamp
340#
341sub do_rrd {
342 my $dbname = shift;
343 my $dbmax = shift;
344 my $time = shift;
345 my $values=join(":",@_);
346 
347 # build new database if needed
348 if ( ! -e "rrd/$dbname.rrd" ) { system("./makerrd","$dbname","$dbmax") }
349 
350 # update database
351 RRDs::update "rrd/$dbname.rrd", $time.":".$values;
352 if ($ERROR = RRDs::error) { print $time," ",$MODNAME,": unable to update '$dbname.rrd': $ERROR\n"; }
353 }
354 
3551;
356 

Powered by WebSVN 2.2.1