add flex-grid folder for flexlm license manager accounting
This commit is contained in:
parent
d26631afd2
commit
81897cf285
1
flex-grid/cache
Symbolic link
1
flex-grid/cache
Symbolic link
@ -0,0 +1 @@
|
||||
/rscratch/minos19/flex_grid_cache
|
33
flex-grid/config/abaqus_licenses.conf
Normal file
33
flex-grid/config/abaqus_licenses.conf
Normal file
@ -0,0 +1,33 @@
|
||||
<?xml version="1.0"?>
|
||||
<qlicserverConfig>
|
||||
<parameters type="overwrite">
|
||||
<param name="lmutil">/opt/SGE/flex-grid/scripts/abaqus_lmutil</param>
|
||||
<!-- <param name="LM_LICENSE_FILE">27000@abaqus-lizenz.rz.ruhr-uni-bochum.de</param> -->
|
||||
<param name="LM_LICENSE_FILE">27000@vmrz0300.vm.ruhr-uni-bochum.de</param>
|
||||
<param name="dir">/opt/SGE/flex-grid/cache</param>
|
||||
<param name="output">qlicserver_abaqus.xml</param>
|
||||
</parameters>
|
||||
<!--
|
||||
| Map resource names (complexes) to values (features)
|
||||
| served by the license manager(s).
|
||||
| Resources without a "served" attribute are considered internal
|
||||
| Resources with type "track" are reported but not managed
|
||||
| The urgency is how much extra weight to give to particular resources.
|
||||
| If a 'slot' is weighted with 1000, we can give an extra 10% to
|
||||
| a few resources. [Format: INTEGER]
|
||||
|
|
||||
| The resource 'limit' specifies an upper limit to prevent applications
|
||||
| from flooding the cluster and/or prevent jobs from consuming all the
|
||||
| available licenses. A negative limit is subtracted from the total
|
||||
| to obtain the limit. [Format: INTEGER]
|
||||
|
|
||||
| Derived resources are combined from sub-elements and inherit the
|
||||
| limits from their sub-elements.
|
||||
|
|
||||
| Resources that are not served and not derived are internal resources
|
||||
+ -->
|
||||
<resources type="overwrite">
|
||||
<resource name="abaqus" served="abaqus" limit="30" type="job"/>
|
||||
<resource name="cae" served="cae" limit="2" type="job"/>
|
||||
</resources>
|
||||
</qlicserverConfig>
|
31
flex-grid/config/comsol_licenses.conf
Normal file
31
flex-grid/config/comsol_licenses.conf
Normal file
@ -0,0 +1,31 @@
|
||||
<?xml version="1.0"?>
|
||||
<qlicserverConfig>
|
||||
<parameters type="overwrite">
|
||||
<param name="lmutil">/opt/matlab/etc/glnxa64/lmutil</param>
|
||||
<param name="LM_LICENSE_FILE">/opt/SGE/flex-grid/licenses/comsol.lic</param>
|
||||
<param name="dir">/opt/SGE/flex-grid/cache</param>
|
||||
<param name="output">qlicserver_comsol.xml</param>
|
||||
</parameters>
|
||||
<!--
|
||||
| Map resource names (complexes) to values (features)
|
||||
| served by the license manager(s).
|
||||
| Resources without a "served" attribute are considered internal
|
||||
| Resources with type "track" are reported but not managed
|
||||
| The urgency is how much extra weight to give to particular resources.
|
||||
| If a 'slot' is weighted with 1000, we can give an extra 10% to
|
||||
| a few resources. [Format: INTEGER]
|
||||
|
|
||||
| The resource 'limit' specifies an upper limit to prevent applications
|
||||
| from flooding the cluster and/or prevent jobs from consuming all the
|
||||
| available licenses. A negative limit is subtracted from the total
|
||||
| to obtain the limit. [Format: INTEGER]
|
||||
|
|
||||
| Derived resources are combined from sub-elements and inherit the
|
||||
| limits from their sub-elements.
|
||||
|
|
||||
| Resources that are not served and not derived are internal resources
|
||||
+ -->
|
||||
<resources type="overwrite">
|
||||
<resource name="comsol" served="COMSOL" type="job"/>
|
||||
</resources>
|
||||
</qlicserverConfig>
|
36
flex-grid/config/local_licenses.conf
Normal file
36
flex-grid/config/local_licenses.conf
Normal file
@ -0,0 +1,36 @@
|
||||
<?xml version="1.0"?>
|
||||
<qlicserverConfig>
|
||||
<parameters type="overwrite">
|
||||
<param name="lmutil">/opt/matlab/etc/glnxa64/lmutil</param>
|
||||
<param name="LM_LICENSE_FILE">/opt/SGE/flex-grid/licenses/multiphysics.lic</param>
|
||||
<param name="dir">/opt/SGE/flex-grid/cache</param>
|
||||
<param name="output">qlicserver_local.xml</param>
|
||||
<param name="qhost">qhost.xml</param>
|
||||
<param name="qstat">qstat.xml</param>
|
||||
</parameters>
|
||||
<!--
|
||||
| Map resource names (complexes) to values (features)
|
||||
| served by the license manager(s).
|
||||
| Resources without a "served" attribute are considered internal
|
||||
| Resources with type "track" are reported but not managed
|
||||
| The urgency is how much extra weight to give to particular resources.
|
||||
| If a 'slot' is weighted with 1000, we can give an extra 10% to
|
||||
| a few resources. [Format: INTEGER]
|
||||
|
|
||||
| The resource 'limit' specifies an upper limit to prevent applications
|
||||
| from flooding the cluster and/or prevent jobs from consuming all the
|
||||
| available licenses. A negative limit is subtracted from the total
|
||||
| to obtain the limit. [Format: INTEGER]
|
||||
|
|
||||
| Derived resources are combined from sub-elements and inherit the
|
||||
| limits from their sub-elements.
|
||||
|
|
||||
| Resources that are not served and not derived are internal resources
|
||||
resource name="hyper" served="GridWorks" type="job"
|
||||
<resource name="matlab" served="MATLAB" type="job" limit="-2"/>
|
||||
<resource name="signal_toolbox" served="Signal_Toolbox" type="job" limit="-2"/>
|
||||
+ -->
|
||||
<resources type="overwrite">
|
||||
<resource name="femlab" served="COMSOL" type="track"/>
|
||||
</resources>
|
||||
</qlicserverConfig>
|
32
flex-grid/config/matlab_licenses.conf
Normal file
32
flex-grid/config/matlab_licenses.conf
Normal file
@ -0,0 +1,32 @@
|
||||
<?xml version="1.0"?>
|
||||
<qlicserverConfig>
|
||||
<parameters type="overwrite">
|
||||
<param name="lmutil">/opt/matlab/etc/glnxa64/lmutil</param>
|
||||
<param name="LM_LICENSE_FILE">/opt/SGE/flex-grid/licenses/matlab.lic</param>
|
||||
<param name="dir">/opt/SGE/flex-grid/cache</param>
|
||||
<param name="output">qlicserver_matlab.xml</param>
|
||||
</parameters>
|
||||
<!--
|
||||
| Map resource names (complexes) to values (features)
|
||||
| served by the license manager(s).
|
||||
| Resources without a "served" attribute are considered internal
|
||||
| Resources with type "track" are reported but not managed
|
||||
| The urgency is how much extra weight to give to particular resources.
|
||||
| If a 'slot' is weighted with 1000, we can give an extra 10% to
|
||||
| a few resources. [Format: INTEGER]
|
||||
|
|
||||
| The resource 'limit' specifies an upper limit to prevent applications
|
||||
| from flooding the cluster and/or prevent jobs from consuming all the
|
||||
| available licenses. A negative limit is subtracted from the total
|
||||
| to obtain the limit. [Format: INTEGER]
|
||||
|
|
||||
| Derived resources are combined from sub-elements and inherit the
|
||||
| limits from their sub-elements.
|
||||
|
|
||||
| Resources that are not served and not derived are internal resources
|
||||
+ -->
|
||||
<resources type="overwrite">
|
||||
<resource name="matlab" served="MATLAB" type="job" limit="100"/>
|
||||
<resource name="mcc" served="Compiler" type="job" limit="100"/>
|
||||
</resources>
|
||||
</qlicserverConfig>
|
31
flex-grid/config/trelis_licenses.conf
Normal file
31
flex-grid/config/trelis_licenses.conf
Normal file
@ -0,0 +1,31 @@
|
||||
<?xml version="1.0"?>
|
||||
<qlicserverConfig>
|
||||
<parameters type="overwrite">
|
||||
<param name="lmutil">/opt/matlab/etc/glnxa64/lmutil</param>
|
||||
<param name="LM_LICENSE_FILE">/opt/SGE/flex-grid/licenses/matlab.lic</param>
|
||||
<param name="dir">/opt/SGE/flex-grid/cache</param>
|
||||
<param name="output">qlicserver_trelis.xml</param>
|
||||
</parameters>
|
||||
<!--
|
||||
| Map resource names (complexes) to values (features)
|
||||
| served by the license manager(s).
|
||||
| Resources without a "served" attribute are considered internal
|
||||
| Resources with type "track" are reported but not managed
|
||||
| The urgency is how much extra weight to give to particular resources.
|
||||
| If a 'slot' is weighted with 1000, we can give an extra 10% to
|
||||
| a few resources. [Format: INTEGER]
|
||||
|
|
||||
| The resource 'limit' specifies an upper limit to prevent applications
|
||||
| from flooding the cluster and/or prevent jobs from consuming all the
|
||||
| available licenses. A negative limit is subtracted from the total
|
||||
| to obtain the limit. [Format: INTEGER]
|
||||
|
|
||||
| Derived resources are combined from sub-elements and inherit the
|
||||
| limits from their sub-elements.
|
||||
|
|
||||
| Resources that are not served and not derived are internal resources
|
||||
+ -->
|
||||
<resources type="overwrite">
|
||||
<resource name="trelis" served="TRELIS" type="job"/>
|
||||
</resources>
|
||||
</qlicserverConfig>
|
1
flex-grid/licenses/comsol.lic
Symbolic link
1
flex-grid/licenses/comsol.lic
Symbolic link
@ -0,0 +1 @@
|
||||
/opt/comsol53a/multiphysics/license/license.dat
|
2
flex-grid/licenses/hyperworks.lic
Executable file
2
flex-grid/licenses/hyperworks.lic
Executable file
@ -0,0 +1,2 @@
|
||||
SERVER kamikaze 80b660b0 7788
|
||||
USE_SERVER
|
2
flex-grid/licenses/ifort.lic
Executable file
2
flex-grid/licenses/ifort.lic
Executable file
@ -0,0 +1,2 @@
|
||||
SERVER kamikaze 80b660b0 28518
|
||||
USE_SERVER
|
1
flex-grid/licenses/matlab.lic
Symbolic link
1
flex-grid/licenses/matlab.lic
Symbolic link
@ -0,0 +1 @@
|
||||
/opt/matlab/licenses/01network.lic
|
2
flex-grid/licenses/multiphysics.lic
Executable file
2
flex-grid/licenses/multiphysics.lic
Executable file
@ -0,0 +1,2 @@
|
||||
SERVER phaidra.geophysik.ruhr-uni-bochum.de 00163ef90680 1718
|
||||
USE_SERVER
|
221
flex-grid/scripts/GridEngine-git-config
Executable file
221
flex-grid/scripts/GridEngine-git-config
Executable file
@ -0,0 +1,221 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Snapshot of the current GridEngine configuration using git for the
|
||||
# backend storage and tracking mechanism.
|
||||
#
|
||||
# Should normally be called via a cronjob.
|
||||
#
|
||||
# Following Edward Dale's idea:
|
||||
# http://scompt.com/blog/archives/2009/10/13/versioned-grid-engine-configuration
|
||||
# but using git for the backend
|
||||
#
|
||||
# initialize:
|
||||
#
|
||||
# git --git-dir=$GIT_DIR init --bare --shared=world
|
||||
#
|
||||
# Note: we use Perl for inplace editing since some versions of sed have
|
||||
# problems with this task.
|
||||
################################################################################
|
||||
################################################################################
|
||||
# CUSTOMIZE THESE SETTINGS TO MATCH YOUR REQUIREMENTS:
|
||||
|
||||
SGE_ROOT=/opt/grid
|
||||
SGE_CELL=default
|
||||
GIT_DIR=/data/cfd/share/git-repo/gridengine-config.git
|
||||
|
||||
#
|
||||
# END OF CUSTOMIZE SETTINGS
|
||||
################################################################################
|
||||
################################################################################
|
||||
Script=${0##.*/}
|
||||
saveScript="$SGE_ROOT/util/upgrade_modules/save_sge_config.sh"
|
||||
export SGE_ROOT SGE_CELL GIT_DIR
|
||||
|
||||
for i in git perl
|
||||
do
|
||||
type $i >/dev/null 2>&1 || {
|
||||
echo "Error: $Script - no '$i' found"
|
||||
exit 1
|
||||
}
|
||||
done
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
usage() {
|
||||
while [ "$#" -ge 1 ]; do echo "$1"; shift; done
|
||||
cat<<USAGE
|
||||
|
||||
usage: ${0##*/} [OPTION | GIT_COMMAND]
|
||||
options:
|
||||
-help display this usage
|
||||
init initialize git repo in $GIT_DIR
|
||||
|
||||
pass-through git commands:
|
||||
log ls-files
|
||||
show whatchanged
|
||||
|
||||
Snapshot of the current GridEngine configuration using git for the
|
||||
backend storage and tracking mechanism.
|
||||
|
||||
* git repository stored here:
|
||||
$GIT_DIR
|
||||
|
||||
copyright (c) 2009-10 <Mark.Olesen@faurecia.com>
|
||||
|
||||
USAGE
|
||||
exit 1
|
||||
}
|
||||
#------------------------------------------------------------------------------
|
||||
# parse options
|
||||
while [ "$#" -gt 0 ]
|
||||
do
|
||||
case "$1" in
|
||||
( help | -h | -help )
|
||||
usage
|
||||
;;
|
||||
( init )
|
||||
shift
|
||||
if [ -d "$GIT_DIR" ]
|
||||
then
|
||||
echo "Error: $Script - $GIT_DIR already exists"
|
||||
exit 1
|
||||
else
|
||||
git --git-dir=$GIT_DIR init --bare --shared=world $@
|
||||
rc=$?
|
||||
|
||||
# add a description for gitweb
|
||||
i="$GIT_DIR/description"
|
||||
if [ -f "$i" -a -w "$i" ]
|
||||
then
|
||||
echo "snapshot of the current GridEngine configuration" > $i
|
||||
fi
|
||||
fi
|
||||
exit $rc
|
||||
;;
|
||||
( log | ls-files | show | whatchanged )
|
||||
git --git-dir=$GIT_DIR $@
|
||||
exit $?
|
||||
;;
|
||||
(*)
|
||||
usage "unknown option/argument: '$*'"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
|
||||
|
||||
[ -d "$GIT_DIR" ] || {
|
||||
echo "git repo: $GIT_DIR does not exist"
|
||||
exit 1
|
||||
}
|
||||
|
||||
|
||||
i="$SGE_ROOT/$SGE_CELL/common/settings.sh"
|
||||
if [ -f "$i" -a -r "$i" ]
|
||||
then
|
||||
. "$i"
|
||||
else
|
||||
echo "cannot read $i"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
[ -f "$saveScript" -a -r "$saveScript" ] || {
|
||||
echo "cannot read $i"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Create a fresh empty directory
|
||||
# cannot use --tmpdir on older systems
|
||||
tmpDir=$(mktemp -d "/tmp/sgeSaveConfig.XXXXXXXXXX")
|
||||
trap "rm -rf $tmpDir 2>/dev/null; exit 0" EXIT TERM INT
|
||||
|
||||
[ -d "$tmpDir" ] || {
|
||||
echo "Error: temp dir '$tmpDir' does not exist"
|
||||
exit 1
|
||||
}
|
||||
|
||||
$saveScript $tmpDir
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# cleanup
|
||||
#
|
||||
(
|
||||
cd $tmpDir || exit 1
|
||||
|
||||
# all operations are now in the current directory
|
||||
GIT_WORK_TREE=.
|
||||
export GIT_WORK_TREE
|
||||
|
||||
# minor error checking that the save script worked
|
||||
if [ -f backup_date -a -r backup_date ]
|
||||
then
|
||||
msg=$(cat backup_date)
|
||||
else
|
||||
echo "cannot read backup_date - $saveScript might have failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
# ignore accounting (too big)
|
||||
rm -f cell/accounting
|
||||
|
||||
# ignore current users
|
||||
rm -f users/*
|
||||
|
||||
# ignore current load_values for exec hosts
|
||||
perl -i -ne '/^load_values/ or print' execution/*
|
||||
|
||||
# assign (consumable) complex_values to zero - otherwise we indirectly
|
||||
# track the external license usage when qlicserver is being used
|
||||
# also sort the complexes to avoid spurious changes
|
||||
perl -i -p -e 'if (/^complex_values/) { chomp; ' \
|
||||
-e 's/=\d+/=0/g; s/^(complex\S+\s+)//; ' \
|
||||
-e '$_ = $1 . join("," => sort split /,/) . "\n" }' \
|
||||
execution/global
|
||||
|
||||
#
|
||||
# determine if the configuration changed
|
||||
#
|
||||
# this is fairly roundabout until we find a better way
|
||||
needsCommit=false
|
||||
|
||||
if [ -n "$(git ls-files -d)" ] # files deleted?
|
||||
then
|
||||
needsCommit=true
|
||||
elif [ -n "$(git ls-files -o)" ] # files added?
|
||||
then
|
||||
needsCommit=true
|
||||
else
|
||||
# files modified?
|
||||
# do it the long way to ensure we also get staged modifications
|
||||
set -- $(git status | perl -ne 's/^#\s+modified:// and print')
|
||||
|
||||
# changes in backup_date, jobseqnum etc alone are not enough
|
||||
# to warrant a commit
|
||||
while [ "$#" -ge 1 ]
|
||||
do
|
||||
case $1 in
|
||||
( arseqnum | backup_date | jobseqnum )
|
||||
shift
|
||||
;;
|
||||
(*)
|
||||
needsCommit=true
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
if [ "$needsCommit" = true ]
|
||||
then
|
||||
# register all new files
|
||||
git add .
|
||||
|
||||
# commit everything
|
||||
git commit -a -m "$msg"
|
||||
else
|
||||
echo "no changes to be committed $msg"
|
||||
fi
|
||||
)
|
||||
|
||||
exit 0
|
||||
#------------------------------------------------------------------------------
|
5
flex-grid/scripts/abaqus_lmutil
Executable file
5
flex-grid/scripts/abaqus_lmutil
Executable file
@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
# $Id: abaqus_lmutil 180 2010-09-17 15:46:41Z kasper $
|
||||
|
||||
/opt/abaqus/Commands/abaqus licensing lmstat -a -f abaqus -S ABAQUSLM
|
||||
/opt/abaqus/Commands/abaqus licensing lmstat -a -f cae -S ABAQUSLM
|
124
flex-grid/scripts/filter-accounting
Executable file
124
flex-grid/scripts/filter-accounting
Executable file
@ -0,0 +1,124 @@
|
||||
#!/usr/bin/perl -w
|
||||
use strict;
|
||||
use Getopt::Std qw( getopts );
|
||||
use Time::Local qw( timelocal );
|
||||
|
||||
my ($releaseDate) = qw( 2009-10-02 );
|
||||
|
||||
( my $Script = $0 ) =~ s{^.*/}{};
|
||||
# -------------------------------------------------------------------------
|
||||
sub usage {
|
||||
$! = 0; # clean exit
|
||||
warn "@_\n" if @_;
|
||||
die <<"USAGE";
|
||||
usage:
|
||||
$Script [OPTION] file1 [ .. fileN ]
|
||||
|
||||
with options:
|
||||
-b YYYY[-MM[-DD]]
|
||||
begin date for accounting (job end_time > DATE 2 A.M.)
|
||||
-e YYYY[-MM[-DD]]
|
||||
end date for accounting (job end_time <= DATE 2 A.M.)
|
||||
-h usage
|
||||
|
||||
Extract portions of the GridEngine accounting(5) file according to the
|
||||
job end_time. For example,
|
||||
$Script -b 2008-01-01 -e 2009 ...
|
||||
extracts the accounting for jobs that finished running in 2008.
|
||||
|
||||
The value of 2 A.M. avoids problems that daylight savings time might
|
||||
otherwise cause.
|
||||
|
||||
version ($releaseDate)
|
||||
copyright (c) 2009 <Mark.Olesen\@faurecia.com>
|
||||
|
||||
Licensed and distributed under the Creative Commons
|
||||
Attribution-NonCommercial-ShareAlike 3.0 License.
|
||||
http://creativecommons.org/licenses/by-nc-sa/3.0
|
||||
USAGE
|
||||
}
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
my %opt;
|
||||
getopts( "hb:e:", \%opt ) or usage();
|
||||
usage() if $opt{h};
|
||||
|
||||
@ARGV or usage();
|
||||
|
||||
for (@ARGV) {
|
||||
-f $_ or die "no file '$_'\n";
|
||||
|
||||
## handle compressed files transparently
|
||||
if (/\.bz2$/) {
|
||||
$_ = qq{bzip2 -dc "$_"|};
|
||||
}
|
||||
elsif (/\.gz$/) {
|
||||
$_ = qq{gzip -dc "$_"|};
|
||||
}
|
||||
}
|
||||
|
||||
for (qw( b e )) {
|
||||
if ( $opt{$_} ||= 0 ) {
|
||||
my ( $yy, $mm, $dd );
|
||||
|
||||
if ( $opt{$_} =~ /^(\d{2,4})-(\d{1,2})-(\d{1,2})$/ ) {
|
||||
## YYYY-MM-DD
|
||||
( $yy, $mm, $dd ) = ( $1, $2, $3 );
|
||||
}
|
||||
elsif ( $opt{$_} =~ /^(\d{2,4})-(\d{1,2})$/ ) {
|
||||
## YYYY-MM
|
||||
( $yy, $mm ) = ( $1, $2 );
|
||||
}
|
||||
elsif ( $opt{$_} =~ /^(\d{2,4})$/ ) {
|
||||
## YYYY
|
||||
($yy) = ($1);
|
||||
}
|
||||
else {
|
||||
usage("invalid date format: '$opt{$_}'");
|
||||
}
|
||||
|
||||
# treat missing month/day as '1'
|
||||
$mm ||= 1;
|
||||
$dd ||= 1;
|
||||
|
||||
# convert from YYYY-MM-DD to epoch,
|
||||
# start at 2am - avoid problems with daylight savings time
|
||||
$opt{$_} = timelocal( 0, 0, 2, $dd, $mm - 1, $yy ); # month (0..11)
|
||||
}
|
||||
}
|
||||
|
||||
$opt{b} or $opt{e} or usage("must specify at least one of -b or -e");
|
||||
|
||||
if ( $opt{e} and $opt{b} >= $opt{e} ) {
|
||||
usage("-b DATE must less than -e DATE");
|
||||
}
|
||||
|
||||
my $fileCount;
|
||||
while (<>) {
|
||||
if (/^\s*#/) {
|
||||
## pass-thru comments, but only for the first file
|
||||
print unless $fileCount;
|
||||
next;
|
||||
}
|
||||
|
||||
my ($endtime) = ( split /:/ )[10];
|
||||
|
||||
# only allow things that ran (endtime non-zero)
|
||||
# and that are within the filter limits
|
||||
if ( $endtime
|
||||
and ( $opt{b} ? ( $endtime > $opt{b} ) : 'okay' )
|
||||
and ( $opt{e} ? ( $endtime <= $opt{e} ) : 'okay' ) )
|
||||
{
|
||||
print;
|
||||
}
|
||||
}
|
||||
continue {
|
||||
$fileCount++ if eof;
|
||||
}
|
||||
|
||||
__END__
|
||||
|
||||
FORMAT - see accounting(5)
|
||||
08 submission_time
|
||||
09 start_time
|
||||
10 end_time
|
517
flex-grid/scripts/qlic
Executable file
517
flex-grid/scripts/qlic
Executable file
@ -0,0 +1,517 @@
|
||||
#!/usr/bin/perl -w
|
||||
use strict;
|
||||
use Getopt::Std qw( getopts );
|
||||
use POSIX qw( );
|
||||
|
||||
( my $Script = $0 ) =~ s{^.*/}{};
|
||||
|
||||
my $time = time;
|
||||
my $date = POSIX::strftime( "%F %T", localtime $time );
|
||||
|
||||
$ENV{SGE_ROOT} or die "Error $Script: \$SGE_ROOT is not set\n";
|
||||
$ENV{SGE_CELL} ||= "default"; # sge_cell
|
||||
|
||||
my ($siteLocation) = join "/" => ( $ENV{SGE_ROOT}, $ENV{SGE_CELL}, "site" );
|
||||
|
||||
my $config = {
|
||||
-site => ( $siteLocation || '' ),
|
||||
-cache => ( $siteLocation || '' ) . "/cache/" . "qlicserver.xml",
|
||||
-limits => ( $siteLocation || '' ) . "/" . "qlicserver.limits",
|
||||
};
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# utils
|
||||
|
||||
#
|
||||
# calculate age from an epoch value
|
||||
#
|
||||
sub age {
|
||||
my ( $a, $b ) = @_;
|
||||
my $diff = ( $a - $b );
|
||||
|
||||
my $sign = '';
|
||||
if ( $diff < 0 ) { # handle negatives
|
||||
$sign = '-';
|
||||
$diff = abs($diff);
|
||||
}
|
||||
|
||||
sprintf "$sign%d:%02d:%02d", # format into hh:mm:ss
|
||||
( int $diff / 3_600 ), # hh
|
||||
( ( int $diff / 60 ) % 60 ), # mm
|
||||
( $diff % 60 ); # ss
|
||||
}
|
||||
|
||||
#
|
||||
# change hash references to a comma-delimited string of key=value entries
|
||||
#
|
||||
sub hashRefToString {
|
||||
map {
|
||||
my $ref = $_;
|
||||
ref $ref ? map { "$_=$ref->{$_}" } sort keys %$ref : ()
|
||||
} @_;
|
||||
}
|
||||
|
||||
#
|
||||
# extract attrib="value" ... attrib="value"
|
||||
#
|
||||
sub parseXMLattrib {
|
||||
my $str = shift || '';
|
||||
my %attr;
|
||||
|
||||
while ($str =~ s{^\s*(\w+)=\"([^\"]*)\"}{}s
|
||||
or $str =~ s{^\s*(\w+)=\'([^\']*)\'}{}s )
|
||||
{
|
||||
$attr{$1} = $2;
|
||||
}
|
||||
|
||||
%attr;
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# processing of qlicserver.xml output
|
||||
#
|
||||
package qlicCache;
|
||||
|
||||
sub new {
|
||||
my $caller = shift;
|
||||
my $file = shift;
|
||||
|
||||
my $self = bless {
|
||||
( map { $_ => {} } qw( -rc ) ),
|
||||
( map { $_ => '' } qw( -date -host -age ) )
|
||||
}, $caller;
|
||||
|
||||
-f $file or return $self;
|
||||
|
||||
local $_ = do { local ( @ARGV, $/ ) = $file; <>; };
|
||||
|
||||
# strip out all xml comments
|
||||
s{<!--.*?-->\s*}{}sg;
|
||||
|
||||
# get the header section
|
||||
s{^(.+?)</query>}{}s or return;
|
||||
my $header = $1;
|
||||
|
||||
for ($header) {
|
||||
if (m{<host (?:\s+([^<>]*))? > \s*(.+?)\s* </host>}sx) {
|
||||
my ( $attr, $content ) = ( $1, $2 );
|
||||
$self->{-host} = $content;
|
||||
}
|
||||
if (m{<time (?:\s+([^<>]*))? > \s*(.+?)\s* </time>}sx) {
|
||||
my ( $attr, $content ) = ( $1, $2 );
|
||||
my %attr = main::parseXMLattrib($attr);
|
||||
|
||||
$self->{-age} = main::age( $time, $attr{epoch} ) if $attr{epoch};
|
||||
$self->{-date} = $content;
|
||||
}
|
||||
}
|
||||
|
||||
# only retain the <resources> contents
|
||||
s{^.*?<resources>}{}s and s{</resources>.*$}{}s or return;
|
||||
|
||||
## process <resource .../>
|
||||
while (s{<resource (?:\s+([^/<>]*))? />}{}sx) {
|
||||
my ($attr) = ($1);
|
||||
my %attr = main::parseXMLattrib($attr);
|
||||
my $name = delete $attr{name};
|
||||
|
||||
if ( defined $name ) {
|
||||
for ( keys %attr ) {
|
||||
$self->{-rc}{$name}{$_} = $attr{$_} || 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
## process <resource ...> CONTENT </resource>
|
||||
while (s{<resource (?:\s+([^<>]*))? > \s* (.*?) \s* </resource>}{}sx) {
|
||||
my ( $attr, $content ) = ( $1, $2 );
|
||||
my %attr = main::parseXMLattrib($attr);
|
||||
my $name = delete $attr{name};
|
||||
|
||||
if ( defined $name ) {
|
||||
for ( keys %attr ) {
|
||||
$self->{-rc}{$name}{$_} = $attr{$_} || 0;
|
||||
}
|
||||
}
|
||||
|
||||
## process <user ...> COUNT </user>
|
||||
while ( $content =~ s{<user (?:\s+([^<>]*))? >\s*(\d+)\s*</user>}{}sx )
|
||||
{
|
||||
my ( $attr, $count ) = ( $1, $2 );
|
||||
my %attr = main::parseXMLattrib($attr);
|
||||
my $user = delete $attr{name};
|
||||
my $host = delete $attr{host};
|
||||
|
||||
if ( defined $user ) {
|
||||
if ( defined $host ) {
|
||||
$self->{-rc}{$name}{-where}{"$user\@$host"} = $count;
|
||||
}
|
||||
else {
|
||||
## tag waiting with '[]'
|
||||
$self->{-rc}{$name}{-where}{$user} = "[$count]";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub query {
|
||||
my $self = shift;
|
||||
%{ $self->{-rc} };
|
||||
}
|
||||
|
||||
sub dump {
|
||||
use Data::Dumper;
|
||||
print Dumper( $_[0] );
|
||||
}
|
||||
|
||||
sub available {
|
||||
my $self = shift;
|
||||
sort keys %{ $self->{-rc} };
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# processing of qlicserver.limits FILE or DIRECTORY
|
||||
#
|
||||
package qlicLimits;
|
||||
|
||||
sub new {
|
||||
my $caller = shift;
|
||||
my $diskValues = shift;
|
||||
|
||||
my $self = bless {}, $caller;
|
||||
|
||||
my $fileString;
|
||||
if ( defined $diskValues and -f $diskValues ) {
|
||||
$fileString = do {
|
||||
local ( *FILE, $/ );
|
||||
|
||||
if ( open FILE, $diskValues ) {
|
||||
<FILE>;
|
||||
}
|
||||
else {
|
||||
undef;
|
||||
}
|
||||
};
|
||||
}
|
||||
elsif ( defined $diskValues and -d $diskValues ) {
|
||||
local *DIR;
|
||||
my $dir = $diskValues;
|
||||
if ( opendir DIR, $dir ) {
|
||||
my @files = grep { -f "$dir/$_" and -r _ } readdir DIR;
|
||||
for my $name (@files) {
|
||||
my $limit;
|
||||
|
||||
# use the last value
|
||||
if ( open FILE, "$dir/$name" ) {
|
||||
$limit = ( map { /^\s*(-?\d+)\s*$/ } <FILE> )[-1];
|
||||
}
|
||||
defined $limit or $limit = "NONE";
|
||||
$self->{$name} = $limit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ($fileString) {
|
||||
defined or next;
|
||||
|
||||
# strip out all comments
|
||||
s{<!--.*?-->\s*}{}sg;
|
||||
|
||||
## process <resource .../> and <resource ...></resource>
|
||||
while (s{<resource (?:\s+([^/<>]*))? />}{}sx
|
||||
or s{<resource (?:\s+([^/<>]*))? >\s*</resource>}{}sx )
|
||||
{
|
||||
my %attr = main::parseXMLattrib($1);
|
||||
my $name = delete $attr{name};
|
||||
my $limit = delete $attr{limit};
|
||||
if ( defined $name and defined $limit ) {
|
||||
$self->{$name} = $limit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub change {
|
||||
my $caller = shift;
|
||||
my $diskValues = shift;
|
||||
my @args = @_;
|
||||
|
||||
@args or return;
|
||||
|
||||
my ( %pending, %adjusted );
|
||||
|
||||
for (@args) {
|
||||
s{,}{ }g; # comma -> space-delimited
|
||||
|
||||
my %h = map { /^(.+?)=(.*)$/ } split;
|
||||
for ( keys %h ) {
|
||||
defined $h{$_} and length $h{$_} or $h{$_} = "NONE";
|
||||
$pending{$_} = $h{$_};
|
||||
}
|
||||
}
|
||||
|
||||
keys %pending or return;
|
||||
|
||||
my $user = getpwuid $<;
|
||||
if ( defined $diskValues and -d $diskValues ) {
|
||||
local *DIR;
|
||||
my $dir = $diskValues;
|
||||
if ( opendir DIR, $dir ) {
|
||||
my @files = grep { -f "$dir/$_" and -w _ } readdir DIR;
|
||||
|
||||
for my $name (@files) {
|
||||
if ( exists $pending{$name} ) {
|
||||
local *FILE;
|
||||
if ( open FILE, ">", "$dir/$name" ) {
|
||||
print FILE "# adjusted by $user $date\n",
|
||||
"$pending{$name}\n";
|
||||
$adjusted{$name} = delete $pending{$name};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( [ "adjusted" => \%adjusted ], [ "not adjusted" => \%pending ], ) {
|
||||
my ( $label, $href ) = @$_;
|
||||
keys %$href or next;
|
||||
print "$label: ",
|
||||
join( "," => map { qq{$_=$href->{$_}} } sort keys %$href ), "\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub output {
|
||||
my $self = shift;
|
||||
|
||||
my @list = map { qq{$_=$self->{$_}} } sort keys %$self;
|
||||
|
||||
print "limits: ";
|
||||
if (@list) {
|
||||
print join( "," => @list ), "\n";
|
||||
}
|
||||
else {
|
||||
print "NONE\n";
|
||||
}
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# main
|
||||
#
|
||||
|
||||
package main;
|
||||
import qlicCache;
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
sub usage {
|
||||
$! = 0; # clean exit
|
||||
warn "@_\n" if @_;
|
||||
die <<"USAGE";
|
||||
usage:
|
||||
$Script [OPTION]
|
||||
$Script [OPTION] resource=limit .. resource=limit
|
||||
|
||||
with options:
|
||||
-c FILE alternative location for the license cache
|
||||
-C FILE alternative location for the license limit
|
||||
-d dump cache file as raw xml
|
||||
-D dump license cache in perl format
|
||||
-f display free licenses only
|
||||
-l list license limit
|
||||
-q display free licenses via qhost query
|
||||
-u license usage via 'lacct'
|
||||
-U license usage per user via 'lacct -u'
|
||||
-w show who/where ('[]' indicates waiting jobs)
|
||||
-h this help
|
||||
|
||||
* extract / display information for the GridEngine license cache
|
||||
$config->{-cache}
|
||||
|
||||
* adjust / display information for the license limits
|
||||
$config->{-limits}
|
||||
|
||||
copyright (c) 2003-10 <Mark.Olesen\@faurecia.com>
|
||||
|
||||
Licensed and distributed under the Creative Commons
|
||||
Attribution-NonCommercial-ShareAlike 3.0 License.
|
||||
http://creativecommons.org/licenses/by-nc-sa/3.0
|
||||
USAGE
|
||||
}
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
my %opt;
|
||||
getopts( 'hc:C:DdflqUuw', \%opt ) or usage();
|
||||
$opt{h} and usage();
|
||||
|
||||
if ( $opt{U} ) {
|
||||
## user-based usage from accounting
|
||||
my @query = ( "lacct", "-u" );
|
||||
exec @query;
|
||||
exit 2;
|
||||
}
|
||||
elsif ( $opt{u} ) {
|
||||
## usage from accounting
|
||||
my @query = ( "lacct", $opt{w} ? "-w" : () );
|
||||
exec @query;
|
||||
exit 2;
|
||||
}
|
||||
|
||||
if ( $opt{d} ) {
|
||||
my $file = $opt{c} || $config->{-cache};
|
||||
|
||||
if ( not -f $file and $file !~ m{/} ) {
|
||||
$file = "$config->{-site}/$file";
|
||||
}
|
||||
|
||||
-f $file or exit 1;
|
||||
|
||||
local $_ = do { local ( @ARGV, $/ ) = $file; <>; };
|
||||
|
||||
# do a basic check for well-formed xml
|
||||
# this might not be the case if there is a race condition
|
||||
# and the file has not been fully written
|
||||
|
||||
# check for '<?xml version="1.0"?><someTag ...' at the start
|
||||
# and '</someTag>' at the end
|
||||
my ($tag) = m{^<\?xml (?:\s+[^<>]*?)? \?>\s*\<(\w+)}sx;
|
||||
unless ( $tag and m{</\Q$tag\E>\s*$} ) {
|
||||
sleep 2; ## wait and try again
|
||||
$_ = do { local ( @ARGV, $/ ) = $file; <>; };
|
||||
}
|
||||
|
||||
$_ ||= ''; ## avoid uninitialized
|
||||
|
||||
print;
|
||||
exit;
|
||||
}
|
||||
|
||||
if ( $opt{q} ) {
|
||||
my %free =
|
||||
map { /^\s+gc:(\S+?)=(\d\S*)\s*$/ }
|
||||
grep { /^global/ ... /^\S/ } qx{qhost -F};
|
||||
|
||||
$_ += 0 for values %free;
|
||||
|
||||
for ( sort keys %free ) {
|
||||
my $intval = $free{$_} + 0; # normalize as integers
|
||||
print "$_=$intval\n";
|
||||
}
|
||||
exit;
|
||||
}
|
||||
|
||||
if ( $opt{l} ) {
|
||||
qlicLimits->new( $opt{C} || $config->{-limits} )->output();
|
||||
exit;
|
||||
}
|
||||
|
||||
if (@ARGV) {
|
||||
qlicLimits->change( $opt{C} || $config->{-limits}, @ARGV );
|
||||
exit;
|
||||
}
|
||||
|
||||
my $info = qlicCache->new( $opt{c} || $config->{-cache} );
|
||||
$info->dump() if $opt{D};
|
||||
|
||||
my %resources = $info->query();
|
||||
|
||||
#
|
||||
# display free licenses
|
||||
#
|
||||
if ( $opt{f} ) {
|
||||
for my $resource ( sort keys %resources ) {
|
||||
my $count = $resources{$resource} || {};
|
||||
my $free = $count->{free} || 0;
|
||||
print "$resource=$free\n" if $free;
|
||||
}
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
#
|
||||
# display who/where
|
||||
#
|
||||
if ( $opt{w} ) {
|
||||
my ($len) = sort { $b <=> $a } map { length } keys %resources;
|
||||
$len += 2;
|
||||
|
||||
my $fmt = "%-${len}s";
|
||||
my $indent = sprintf "\n$fmt", '';
|
||||
|
||||
for my $resource ( sort keys %resources ) {
|
||||
my $count = $resources{$resource} || {};
|
||||
my @list = hashRefToString( $count->{-where} );
|
||||
if (@list) {
|
||||
printf $fmt, $resource;
|
||||
print join( $indent => @list ), "\n";
|
||||
}
|
||||
}
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
#
|
||||
# define table output format
|
||||
#
|
||||
my @outputList;
|
||||
|
||||
format =
|
||||
# name total limit extern intern wait free
|
||||
@<<<<<<<<<<< @>>>>> @>>>>> @>>>>> @>>>>> @>>>> @>>>>
|
||||
@outputList
|
||||
.
|
||||
|
||||
#
|
||||
# display table header
|
||||
# --------------------
|
||||
{
|
||||
my @info = qw( host age );
|
||||
my ($len) = sort { $b <=> $a } map { length } @info;
|
||||
|
||||
print map {
|
||||
my $k = sprintf "%-${len}s", $_;
|
||||
my $v = $info->{"-$_"};
|
||||
$v ? "$k = $v\n" : ();
|
||||
} @info;
|
||||
|
||||
print "\n";
|
||||
|
||||
@outputList = qw( resource total limit extern intern wait free );
|
||||
|
||||
write;
|
||||
s/./-/g for @outputList;
|
||||
write;
|
||||
}
|
||||
|
||||
#
|
||||
# display table body
|
||||
# ------------------
|
||||
for my $resource ( sort keys %resources ) {
|
||||
my $count = $resources{$resource} || {};
|
||||
@outputList =
|
||||
( $resource, @{$count}{qw( total limit extern intern waiting free )} );
|
||||
|
||||
my $type = $resources{$resource}{type} || 0;
|
||||
|
||||
# no total?
|
||||
$_ ||= "?" for $outputList[1];
|
||||
|
||||
if ( $type eq "intern" ) {
|
||||
$_ = "*" for $outputList[3];
|
||||
}
|
||||
elsif ( $type eq "track" ) {
|
||||
$_ = "*" for $outputList[4];
|
||||
}
|
||||
|
||||
# easy to read representation for zero
|
||||
for (@outputList) {
|
||||
defined $_ or $_ = '.';
|
||||
}
|
||||
|
||||
write;
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------
|
2327
flex-grid/site/qlicserver
Executable file
2327
flex-grid/site/qlicserver
Executable file
File diff suppressed because it is too large
Load Diff
325
flex-grid/site/qloadsensor
Executable file
325
flex-grid/site/qloadsensor
Executable file
@ -0,0 +1,325 @@
|
||||
#!/bin/bash
|
||||
# $Id: qloadsensor 180 2010-09-17 15:46:41Z kasper $
|
||||
#
|
||||
# qloadsensor:
|
||||
# load sensor for particular file systems and floating licenses
|
||||
#
|
||||
# NB:
|
||||
# 1) add the new complexes (via qconf -mc) for the following:
|
||||
# * complex configurations managed in the shell script
|
||||
# eg, 'perl -x qloadsensor'
|
||||
# * complex consumables managed global
|
||||
# eg, 'qlicserver -c'
|
||||
# 2) initialize the global complex consumables to be managed
|
||||
# eg, 'qlicserver -C'
|
||||
#
|
||||
# copyright (c) 2003-10 <Mark.Olesen@faurecia.com>
|
||||
#
|
||||
# Licensed and distributed under the Creative Commons
|
||||
# Attribution-NonCommercial-ShareAlike 3.0 License.
|
||||
# http://creativecommons.org/licenses/by-nc-sa/3.0
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
#
|
||||
# impose default GridEngine environment + ascertain the binary architecture
|
||||
#
|
||||
# you likely don't need to adjust these values, since the loadsensor is called
|
||||
# from sge_execd, which in turn is started from /etc/init.d/n1ge and
|
||||
# these variables should be correctly exported there
|
||||
#
|
||||
[ -d "$SGE_ROOT" ] || { echo "Error: SGE_ROOT=$SGE_ROOT not found"; exit 1; }
|
||||
: ${SGE_CELL:=default}
|
||||
: ${SGE_ARCH:=`$SGE_ROOT/util/arch`}
|
||||
|
||||
export SGE_ROOT SGE_CELL SGE_ARCH
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# this script should run as the 'admin_user' registered in 'bootstrap'
|
||||
#
|
||||
if [ "$UID" -eq 0 ]
|
||||
then
|
||||
admin_user=$(sed -ne 's/^admin_user *//p' $SGE_ROOT/$SGE_CELL/common/bootstrap)
|
||||
: ${admin_user:=root}
|
||||
if [ $admin_user != root -a $(echo $admin_user | tr "A-Z" "a-z") != none ]
|
||||
then
|
||||
exec $SGE_ROOT/utilbin/$SGE_ARCH/adminrun $admin_user $0
|
||||
fi
|
||||
fi
|
||||
|
||||
# <settings>
|
||||
# ========================================================================
|
||||
# now that we are the admin_user, we can source our standard settings
|
||||
# - customize *all* settings there (eg, license server settings)
|
||||
# - ENSURE THAT '$SGE_site' IS DEFINED !!!
|
||||
#
|
||||
for i in $SGE_ROOT/$SGE_CELL/site/environ; do [ -f $i ] && . $i; done
|
||||
|
||||
# define (unique) cluster name if not already defined
|
||||
if [ -z "$SGE_CLUSTER_NAME" -a -r "$SGE_ROOT/$SGE_CELL/common/cluster_name" ]
|
||||
then
|
||||
SGE_CLUSTER_NAME=$(cat $SGE_ROOT/$SGE_CELL/common/cluster_name 2>/dev/null)
|
||||
fi
|
||||
: ${SGE_CLUSTER_NAME:=default}
|
||||
export SGE_CLUSTER_NAME
|
||||
|
||||
SGE_site="$SGE_ROOT/flex-grid/site"
|
||||
|
||||
#
|
||||
# ========================================================================
|
||||
# </settings>
|
||||
|
||||
###############################################################################
|
||||
###############################################################################
|
||||
# CUSTOMIZE THESE SETTINGS - iff. required
|
||||
|
||||
qlicserver="$SGE_site/qlicserver config=$SGE_site/../config/local_licenses.conf dir=$SGE_ROOT/flex-grid/cache output=$SGE_ROOT/flex-grid/cache/qlicserver.xml qhost=qhost.xml qstat=qstat.xml"
|
||||
diskmon="$SGE_site/diskmon.pl"
|
||||
|
||||
# END OF CUSTOMIZE SETTINGS
|
||||
###############################################################################
|
||||
###############################################################################
|
||||
|
||||
#
|
||||
# the real (not compiled in) architecture
|
||||
#
|
||||
os_arch=`$SGE_ROOT/util/arch`
|
||||
SGE_utilbin=$SGE_ROOT/utilbin/$os_arch
|
||||
|
||||
#
|
||||
# set some constants
|
||||
#
|
||||
HOST=$($SGE_utilbin/gethostname -aname)
|
||||
UQHOST=$(echo $HOST | cut -f1 -d.)
|
||||
SGE_qmaster=unknown; export SGE_qmaster
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# act_qmaster
|
||||
#
|
||||
# extract the unqualified host name from the "act_qmaster" file
|
||||
# return this value or 'unknown' on failure
|
||||
#
|
||||
act_qmaster()
|
||||
{
|
||||
tmp=$(cat $SGE_common/act_qmaster 2>/dev/null)
|
||||
echo ${tmp:-unknown}
|
||||
}
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# df_info
|
||||
#
|
||||
# echo the $1_{total,used,free} space on filesystem $2
|
||||
#
|
||||
# gridengine uses the suffixes
|
||||
# 'k' => blocksize 1000
|
||||
# 'K' => blocksize 1024
|
||||
#
|
||||
# return 0 if 'df' fails
|
||||
df_info()
|
||||
{
|
||||
# 1:tag 2:mount 3:filesys 4:total 5:Used 6:Avail 7:Used% 8:Mount
|
||||
[ -d "$2" ] && set -- $1 $2 $( df -k -P $2 2>/dev/null | tail -1 )
|
||||
|
||||
#!# we could add the following check:
|
||||
#!# [ "$2" != "$8" ] && set -- $1 $2; # mount point mismatch?
|
||||
|
||||
[ "$#" -ge 6 ] || set -- $1 $2 filesystem 0 0 0
|
||||
|
||||
echo "$UQHOST:$1_total:$4K"
|
||||
echo "$UQHOST:$1_used:$5K"
|
||||
|
||||
#if [ -w "$2" ]
|
||||
#then
|
||||
echo "$UQHOST:$1_free:$6K"
|
||||
#else
|
||||
# echo "$UQHOST:$1_free:0"
|
||||
#fi
|
||||
}
|
||||
|
||||
# invariant values
|
||||
if [ -e "/proc/cpuinfo" ]
|
||||
then
|
||||
# mips=$(awk '{if (/mips/) printf "%.0f\n", $NF}' /proc/cpuinfo | tail -1)
|
||||
mips=$(awk 'BEGIN {mips=0} /mips/ {if ($NF > mips) mips=$NF }; END {print mips}' /proc/cpuinfo)
|
||||
else
|
||||
mips=0
|
||||
fi
|
||||
|
||||
unset os_name
|
||||
# extract lsb_release
|
||||
if [ -e "/usr/bin/lsb_release" ]
|
||||
then
|
||||
os_name=$(/usr/bin/lsb_release -ircs | xargs echo | sed 's/ /_/g')
|
||||
else
|
||||
os_name='unkown'
|
||||
fi
|
||||
: ${os_name:=NONE}
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# host_info
|
||||
#
|
||||
# report host specific information about filesystems, logins,
|
||||
# special hardware extensions, etc.
|
||||
#
|
||||
host_info()
|
||||
{
|
||||
echo "$UQHOST:arch:$os_arch"
|
||||
echo "$UQHOST:os:$os_name"
|
||||
# df_info tmp /tmp
|
||||
df_info scratch /scratch
|
||||
echo "$UQHOST:mips:$mips"
|
||||
}
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# iidle_info()
|
||||
# report a machine's idle time
|
||||
#
|
||||
# parse the contents from /proc/interrupts, which looks like the following:
|
||||
#
|
||||
# CPU0
|
||||
# 0: 23024789 XT-PIC timer
|
||||
# 1: 13 XT-PIC keyboard
|
||||
# 2: 0 XT-PIC cascade
|
||||
# 5: 0 XT-PIC usb-uhci
|
||||
# 8: 2 XT-PIC rtc
|
||||
# 9: 0 XT-PIC acpi
|
||||
# 10: 0 XT-PIC ehci-hcd, usb-uhci
|
||||
# 11: 16687253 XT-PIC eth0, usb-uhci, Intel 82801DB-ICH4, nvidia
|
||||
# 12: 20 XT-PIC PS/2 Mouse
|
||||
# 14: 77178 XT-PIC ide0
|
||||
# 15: 2 XT-PIC ide1
|
||||
# NMI: 0
|
||||
# LOC: 0
|
||||
# ERR: 0
|
||||
# MIS: 0
|
||||
#
|
||||
# or,
|
||||
#
|
||||
# CPU0 CPU1
|
||||
# 0: 12820049 12818168 IO-APIC-edge timer
|
||||
# 1: 42889 43309 IO-APIC-edge keyboard
|
||||
# 2: 0 0 XT-PIC cascade
|
||||
# 8: 2 0 IO-APIC-edge rtc
|
||||
# 9: 0 0 IO-APIC-edge acpi
|
||||
# 12: 287235 296531 IO-APIC-edge PS/2 Mouse
|
||||
# 14: 47423 40923 IO-APIC-edge ide0
|
||||
# 15: 2 3 IO-APIC-edge ide1
|
||||
# 16: 7733868 7737081 IO-APIC-level nvidia
|
||||
# 17: 159 156 IO-APIC-level Intel ICH 82801AA
|
||||
# 19: 2155710 2159943 IO-APIC-level e100, usb-uhci
|
||||
# NMI: 0 0
|
||||
# LOC: 25641034 25641033
|
||||
# ERR: 0
|
||||
# MIS: 0
|
||||
#
|
||||
# Thus, we need the [-1, 1..$ncpu] fields for the following sources:
|
||||
# keyboard, Mouse, serial
|
||||
#
|
||||
# NB: adding 'usb-uhci' gives problems, since this is sometimes
|
||||
# attached to the ethernet card
|
||||
#
|
||||
# set the variable 'iidle' to the idle time (seconds) since the last call
|
||||
#
|
||||
last="0 -1";
|
||||
iidle_info()
|
||||
{
|
||||
set -- $(
|
||||
perl -e '
|
||||
my @last = @ARGV;
|
||||
@ARGV = "/proc/interrupts";
|
||||
$_ = <>;
|
||||
|
||||
my $ncpu = s/\s*CPU\d+//g || 0;
|
||||
my ( $iidle, $int, $now ) = ( 0, 0, time );
|
||||
|
||||
$int += $_
|
||||
for
|
||||
map { /\s+(keyboard|Mouse|serial)$/ ? (split)[ 1 .. $ncpu ] : (); }
|
||||
<>;
|
||||
|
||||
if ( $int == $last[-1] ) { # no interactivity since last round
|
||||
$iidle = ( $now - $last[0] );
|
||||
}
|
||||
else {
|
||||
@last = ( $now, $int );
|
||||
}
|
||||
|
||||
print "$iidle @last\n";
|
||||
' $last
|
||||
);
|
||||
|
||||
echo "$UQHOST:iidle:$1";
|
||||
|
||||
shift; last="$@"; # save for later
|
||||
}
|
||||
# -----------------------------------------------------------------------------
|
||||
#
|
||||
# The execd running on the qmaster queries the license server
|
||||
# The contents of 'act_qmaster' should suffice to migrate the load sensor
|
||||
# for a controlled migration.
|
||||
#
|
||||
|
||||
while :
|
||||
do
|
||||
read input || exit 1 # wait for input
|
||||
[ "$input" = quit ] && exit 0
|
||||
|
||||
echo begin # begin load report
|
||||
host_info # host information
|
||||
iidle_info # machine's idle time
|
||||
echo end # end load report
|
||||
|
||||
# let the license query run between load reports
|
||||
# SGE_qmaster=`act_qmaster` # refresh the name of the qmaster
|
||||
# if [ "$HOST" = "$SGE_qmaster" ]
|
||||
if [ "$HOST" = "minos19" ]
|
||||
then
|
||||
# $qlicserver 2>> qloadsensor.err
|
||||
$SGE_ROOT/flex-grid/site/qlicserver config=$SGE_ROOT/flex-grid/config/local_licenses.conf output=$SGE_ROOT/flex-grid/cache/qlicserver_local.xml
|
||||
$SGE_ROOT/flex-grid/site/qlicserver config=$SGE_ROOT/flex-grid/config/abaqus_licenses.conf timeout=60 output=$SGE_ROOT/flex-grid/cache/qlicserver_abaqus.xml
|
||||
# $SGE_ROOT/flex-grid/site/qlicserver config=/opt/SGE/flex-grid/config/trelis_licenses.conf timeout=60 output=$SGE_ROOT/flex-grid/cache/qlicserver_trelis.xml
|
||||
$SGE_ROOT/flex-grid/site/qlicserver config=/opt/SGE/flex-grid/config/comsol_licenses.conf timeout=60 output=$SGE_ROOT/flex-grid/cache/qlicserver_comsol.xml
|
||||
$SGE_ROOT/flex-grid/site/qlicserver config=$SGE_ROOT/flex-grid/config/matlab_licenses.conf timeout=60 output=$SGE_ROOT/flex-grid/cache/qlicserver_matlab.xml
|
||||
lockfile $SGE_ROOT/flex-grid/cache/qlicserver.xml.lock
|
||||
# (sed '/<\/resources>/,$ d' $SGE_ROOT/flex-grid/cache/qlicserver_abaqus.xml ; sed '1,/<resources>/d' $SGE_ROOT/flex-grid/cache/qlicserver_trelis.xml | grep -v qlicserver | grep -v resources ; sed '1,/<resources>/d' $SGE_ROOT/flex-grid/cache/qlicserver_local.xml | grep -v qlicserver | grep -v resources ; sed '1,/<resources>/d' $SGE_ROOT/flex-grid/cache/qlicserver_matlab.xml;) > $SGE_ROOT/flex-grid/cache/qlicserver.xml
|
||||
# (sed '/<\/resources>/,$ d' $SGE_ROOT/flex-grid/cache/qlicserver_abaqus.xml ; sed '1,/<resources>/d' $SGE_ROOT/flex-grid/cache/qlicserver_local.xml | grep -v qlicserver | grep -v resources ; sed '1,/<resources>/d' $SGE_ROOT/flex-grid/cache/qlicserver_matlab.xml;) > $SGE_ROOT/flex-grid/cache/qlicserver.xml
|
||||
(sed '/<\/resources>/,$ d' $SGE_ROOT/flex-grid/cache/qlicserver_abaqus.xml ; sed '1,/<resources>/d' $SGE_ROOT/flex-grid/cache/qlicserver_local.xml | grep -v qlicserver | grep -v resources; sed '1,/<resources>/d' $SGE_ROOT/flex-grid/cache/qlicserver_comsol.xml | grep -v qlicserver | grep -v resources ; sed '1,/<resources>/d' $SGE_ROOT/flex-grid/cache/qlicserver_matlab.xml;) > $SGE_ROOT/flex-grid/cache/qlicserver.xml
|
||||
rm -f $SGE_ROOT/flex-grid/cache/qlicserver.xml.lock
|
||||
# $diskmon -m 2>> qloadsensor.err
|
||||
# force rescheduling of express jobs
|
||||
# $SGE_site/qxprs >/dev/null 2>&1
|
||||
# else
|
||||
# $diskmon 2>> qloadsensor.err
|
||||
fi
|
||||
done
|
||||
exit 0 # we never get here, but just in case
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# feed via 'perl -x' to extract the 'host' complex configuration
|
||||
|
||||
#!/usr/bin/perl -w
|
||||
print <DATA>
|
||||
__DATA__
|
||||
#
|
||||
# host complex configuration
|
||||
#
|
||||
#name shortcut type relop requestable consumable default urgency
|
||||
#---------------------------------------------------------------------------
|
||||
tmp_total tmpt MEMORY <= YES NO 0 0
|
||||
tmp_used tmpu MEMORY >= NO NO 0 0
|
||||
tmp_free tmpf MEMORY <= YES NO 0 0
|
||||
iidle iidle INT <= YES NO 0 0
|
||||
mips mips INT <= YES NO 0 0
|
||||
os os RESTRING == YES NO NONE 0
|
||||
abaqus abaqus DOUBLE <= YES YES 0 0
|
||||
cae cae DOUBLE <= YES YES 0 0
|
||||
comsol comsol DOUBLE <= YES YES 0 0
|
||||
hyper hyper DOUBLE <= YES YES 0 0
|
||||
ifort ifort DOUBLE <= YES YES 0 0
|
||||
matlab matlab DOUBLE <= YES YES 0 0
|
||||
mcc mcc DOUBLE <= YES YES 0 0
|
||||
multiphysics multiphysics DOUBLE <= YES YES 0 0
|
||||
trelis trelis DOUBLE <= YES YES 0 0
|
||||
scratch_free scratch_free MEMORY <= YES YES 0 0
|
||||
scratch_total scratch_total MEMORY <= YES NO 0 0
|
||||
scratch_used scratch_used MEMORY >= NO NO 0 0
|
||||
# -----------------------------------------------------------------------------
|
Loading…
Reference in New Issue
Block a user