add a timeout command to the client package
authorStephen Soltesz <soltesz@cs.princeton.edu>
Thu, 9 Jul 2009 22:04:11 +0000 (22:04 +0000)
committerStephen Soltesz <soltesz@cs.princeton.edu>
Thu, 9 Jul 2009 22:04:11 +0000 (22:04 +0000)
new boot manager sequence to bootman.py
use timeout with scanapi operations

Monitor.spec
monitor/bootman.py
monitor/scanapi.py
timeout.pl [new file with mode: 0755]

index 8e237e7..f8986d9 100644 (file)
@@ -130,6 +130,8 @@ rm -rf $RPM_BUILD_ROOT
 #################### CLIENT 
 install -D -m 755 monitor-client.init $RPM_BUILD_ROOT/%{_initrddir}/monitor
 install -D -m 644 monitor.cron $RPM_BUILD_ROOT/%{_sysconfdir}/cron.d/monitor
+install -D -m 755 timeout.pl $RPM_BUILD_ROOT/usr/bin/timeout.pl
+
 
 #################### SERVER
 install -d $RPM_BUILD_ROOT/usr/share/%{name}
@@ -207,6 +209,7 @@ rm -rf $RPM_BUILD_ROOT
 %defattr(-,root,root)
 %{_initrddir}/monitor
 %{_sysconfdir}/cron.d/monitor
+/usr/bin/timeout.pl
 
 %files pcucontrol
 %{python_sitearch}/pcucontrol
index fdfadb2..c127611 100755 (executable)
@@ -448,6 +448,7 @@ class DebugInterface:
                                "bminit-cfg-auth-getplc-update-installinit-validate-exception-bmexceptmount-exception-noinstall-update-debug-done",
                                "bminit-cfg-auth-getplc-update-installinit-validate-bmexceptvgscan-exception-noinstall-update-debug-validate-bmexceptvgscan-done",
                                "bminit-cfg-auth-getplc-update-installinit-validate-exception-noinstall-update-debug-validate-done",
+                               "bminit-cfg-auth-getplc-installinit-validate-bmexceptvgscan-exception-noinstall-update-debug-validate-bmexceptvgscan-done",
                                ]:
                        sequences.update({n : "restart_bootmanager_rins"})
 
index 5928c5a..60ba41d 100644 (file)
@@ -197,7 +197,6 @@ class ScanNodeInternal(ScanInterface):
                        try:
                                for port in [22, 806]: 
                                        ssh = command.SSH('root', nodename, port)
-                                       #echo '  "fs_status":"'`touch /var/log/monitor 2>&1 ; if [ -d /vservers/ ] ; then touch /vservers/monitor.log 2>&1 ; fi ; grep proc /proc/mounts | grep ro,`'",'
 
                                        (oval, errval) = ssh.run_noexcept2(""" <<\EOF
                                                echo "{"
@@ -211,11 +210,12 @@ class ScanNodeInternal(ScanInterface):
                                                ID=`grep princeton_comon /etc/passwd | awk -F : '{if ( $3 > 500 ) { print $3}}'` 
                                                echo '  "princeton_comon_running":"'`ls -d /proc/virtual/$ID`'",'
                                                echo '  "princeton_comon_procs":"'`vps ax | grep $ID | grep -v grep | wc -l`'",'
-                                               echo '  "rpm_version":"'`rpm -q NodeManager`'",'
-                                               echo '  "rpm_versions":"'`rpm -q -a`'",'
+                                               echo '  "fs_status":"'`grep proc /proc/mounts | grep ro, ; if [ -x /usr/bin/timeout.pl ] ; then timeout.pl 20 touch /var/log/monitor 2>&1 ; if [ -d /vservers/ ] ; then timeout.pl 20 touch /vservers/monitor.log 2>&1  ; fi ; fi`'",'
+                                               echo '  "rpm_version":"'`if [ -x /usr/bin/timeout.pl ] ; then timeout.pl 30 rpm -q NodeManager ; fi`'",'
+                                               echo '  "rpm_versions":"'`if [ -x /usr/bin/timeout.pl ] ; then timeout.pl 45 rpm -q -a ; fi`'",'
                                                echo "}"
 EOF                            """)
-                                       
+
                                        values['ssh_error'] = errval
                                        if len(oval) > 0:
                                                #print "OVAL: %s" % oval
diff --git a/timeout.pl b/timeout.pl
new file mode 100755 (executable)
index 0000000..7ce8367
--- /dev/null
@@ -0,0 +1,275 @@
+#!/usr/bin/perl
+
+## timeout
+##
+## (c) 2004-2007 Piotr Roszatycki <dexter@debian.org>, GPL
+##
+## $Id: timeout.pl 4 2007-06-19 11:58:08Z piotr.roszatycki $
+
+=head1 NAME
+
+timeout - Run command with bounded time.
+
+=head1 SYNOPSIS
+
+B<timeout> S<B<-h>>
+
+B<timeout>
+S<[-I<signal>]>
+I<time>
+I<command>
+...
+
+=head1 README
+
+B<timeout> executes a command and imposes an elapsed time limit.  When the
+time limit is reached, B<timeout> sends a predefined signal to the target
+process.
+
+=cut
+
+
+use 5.006;
+use strict;
+
+use Config;
+use POSIX ();
+
+
+##############################################################################
+
+## Default values for constant variables
+##
+
+## Program name
+my $NAME = 'timeout';
+
+## Program version
+my $VERSION = '0.11';
+
+
+##############################################################################
+
+## Signals to handle
+##
+my @signals = qw< HUP INT QUIT TERM SEGV PIPE XCPU XFSZ ALRM >;
+
+
+##############################################################################
+
+## Signal to send after timeout. Default is KILL.
+my $signal = 'KILL';
+
+## Time to wait
+my $time = 0;
+
+## Command to execute as array of arguments
+my @command = ();
+
+## PID for fork function
+my $child_pid;
+
+## PID for wait function
+my $pid;
+
+
+##############################################################################
+
+## usage()
+##
+## Prints usage message.
+##
+sub usage() {
+    # Lazy loading for Pod::Usage
+    eval 'use Pod::Usage;';
+    die $@ if $@;
+
+    pod2usage(2);
+}
+
+
+## help()
+##
+## Prints help message.
+##
+sub help() {
+    # Lazy loading for Pod::Usage
+    eval 'use Pod::Usage;';
+    die $@ if $@;
+
+    pod2usage(-verbose=>1, -message=>"$NAME $VERSION\n");
+}
+
+
+## signal_handler($sig)
+##
+## Handler for signals to clean up child processes
+##
+sub signal_handler($) {
+    my ($sig) = @_;
+    if ($sig eq 'ALRM') {
+        printf STDERR "Timeout: aborting ``%s'' with SIG%s\n", join(' ', @command), $signal;
+    } else {
+        printf STDERR "Got signal SIG%s: aborting command ``%s'' with signal SIG%s\n", $sig, join(' ', @command), $signal;
+    }
+    kill $signal, -$child_pid;
+    exit -1;
+}
+
+
+##############################################################################
+
+## Main subroutine
+##
+
+
+## Parse command line arguments
+my $arg = $ARGV[0];
+if ($arg =~ /^-(.*)$/) {
+    my $opt = $1;
+    if ($arg eq '-h' || $arg eq '--help') {
+        help();
+    } elsif ($opt =~ /^[A-Z0-9]+$/) {
+        if ($opt =~ /^\d+/) {
+           # Convert numeric signal to name by using the perl interpreter's
+           # configuration:
+            usage() unless defined $Config{sig_name};
+            $signal = (split(' ', $Config{sig_name}))[$opt];
+        } else {
+            $opt =~ s/^SIG//;
+            $signal = $opt;
+        }
+       shift @ARGV;
+    } else {
+        usage();
+    }
+}
+
+usage() if @ARGV < 2;
+
+$arg = $ARGV[0];
+
+usage() unless $arg =~ /^\d+$/;
+
+$time = $arg;
+
+shift @ARGV;
+
+@command = @ARGV;
+
+
+## Fork for exec
+if (! defined($child_pid = fork)) {
+    die "Could not fork: $!\n";
+    exit 1;
+} elsif ($child_pid == 0) {
+    ## child
+
+    ## Set new process group
+    POSIX::setsid;
+    
+    ## Execute command
+    exec @command or die "Can not run command `" . join(' ', @command) . "': $!\n";
+}
+
+## parent
+
+## Set the handle for signals
+foreach my $sig (@signals) {
+    $SIG{$sig} = \&signal_handler;
+}
+
+## Set the alarm
+alarm $time;
+
+## Wait for child
+while (($pid = wait) != -1 && $pid != $child_pid) {}
+
+## Clean exit
+exit ($pid == $child_pid ? $? >> 8 : -1);
+
+
+=head1 DESCRIPTION
+
+B<timeout> executes a command and imposes an elapsed time limit.
+The command is run in a separate POSIX process group so that the
+right thing happens with commands that spawn child processes.
+
+=head1 OPTIONS
+
+=over 8
+
+=item -I<signal>
+
+Specify an optional signal name to send to the controlled process. By default,
+B<timeout> sends B<KILL>, which cannot be caught or ignored.
+
+=item I<time>
+
+The elapsed time limit after which the command is terminated.
+
+=item I<command>
+
+The command to be executed.
+
+=back
+
+=head1 RETURN CODES
+
+=over 8
+
+=item 0..253
+
+Return code from called command.
+
+=item 254
+
+Internal error. No return code could be fetched.
+
+=item 255
+
+The timeout was occured.
+
+=back
+
+=head1 PREREQUISITES
+
+=over
+
+=item *
+
+L<perl> >= 5.006
+
+=item *
+
+L<POSIX>
+
+=back
+
+=head1 COREQUISITES
+
+=over
+
+=item
+
+L<Pod::Usage>
+
+=back
+
+=head1 SCRIPT CATEGORIES
+
+UNIX/System_administration
+
+=head1 AUTHORS
+
+Piotr Roszatycki E<lt>dexter@debian.orgE<gt>
+
+=head1 LICENSE
+
+Copyright 2004-2007 by Piotr Roszatycki E<lt>dexter@debian.orgE<gt>.
+
+Inspired by timeout.c that is part of The Coroner's Toolkit.
+
+All rights reserved.  This program is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License, the
+latest version.