This file is indexed.

/usr/share/arc/LRMS.pm is in nordugrid-arc-aris 4.0.0-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
package LRMS;

# Interface to LRMS
#
# To include a new LRMS:
#
# 1. Each LRMS specific module needs to provide subroutines
#    cluster_info, queue_info, jobs_info, and users_info.
#
#    The interfaces are documented in this file. All variables
#    required in the interface should be defined in LRMS modules.
#    Returning empty variable "" is perfectly ok if variable does not apply
#    to a LRMS.
#    
# 2. References to subroutines defined in new LRMS modules are added
#    to the select_lrms subroutine in this module, and the module reference
#    itself, naturally.

use strict;
use Exporter;
our @ISA = ('Exporter');     # Inherit from Exporter
our @EXPORT_OK = ( 'select_lrms',
	       'cluster_info',
	       'queue_info',
	       'jobs_info',
	       'users_info');
use LogUtils ( 'start_logging', 'error', 'warning', 'debug' ); 
use SGE;
use Fork;
use PBS;
use LL;
use LSF;
use Condor;
use SLURM;

our ( $lrms_name, $cluster_info, $queue_info, $jobs_info, $users_info ); 

sub select_lrms ($) {
    # %config read from arc.conf
    my ($config) = shift;

    my ($config_lrms, $config_defqueue) = split " ", $$config{lrms};
    $lrms_name = $config_lrms;

    if (!defined($lrms_name)) {
        error("LRMS $lrms_name not defined.");
    } elsif ( lc($lrms_name) eq "sge" ) {
	$cluster_info = \&SGE::cluster_info;
	$queue_info   = \&SGE::queue_info;
	$jobs_info    = \&SGE::jobs_info;
	$users_info   = \&SGE::users_info;
    } elsif ( lc($lrms_name) eq "fork" ) {
	$cluster_info = \&Fork::cluster_info;
	$queue_info   = \&Fork::queue_info;
	$jobs_info    = \&Fork::jobs_info;
	$users_info   = \&Fork::users_info;
    } elsif ( lc($lrms_name) eq "pbs" ) {
	$cluster_info = \&PBS::cluster_info;
	$queue_info   = \&PBS::queue_info;
	$jobs_info    = \&PBS::jobs_info;
	$users_info   = \&PBS::users_info;
    } elsif ( lc($lrms_name) eq "ll" ) {
	$cluster_info = \&LL::cluster_info;
	$queue_info   = \&LL::queue_info;
	$jobs_info    = \&LL::jobs_info;
	$users_info   = \&LL::users_info;
    } elsif ( lc($lrms_name) eq "lsf" ) {
	$cluster_info = \&LSF::cluster_info;
	$queue_info   = \&LSF::queue_info;
	$jobs_info    = \&LSF::jobs_info;
	$users_info   = \&LSF::users_info;
    } elsif ( lc($lrms_name) eq "condor" ) {
	$cluster_info = \&Condor::cluster_info;
	$queue_info   = \&Condor::queue_info;
	$jobs_info    = \&Condor::jobs_info;
	$users_info   = \&Condor::users_info;
    } elsif ( uc($lrms_name) eq "SLURM" ) {
	$cluster_info = \&SLURM::cluster_info;
	$queue_info   = \&SLURM::queue_info;
	$jobs_info    = \&SLURM::jobs_info;
	$users_info   = \&SLURM::users_info;
    } else {
	error("LRMS $lrms_name not implemented.");  
    }
}


sub cluster_info ($) {
    # Path to LRMS commands
    my ($config) = shift;

    my (%lrms_cluster) = &$cluster_info($config);

    # lrms_type
    # lrms_version
    # has_total_cputime_limit 
    #                    whether the cputime limit for parallel/multi-slot
    #                    jobs is treated as a job-total limit by this LRMS
    #                    (as opposed to a per-process or a per-slot limit)
    # totalcpus          total number of cpus in the system
    # queuedjobs         number of queueing jobs in LRMS
    # queuedcpus         number of cpus in queueing jobs in LRMS
    # usedcpus           used cpus in the system
    # cpudistribution    cpu distribution string
    # queue              names of the LRMS queues
    # runningjobs        number of running jobs in LRMS
    my (@scalar_checklist) = ( 'lrms_type',
			       'lrms_version',
			       'has_total_cputime_limit',
			       'totalcpus',
			       'queuedcpus',
			       'usedcpus',
			       'cpudistribution',
			       'queuedjobs',
	                       'runningjobs');

    my (@array_checklist) = ( 'queue' );

    # Check that all got defined

    foreach my $k ( @scalar_checklist ) {
	unless ( defined $lrms_cluster{$k} ) {
	    debug("${lrms_name}::cluster_info failed to ".
		  "populate \$lrms_cluster{$k}.");
	    $lrms_cluster{$k} = "";
	}
    }

    foreach my $k ( @array_checklist ) {
	unless ( defined $lrms_cluster{$k} ) {
	    debug("${lrms_name}::cluster_info failed to ".
		  "populate \@{\$lrms_cluster{$k}}.");
	    @{ $lrms_cluster{$k} } = ( );
	}
    }
    
    # Check for extras ;-)
    
    foreach my $k (keys %lrms_cluster ) {
	if ( ! grep /$k/, (@scalar_checklist, @array_checklist) ) {
	    debug("\%lrms_cluster contains a key $k which is not defined".
		  "in the LRMS interface in LRMS.pm")
	}
    }

    return %lrms_cluster;
}


sub queue_info ($$) {
    # Path to LRMS commands
    my ($config) = shift;
    # Name of the queue to query
    my ($queue_name) = shift;
    
    my (%lrms_queue) = &$queue_info( $config, $queue_name );

    # status        available slots in the queue, negative number signals
    #               some kind of LRMS error state for the queue
    # maxrunning    queue limit for number of running jobs
    # maxqueuable   queue limit for number of queueing jobs
    # maxuserrun    queue limit for number of running jobs per user
    # maxcputime    queue limit for max cpu time for a job
    # mincputime    queue limit for min cpu time for a job
    # defaultcput   queue default for cputime
    # running       number of procs used by running jobs in the queue
    # queued        number of procs requested by queueing jobs in the queue
    # totalcpus     number of procs in the queue

    my (@scalar_checklist) = ( 'status',
			       'maxrunning',
			       'maxqueuable',
			       'maxuserrun',
			       'maxcputime',
			       'mincputime',
			       'defaultcput',
			       'maxwalltime',
			       'minwalltime',
			       'defaultwallt',
			       'running',
			       'queued',
			       'totalcpus');

    # Check that all got defined
    
    foreach my $k ( @scalar_checklist ) {
	unless ( defined $lrms_queue{$k} ) {
	    debug("${lrms_name}::queue_info failed to ".
		  "populate \$lrms_queue{$k}.");
	    $lrms_queue{$k} = "";
	}
    }

    # Check for extras ;-)

    foreach my $k (keys %lrms_queue ) {
	if ( ! grep /$k/, @scalar_checklist ) {
	    debug("\%lrms_queue contains a key $k which is not defined".
		  "in the LRMS interface in LRMS.pm")
	}
    }

    return %lrms_queue;
}

sub jobs_info ($$@) {
    # Path to LRMS commands
    my ($config) = shift;
    # Name of the queue to query
    my ($queue_name) = shift;
    # LRMS job IDs from Grid Manager (jobs with "INLRMS" GM status)
    my ($lrms_jids) = shift;
    
    my (%lrms_jobs) = &$jobs_info($config, $queue_name, \@{$lrms_jids});

    # status        Status of the job: Running 'R', Queued'Q',
    #                                  Suspended 'S', Exiting 'E', Other 'O'
    # rank          Position in the queue
    # mem           Used (virtual) memory
    # walltime      Used walltime
    # cputime       Used cpu-time
    # reqwalltime   Walltime requested from LRMS
    # reqcputime    Cpu-time requested from LRMS
    # nodes         List of execution hosts. (one host in case of serial jobs)
    # cpus          Number of cpus used by job
    # comment       Comment about the job in LRMS, if any

    my (@scalar_checklist) = ( 'status',
			       'rank',
			       'mem',
			       'walltime',
			       'cputime',
			       'reqwalltime',
			       'reqcputime',
                               'cpus');

    my (@array_checklist) = ( 'nodes', 'comment' );

    # Check returned hash

    foreach my $jid ( @{$lrms_jids} ) {
	unless ( exists $lrms_jobs{$jid} ) {
	    debug("Data not acquired for job lrms id = $jid.");
	}
	
	# Check that all got defined
	
	foreach my $k ( @scalar_checklist ) {
	    unless ( exists $lrms_jobs{$jid}{$k} ) {
		debug("${lrms_name}::jobs_info failed to ".
		      "populate \$lrms_jobs{$jid}{$k}.");
		$lrms_jobs{$jid}{$k} = "";
	    }
	}

	foreach my $k ( @array_checklist ) {
	    unless ( exists $lrms_jobs{$jid}{$k} ) {
		debug("${lrms_name}::jobs_info failed to ".
		      "populate \@{\$lrms_jobs{$jid}{$k}}.");
		@{ $lrms_jobs{$jid}{$k} } = ( );
	    }
	}

	# Check for extras ;-)

	foreach my $k (keys %{$lrms_jobs{$jid}} ) {
	    if ( ! grep /$k/, ( @scalar_checklist, @array_checklist) ) {
		debug("\%lrms_jobs{$jid} contains a key $k which is not".
		      "defined in the LRMS interface in LRMS.pm");
	    }
	}
    }
    
    return %lrms_jobs;
}


sub users_info ($$@) {
    # Path to LRMS commands
    my ($config) = shift;
    # Name of the queue to query
    my ($queue_name) = shift;
    # Unix user names mapped to grid users
    my ($user) = shift;
    
    my (%lrms_users) = &$users_info($config, $queue_name, \@{$user});

    # freecpus       free cpus available for the specified user
    # queuelength    estimated queue length for the specified user

    my (@scalar_checklist) = ( 'freecpus',
			       'queuelength');
    # Check returned hash

    foreach my $u ( @{$user} ) {
	unless ( exists $lrms_users{$u} ) {
	    debug("Data not acquired for user $user.");
	}
	
	# Check that all got defined
	
	foreach my $k ( @scalar_checklist ) {
	    unless ( exists $lrms_users{$u}{$k} ) {
		debug("${lrms_name}::users_info failed to ".
		      "populate \$lrms_users{$u}{$k}.");
	    }
	}

	# Check for extras ;-)

	foreach my $k (keys %{$lrms_users{$u}} ) {
	    if ( ! grep /$k/, @scalar_checklist ) {
		debug("\%lrms_users{$u} contains a key $k which is not".
		      "defined in the LRMS interface in LRMS.pm");
	    }
	}
    }
    
    return %lrms_users;
}

1;