Current location

narf Source control manager Git

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Mehani <shtrom@ssji.net>2017-04-27 03:25:32 +0200
committerOlivier Mehani <shtrom@ssji.net>2017-04-27 03:25:32 +0200
commit90b0b63645368e13c7952abced0a4c04e84858c7 (patch)
tree6ff85b01af4547aa02f19a08a89101a7808721c1
parenteaba4e57f3b0ab4ab6ac6b3de46ef197b2ab0b90 (diff)
Import install_rtm-freebsd.sh from OVH
Signed-off-by: Olivier Mehani <shtrom@ssji.net>
-rw-r--r--openbsd/install_rtm-freebsd.sh1854
1 files changed, 1854 insertions, 0 deletions
diff --git a/openbsd/install_rtm-freebsd.sh b/openbsd/install_rtm-freebsd.sh
new file mode 100644
index 0000000..c6b5a28
--- /dev/null
+++ b/openbsd/install_rtm-freebsd.sh
@@ -0,0 +1,1854 @@
+#!/usr/local/bin/bash
+
+PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH
+export PATH
+
+VERSION="0.9.4-4"
+RELEASE_DATE="2016-02-25"
+
+LC_ALL=POSIX
+
+DIR="/usr/local/rtm"
+DIR_SCRIPTS_DAILY="${DIR}/scripts/daily"
+DIR_SCRIPTS_MIN="${DIR}/scripts/min"
+DIR_SCRIPTS_HOUR="${DIR}/scripts/hour"
+DNSSERVER="213.186.33.99"
+SCRIPTS_TO_INSTALL="check kernel release usage usage_root hwinfo hwinfo_root hddinfo smart raid listen_ports"
+
+RTM_PL=$DIR/bin/rtm-${VERSION}.pl
+RTM_SH=$DIR/bin/rtm
+RTM_UPDATE_IP=$DIR/bin/rtm-update-ip.sh
+
+RTM_REPORT=$DIR/bin/update-report.pl
+
+
+if [ "$SCREENDIR" != "" ]; then SCREEN="$SCREENDIR -d -m"; fi
+SCRIPTDIR="$DIR/scripts"
+
+# add user ovh and group ovh to run rtm on it:
+if [ -z "`pw usershow ovh 2>\/dev\/null`" ]; then
+ pw useradd ovh -d /nonexistent -c "OVH user for RTM running" -s /usr/bin/false -P no
+fi
+
+OVHUID=`pw usershow ovh | cut -d: -f3`
+OVHGID=`pw usershow ovh | cut -d: -f4`
+
+
+#
+# Generate update-report.pl file
+generate_update_report() {
+ echo "Generating update-report.pl..."
+ cat << EOF > $RTM_REPORT
+#! /usr/local/bin/perl
+# version: $VERSION ($RELEASE_DATE)
+
+\$ENV{"LC_ALL"} = "POSIX";
+
+EOF
+ cat <<'EOF' >> $RTM_REPORT
+#!/usr/local/bin/perl
+
+use strict;
+use Socket;
+
+EOF
+ echo "my \$destination_ip = '$ip';" >> $RTM_REPORT
+ cat <<'EOF' >> $RTM_REPORT
+my $message = <>;
+chomp($message);
+exit if ($message eq '');
+
+send_info($message);
+
+sub send_info {
+ my $message = shift;
+ $message = "rtm dINFO_RTM_update|$message\n";
+ my $port = 6100 + int(rand(100));
+ my $ok = eval {
+ local $SIG{ALRM} = sub { print "rtm timeout\n"; die; };
+ alarm(10);
+
+ my $proto = getprotobyname('udp');
+ socket(Socket_Handle, PF_INET, SOCK_DGRAM, $proto);
+ my $iaddr = gethostbyname($destination_ip);
+ my $sin = sockaddr_in("$port", $iaddr);
+ send(Socket_Handle, "$message", 10, $sin);
+ print "$message";
+ alarm(0);
+ };
+ if (!defined($ok)) {
+ warn "error: $@\n";
+ }
+}
+EOF
+ chown 0:0 "$RTM_REPORT"
+ chmod 750 "$RTM_REPORT"
+}
+
+# check if script dirs point to reasonable paths
+for scr in "$DIR_SCRIPTS_DAILY", "$DIR_SCRIPTS_MIN", "$DIR_SCRIPTS_HOUR"; do
+ if ! echo "$scr" | grep -q '^/usr/local/'; then
+ echo "invalid script directory: $scr" >&2
+ exit 1
+ fi
+done
+# Remove old scripts dirs so there are no unwanted scripts hanging
+# around
+rm -rf "$DIR_SCRIPTS_DAILY"
+rm -rf "$DIR_SCRIPTS_MIN"
+rm -rf "$DIR_SCRIPTS_HOUR"
+
+if [ ! -e "$DIR" ]; then mkdir -p $DIR; fi
+if [ ! -e "$DIR_SCRIPTS_DAILY" ]; then mkdir -p "$DIR_SCRIPTS_DAILY"; fi
+if [ ! -e "$DIR_SCRIPTS_MIN" ]; then mkdir -p "$DIR_SCRIPTS_MIN"; fi
+if [ ! -e "$DIR_SCRIPTS_HOUR" ]; then mkdir -p "$DIR_SCRIPTS_HOUR"; fi
+if [ ! -e "$DIR/bin" ]; then mkdir -p "$DIR/bin"; fi
+if [ ! -e "$DIR/etc" ]; then mkdir -p "$DIR/etc"; fi
+
+get_interface_ip() {
+ iface=$1
+ ifconfig $iface 2>\/dev\/null | grep "inet.*netmask" | awk '{print $2}' | egrep '[0-9]+(\.[0-9]+){3}'
+}
+
+mainif="$(netstat -rn|grep "^default" | awk '{print $NF}'|sort|uniq|head -n1)"
+mainip="$(get_interface_ip $mainif)"
+
+arpa=`echo "$mainip" | sed "s/\./ /g" | awk '{print $3"."$2"."$1}'`;
+ip=`host -t A mrtg.$arpa.in-addr.arpa $DNSSERVER 2>/dev/null | grep "has address" | awk '{print $4}' | egrep '[0-9]+(\.[0-9]+){3}'`
+
+if [ -z "$ip" ]; then
+ echo "No IP from OVH network !"
+ exit 1;
+fi
+echo $ip > "$DIR/etc/rtm-ip"
+
+
+cd `dirname $0`
+
+upgrade=$1
+if [ "$upgrade" != "-u" ]; then
+ upgrade=""
+fi
+
+if [ -z "`which bzip2`" ]; then
+ echo "bzip2 not found!!"
+ echo "Please install bzip2."
+ exit
+fi
+
+#
+# Generate /scripts/min/check.pl file
+generate_check() {
+ echo "Generating $DIR_SCRIPTS_MIN/check.pl..."
+ cat << EOF > $DIR_SCRIPTS_MIN/check.pl
+#! /usr/local/bin/perl
+# version: $VERSION ($RELEASE_DATE)
+
+\$ENV{"LC_ALL"} = "POSIX";
+
+EOF
+ cat <<'EOF' >> $DIR_SCRIPTS_MIN/check.pl
+use strict;
+
+# nothing here at the moment
+EOF
+ chown 0:0 "$DIR_SCRIPTS_MIN/check.pl"
+ chmod 750 "$DIR_SCRIPTS_MIN/check.pl"
+}
+
+#
+# Generate /scripts/day/kernel.sh file
+generate_kernel() {
+ echo "Generating $DIR_SCRIPTS_DAILY/kernel.sh..."
+ cat << EOF > $DIR_SCRIPTS_DAILY/kernel.sh
+#! /bin/sh
+# version: $VERSION ($RELEASE_DATE)
+
+LC_ALL=POSIX
+
+EOF
+ cat <<'EOF' >> $DIR_SCRIPTS_DAILY/kernel.sh
+#
+# This script determines running kernel version.
+#
+
+
+rel=`uname -r`
+ver=`uname -v`
+
+if [ ! -z "$ver" ]; then
+ echo "dINFO_KERNEL_release|$rel";
+ echo "dINFO_KERNEL_version|$ver"
+fi
+EOF
+ chown $OVHUID:$OVHGID "$DIR_SCRIPTS_DAILY/kernel.sh"
+ chmod 750 "$DIR_SCRIPTS_DAILY/kernel.sh"
+}
+
+#
+# Generate /scripts/day/release.sh file
+generate_release() {
+ echo "Generating $DIR_SCRIPTS_DAILY/release.sh..."
+ cat << EOF > $DIR_SCRIPTS_DAILY/release.sh
+#! /bin/sh
+# version: $VERSION ($RELEASE_DATE)
+
+LC_ALL=POSIX
+
+EOF
+ cat <<'EOF' >> $DIR_SCRIPTS_DAILY/release.sh
+#
+# The script below is used to determine OS release.
+#
+
+distro=`uname -sr`
+test -f /etc/ovhrelease && release_ovh=`cat /etc/ovhrelease`
+
+echo "dINFO_RELEASE_os|$distro";
+echo "dINFO_RELEASE_ovh|$release_ovh";
+EOF
+ chown $OVHUID:$OVHGID "$DIR_SCRIPTS_DAILY/release.sh"
+ chmod 750 "$DIR_SCRIPTS_DAILY/release.sh"
+}
+
+#
+# Generate /scripts/hour/raid.pl file
+generate_raid() {
+ echo "Generating $DIR_SCRIPTS_HOUR/raid.pl..."
+ cat << EOF > $DIR_SCRIPTS_HOUR/raid.pl
+#! /usr/local/bin/perl
+# version: $VERSION ($RELEASE_DATE)
+
+\$ENV{"LC_ALL"} = "POSIX";
+
+EOF
+ cat <<'EOF' >> $DIR_SCRIPTS_HOUR/raid.pl
+#
+# Shows information about RAID arrays such as disks capacity, models, overal array status.
+#
+
+
+use strict;
+use IO::Select;
+
+chomp(my @sysctl = `\/sbin\/sysctl dev 2>\/dev\/null`);
+
+# TODO: Soft RAID with:
+# - gvinum and raid-5
+#
+# TODO: Mylex RAID support (no tools found. Only megarc/amrstat but not working for all cards)
+
+
+# gmirror/gstripe:
+chomp(my @gmirror = `gmirror status -s 2>\/dev\/null`);
+chomp(my @gstripe = `gstripe status -s 2>\/dev\/null`);
+if($#gmirror != -1 or $#gstripe != -1){
+ my %raid;
+
+ # gmirror/gstripe enabled
+ foreach(@gmirror, @gstripe){
+ # mirror/home DEGRADED da0s1f (65%)
+ next unless $_ =~ m/^\s*(mirror|stripe)\/(\S+)\s+(\S+)\s+(.*?)(?:\s+\((\d+)%\))?\s*$/;
+ $raid{$1}{$2}{state} = $3;
+ my %tmp = (name=>$4);
+ $tmp{syncpercent} = $5 if $5;
+ push @{$raid{$1}{$2}{disks}}, \%tmp;
+ }
+
+ foreach my $type (keys %raid){
+ foreach my $vol (keys %{$raid{$type}}){
+ my @data;
+ if($type eq 'mirror'){
+ chomp(@data = `gmirror list $vol 2>\/dev\/null`);
+ print "hHW_SCSIRAID_UNIT_$type\_vol-$vol\_type|MIRROR\n";
+ }elsif($type eq 'stripe'){
+ chomp(@data = `gstripe list $vol 2>\/dev\/null`);
+ print "hHW_SCSIRAID_UNIT_$type\_vol-$vol\_type|STRIPE\n";
+ }
+
+ # volume info:
+ foreach(@data){
+ last if /Consumers/i;
+
+ print "hHW_SCSIRAID_UNIT_$type\_vol-$vol\_capacity|$1 $2\n"
+ if /Mediasize:\s+\d+\s+\((\d+)(\w+)\)$/i;
+
+ print "hHW_SCSIRAID_UNIT_$type\_vol-$vol\_phys|$1\n"
+ if /Components:\s+(\d+)$/i;
+
+ if(/State:\s+(\w+)$/){
+ my $st = $1;
+ $st eq 'COMPLETE' and $st = 'OK';
+ print "hHW_SCSIRAID_UNIT_$type\_vol-$vol\_status|$st\n"
+ }
+
+ print "hHW_SCSIRAID_UNIT_$type\_vol-$vol\_flags|$1\n"
+ if /Flags:\s*(\w+)$/;
+ }
+
+ # disk info:
+ my ($ldn, $ldi); # lastDiskName and lastDiskId
+ my $consumers = 0;
+
+ foreach(@data){
+ # skip volume info:
+ $consumers = 1 if /Consumers/i;
+ next unless $consumers;
+
+
+ ($ldi, $ldn) = ($1-1, $2)
+ if /^(\d+)\.\s*Name:\s*(\S+)$/;
+
+ print "hHW_SCSIRAID_PORT_$type\_vol-$vol\_phy$ldi\_capacity|$1 $2\n"
+ if /Mediasize:\s+\d+\s+\((\d+)(\w+)\)$/i;
+
+ print "hHW_SCSIRAID_PORT_$type\_vol-$vol\_phy$ldi\_status|$1\n"
+ if /State:\s*(\w+)$/;
+
+ print "hHW_SCSIRAID_PORT_$type\_vol-$vol\_phy$ldi\_flags|$1\n"
+ if /Flags:\s*(\S+)$/;
+
+ print "hHW_SCSIRAID_PORT_$type\_vol-$vol\_phy$ldi\_syncprogress|$1\n"
+ if /Synchronized:\s*(\d+)%/;
+ }
+
+ }
+ }
+}
+
+
+# 3ware (all)
+if (map {$_ =~ /3ware/i} @sysctl) {
+ my (%units, @controlers, %models);
+
+ chomp(my @twCliInfo = `\/usr\/local\/sbin\/tw_cli info 2>\/dev\/null`);
+
+ # parse tw_cli basis view:
+ foreach my $line (@twCliInfo) {
+ if ($line =~ m/Controller (\d+):/) { push @controlers, $1;}
+ if ($line =~ /^c(\d+)\s+(\S+)\s+/) { push @controlers, $1; $models{$1} = $2;}
+ }
+
+
+ foreach my $controler (@controlers) {
+ chomp(@twCliInfo = `\/usr\/local\/sbin\/tw_cli info c$controler 2>\/dev\/null`);
+
+ # parse tw_cli detailed info:
+ foreach my $line (@twCliInfo) {
+ if ( $line =~ m/Unit\s(\d):\s+(RAID\s+\d+|[^\s]+)\s([^\s]+)\s([^\s]+)[^:]+:\s(.+)/) {
+ print "hHW_SCSIRAID_UNIT_c$controler\_u$1_capacity|$3 $4\n";
+ print "hHW_SCSIRAID_UNIT_c$controler\_u$1_type|$2\n";
+ print "hHW_SCSIRAID_UNIT_c$controler\_u$1_status|$5\n";
+ }
+ if ( $line =~ m/Port\s(\d+):\s([^\s]+)\s([^\s]+)\s([^\s]+)\s([^\s]+)\s([^\s]+)[^:]+:\s([^\(]+)\(unit\s(\d+)/) {
+ print "hHW_SCSIRAID_PORT_c$controler\_u$8_phy$1_capacity|$5 $6\n";
+ print "hHW_SCSIRAID_PORT_c$controler\_u$8_phy$1_model|$2 $3\n";
+ print "hHW_SCSIRAID_PORT_c$controler\_u$8_phy$1_status|$7\n";
+ if (! exists $units{$controler}{$8}) {$units{$controler}{$8} = 0;}
+ $units{$controler}{$8} = $units{$controler}{$8} + 1;
+ }
+
+ # 3ware models: 7xxx, 8xxx, 9xxx, 95xx:
+ # Units:
+ # ONLY FreeBSD:
+ # Unit UnitType Status %RCmpl %V/I/M Stripe Size(GB) Cache AVrfy
+ if ( $line =~ /^u(\d+)\s+(RAID\-\d+)\s+(\S+)\s+\S+\s+\S+\s+(\S+)\s+(\S+).*/ )
+ {
+ print "hHW_SCSIRAID_UNIT_c$controler\_u$1_capacity|$5 GB\n";
+ print "hHW_SCSIRAID_UNIT_c$controler\_u$1_type|$2\n";
+ print "hHW_SCSIRAID_UNIT_c$controler\_u$1_status|$3\n";
+ }
+ # Ports:
+ if ( $line =~ /^p(\d+)\s+(\S+)\s+u(\S+)\s+(\S+\s\S+)\s+(\d+)\s+(\S+)\s*$/ )
+ {
+
+ print "hHW_SCSIRAID_PORT_c$controler\_u$3_phy$1_capacity|$4\n";
+ print "hHW_SCSIRAID_PORT_c$controler\_u$3_phy$1_serial|$6\n";
+ print "hHW_SCSIRAID_PORT_c$controler\_u$3_phy$1_status|$2\n";
+
+ if (! exists $units{$controler}{$3}) {$units{$controler}{$3} = 0;}
+ $units{$controler}{$3} += 1 if $2 ne "NOT-PRESENT";
+
+ my $p = $1;
+ my $u = $3;
+ chomp(my $model = `\/usr\/local\/sbin\/tw_cli info c$controler p$p model 2>\/dev\/null`);
+ print "hHW_SCSIRAID_PORT_c$controler\_u$u\_phy$p\_model|$1\n"
+ if $model =~ /Model\s+=\s+(.*)$/;
+
+ }
+ }
+ foreach (keys %{$units{$controler}}) {print "hHW_SCSIRAID_UNIT_c$controler\_u$_\_phys|".($units{$controler}{$_})."\n";}
+ print "hHW_SCSIRAID_CONTROLLER_c$controler\_model|$models{$controler}\n" if defined $models{$controler};
+ }
+} elsif (map {$_ =~ /LSILogic/i} @sysctl) {
+ # LSILOGIC MPT adapter:
+
+ my (%units, $count);
+ chomp(my @dmesg = `dmesg | grep "mpt"`);
+ chomp(my @camcontrolDevlist = `\/sbin\/camcontrol devlist`);
+
+ # check UNIT number:
+ $count = 0;
+ while(my $a = grep {$_ =~ /^mpt$count: (\d+) Active Volume/i} @dmesg) {
+ $units{$count}{volumeCount} = $a;
+ $count++;
+ }
+
+ # foreach unit (mpt0, mpt1, ...)
+ foreach my $u (keys %units){
+
+ foreach(@dmesg){
+ /^mpt$u:\s*(\d+).*Drive Members/i and $units{$u}{driveCount} = $1;
+ /^mpt$u: Capabilities: \( (.*?) \)$/i and $units{$u}{capabilities} = $1;
+ }
+
+ # foreach volume: (vol0, vol1, ...)
+ for(my $volume=0; $volume<$units{$u}{volumeCount}; $volume++){
+ my @revDmesg = reverse @dmesg;
+ my ($lastVolStatus, $lastSyncPercent, $lastFlags);
+
+ foreach(@revDmesg) {
+ # print capacity of the volume using bus/target/lun from dmesg,
+ # from the line with unix device (ad0) at bus .. target .. lun ..
+ # WARNING: we assume that unix device numeration is same as scsi volume numeration
+ # example:
+ # daX is on scsi volume X
+ # TODO improve this
+ if(/.*$volume at mpt$u bus (\d+) target (\d+) lun (\d+)/){
+ chomp(my $c = `\/sbin\/camcontrol readcap $1:$2:$3 -q`);
+ if($c =~ /^(\d+),\s*(\d+)$/){
+ print "hHW_SCSIRAID_UNIT_mpt$u\_vol-id$volume\_capacity|".(normalize($1*$2))."\n";
+ }
+ }
+
+
+ next unless /mpt$u:vol$volume/;
+
+ # status:
+ if(/: Status \( (.*?) \)$/ and not $lastFlags){ $lastFlags = uc $1; }
+
+ # state:
+ if(/: RAID-\d+ - (.*)$/i){ $lastVolStatus = uc $1;}
+
+ # sync percentage:
+ if(/: (\d+) of (\d+) blocks remaining/i){ $lastSyncPercent = int($1/$2 * 100); }
+
+ # we search backwards only till this line:
+ last if /Volume Status Changed/;
+ }
+
+ print "hHW_SCSIRAID_UNIT_mpt$u\_vol-id$volume\_flags|$lastFlags\n";
+ print "hHW_SCSIRAID_UNIT_mpt$u\_vol-id$volume\_status|$lastVolStatus\n";
+ print "hHW_SCSIRAID_UNIT_mpt$u\_vol-id$volume\_type|$units{$u}{capabilities}\n";
+ print "hHW_SCSIRAID_UNIT_mpt$u\_vol-id$volume\_phys|".$units{$u}{driveCount}."\n";
+ print "hHW_SCSIRAID_UNIT_mpt$u\_vol-id$volume\_syncprogress|$lastSyncPercent\n"
+ if $lastFlags =~ /syncing/i;
+
+ # foreach drive in volume
+ for(my $d=0; $d<$units{$u}{driveCount}; $d++){
+ my $lastStatus = '';
+ my $lastFlags = '';
+
+ foreach(@revDmesg) {
+ next unless /^\(mpt$u:vol$volume:$d\):/;
+
+ if(/\(mpt$u:vol$volume:$d\): Status \( (.*) \)$/ and not $lastFlags){
+ $lastFlags = uc $1;
+ } elsif(/\(mpt$u:vol$volume:$d\): Physical.* Pass-thru \(mpt$u:(\d+):(\d+):(\d+)\)\s*$/){
+ my ($bus, $target, $lun) = ($1, $2, $3);
+ foreach(@camcontrolDevlist){
+ /<(.*?)>\s+at scbus$bus target $target lun $lun/
+ and print "hHW_SCSIRAID_PORT_mpt$u\_vol-id$volume\_phy$d\_model|$1\n"
+ and last;
+ };
+ chomp(my $c = `\/sbin\/camcontrol readcap $bus:$target:$lun -q`);
+ print "hHW_SCSIRAID_PORT_mpt$u\_vol-id$volume\_phy$d\_capacity|".(normalize($1*$2))."\n"
+ if ($c =~ /^(\d+),\s*(\d+)$/);
+ # none
+ } elsif(/\(mpt$u:vol$volume:$d\): Volume Status Changed.*$/){
+ # none
+ } elsif(/\(mpt$u:vol$volume:$d\): (.*)$/ and not $lastStatus){
+ $lastStatus = uc $1;
+ }
+
+ # we search backwards only till this line:
+ last if /Physical Disk Status Changed/;
+ }
+ $lastFlags = 'NONE' if $lastFlags eq 'ENABLED' or $lastFlags eq '';
+
+ print "hHW_SCSIRAID_PORT_mpt$u\_vol-id$volume\_phy$d\_status|$lastStatus\n";
+ print "hHW_SCSIRAID_PORT_mpt$u\_vol-id$volume\_phy$d\_flags|$lastFlags\n";
+ }
+ }
+ }
+
+}
+
+sub normalize {
+ my $bytes = shift || return 0;
+ my @units = qw/KB MB GB TB PB/;
+ my $i = -1;
+
+ # if we get bytes/MB/TB and still want to normalize:
+ if($bytes =~ /^(\d+)\s*([a-zA-Z]+)\s*$/){
+ $bytes = $1;
+ my $unit = $2;
+ foreach(@units){
+ $i++;
+ last if uc($unit) eq $_;
+ }
+ }
+ return -1 if $bytes > 1024 and $i >= $#units; # error
+
+ while($bytes > 1024){
+ $i++;
+ $bytes = int($bytes/1024);
+ }
+ return $bytes." $units[$i]";
+}
+
+EOF
+ chown 0:0 "$DIR_SCRIPTS_HOUR/raid.pl"
+ chmod 750 "$DIR_SCRIPTS_HOUR/raid.pl"
+}
+
+#
+# Generate /scripts/hour/smart.pl file
+generate_smart() {
+ echo "Generating $DIR_SCRIPTS_HOUR/smart.pl..."
+ cat << EOF > $DIR_SCRIPTS_HOUR/smart.pl
+#! /usr/local/bin/perl
+# version: $VERSION ($RELEASE_DATE)
+
+\$ENV{"LC_ALL"} = "POSIX";
+
+EOF
+ cat <<'EOF' >> $DIR_SCRIPTS_HOUR/smart.pl
+#
+# This script monitors SMART Errors count and critical SMART values.
+#
+
+# TODO: LSI Logic or Mylex smart error detection (via scsi?)
+
+use strict;
+use IO::Select;
+
+exit if (! -e '/usr/local/sbin/smartctl');
+
+my %smartData;
+
+sub parse_smartctl_line {
+ my $line = shift;
+ my $dev = shift;
+
+ if($line =~ /^SMART Attributes Data Structure revision number: (\d+\w*)$/) {
+ print "hINFO_RTM_SMART_versionnotcompatible|$1\n"
+ unless $1 eq '10';
+ }
+
+ if($line =~ /^SMART overall-health.*result: (\w+)$/) {
+ # $1 - PASSED or problem description
+ print "hINFO_HDD_$dev\_SMART-SELF_overall-health-test|$1\n"
+ if $1 and $1 ne 'PASSED';
+ }
+
+ # Check for Vendor Specific SMART Attributes with Thresholds:
+ if ($line =~ /^(\s{0,2}\d{1,3})\s+(\w+)\s+0x[\dabcdef]{4}\s+(\d+)\s+(\d+)\s+(\d+)\s+(\w+)\s+\w+\s+(\w+)\s+\d+.*$/) {
+ # $1 - ID arr[0]
+ # $2 - name arr[1]
+ # $3 - value arr[2]
+ # $4 - worst arr[3]
+ # $5 - thresh arr[4]
+ # $6 - type arr[5]
+ # $7 - when failed arr[6]
+ my @arr = ($1, $2, $3, $4, $5, $6, $7);
+
+ # we want only Pre-fail type attributes:
+ if($6 =~ /Pre-fail/i) {
+ my $n = $arr[1];
+ $n =~ s/_/-/g;
+ $n = lc($n);
+
+ print "hINFO_HDD_$dev\_SMART-ATTR_$n|$arr[6]\n"
+ if $arr[6] ne "-";
+ }
+ }
+
+ # check for number of ATA errors:
+ if ($line =~ /^ATA Error Count: (\d+)$/) {
+ print "hINFO_HDD_$dev\_SMART-ATA_error-count|$1\n"
+ if $1 > 0;
+ }
+}
+
+sub check_ide {
+ chomp(my $d = `\/sbin\/sysctl -n kern.disks 2>\/dev\/null`);
+ my @diskList = split ' ', $d;
+
+ foreach my $dev (@diskList) {
+ next if $dev =~ /^ad/;
+ chomp(my @smartctlData = `\/usr\/local\/sbin\/smartctl -a \/dev\/$dev 2>\/dev\/null`);
+ foreach my $line (@smartctlData) {
+ parse_smartctl_line($line, $dev);
+ }
+ }
+}
+
+sub check_scsi {
+ chomp(my $d = `\/sbin\/sysctl -n kern.disks 2>\/dev\/null`);
+ my @diskList = split ' ', $d;
+
+ foreach my $dev (@diskList) {
+ next if $dev =~ /^da/;
+ chomp(my @smartctlData = `\/usr\/local\/sbin\/smartctl -a \/dev\/$dev 2>\/dev\/null`);
+ foreach my $line (@smartctlData) {
+ if ($line =~ /^read:.+(\d+)$/) {
+ print "hINFO_HDD_$dev\_SMART_uncorrected-read-errors|$1\n";
+ }
+ if ($line =~ /^write:.+(\d+)$/) {
+ print "hINFO_HDD_$dev\_SMART_uncorrected-write-errors|$1\n";
+ }
+ }
+ }
+}
+
+sub _3ware_get_ports_for_disk {
+ my $disk = shift;
+ my @ports = ();
+ open my $TWCLI_OUTPUT, "\/usr\/local\/sbin\/tw_cli info c$disk 2>\/dev\/null |" or die("failed to run 'tw_cli'");
+ while (<$TWCLI_OUTPUT>) {
+ next unless /^p(\d+) /;
+ push @ports, $1;
+ }
+ close $TWCLI_OUTPUT;
+ return @ports;
+}
+
+sub check_3ware {
+ my (@controlers, $read_set);
+ chomp(my @twCliInfo = `\/usr\/local\/sbin\/tw_cli info 2>\/dev\/null`);
+ map {push @controlers, $1 if /^c(\d+)\s+/} @twCliInfo;
+ my $name;
+ $name = "twe" if </dev/twe?>; # twe for 6/7/8000 series controller
+ $name = "twa" if </dev/twa?>; # twa for 9000 series controller
+ return unless $name;
+
+ $read_set = IO::Select->new();
+ foreach my $controler (@controlers) {
+ next unless $controler =~ /^\d+$/;
+ foreach my $port (_3ware_get_ports_for_disk($controler)) {
+ pipe my $P_READ, my $P_WRITE or die "pipe(): $!";
+ my $pid = fork();
+ die "cannot fork: $!" if $pid < 0;
+ if ($pid == 0) {
+ open my $SMARTCTL_OUTPUT, "\/usr\/local\/sbin\/smartctl --device=3ware,$port /dev/${name}$controler -a |" or die("failed to run smartctl");
+ close $P_READ;
+ select($P_WRITE);
+ while (<$SMARTCTL_OUTPUT>) {
+ parse_smartctl_line($_, "${name}$controler-$port");
+ }
+ exit();
+ }
+ close $P_WRITE;
+ $read_set->add($P_READ);
+ }
+ }
+ while (my @fds = $read_set->can_read()) {
+ foreach my $fd (@fds) {
+ my @lines = <$fd>;
+ if (!@lines) {
+ close $fd;
+ next;
+ }
+ print join('', @lines);
+ }
+ }
+ while (waitpid(-1, 0) > 0) {
+ }
+}
+
+
+check_ide();
+check_scsi();
+check_3ware();
+EOF
+ chown 0:0 "$DIR_SCRIPTS_HOUR/smart.pl"
+ chmod 750 "$DIR_SCRIPTS_HOUR/smart.pl"
+}
+
+#
+# Generate /scripts/hour/listen_ports.pl file
+generate_listen_ports() {
+ echo "Generating $DIR_SCRIPTS_HOUR/listen_ports.pl..."
+ cat << EOF > $DIR_SCRIPTS_HOUR/listen_ports.pl
+#! /usr/local/bin/perl
+# version: $VERSION ($RELEASE_DATE)
+
+\$ENV{"LC_ALL"} = "POSIX";
+
+EOF
+ cat <<'EOF' >> $DIR_SCRIPTS_HOUR/listen_ports.pl
+#
+# This script monitors all listening TCP connections in OS.
+#
+
+use strict;
+use utf8; # for \x{nnn} regex
+
+my (@netstatTable, $line, $socketInfo, $procInfo, @tempTable, $port, $pid, $procName, $ip, $cmdline, $exe, @status, $statusLine, $uid, @passwd, $passwdLine, %passwdHash);
+
+chomp(@netstatTable = `\/usr\/bin\/sockstat -lP tcp \| \/usr\/bin\/awk \'NR>1 {print \$1"|"\$2"|"\$3"|"\$6;}\'`);
+map {s/\|\*:/\|0.0.0.0:/; s/:(\d+)$/\|$1/;} @netstatTable; # change to behave as on linux systems
+# $netstatTable[x] = 'bind|named|517|127.0.0.1|953'
+
+# username <=> uid transformation table
+open(FILE, "/etc/passwd");
+chomp(my @passwd = <FILE>);
+close(FILE);
+my %passwdHash;
+foreach (@passwd) {
+ /^([^:]+):[^:+]:(\d+):/;
+ $passwdHash{$1} = $2;
+ $passwdHash{$2} = $1;
+}
+
+
+foreach (@netstatTable) {
+ my @lineTab = split /\|/;
+
+ if ($lineTab[0] =~ /^\d+$/) {
+ push @lineTab, $lineTab[0];
+ $lineTab[0] = (defined $passwdHash{$lineTab[0]})?$passwdHash{$lineTab[0]}:'-';
+ } elsif (defined $passwdHash{$lineTab[0]}) {
+ push @lineTab, $passwdHash{$lineTab[0]};
+ } else {
+ push @lineTab, '-';
+ }
+
+ # get cmdline from procfs:
+ open(FILE, "/proc/$lineTab[2]/cmdline");
+ chomp(my $cmdline = <FILE>);
+ $cmdline =~ s/\x{0}/ /g;
+ close(FILE);
+ push @lineTab, $cmdline;
+
+ # exe:
+ push @lineTab, readlink("/proc/$lineTab[2]/file");
+
+# $lineTab = [
+# 'bind', username
+# 'named', procname
+# '517', PID
+# '::1', listen IP
+# '953', listen PORT
+# '53', UID
+# '/usr/sbin/named -t /var/named -u bind ', cmdline
+# '/usr/sbin/named' exe
+# ];
+
+ print "hINFO_TCP_LISTEN_IP-$lineTab[3]\_PORT-$lineTab[4]\_pid\|$lineTab[2]\n";
+ print "hINFO_TCP_LISTEN_IP-$lineTab[3]\_PORT-$lineTab[4]\_procname\|$lineTab[1]\n";
+ print "hINFO_TCP_LISTEN_IP-$lineTab[3]\_PORT-$lineTab[4]\_cmdline\|$lineTab[6]\n";
+ print "hINFO_TCP_LISTEN_IP-$lineTab[3]\_PORT-$lineTab[4]\_exe\|$lineTab[7]\n";
+ print "hINFO_TCP_LISTEN_IP-$lineTab[3]\_PORT-$lineTab[4]\_username\|$lineTab[0]\n";
+ print "hINFO_TCP_LISTEN_IP-$lineTab[3]\_PORT-$lineTab[4]\_uid\|$lineTab[5]\n";
+
+}
+
+
+EOF
+ chown 0:0 "$DIR_SCRIPTS_HOUR/listen_ports.pl"
+ chmod 750 "$DIR_SCRIPTS_HOUR/listen_ports.pl"
+}
+
+#
+# Generate /scripts/min/usage.pl file
+generate_usage() {
+ echo "Generating $DIR_SCRIPTS_MIN/usage.pl..."
+ cat << EOF > $DIR_SCRIPTS_MIN/usage.pl
+#! /usr/local/bin/perl
+# version: $VERSION ($RELEASE_DATE)
+
+\$ENV{"LC_ALL"} = "POSIX";
+
+EOF
+ cat <<'EOF' >> $DIR_SCRIPTS_MIN/usage.pl
+#
+# Script used for monitoring overall server load. Memory/swap/load/cpu_usage are entrained.
+#
+
+
+use strict;
+
+# tmp file for storing cpu stats from /proc/stat (Linux) or sysctl kern.cp_time (FreeBSD)
+my $CPU_STATS_FILE = "/tmp/cpu_stats";
+
+sub send_loadavg {
+ my %loadavg = get_loadavg();
+ print "mINFO_LOAD_loadavg1|" . $loadavg{'loadavg1'} . "\n";
+ print "mINFO_LOAD_loadavg2|" . $loadavg{'loadavg2'} . "\n";
+ print "mINFO_LOAD_loadavg3|" . $loadavg{'loadavg3'} . "\n";
+}
+
+sub send_mem_swap_usage {
+ my %mem_swap_usage = get_mem_swap_usage();
+ print "mINFO_MEM_memusage|" . $mem_swap_usage{'mem_used_pr'} . "\n";
+ print "mINFO_MEM_swapusage|" . $mem_swap_usage{'swap_used_pr'} . "\n";
+}
+
+sub send_cpu_usage {
+ my $cpu_usage = get_cpu_usage();
+ print "mINFO_CPU_usage|" . $cpu_usage . "\n";
+}
+
+sub send_hdd_usage {
+ my %hdd_usage = get_hdd_usage();
+ foreach (keys %{$hdd_usage{'usage'}}) {
+ print "mINFO_PART_$_\_mount|" . $hdd_usage{'mount'}{$_} . "\n";
+ print "mINFO_PART_$_\_usage|" . $hdd_usage{'usage'}{$_} . "\n";
+ print "mINFO_PART_$_\_inodes|" . $hdd_usage{'inodes'}{$_} . "\n";
+ }
+}
+
+sub get_loadavg {
+ chomp(my $load = `\/sbin\/sysctl vm.loadavg 2>\/dev\/null`);
+ $load =~ s/.*{\s*(.*)\s*}.*/$1/;
+ chomp(my @load = split(/\s/, $load));
+ return ('loadavg1' => $load[0],
+ 'loadavg2' => $load[1],
+ 'loadavg3' => $load[2],);
+}
+
+
+sub get_cpu_usage {
+ my ($cpu_usage, @cpu_usage1, @cpu_usage2, $delta);
+ @cpu_usage1 = (0, 0, 0, 0);
+ @cpu_usage2 = (0, 0, 0, 0);
+
+ chomp(my $cpu_time = `\/sbin\/sysctl kern.cp_time 2>\/dev\/null`);
+ if ($cpu_time =~ /^kern.cp_time:\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s*$/i) {
+ # CPU USAGE LINUX: user, nice, system, idle
+ # CPU USAGE FreeBSD: user, nice, system, interrupt, idle
+ @cpu_usage2 = ($1, $2, $3, $5);
+ }
+
+
+ # get historical stats:
+ if(-e $CPU_STATS_FILE) {
+ open(TMP, "+< $CPU_STATS_FILE") or die "$CPU_STATS_FILE: $!\n";
+ while (<TMP>) {
+ if (/^kern.cp_time:\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s*$/i) {
+ @cpu_usage1 = ($1, $2, $3, $5);
+ }
+ }
+ seek(TMP, 0, 0);
+ } else {
+ # if there is no historical data, use actual as a historical:
+ open(TMP, "> $CPU_STATS_FILE") or die "$CPU_STATS_FILE: $!\n";
+ @cpu_usage1 = @cpu_usage2 ;
+ }
+ print TMP $cpu_time;
+ close (TMP);
+
+ $delta = $cpu_usage2[0]+$cpu_usage2[1]+$cpu_usage2[2]+$cpu_usage2[3]-
+ ($cpu_usage1[0]+$cpu_usage1[1]+$cpu_usage1[2]+$cpu_usage1[3]);
+ if ($delta > 0) {
+ $cpu_usage = sprintf("%d", 100-(($cpu_usage2[3]-$cpu_usage1[3])/$delta*100));
+ } else {
+ $cpu_usage = 0;
+ }
+ return $cpu_usage;
+}
+
+sub get_mem_swap_usage {
+
+ my %mem_swap_usage = ();
+ chomp(my @swap = `\/sbin\/swapctl -kl \| grep "\/dev"`);
+ my %swap;
+ map { /^\/dev.*\s+(\d+)\s+(\d+)\s*$/; $swap{'total'}+=($1*1024); $swap{'used'}+=($2*1024);} @swap; # when we have more than one swap partition
+
+ $mem_swap_usage{'swap_total'} = $swap{'total'};
+ $mem_swap_usage{'swap_used'} = $swap{'used'};
+
+ if ($swap{'total'} == 0) {
+ # prevent division by zero
+ $mem_swap_usage{'swap_used_pr'} = 0;
+ } else {
+ $mem_swap_usage{'swap_used_pr'} = sprintf("%d", $swap{'used'}/$swap{'total'}*100);
+ }
+
+ my %mem_usage;
+
+ # page size
+ chomp(my $page_size = `\/sbin\/sysctl -n vm.stats.vm.v_page_size 2>\/dev\/null`);
+
+ # number of total memory pages
+ chomp(my $mem_size_c = `\/sbin\/sysctl -n vm.stats.vm.v_page_count 2>\/dev\/null`);
+
+ # pages without data content
+ chomp(my $free_c = `\/sbin\/sysctl -n vm.stats.vm.v_free_count`);
+
+ # pages that have percolated from inactive to a status where they maintain their data, but can often be immediately reused
+ chomp(my $cached_c = `\/sbin\/sysctl -n vm.stats.vm.v_cache_count 2>\/dev\/null`);
+
+ # pages used for filesystem buffers
+ chomp(my $buffers = `\/sbin\/sysctl -n vfs.bufspace 2>\/dev\/null`);
+
+ # pages that are fixed into memory, usually for kernel purposes, but also sometimes for special use in processes
+ chomp(my $wired_c = `\/sbin\/sysctl -n vm.stats.vm.v_wire_count 2>\/dev\/null`);
+
+ $mem_usage{'mem_total'} = $page_size * $mem_size_c;
+ $mem_usage{'mem_free'} = $page_size * $free_c;
+# $mem_usage{'mem_shared'} =
+ $mem_usage{'mem_buffers'} = $buffers;
+ $mem_usage{'mem_wired'} = $page_size * $wired_c;
+ $mem_usage{'mem_cached'} = $page_size * $cached_c;
+
+ $mem_usage{'mem_used'} = $mem_usage{'mem_total'} - $mem_usage{'mem_free'} - $mem_usage{'mem_cached'} - $mem_usage{'mem_buffers'};
+ $mem_usage{'mem_used_pr'} = ($mem_usage{'mem_total'} > 0)?sprintf("%d", (($mem_usage{'mem_used'})/$mem_usage{'mem_total'}*100)):0;
+
+ return (%mem_swap_usage, %mem_usage);
+}
+
+
+sub get_hdd_usage {
+ my %hdd_usage = ();
+
+ # inodes and usage:
+ chomp(my @df = `\/bin\/df -lkPi 2>\/dev\/null`);
+ foreach (@df) {
+ if (/^(\/dev\/\S+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\S+)%\s+(\S+)\s+(\S+)\s+(\S+)%\s+(\S+)\s*$/i) {
+ my $hdd_name = $1;
+ my $mount = $9;
+ my $usage = $5;
+ my $inodes = $8;
+
+ $hdd_name =~ s!^/dev/!!;
+ $hdd_name =~ s!/!-!g;
+ $hdd_usage{'usage'}{$hdd_name} = $usage;
+ $hdd_usage{'mount'}{$hdd_name} = $mount;
+ $hdd_usage{'inodes'}{$hdd_name} = ($inodes =~ /^\d+$/)?$inodes:0;
+ }
+ }
+ return %hdd_usage;
+}
+
+send_hdd_usage();
+send_mem_swap_usage();
+send_loadavg();
+send_cpu_usage();
+EOF
+ chown $OVHUID:$OVHGID "$DIR_SCRIPTS_MIN/usage.pl"
+ chmod 750 "$DIR_SCRIPTS_MIN/usage.pl"
+}
+
+#
+# Generate /scripts/min/usage-root.pl file
+generate_usage_root() {
+ echo "Generating $DIR_SCRIPTS_MIN/usage-root.pl..."
+ cat << EOF > $DIR_SCRIPTS_MIN/usage-root.pl
+#! /usr/local/bin/perl
+# version: $VERSION ($RELEASE_DATE)
+
+\$ENV{"LC_ALL"} = "POSIX";
+
+EOF
+ cat <<'EOF' >> $DIR_SCRIPTS_MIN/usage-root.pl
+#
+# This script monitors TOP processes
+#
+
+use strict;
+
+sub send_process {
+ my %processes = get_processes();
+ print "mINFO_LOAD_processesactive|" . $processes{'processesactive'} . "\n";
+ print "mINFO_LOAD_processesup|" . $processes{'processesup'} . "\n";
+}
+
+sub send_top_rss {
+ my $top = get_top_mem_procs();
+ my $n = 1;
+ foreach my $info (@$top) {
+ my $vsz = $info->[0];
+ my $cmd = $info->[1];
+ printf "mINFO_MEM_top_mem_%02d_name|%s\n", $n, $cmd;
+ printf "mINFO_MEM_top_mem_%02d_size|%s\n", $n, $vsz;
+ ++$n;
+ }
+}
+
+sub get_processes {
+ #chomp(my @rtm_sids = `ps --no-headers -C rtm -o sess | sort -n | uniq`);
+ chomp(my @rtm_sids = `\/bin\/ps -o sid,command \| \/usr\/bin\/grep "rtm" \| \/usr\/bin\/sort -n \| \/usr\/bin\/uniq \| \/usr\/bin\/grep -v grep`);
+ #my @ps_output = `ps --no-headers -A -o sess,state,command`;
+ chomp(my @ps_output = `\/bin\/ps -A -o sid,state,command`);
+ shift @ps_output; # shift headers :)
+
+ my $active = 0;
+ my $total = 0;
+ foreach my $line (@ps_output) {
+ next if $line !~ /(\d+)\s+(\S+)/;
+ my $sid = $1;
+ my $state = $2;
+ if (grep $sid == $_, @rtm_sids) {
+ next;
+ }
+ ++$total;
+ ++$active if $state =~ /^R/;
+ }
+ return ('processesactive' => $active, 'processesup' => $total);
+}
+
+sub get_top_mem_procs {
+ my @top;
+ chomp(my @output = `\/bin\/ps -A -ovsz,command \| \/usr\/bin\/awk 'NR>1 {print}' \| \/usr\/bin\/sort -nrk1 \| \/usr\/bin\/grep -v "sort" \| \/usr\/bin\/head -n5`);
+ return [] unless $? == 0;
+ foreach (@output) {
+ next unless m/\s*(\d+)\s+(.+)/;
+ push @top, [$1, $2];
+ }
+ return \@top;
+}
+
+send_process();
+send_top_rss();
+EOF
+ chown 0:0 "$DIR_SCRIPTS_MIN/usage-root.pl"
+ chmod 750 "$DIR_SCRIPTS_MIN/usage-root.pl"
+}
+
+#
+# Generate /scripts/hour/hwinfo.pl file
+generate_hwinfo() {
+ echo "Generating $DIR_SCRIPTS_HOUR/hwinfo.pl..."
+ cat << EOF > $DIR_SCRIPTS_HOUR/hwinfo.pl
+#! /usr/local/bin/perl
+# version: $VERSION ($RELEASE_DATE)
+
+\$ENV{"LC_ALL"} = "POSIX";
+
+EOF
+ cat <<'EOF' >> $DIR_SCRIPTS_HOUR/hwinfo.pl
+use strict;
+
+sub send_cpu_info {
+ my %cpu_info = get_cpu_info();
+ print "dHW_CPU_name|" . $cpu_info{'cpu_name'} . "\n";
+ print "dHW_CPU_mhz|" . $cpu_info{'cpu_mhz'} . "\n";
+ print "dHW_CPU_cache|" . $cpu_info{'cpu_cache'} . "\n";
+ print "dHW_CPU_number|" . $cpu_info{'cpu_no'} . "\n";
+}
+
+sub send_lspci_info {
+ my %lspci_info = get_lspci_info();
+ foreach (keys %lspci_info) {
+ my $tempKey = $_;
+ $tempKey =~ s/\:|\.|\_/-/g;
+ print "dHW_LSPCI_PCI-$tempKey|" . $lspci_info{$_} . "\n";
+ }
+}
+
+
+sub get_cpu_info {
+ my %cpu_info = ( 'cpu_no' => 0 );
+
+ chomp(my @cpuinfo = `\/sbin\/sysctl hw dev.cpu 2>\/dev\/null`);
+
+ foreach(@cpuinfo) {
+ if (/^hw\.model:\s*(.*)$/) {
+ $cpu_info{'cpu_name'} = $1;
+ }
+ if (/^dev\.cpu\.\d{1,2}\.freq:\s*(.*)$/) {
+ $cpu_info{'cpu_mhz'} = $1;
+ }
+# TODO - FreeBSD no CPU cache found!
+# if ($_ =~ /^cache size/) {
+# s/cache size\s+:\s*//g;
+# $cpu_info{'cpu_cache'} = $_;
+# }
+ if (/^hw\.ncpu:\s*(.*)$/){
+ $cpu_info{'cpu_no'} = $1;
+ }
+
+ }
+
+ $cpu_info{'cpu_cache'} = '';
+
+ return %cpu_info;
+}
+
+
+sub get_lspci_info {
+ my %lspci_info = ();
+ chomp(my @pciconf = `\/usr\/sbin\/pciconf -l 2>\/dev\/null`);
+ if ($? == 0) {
+ foreach (@pciconf) {
+ if(/^\S+@\S+:(\S+):\s+class=0x(\S+)\s+card=0x(\S{4})(\S{4})\s+chip=0x(\S{4})(\S{4})\s+rev=0x(\S+)\s+hdr=0x(\S+)\s*$/){
+ # $1 - selector
+ # $2 - class
+ # $3 - subvendor device id
+ # $4 - subvendor id
+ # $5 - vendor device id
+ # $6 - vendor id
+ # $7 - revision
+ # $8 - describes the header type (see man for pciconf)
+ my $value = "$6:$5";
+ my $selector;
+ $_ = $1;
+ while (/(\w+)(\W+)?/g) {$selector .= length($1)==1?"0$1$2":"$1$2";}
+ $lspci_info{$selector} = $value;
+
+ }
+ }
+ }
+ return %lspci_info;
+}
+
+send_cpu_info();
+send_lspci_info();
+EOF
+ chown $OVHUID:$OVHGID "$DIR_SCRIPTS_HOUR/hwinfo.pl"
+ chmod 750 "$DIR_SCRIPTS_HOUR/hwinfo.pl"
+}
+
+#
+# Generate /scripts/hour/hwinfo-root.pl file
+generate_hwinfo_root() {
+ echo "Generating $DIR_SCRIPTS_HOUR/hwinfo-root.pl..."
+ cat << EOF > $DIR_SCRIPTS_HOUR/hwinfo-root.pl
+#! /usr/local/bin/perl
+# version: $VERSION ($RELEASE_DATE)
+
+\$ENV{"LC_ALL"} = "POSIX";
+
+EOF
+ cat <<'EOF' >> $DIR_SCRIPTS_HOUR/hwinfo-root.pl
+use strict;
+
+chomp(my @dmesg = `\/sbin\/dmesg 2>\/dev\/null`);
+chomp(my @sysctl = `\/sbin\/sysctl dev 2>\/dev\/null`);
+
+sub send_mainboard_memory_info {
+ my %mainboard_memory_info = get_mainboard_memory_info();
+ print "dHW_MB_manufacture|" . $mainboard_memory_info{'mainboard'}{'manufacture'} . "\n";
+ print "dHW_MB_name|" . $mainboard_memory_info{'mainboard'}{'name'} . "\n";
+ foreach (keys %{$mainboard_memory_info{'memory'}}) {
+ print "dHW_MEM_BANK-$_|" . $mainboard_memory_info{'memory'}{$_} . "\n";
+ }
+}
+
+sub send_hdd_info {
+ my $hdd_info = get_hdd_info();
+ foreach (keys %{$hdd_info->{'model'}}) {
+ print "dHW_HDD_$_\_capacity|" . $hdd_info->{'capacity'}{$_} . "\n";
+ print "dHW_HDD_$_\_model|" . $hdd_info->{'model'}{$_} . "\n";
+ }
+}
+
+sub get_mainboard_memory_info {
+ my %mainboard_memory_info = ();
+ my @dmidecode = `dmidecode 2>/dev/null`;
+ if ($? == 0) {
+ my $module = "";
+ for (my $i = 0; $i < @dmidecode; $i++) {
+ if($dmidecode[$i] =~ /^\s*Base Board Information/i) {
+ $dmidecode[$i+1] =~ s/Manufacturer://g;
+ $dmidecode[$i+2] =~ s/Product Name://g;
+ $mainboard_memory_info{'mainboard'}{'manufacture'} = $dmidecode[$i+1];
+ $mainboard_memory_info{'mainboard'}{'name'} = $dmidecode[$i+2];
+ }
+ if($dmidecode[$i] =~ /^\s*Memory Module Information/i) {
+ $dmidecode[$i+1] =~ /^\s+(\S+)\s+(\S+)\s+(.+)$/i;
+ $module = $3;
+ $module =~ s/\W/-/g;
+ chomp($module);
+ }
+ if(($dmidecode[$i] =~ /^\s+Installed Size:/i) && ($module =~ /\S+/)) {
+ $module =~ s/#/_/;
+ $dmidecode[$i] =~ s/Installed Size://g;
+ $mainboard_memory_info{'memory'}{$module} = $dmidecode[$i];
+ $mainboard_memory_info{'memory'}{$module} =~ s/^\s+//;
+ chomp($mainboard_memory_info{'memory'}{$module});
+ $module = "";
+ }
+ }
+ if (!defined $mainboard_memory_info{'memory'}) {
+ for (my $i = 0; $i < @dmidecode; $i++){
+ if($dmidecode[$i] =~ /^\s*Memory Device/i) {
+ my $bank = $dmidecode[$i+9];
+ $bank =~ /Bank Locator:\s+(.*)/;
+ $bank = $1;
+ next if !$bank;
+ $bank =~ s/\s//g;
+ $bank =~ s/[\s\.\/\\_]/-/g;
+ my $locator = $dmidecode[$i+8];
+ $locator =~ /Locator:\s+(.*)/;
+ $locator = $1;
+ next if !$locator;
+ $locator =~ s/\s//g;
+ $locator =~ s![\s./\\_\#]!-!g;
+ my $size = $dmidecode[$i+5];
+ $size =~ /Size:\s+(.*)/;
+ $size = $1;
+ next if !$size;
+ $size =~ s/\s*MB\s*//g;
+ chomp($size);
+ if ($bank . $locator ne "") {
+ $mainboard_memory_info{'memory'}{$bank . "-" . $locator} = $size;
+ }
+ }
+ }
+ }
+ $mainboard_memory_info{'mainboard'}{'manufacture'} =~ s/^\s+//;
+ $mainboard_memory_info{'mainboard'}{'name'} =~ s/^\s+//;
+ chomp($mainboard_memory_info{'mainboard'}{'manufacture'});
+ chomp($mainboard_memory_info{'mainboard'}{'name'});
+ } else {
+ $mainboard_memory_info{'mainboard'}{'manufacture'} = "dmidecode not installed";
+ $mainboard_memory_info{'mainboard'}{'name'} = "dmidecode not installed";
+ }
+ return %mainboard_memory_info;
+}
+
+#sub has_raid {
+# return ((`gmirror status` =~ /mirror/) ||
+# (`gstripe status` =~ /stripe/) ||
+# (grep {$_ =~ m/3w-xxxx: scsi|scsi. : Found a 3ware|3w-9xxx: scsi.: Found|LSISAS|LSILOGIC|Mylex AcceleRAID 160 PCI RAID Controller/i} @dmesg));
+#}
+
+sub get_disk_capacity {
+ my $device = shift;
+ chomp(my $capacity = `diskinfo $device | awk '{print \$3}' 2>\/dev\/null` || 0);
+ return normalize($capacity);
+}
+
+sub get_hdd_info {
+ my %hdd_info;
+ my $disks = get_disks();
+
+ foreach my $disk (@$disks){
+ if($disk =~ /^da/){ #SCSI
+ # TODO
+ # SCSI/SATA not supported for now under FreeBSD
+ next;
+# # camcontrol devlist -v
+# # dmesg | grep mpt
+#
+# # we don't wanna check raid volumes here
+# next if grep {$_ =~ "^$disk at mpt"} @dmesg;
+# $hdd_info{'model'}{$disk} = '';
+
+ } elsif($disk =~ /^ad/) { #IDE
+ # atacontrol list
+ chomp(my @ret = `atacontrol list`);
+ foreach(@ret){
+ $hdd_info{'model'}{$disk} = $1 and last
+ if /\s*(?:Master|Slave):\s+$disk\s*<(.*?)>/;
+ }
+ } else {
+ next;
+ }
+ $hdd_info{'capacity'}{$disk} = get_disk_capacity("/dev/$disk");
+ }
+
+ return \%hdd_info;
+}
+
+sub normalize {
+ my $bytes = shift || return 0;
+ my @units = qw/KB MB GB TB PB/;
+ my $i = -1;
+
+ # if we get bytes/MB/TB and still want to normalize:
+ if($bytes =~ /^(\d+)\s*([a-zA-Z]+)\s*$/){
+ $bytes = $1;
+ my $unit = $2;
+ foreach(@units){
+ $i++;
+ last if uc($unit) eq $_;
+ }
+ }
+ return -1 if $bytes > 1024 and $i >= $#units; # error
+
+ while($bytes > 1024){
+ $i++;
+ $bytes = int($bytes/1024);
+ }
+ return $bytes.$units[$i];
+}
+
+sub get_disks {
+ chomp(my $d = `sysctl -n kern.disks 2>\/dev\/null`);
+ my @disks = split (/\s+/, $d);
+ return \@disks;
+}
+
+send_mainboard_memory_info();
+send_hdd_info();
+EOF
+ chown 0:0 "$DIR_SCRIPTS_HOUR/hwinfo-root.pl"
+ chmod 750 "$DIR_SCRIPTS_HOUR/hwinfo-root.pl"
+}
+
+#
+# Generate /scripts/min/hddinfo.pl file
+generate_hddinfo() {
+ echo "Generating $DIR_SCRIPTS_MIN/hddinfo.pl..."
+ cat << EOF > $DIR_SCRIPTS_MIN/hddinfo.pl
+#! /usr/local/bin/perl
+# version: $VERSION ($RELEASE_DATE)
+
+\$ENV{"LC_ALL"} = "POSIX";
+
+EOF
+ cat <<'EOF' >> $DIR_SCRIPTS_MIN/hddinfo.pl
+#
+# This script provides simple disk tests and temperature
+#
+
+use strict;
+
+# TODO:
+# hddtemp for daX disk
+
+sub send_hdd_status {
+ my @ide;
+ chomp(my $i = `sysctl -n kern.disks 2>\/dev\/null`);
+ map { push @ide, $_ if /^ad/} split(/\s+/,$i);
+
+ chomp(my @status = `dmesg 2>\/dev\/null \| grep -i \"error\\\|drive not ready\" \| grep -i \"\^ad\" \| cut -f 1 -d \":\" \| sort \| uniq`);
+
+ foreach my $ide (@ide) {
+ my $error = 0;
+ foreach (@status) {
+ $error = 1 if $_ eq $ide;
+ }
+ if ($error == 1) {
+ print "mHW_HDD_$ide\_status|ERROR\n";
+ } else {
+ print "mHW_HDD_$ide\_status|OK\n";
+ }
+ }
+
+
+ # check of scsi errors
+ chomp(my @scsi = `sysctl -n kern.disks 2>\/dev\/null \| grep \"\^da\"`);
+
+ my $possible_error;
+ if (scalar @scsi > 0) {
+ open my $dmesg, "dmesg |" or die "Can't launch dmesg: $!";
+ my $status = 'OK';
+ while (<$dmesg>) {
+ if (/Info fld=([^,]+), Deferred (\S+?): sense key (.+ Error)/) {
+ $status = $3;
+ }
+ if (/^da.: .+?: sense key: (.+ Error)/) {
+ $status = $1;
+ }
+ if (/^(da.+?): *rw=\d+/) {
+ $possible_error = $1;
+ next;
+ }
+ if (defined($possible_error) && /^attempt to access beyond/) {
+ $status = 'BAD_ACCESS';
+ }
+ $possible_error = undef;
+ }
+ print "mHW_HDD_scsi_status|$status\n";
+ }
+}
+
+sub send_hdd_temp {
+ my %hdd_temp = get_hdd_temp();
+ foreach (keys %hdd_temp) {
+ print "mINFO_HDD_$_\_temperature|" . $hdd_temp{$_} . "\n";
+ }
+}
+
+
+sub get_hdd_temp {
+ my %hdd_temp = ();
+ chomp(my @ide = `sysctl -n kern.disks 2>\/dev\/null`);
+
+ foreach (@ide) {
+ if (/^ad/) {
+ chomp(my $temp = `\/usr\/local\/sbin\/smartctl -a \/dev\/$_ \| grep "Temperature" 2>\/dev\/null`);
+ my $ide = $_;
+ if ($? == 0) {
+ if ($temp =~ m/\s+(\d{1,3})\s*$/) {
+ $temp = $1;
+ } else {
+ $temp = "-1";
+ }
+ $hdd_temp{$ide} = $temp;
+ } else {
+ $hdd_temp{$ide} = "-2";
+ }
+ }
+ elsif (/^da/) {
+ }
+ }
+ return %hdd_temp;
+}
+
+
+send_hdd_status();
+send_hdd_temp();
+EOF
+ chown 0:0 "$DIR_SCRIPTS_MIN/hddinfo.pl"
+ chmod 750 "$DIR_SCRIPTS_MIN/hddinfo.pl"
+}
+
+#
+# Generate rtm.pl file
+generate_rtm() {
+ echo "Generating rtm.pl..."
+ cat << EOF > $RTM_PL
+#! /usr/local/bin/perl
+# version: $VERSION ($RELEASE_DATE)
+
+\$ENV{"LC_ALL"} = "POSIX";
+
+EOF
+ cat <<'EOF' >> $RTM_PL
+my $LF_DEFAULT = '/tmp/rtm.flock';
+
+sub lockProcess {
+ my $lf = shift || $LF_DEFAULT || return;
+ my $pid = $$;
+
+ if (-e "$lf") {
+ open(LOCKFILE, $lf) or die "Impossible to open lock file: $lf !!!";
+ my $lockPID=<LOCKFILE> || "";
+ close(LOCKFILE);
+
+ if ($lockPID !~ m/^\d+$/ ) {
+ warn("There is no PID in lock. Something is broken...");
+ exit 1;
+ } elsif (-e "/proc/$lockPID") {
+ exit 0;
+ }
+ warn("There is a lock file $lf, but no process for it. Overwritting lock file");
+ }
+
+ open(LOCKFILE, ">$lf") or die "Impossible to open lock file for writting: $lf !!!";
+ print LOCKFILE $pid;
+ close(LOCKFILE);
+
+ $LF_DEFAULT = $lf;
+}
+
+
+sub unlockProcess {
+ my $lf = shift || $LF_DEFAULT || return;
+ unlink($lf);
+}
+
+use strict;
+use Socket;
+use Time::localtime;
+use Symbol qw(gensym);
+use IO::Select;
+use POSIX qw(dup2);
+
+# Check for root permission
+if ($) != 0) {
+ die "You are not a root!";
+}
+
+# Version of script
+EOF
+ echo "my \$version = '$VERSION';" >> $RTM_PL
+ echo "my \$release_date = '$RELEASE_DATE';" >> $RTM_PL
+ cat <<'EOF' >> $RTM_PL
+
+# at this hour all information will be send
+my $HOUR = 2;
+
+# get uptime
+chomp(my $uptime = `\/sbin\/sysctl -n kern.boottime 2>\/dev\/null`);
+chomp(my $date = `\/bin\/date +%s 2>\/dev\/null`);
+$uptime =~ s/{\s+sec = (\d+),\s+.*$/$1/;
+$uptime = $date - $uptime;
+die "Can't get uptime!"
+ unless $uptime =~/^\d+$/;
+
+
+my $script_name = $0;
+# get basename of the script
+$script_name =~ s/(^.*\/)//;
+
+EOF
+ echo "my \$base_dir = '$DIR';" >> $RTM_PL
+ echo "my \$scripts_dir_daily = '$DIR_SCRIPTS_DAILY';" >> $RTM_PL
+ echo "my \$scripts_dir_hour = '$DIR_SCRIPTS_HOUR';" >> $RTM_PL
+ echo "my \$scripts_dir_min = '$DIR_SCRIPTS_MIN';" >> $RTM_PL
+ echo "my \$rtm_update_ip = '$RTM_UPDATE_IP';" >> $RTM_PL
+ cat <<'EOF' >> $RTM_PL
+
+chomp(my @scripts_daily = `\/bin\/ls -1 $scripts_dir_daily`);
+chomp(my @scripts_hour = `\/bin\/ls -1 $scripts_dir_hour`);
+chomp(my @scripts_min = `\/bin\/ls -1 $scripts_dir_min`);
+
+my $env_path = $ENV{'PATH'};
+$ENV{'PATH'} = "/usr/local/sbin:/usr/local/bin:/root/bin:$env_path";
+
+# global variable used to report errors from failed scripts
+my $script_error = 0;
+
+# determine rtm server ip from mrtg config
+my $ipfile = "$base_dir/etc/rtm-ip";
+open FP, "$ipfile" or die("failed to open '$ipfile' for reading: $!");
+chomp(my $destination_ip = <FP>);
+close FP;
+if ($destination_ip !~ /^\d+\.\d+\.\d+\.\d+$/) {
+ die "failed to read destination ip from '$ipfile': invalid ip: $destination_ip";
+}
+
+# lock file is defined with lockProcess() sub
+lockProcess();
+
+my $TIMEOUT = 45;
+
+my $tm = localtime(time);
+my $hour = $tm->hour;
+my $min = $tm->min;
+
+my @scripts_to_run = ();
+
+# per minute data
+push @scripts_to_run, map { "$scripts_dir_min/$_" } @scripts_min;
+
+# hourly data
+if (scalar @ARGV == 0 or $uptime < 900 or $ARGV[0] == $min) {
+ send_info("hINFO_uptime|" . $uptime);
+ push @scripts_to_run, map { "$scripts_dir_hour/$_" } @scripts_hour;
+}
+
+# daily data
+if (scalar @ARGV == 0 or $uptime < 900 or ($hour == $HOUR && $ARGV[0] == $min)) {
+ send_info("dINFO_RTM_version|" . $version);
+ push @scripts_to_run, map { "$scripts_dir_daily/$_" } @scripts_daily;
+}
+
+# update rtm-ip daily
+if (@ARGV > 0 && $hour eq $HOUR && $ARGV[0] == $min) {
+ system("$rtm_update_ip &");
+}
+
+# run collected scripts in separate processes
+my $read_set = IO::Select->new();
+my %scripts_output = ();
+foreach my $script (@scripts_to_run) {
+ my $P_STDOUT_READ = gensym();
+ my $P_STDOUT_WRITE = gensym();
+ my $P_STDERR_READ = gensym();
+ my $P_STDERR_WRITE = gensym();
+ pipe $P_STDOUT_READ, $P_STDOUT_WRITE or die "pipe(): $!";
+ pipe $P_STDERR_READ, $P_STDERR_WRITE or die "pipe(): $!";
+ my @stats = stat($script);
+ my $uid = $stats[4];
+
+ my $pid = fork();
+ die "cannot fork: $!" if $pid < 0;
+ if ($pid == 0) {
+ if($uid > 0) {
+ my $gid = $stats[5];
+ drop_priv($uid, $gid)
+ }
+
+ dup2(fileno($P_STDOUT_WRITE), 1) or die "dup2(): $!";
+ dup2(fileno($P_STDERR_WRITE), 2) or die "dup2(): $!";
+ close $P_STDOUT_READ;
+ close $P_STDERR_READ;
+ close $P_STDOUT_WRITE;
+ close $P_STDERR_WRITE;
+ my $error = "timeout";
+ my $ok = eval {
+ local $SIG{ALRM} = sub { die; };
+ alarm($TIMEOUT);
+ system($script);
+ if ($? == -1) {
+ $error = "failed to execute '$script': $!";
+ die;
+ }
+ };
+ if (!defined($ok)) {
+ print STDERR "$error";
+ exit 1;
+ }
+ exit;
+ }
+ close $P_STDOUT_WRITE;
+ close $P_STDERR_WRITE;
+ $read_set->add($P_STDOUT_READ);
+ $read_set->add($P_STDERR_READ);
+ $scripts_output{$pid} = { 'script' => $script,
+ 'stdout' => $P_STDOUT_READ,
+ 'stderr' => $P_STDERR_READ,
+ 'error' => [],
+ };
+}
+
+# wait for all scripts to complete
+while (my @fds = $read_set->can_read()) {
+ foreach my $fd (@fds) {
+ my $slot;
+ foreach my $s (values %scripts_output) {
+ if ($s->{'stdout'} == $fd || $s->{'stderr'} == $fd) {
+ $slot = $s;
+ last;
+ }
+ }
+ unless (defined($slot)) {
+ warn "FATAL: got event on unknown file descriptor!";
+ $read_set->remove($fd);
+ close $fd;
+ next;
+ }
+ my $line = <$fd>;
+ if (!$line) {
+ $read_set->remove($fd);
+ close $fd;
+ next;
+ }
+ chomp($line);
+ if ($fd == $slot->{'stderr'}) {
+ push @{$slot->{'error'}}, $line;
+ print STDERR "$line\n";
+ } else {
+ send_info($line);
+ }
+ }
+}
+while (1) {
+ my $pid = waitpid(-1, 0);
+ last unless $pid > 0;
+ $scripts_output{$pid}->{'status'} = $? >> 8;
+}
+
+# find scripts which returned error
+foreach my $slot (values %scripts_output) {
+ next if $slot->{'status'} == 0;
+ $slot->{'script'} =~ m!/([^/]+?)$!;
+ my $script_name = $1;
+ my $stderr = join ' ', map { chomp; $_ } @{$slot->{'error'}}; # perl sucks
+ if (length $stderr > 20) {
+ $stderr = substr($stderr, 0, 150);
+ $stderr .= '...';
+ }
+ chomp($stderr);
+ $script_error = "1 $script_name $stderr";
+ # TODO: it currently sends errors for the first failed script
+ last;
+}
+
+send_info("mINFO_RTM_status|$script_error");
+
+unlockProcess();
+exit 0;
+
+
+sub send_info {
+ my $message = shift;
+
+ my $port = 6100 + int(rand(100));
+
+ my $ok = eval {
+ local $SIG{ALRM} = sub { print "rtm timeout\n"; die; };
+ alarm(10);
+
+ my $proto = getprotobyname('udp');
+ socket(Socket_Handle, PF_INET, SOCK_DGRAM, $proto);
+ my $iaddr = gethostbyname($destination_ip);
+ my $sin = sockaddr_in("$port", $iaddr);
+ send(Socket_Handle, "rtm $message", 10, $sin);
+ print "rtm $message\n";
+ alarm(0);
+ };
+ if (!defined($ok)) {
+ $script_error = "1 send_info() rtm timeout";
+ warn "error: $@\n";
+ }
+}
+
+sub drop_priv {
+ my ($uid, $gid) = @_;
+
+ # set EGID
+ $) = "$gid $gid";
+ # set EUID
+ $> = $uid + 0;
+ if ($> != $uid) {
+ die "Can't drop EUID.";
+ }
+}
+EOF
+ chown 0:0 "$RTM_PL"
+ chmod 750 "$RTM_PL"
+}
+
+# ^L
+# Generate rtm-update-ip.sh file
+generate_rtm_update_ip() {
+ echo "Generating rtm-update-ip.sh..."
+ cat << EOF > $RTM_UPDATE_IP.tmp
+#! /bin/sh
+# version: $VERSION ($RELEASE_DATE)
+
+LC_ALL=POSIX
+
+EOF
+ cat <<'EOF' >> $RTM_UPDATE_IP.tmp
+EOF
+ echo "DIR='$DIR'" >> $RTM_UPDATE_IP.tmp
+ cat <<'EOF' >> $RTM_UPDATE_IP.tmp
+
+get_interface_ip() {
+ iface=$1
+ ifconfig $iface 2>\/dev\/null | grep "inet.*netmask" | awk '{print $2}' | egrep '[0-9]+(\.[0-9]+){3}'
+}
+
+mainif="$(netstat -rn|grep "^default" | awk '{print $NF}'|sort|uniq|head -n1)"
+mainip="$(get_interface_ip $mainif)"
+
+arpa=`echo "$mainip" | sed "s/\./ /g" | awk '{print $3"."$2"."$1}'`;
+ip=`host -t A mrtg.$arpa.in-addr.arpa $DNSSERVER 2>/dev/null | tail -n 1 | sed -ne 's/.*[\t ]\([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+\).*/\1/p'`
+if [ -z "$ip" ]; then
+ echo "No IP from OVH network !"
+ exit 1;
+fi
+echo $ip > "$DIR/etc/rtm-ip"
+
+EOF
+ chown 0:0 "$RTM_UPDATE_IP.tmp"
+ chmod 750 "$RTM_UPDATE_IP.tmp"
+ mv "$RTM_UPDATE_IP.tmp" "$RTM_UPDATE_IP"
+ test -f $DIR/bin/rtm-update-ip.pl && rm $DIR/bin/rtm-update-ip.pl
+ $RTM_UPDATE_IP
+}
+
+
+lock_process() {
+ if [ -e "$lockfile" ]; then
+ lockpid=`cat "$lockfile"`
+ if [ -e "/proc/$lockpid" ]; then
+ echo "there seems to be stale $scriptname process running. check \"ps aux | grep $scriptname\"" >&2
+ exit 1;
+ fi
+ echo "Lock $lockfile with pid $lockpid exist for script $scriptname but no process not exist, replaced by new one!!" >&2
+ echo $$ > "$lockfile"
+ fi
+ echo $$ > "$lockfile.$$"
+ mv "$lockfile.$$" "$lockfile"
+}
+
+unlock_process() {
+ rm -f "$lockfile"
+}
+
+wait_for_lock() {
+ echo "Waiting for finish rtm running from CRON"
+ for i in `\/usr\/bin\/jot - 1 30`; do
+ if [ -e "$lockfile" ]; then
+ echo -n "."
+ sleep 2
+ else
+ echo -e "\nFinished."
+ break
+ fi
+ done
+}
+
+
+#
+# RTM installation code
+
+lockfile='/tmp/rtm.flock'
+if [ -e "$lockfile" ]; then
+ wait_for_lock
+fi
+lock_process
+
+# Generate selected scripts
+for script in $SCRIPTS_TO_INSTALL; do
+ generate_$script
+done
+generate_rtm_update_ip
+generate_rtm
+
+unlock_process
+
+if [ -e "$RTM_SH" ];then
+ mv $RTM_SH $RTM_SH.old
+fi
+ln -s $RTM_PL $RTM_SH
+
+rm -rf /rpms
+
+CRONTAB=/etc/crontab
+if [ -z "`cat $CRONTAB | grep \"$RTM_SH\"`" ]; then
+ minute=`perl -e 'print ((rand()*100)%60)'`
+ CRONTABLINE='*/1 * * * * root '$RTM_SH' '$minute' > /dev/null 2> /dev/null'
+ echo "$CRONTABLINE" >> $CRONTAB
+else
+ perl -pe 's!>/dev/null!> /dev/null!g' -i "$CRONTAB"
+fi
+
+# List entries in crontab
+echo ""
+echo "Crontab entries:"
+cat $CRONTAB
+sleep 2
+echo ""
+# restarting CRON
+for i in `jot 5 1` ; do
+ echo "Restarting CRON. Try $i"
+ if [ -x "/etc/rc.d/crond" ];then
+ killall -9 crond
+ $SCREEN /etc/rc.d/init.d/crond restart
+ elif [ -x "/etc/rc.d/cron" ];then
+ killall -9 cron
+ $SCREEN /etc/rc.d/cron restart
+ else
+ echo "WARNING: Didn't find any method of restarting cron on your distribution!" >&2
+ fi
+ sleep 2
+ if [ -z "`ps aux | grep -v grep |grep cron`" ]; then
+ echo "Cron didn't start."
+ else
+ break
+ fi
+done
+
+if [ -z "`ps aux | grep -v grep | grep cron`" ]; then
+ echo "Please check it!"
+ sleep 10
+else
+ echo "CRON restarted succefully."
+ sleep 2
+fi
+
+echo ""
+echo "in $DIR_SCRIPTS_MIN/check.pl you can add more things to check (monitors):"
+echo "when everything is fine:"
+echo "CHECK_vm|"
+echo "CHECK_oops|"
+echo "on breakdown:"
+echo "CHECK_vm|1"
+echo "CHECK_oops|1"
+echo
+echo "for exemple:"
+echo "# $DIR_SCRIPTS_MIN/check.pl"
+$DIR_SCRIPTS_MIN/check.pl
+echo ""
+echo "Sending all informations:"
+
+$RTM_SH
+
+# Local variables:
+# page-delimiter: "^# *\f"
+# sh-basic-offset: 4
+# End:
+