diff --git a/NEWS b/NEWS index 09587ea2edf468a766c725340f59a281a3027da4..7758b361f6cd11f7f10bdd04b1ab98b682a21d5a 100644 --- a/NEWS +++ b/NEWS @@ -134,6 +134,8 @@ documents those changes that are of interest to users and admins. -- BLUEGENE - New blocks in dynamic mode will only be made in the system when the block is actually needed for a job, not when testing. -- BLUEGENE - Don't remove larger block used for small block until job starts. + -- Add new squeue output format and sort option of "%L" to print a job's time + left (time limit minus time used). * Changes in SLURM 2.0.4 ======================== diff --git a/doc/man/man1/squeue.1 b/doc/man/man1/squeue.1 index cb8bd339cded2f1aff602277fe5ddf25da4ff83a..30a0b685fd70ea921c8054fe15d3f91918dffdf0 100644 --- a/doc/man/man1/squeue.1 +++ b/doc/man/man1/squeue.1 @@ -162,6 +162,12 @@ This reports the value of the \fBsrun \-\-minthreads\fR option. Time limit of the job or job step in days\-hours:minutes:seconds. The value may be "NOT_SET" if not yet established or "UNLIMITED" for no limit. .TP +\fB%L\fR +Time left for the job to execute in days\-hours:minutes:seconds. +This value is calculated by subtracting the job's time used from its time +limit. +The value may be "NOT_SET" if not yet established or "UNLIMITED" for no limit. +.TP \fB%m\fR Minimum size of memory (in MB) requested by the job .TP diff --git a/src/smap/job_functions.c b/src/smap/job_functions.c index b8442114dd74068d30b360f9705e05a535cc1eae..4e12675ca8551597d235fabdcc531f5edadb85af 100644 --- a/src/smap/job_functions.c +++ b/src/smap/job_functions.c @@ -247,7 +247,7 @@ static void _print_header_job(void) main_xcord = 1; main_ycord++; } else { - printf("JOBID "); + printf(" JOBID "); printf("PARTITION "); #ifdef HAVE_BG printf(" BG_BLOCK "); diff --git a/src/squeue/opts.c b/src/squeue/opts.c index d9f1b0686d1dcc6acd08ee3814205ae4f67d8231..49b161245b8f66a13ffd7fc2e92c4afeef9b8568 100644 --- a/src/squeue/opts.c +++ b/src/squeue/opts.c @@ -458,7 +458,7 @@ extern int parse_format( char* format ) right_justify, suffix ); else if (field[0] == 'S') - step_format_add_time_start( params.format_list, + step_format_add_time_start( params.format_list, field_size, right_justify, suffix ); @@ -473,8 +473,9 @@ extern int parse_format( char* format ) right_justify, suffix ); else - error ("Invalid job step format specification: %c", - field[0] ); + error ( "Invalid job step format " + "specification: %c", + field[0] ); } else { if (field[0] == 'a') job_format_add_account( params.format_list, @@ -533,7 +534,7 @@ extern int parse_format( char* format ) right_justify, suffix ); else if (field[0] == 'H') - job_format_add_min_sockets( params.format_list, + job_format_add_min_sockets( params.format_list, field_size, right_justify, suffix ); @@ -552,7 +553,7 @@ extern int parse_format( char* format ) field_size, right_justify, suffix ); else if (field[0] == 'J') - job_format_add_min_threads( params.format_list, + job_format_add_min_threads( params.format_list, field_size, right_justify, suffix ); @@ -561,6 +562,11 @@ extern int parse_format( char* format ) field_size, right_justify, suffix ); + else if (field[0] == 'L') + job_format_add_time_left( params.format_list, + field_size, + right_justify, + suffix ); else if (field[0] == 'm') job_format_add_min_memory( params.format_list, field_size, @@ -601,7 +607,8 @@ extern int parse_format( char* format ) right_justify, suffix ); else if (field[0] == 'Q') - job_format_add_priority_long( params.format_list, + job_format_add_priority_long( + params.format_list, field_size, right_justify, suffix ); @@ -611,12 +618,13 @@ extern int parse_format( char* format ) right_justify, suffix ); else if (field[0] == 'R') - job_format_add_reason_list( params.format_list, + job_format_add_reason_list( params.format_list, field_size, right_justify, suffix ); else if (field[0] == 's') - job_format_add_select_jobinfo( params.format_list, + job_format_add_select_jobinfo( + params.format_list, field_size, right_justify, suffix ); @@ -647,7 +655,7 @@ extern int parse_format( char* format ) right_justify, suffix ); else if (field[0] == 'v') - job_format_add_reservation( params.format_list, + job_format_add_reservation( params.format_list, field_size, right_justify, suffix ); diff --git a/src/squeue/print.c b/src/squeue/print.c index f70c8907946bffc562b9b3bd1fd894976d111f8c..cdda1b7ec36f73fcb3cf4d112a0ffc38404535f5 100644 --- a/src/squeue/print.c +++ b/src/squeue/print.c @@ -450,6 +450,24 @@ int _print_job_job_state_compact(job_info_t * job, int width, bool right, return SLURM_SUCCESS; } +int _print_job_time_left(job_info_t * job, int width, bool right, + char* suffix) +{ + if (job == NULL) /* Print the Header instead */ + _print_str("TIME_LEFT", width, right, true); + else if (job->time_limit == INFINITE) + _print_str("UNLIMITED", width, right, true); + else if (job->time_limit == NO_VAL) + _print_str("NOT_SET", width, right, true); + else { + time_t time_left = job->time_limit * 60 - job_time_used(job); + _print_secs(time_left, width, right, false); + } + if (suffix) + printf("%s", suffix); + return SLURM_SUCCESS; +} + int _print_job_time_limit(job_info_t * job, int width, bool right, char* suffix) { diff --git a/src/squeue/print.h b/src/squeue/print.h index 05a8cda8cc9c920c7b58c4026364973aef86f25a..9fa7ebc187389e444d559b37b2905e9fdd0a6018 100644 --- a/src/squeue/print.h +++ b/src/squeue/print.h @@ -1,7 +1,8 @@ /*****************************************************************************\ * print.h - squeue print job definitions ***************************************************************************** - * Copyright (C) 2002-2006 The Regents of the University of California. + * Copyright (C) 2002-2007 The Regents of the University of California. + * Copyright (C) 2008-2009 Lawrence Livermore National Security * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Joey Ekstrom <ekstrom1@llnl.gov> * CODE-OCEC-09-009. All rights reserved. @@ -16,7 +17,7 @@ * any later version. * * In addition, as a special exception, the copyright holders give permission - * to link the code of portions of this program with the OpenSSL library under + * to link the code of portions of this program with the OpenSSL library under * certain conditions as described in each individual source file, and * distribute linked combinations including the two. You must obey the GNU * General Public License in all respects for all of the code used other than @@ -107,6 +108,9 @@ int job_format_add_function(List list, int width, bool right_justify, #define job_format_add_job_state_compact(list,wid,right,suffix) \ job_format_add_function(list,wid,right,suffix, \ _print_job_job_state_compact) +#define job_format_add_time_left(list,wid,right,suffix) \ + job_format_add_function(list,wid,right,suffix, \ + _print_job_time_left) #define job_format_add_time_limit(list,wid,right,suffix) \ job_format_add_function(list,wid,right,suffix, \ _print_job_time_limit) @@ -196,6 +200,8 @@ int _print_job_job_state(job_info_t * job, int width, bool right_justify, char* suffix); int _print_job_job_state_compact(job_info_t * job, int width, bool right_justify, char* suffix); +int _print_job_time_left(job_info_t * job, int width, bool right_justify, + char* suffix); int _print_job_time_limit(job_info_t * job, int width, bool right_justify, char* suffix); int _print_job_time_used(job_info_t * job, int width, bool right_justify, diff --git a/src/squeue/sort.c b/src/squeue/sort.c index 62bd4cad295236eb5e307d07493727f841f631a0..6f975d8f9a13b77098aea172729fd7bc1021eb4c 100644 --- a/src/squeue/sort.c +++ b/src/squeue/sort.c @@ -1,7 +1,8 @@ /*****************************************************************************\ * sort.c - squeue sorting functions ***************************************************************************** - * Copyright (C) 2002 The Regents of the University of California. + * Copyright (C) 2002-2007 The Regents of the University of California. + * Copyright (C) 2008-2009 Lawrence Livermore National Security. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Morris Jette <jette1@llnl.gov>, et. al. * CODE-OCEC-09-009. All rights reserved. @@ -57,6 +58,7 @@ static int _sort_job_by_name(void *void1, void *void2); static int _sort_job_by_state(void *void1, void *void2); static int _sort_job_by_state_compact(void *void1, void *void2); static int _sort_job_by_time_end(void *void1, void *void2); +static int _sort_job_by_time_left(void *void1, void *void2); static int _sort_job_by_time_limit(void *void1, void *void2); static int _sort_job_by_time_start(void *void1, void *void2); static int _sort_job_by_time_used(void *void1, void *void2); @@ -133,6 +135,8 @@ void sort_job_list(List job_list) list_sort(job_list, _sort_job_by_min_threads); else if (params.sort[i] == 'l') list_sort(job_list, _sort_job_by_time_limit); + else if (params.sort[i] == 'L') + list_sort(job_list, _sort_job_by_time_left); else if (params.sort[i] == 'm') list_sort(job_list, _sort_job_by_min_memory); else if (params.sort[i] == 'M') @@ -482,13 +486,45 @@ static int _sort_job_by_time_end(void *void1, void *void2) return diff; } +static int _sort_job_by_time_left(void *void1, void *void2) +{ + int diff; + job_info_t *job1 = (job_info_t *) void1; + job_info_t *job2 = (job_info_t *) void2; + time_t time1, time2; + + if ((job1->time_limit == INFINITE) || (job1->time_limit == NO_VAL)) + time1 = INFINITE; + else + time1 = job1->time_limit - job_time_used(job1); + if ((job2->time_limit == INFINITE) || (job2->time_limit == NO_VAL)) + time2 = INFINITE; + else + time2 = job2->time_limit - job_time_used(job2); + if (time1 > time2) + diff = 1; + else if (time1 == time2) + diff = 0; + else + diff = -1; + + if (reverse_order) + diff = -diff; + return diff; +} + static int _sort_job_by_time_limit(void *void1, void *void2) { int diff; job_info_t *job1 = (job_info_t *) void1; job_info_t *job2 = (job_info_t *) void2; - diff = job1->time_limit - job2->time_limit; + if (job1->time_limit > job2->time_limit) + diff = 1; + else if (job1->time_limit == job2->time_limit) + diff = 0; + else + diff = -1; if (reverse_order) diff = -diff;