diff --git a/META b/META index fcab221ab288f8e05385eaf0c76b79f99f4d1e8b..7b2a9a9df34139df7a2cc8ccfdd2d394aae01a5f 100644 --- a/META +++ b/META @@ -3,9 +3,9 @@ Api_revision: 0 Major: 2 Meta: 1 - Micro: 5 + Micro: 6 Minor: 1 Name: slurm Release: 1 Release_tags: dist - Version: 2.1.5 + Version: 2.1.6 diff --git a/NEWS b/NEWS index cc822f2f756673e6dd854216a2ca3c41a2c6c27b..0990fda7c72a04ba6d1a1876aee43fa3161ed06a 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,28 @@ This file describes changes in recent versions of SLURM. It primarily documents those changes that are of interest to users and admins. +* Changes in SLURM 2.1.6 +======================== + -- For newly submitted jobs, report expected start time in squeue --start as + "N/A" rather than current time. + -- Correct sched/backfill logic so that it runs in a more timely fashion. + -- Fixed issue if running on accounting cache and priority/multifactor to + initialize the root association when the database comes back up. + -- Emulated BLUEGENE - fixed issue where blocks weren't always created + correctly when loading from state. This does not apply to a real + bluegene system, only emulated. + -- Fixed bug when job is completing and its cpu_cnt would be calculated + incorrectly, possibly resulting in an underflow being logged. + -- Fixed bug where if there are pending jobs in a partition which was + updated to have no nodes in it the slurmctld would dump core. + -- Fixed smap and sview to display partitions with no nodes in them. + -- Improve configure script's logic to detect LUA libraries. + -- Fix bug that could cause slurmctld to abort if select/cons_res is used AND a + job is submitted using the --no-kill option AND one of the job's nodes goes + DOWN AND slurmctld restarts while that job is still running. + -- In jobcomp plugins, job time limit was sometimes recorded improperly if not + set by user (recorded huge number rather than partition's time limit). + * Changes in SLURM 2.1.5 ======================== -- BLUEGENE - Fixed display of draining nodes for sinfo -R. @@ -4935,4 +4957,4 @@ documents those changes that are of interest to users and admins. -- Change directory to /tmp in slurmd if daemonizing. -- Logfiles are reopened on reconfigure. -$Id: NEWS 19780 2010-03-17 23:56:43Z jette $ +$Id: NEWS 19896 2010-03-26 21:49:42Z jette $ diff --git a/auxdir/x_ac_lua.m4 b/auxdir/x_ac_lua.m4 index 2e9ca2bfe2cbc2ad4d8630a041808d52769eae38..d4033afb0a6a2489284c39bbdf69cb811981f86b 100644 --- a/auxdir/x_ac_lua.m4 +++ b/auxdir/x_ac_lua.m4 @@ -19,13 +19,26 @@ AC_DEFUN([X_AC_LUA], PKG_CHECK_MODULES([lua], ${x_ac_lua_pkg_name}, [x_ac_have_lua="yes"], [x_ac_have_lua="no"]) - - if test "x$x_ac_have_lua" = "xyes"; then - x_ac_lua_saved_LIBS="$LIBS" - AC_SEARCH_LIBS([luaL_newstate], [lua lua5.1], - [x_ac_have_lua="yes"], - [x_ac_have_lua="no"]) - LIBS="$x_ac_lua_saved_LIBS" - fi + + if test x"$x_ac_have_lua" = "xyes"; then + saved_CFLAGS="$CFLAGS" + saved_LDFLAGS="$LDFLAGS" + CFLAGS="$CFLAGS $lua_CFLAGS" + LDFLAGS="$LDFLAGS $lua_LIBS" + AC_MSG_CHECKING([for whether we can link to liblua]) + AC_TRY_LINK( + [#include <lua.h> + #include <lauxlib.h> + #include <lualib.h> + ], + [lua_State *L = luaL_newstate (); + ], + [], [x_ac_have_lua="no"]) + + AC_MSG_RESULT([$x_ac_have_lua]) + CFLAGS="$saved_CFLAGS" + LDFLAGS="$saved_LDFLAGS" + fi + AM_CONDITIONAL(HAVE_LUA, test "x$x_ac_have_lua" = "xyes") ]) diff --git a/configure b/configure index b51eac17914d40b4a9d49086a74e3952d7825d22..87370096b8ab2a427fab7015d643e05f6ac3cd27 100755 --- a/configure +++ b/configure @@ -19584,68 +19584,42 @@ $as_echo "yes" >&6; } x_ac_have_lua="yes" fi - if test "x$x_ac_have_lua" = "xyes"; then - x_ac_lua_saved_LIBS="$LIBS" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing luaL_newstate" >&5 -$as_echo_n "checking for library containing luaL_newstate... " >&6; } -if test "${ac_cv_search_luaL_newstate+set}" = set; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext + if test x"$x_ac_have_lua" = "xyes"; then + saved_CFLAGS="$CFLAGS" + saved_LDFLAGS="$LDFLAGS" + CFLAGS="$CFLAGS $lua_CFLAGS" + LDFLAGS="$LDFLAGS $lua_LIBS" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for whether we can link to liblua" >&5 +$as_echo_n "checking for whether we can link to liblua... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ +#include <lua.h> + #include <lauxlib.h> + #include <lualib.h> -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char luaL_newstate (); int main () { -return luaL_newstate (); +lua_State *L = luaL_newstate (); + ; return 0; } _ACEOF -for ac_lib in '' lua lua5.1; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_luaL_newstate=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if test "${ac_cv_search_luaL_newstate+set}" = set; then : - break -fi -done -if test "${ac_cv_search_luaL_newstate+set}" = set; then : +if ac_fn_c_try_link "$LINENO"; then : -else - ac_cv_search_luaL_newstate=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_luaL_newstate" >&5 -$as_echo "$ac_cv_search_luaL_newstate" >&6; } -ac_res=$ac_cv_search_luaL_newstate -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - x_ac_have_lua="yes" else x_ac_have_lua="no" fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $x_ac_have_lua" >&5 +$as_echo "$x_ac_have_lua" >&6; } + CFLAGS="$saved_CFLAGS" + LDFLAGS="$saved_LDFLAGS" + fi - LIBS="$x_ac_lua_saved_LIBS" - fi if test "x$x_ac_have_lua" = "xyes"; then HAVE_LUA_TRUE= HAVE_LUA_FALSE='#' diff --git a/doc/html/documentation.shtml b/doc/html/documentation.shtml index a500e958ceee8c9b0f7ae636e828b2185c7da043..c4a09736f7f32afcf9062154d10662b811888fd2 100644 --- a/doc/html/documentation.shtml +++ b/doc/html/documentation.shtml @@ -32,7 +32,7 @@ Also see <a href="publications.html">Publications and Presentations</a>. <li><a href="gang_scheduling.html">Gang Scheduling</a></li> <li><a href="priority_multifactor.html">Multifactor Job Priority</a></li> <li><a href="preempt.html">Preemption</a></li> -<li><a href="qos.html">Quality of Service</a></li> +<li><a href="qos.html">Quality of Service (QOS)</a></li> <li><a href="resource_limits.html">Resource Limits</a></li> <li><a href="reservations.html">Resource Reservation Gude</a></li> <li><a href="cons_res_share.html">Sharing Consumable Resources</a></li> diff --git a/doc/html/jobcompplugins.shtml b/doc/html/jobcompplugins.shtml index c6721a929ae0a3ad3d9edb2892b7a517341ebd1e..8dc3415e69be8068bf59625a7fbaf7364372d2e4 100644 --- a/doc/html/jobcompplugins.shtml +++ b/doc/html/jobcompplugins.shtml @@ -62,14 +62,14 @@ SLURM_SUCCESS. </p> <p style="margin-left:.2in"><b>Description</b>: Specify the location to be used for job logging.</p> <p style="margin-left:.2in"><b>Argument</b>:<span class="commandline"> location</span> (input) specification of where logging should be done. The interpretation of -this string is at the discresion of the plugin implementation.</p> +this string is at the discretion of the plugin implementation.</p> <p style="margin-left:.2in"><b>Returns</b>: SLURM_SUCCESS if successful. On failure, the plugin should return SLURM_ERROR and set the errno to an appropriate value to indicate the reason for failure.</p> <p class="footer"><a href="#top">top</a></p> <p class="commandline">int slurm_jobcomp_log_record (struct job_record *job_ptr);</p> -<p style="margin-left:.2in"><b>Description</b>: Note termin ation of a job +<p style="margin-left:.2in"><b>Description</b>: Note termination of a job with the specified characteristics.</p> <p style="margin-left:.2in"><b>Argument</b>: <br> <span class="commandline"> job_ptr</span> (input) Pointer to job record as defined @@ -96,19 +96,18 @@ or NULL if no description found in this plugin.</p> <p class="footer"><a href="#top">top</a></p> <p class="commandline"> -void slurm_jobcomp_get_jobs(List job_list, List selected_steps, List selected_parts, void *paramsint errnum);</a></p> -<p style="margin-left:.2in"><b>Description</b>: Get completed job info from the storage.</p> +List slurm_jobcomp_get_jobs(acct_job_cond_t *job_cond);</a></p> +<p style="margin-left:.2in"><b>Description</b>: Get completed job info from +storage.</p> <p style="margin-left:.2in"><b>Arguments</b>:<br> -<span class="commandline"> job_list</span> -(input/output) List of job_rec_t pointers of requested jobs.<br> -<span class="commandline">selected_steps </span> -(input) list containing type jobacct_select_step_t to query against.<br> -<span class="commandline">selected_parts </span> -(input) list containing char *'s of names of partitions to query against.<br> -<span class="commandline">params </span> -(input) to be cast as sacct_parameters_t in the plugin. -<p style="margin-left:.2in">jobcomp_job_rec_t is defined in common/slurm_jobcomp.h -<p style="margin-left:.2in"><b>Returns</b>: None</p> +<span class="commandline"> job_cond</span> +(input) specification of filters to identify the jobs we wish information about +(start time, end time, cluster name, user id, etc). +acct_job_cond_t is defined in common/slurm_accounting_storage.h. +<p style="margin-left:.2in"><b>Returns</b>: A list of job records or NULL on +error. Elements on the list are of type jobcomp_job_rec_t, which is +defined in common/slurm_jobcomp.h. +Any returned list must be destroyed to avoid memory leaks. <p class="footer"><a href="#top">top</a></p> <p class="commandline"> @@ -129,6 +128,6 @@ releases of SLURM may revise this API. A job completion plugin conveys its abili to implement a particular API version using the mechanism outlined for SLURM plugins.</p> <p class="footer"><a href="#top">top</a></p> -<p style="text-align:center;">Last modified 10 September 2007</p> +<p style="text-align:center;">Last modified 24 March 2010</p> <!--#include virtual="footer.txt"--> diff --git a/doc/man/man1/srun.1 b/doc/man/man1/srun.1 index 1f51e4df0f1005b439cbcc87848a16fe4264aa73..3e58d440d82f93e5a8debc757b4cca2777fbe682 100644 --- a/doc/man/man1/srun.1 +++ b/doc/man/man1/srun.1 @@ -890,7 +890,9 @@ The maximum stack size Execute task zero in pseudo terminal. Implicitly sets \fB\-\-unbuffered\fR. Implicitly sets \fB\-\-error\fR and \fB\-\-output\fR to /dev/null -for all tasks except task zero. +for all tasks except task zero, which may cause those tasks to +exit immediately (e.g. shells will typically exit immediately +in that situation). Not currently supported on AIX platforms. .TP @@ -1208,6 +1210,9 @@ will consider this an error, as 15 processes cannot run across 16 nodes. By default, stdout and stderr will be redirected from all tasks to the stdout and stderr of \fBsrun\fR, and stdin will be redirected from the standard input of \fBsrun\fR to all remote tasks. +If stdin is only to be read by a subset of the spawned tasks, specifying a +file to read from rather than forwarding stdin from the \fBsrun\fR command may +be preferable as it avoids moving and storing data that will never be read. For OS X, the poll() function does not support stdin, so input from a terminal is not possible. This behavior may be changed with the diff --git a/doc/man/man5/slurm.conf.5 b/doc/man/man5/slurm.conf.5 index e7a3e9ee3bafd7b8fa2344c866eec22cfcae9713..a5f683cdb8a7a3d3e439aac851663f7ef9196d75 100644 --- a/doc/man/man5/slurm.conf.5 +++ b/doc/man/man5/slurm.conf.5 @@ -458,7 +458,7 @@ The default value is 1. Used for Moab scheduled jobs only. Controls how long job should wait in seconds for loading the user's environment before attempting to load it from a cache file. Applies when the srun or sbatch -\fI--get-user-env\fR option is used. If set to 0 then always load +\fI\-\-get\-user\-env\fR option is used. If set to 0 then always load the user's environment from the cache file. The default value is 2 seconds. @@ -2127,6 +2127,15 @@ If user root attempts to execute a job as another user (e.g. using srun's \-\-uid option), this other user must be in one of groups identified by AllowGroups for the job to successfully execute. The default value is "ALL". +\fBNOTE:\fR For performance reasons, SLURM maintains a list of user IDs +allowed to use each partition and this is checked at job submission time. +This list of user IDs is updated when the \fBslurmctld\fR daemon is restarted, +reconfigured (e.g. "scontrol reconfig") or the partition's \fBAllowGroups\fR +value is reset, even if is value is unchanged +(e.g. "scontrol update PartitionName=name AllowGroups=group"). +For a user's access to a partition to change, both his group membership must +change and SLURM's internal user ID list must change using one of the methods +described above. .TP \fBDefault\fR diff --git a/slurm.spec b/slurm.spec index 2d1945d1e24b8170a2916eedbea8085bf8ff502b..2e4a03b821c3b125c56dfdbb5b9ac7bfba55d6de 100644 --- a/slurm.spec +++ b/slurm.spec @@ -83,14 +83,14 @@ %endif Name: slurm -Version: 2.1.5 +Version: 2.1.6 Release: 1%{?dist} Summary: Simple Linux Utility for Resource Management License: GPL Group: System Environment/Base -Source: slurm-2.1.5.tar.bz2 +Source: slurm-2.1.6.tar.bz2 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release} URL: https://computing.llnl.gov/linux/slurm/ @@ -352,7 +352,7 @@ Gives the ability for SLURM to use Berkeley Lab Checkpoint/Restart ############################################################################# %prep -%setup -n slurm-2.1.5 +%setup -n slurm-2.1.6 %build %configure --program-prefix=%{?_program_prefix:%{_program_prefix}} \ diff --git a/src/common/assoc_mgr.c b/src/common/assoc_mgr.c index 9fd367779c2244fa73562e3e7049d414d9d4c67d..6a8ac27e018da988248cc23fec2218162380d39c 100644 --- a/src/common/assoc_mgr.c +++ b/src/common/assoc_mgr.c @@ -282,8 +282,18 @@ static int _set_assoc_parent_and_user(acct_association_rec_t *assoc, error("association %u was pointing to " "itself as it's parent"); } - } else + } else { + acct_association_rec_t *last_root = assoc_mgr_root_assoc; + assoc_mgr_root_assoc = assoc; + /* set up new root since if running off cache the + total usage for the cluster doesn't get set up again */ + if(last_root) { + assoc_mgr_root_assoc->usage_raw = last_root->usage_raw; + assoc_mgr_root_assoc->usage_norm = + last_root->usage_norm; + } + } if(assoc->user) { uid_t pw_uid; diff --git a/src/common/job_resources.c b/src/common/job_resources.c index dff30bc77c05ca9b4ed09cbf7ea93dce2d64d16a..ba73b6e0962c85fd0f34b26f074d7b3961dfacb3 100644 --- a/src/common/job_resources.c +++ b/src/common/job_resources.c @@ -228,7 +228,9 @@ extern void reset_node_bitmap(job_resources_t *job_resrcs_ptr, if (new_node_bitmap) { job_resrcs_ptr->node_bitmap = bit_copy(new_node_bitmap); - } + job_resrcs_ptr->nhosts = bit_set_count(new_node_bitmap); + } else + job_resrcs_ptr->nhosts = 0; } } @@ -902,6 +904,7 @@ extern void add_job_to_cores(job_resources_t *job_resrcs_ptr, { uint32_t i, n, count = 1, last_bit = 0; uint32_t c = 0, j = 0, k = 0; + int node_len; if (!job_resrcs_ptr->core_bitmap) return; @@ -917,12 +920,17 @@ extern void add_job_to_cores(job_resources_t *job_resrcs_ptr, fatal("add_job_to_cores: bitmap memory error"); } + node_len = bit_size(job_resrcs_ptr->node_bitmap); for (i = 0, n = 0; i < job_resrcs_ptr->nhosts; n++) { last_bit += cores_per_node[k]; if (++count > core_rep_count[k]) { k++; count = 1; } + if (n >= node_len) { + error("add_job_to_cores: Invalid nhosts"); + break; + } if (bit_test(job_resrcs_ptr->node_bitmap, n) == 0) { c = last_bit; continue; @@ -934,3 +942,49 @@ extern void add_job_to_cores(job_resources_t *job_resrcs_ptr, i++; } } + +/* Given a job pointer and a global node index, return the index of that + * node in the job_resrcs_ptr->cpu_array_value. Return -1 if invalid */ +extern int job_resources_node_inx_to_cpu_array_inx( + job_resources_t *job_resrcs_ptr, int node_inx) +{ + int first_inx, i, node_cnt, node_sum; + + /* Test for error cases */ + if (!job_resrcs_ptr || !job_resrcs_ptr->node_bitmap) { + error("job_resources_node_inx_to_cpu_array_inx: " + "no job_resrcs or node_bitmap"); + return -1; + } + if (!bit_test(job_resrcs_ptr->node_bitmap, node_inx)) { + error("job_resources_node_inx_to_cpu_array_inx: " + "Invalid node_inx"); + return -1; + } + if (job_resrcs_ptr->cpu_array_cnt == 0) { + error("job_resources_node_inx_to_cpu_array_inx: " + "Invalid cpu_array_cnt"); + return -1; + } + + /* Only one record, no need to search */ + if (job_resrcs_ptr->cpu_array_cnt == 1) + return 0; + + /* Scan bitmap, convert node_inx to node_cnt within job's allocation */ + first_inx = bit_ffs(job_resrcs_ptr->node_bitmap); + for (i=first_inx, node_cnt=0; i<node_inx; i++) { + if (bit_test(job_resrcs_ptr->node_bitmap, i)) + node_cnt++; + } + /* if (bit_test(job_resrcs_ptr->node_bitmap, node_inx)) */ + node_cnt++; + + for (i=0, node_sum=0; i<job_resrcs_ptr->cpu_array_cnt; i++) { + node_sum += job_resrcs_ptr->cpu_array_reps[i]; + if (node_sum >= node_cnt) + return i; + } + + return -1; +} diff --git a/src/common/job_resources.h b/src/common/job_resources.h index 7702cf5c909a8eaf814761305056d62a85527e5e..f5426a360a9ca9458614dc12e3b2d6e36d8b9f3e 100644 --- a/src/common/job_resources.h +++ b/src/common/job_resources.h @@ -232,4 +232,9 @@ extern void add_job_to_cores(job_resources_t *job_resrcs_ptr, const uint16_t *cores_per_node, const uint32_t *core_rep_count); +/* Given a job pointer and a global node index, return the index of that + * node in the job_resrcs_ptr->cpu_array_value. Return -1 if invalid */ +extern int job_resources_node_inx_to_cpu_array_inx( + job_resources_t *job_resrcs_ptr, int node_inx); + #endif /* !_JOB_RESOURCES_H */ diff --git a/src/plugins/auth/munge/auth_munge.c b/src/plugins/auth/munge/auth_munge.c index 872f4c7a3ebcbc1b547eba581514c5bcc9660c76..83d8eb0f0ab8d192794228ced5c0a711b592c47c 100644 --- a/src/plugins/auth/munge/auth_munge.c +++ b/src/plugins/auth/munge/auth_munge.c @@ -1,6 +1,6 @@ /*****************************************************************************\ * auth_munge.c - SLURM auth implementation via Chris Dunlap's Munge - * $Id: auth_munge.c 19303 2010-01-21 22:42:24Z da $ + * $Id: auth_munge.c 19789 2010-03-18 18:04:15Z jette $ ***************************************************************************** * Copyright (C) 2002-2007 The Regents of the University of California. * Copyright (C) 2008-2009 Lawrence Livermore National Security. @@ -527,6 +527,8 @@ _decode_cred(slurm_auth_credential_t *c, char *socket) error ("Munge decode failed: %s", munge_ctx_strerror(ctx)); _print_cred(ctx); + if (e == EMUNGE_CRED_REWOUND) + error("Check for out of sync clocks"); c->cr_errno = e + MUNGE_ERRNO_OFFSET; #ifdef MULTIPLE_SLURMD diff --git a/src/plugins/jobcomp/filetxt/jobcomp_filetxt.c b/src/plugins/jobcomp/filetxt/jobcomp_filetxt.c index 5e2127c6ddfcd4c649a82b4f4b32c80ef130d6e3..8031ee3bba0663d4a7c8c7b4dbd3fbec9873d36b 100644 --- a/src/plugins/jobcomp/filetxt/jobcomp_filetxt.c +++ b/src/plugins/jobcomp/filetxt/jobcomp_filetxt.c @@ -250,6 +250,7 @@ extern int slurm_jobcomp_log_record ( struct job_record *job_ptr ) char select_buf[128], *work_dir; size_t offset = 0, tot_size, wrote; enum job_states job_state; + uint32_t time_limit; if ((log_name == NULL) || (job_comp_fd < 0)) { error("JobCompLoc log file %s not open", log_name); @@ -259,11 +260,17 @@ extern int slurm_jobcomp_log_record ( struct job_record *job_ptr ) slurm_mutex_lock( &file_lock ); _get_user_name(job_ptr->user_id, usr_str, sizeof(usr_str)); _get_group_name(job_ptr->group_id, grp_str, sizeof(grp_str)); - if (job_ptr->time_limit == INFINITE) - strcpy(lim_str, "UNLIMITED"); + + if ((job_ptr->time_limit == NO_VAL) && job_ptr->part_ptr) + time_limit = job_ptr->part_ptr->max_time; else + time_limit = job_ptr->time_limit; + if (time_limit == INFINITE) + strcpy(lim_str, "UNLIMITED"); + else { snprintf(lim_str, sizeof(lim_str), "%lu", - (unsigned long) job_ptr->time_limit); + (unsigned long) time_limit); + } /* Job will typically be COMPLETING when this is called. * We remove the flags to get the eventual completion state: diff --git a/src/plugins/jobcomp/mysql/jobcomp_mysql.c b/src/plugins/jobcomp/mysql/jobcomp_mysql.c index 2e91823e5567b9261c1530823bb9a8b828e528cc..969a7a84fbfbadee975790432b67fef445006f1c 100644 --- a/src/plugins/jobcomp/mysql/jobcomp_mysql.c +++ b/src/plugins/jobcomp/mysql/jobcomp_mysql.c @@ -290,6 +290,7 @@ extern int slurm_jobcomp_log_record(struct job_record *job_ptr) *blockid = NULL; enum job_states job_state; char *query = NULL; + uint32_t time_limit; if(!jobcomp_mysql_db || mysql_ping(jobcomp_mysql_db) != 0) { char *loc = slurm_get_jobcomp_loc(); @@ -302,11 +303,17 @@ extern int slurm_jobcomp_log_record(struct job_record *job_ptr) usr_str = _get_user_name(job_ptr->user_id); grp_str = _get_group_name(job_ptr->group_id); - if (job_ptr->time_limit == INFINITE) - strcpy(lim_str, "UNLIMITED"); + + if ((job_ptr->time_limit == NO_VAL) && job_ptr->part_ptr) + time_limit = job_ptr->part_ptr->max_time; else + time_limit = job_ptr->time_limit; + if (time_limit == INFINITE) + strcpy(lim_str, "UNLIMITED"); + else { snprintf(lim_str, sizeof(lim_str), "%lu", - (unsigned long) job_ptr->time_limit); + (unsigned long) time_limit); + } /* Job will typically be COMPLETING when this is called. * We remove the flags to get the eventual completion state: diff --git a/src/plugins/jobcomp/pgsql/jobcomp_pgsql.c b/src/plugins/jobcomp/pgsql/jobcomp_pgsql.c index b7c8cedad580e24710fa419eda63bf281116db65..ba599696491bb9bb02c42f28429840a60c1eb9fe 100644 --- a/src/plugins/jobcomp/pgsql/jobcomp_pgsql.c +++ b/src/plugins/jobcomp/pgsql/jobcomp_pgsql.c @@ -312,6 +312,7 @@ extern int slurm_jobcomp_log_record(struct job_record *job_ptr) *blockid = NULL; enum job_states job_state; char *query = NULL; + uint32_t time_limit; if(!jobcomp_pgsql_db || PQstatus(jobcomp_pgsql_db) != CONNECTION_OK) { char *loc = slurm_get_jobcomp_loc(); @@ -324,11 +325,17 @@ extern int slurm_jobcomp_log_record(struct job_record *job_ptr) usr_str = _get_user_name(job_ptr->user_id); grp_str = _get_group_name(job_ptr->group_id); - if (job_ptr->time_limit == INFINITE) - strcpy(lim_str, "UNLIMITED"); + + if ((job_ptr->time_limit == NO_VAL) && job_ptr->part_ptr) + time_limit = job_ptr->part_ptr->max_time; else + time_limit = job_ptr->time_limit; + if (time_limit == INFINITE) + strcpy(lim_str, "UNLIMITED"); + else { snprintf(lim_str, sizeof(lim_str), "%lu", - (unsigned long) job_ptr->time_limit); + (unsigned long) time_limit); + } /* Job will typically be COMPLETING when this is called. * We remove the flags to get the eventual completion state: diff --git a/src/plugins/jobcomp/script/jobcomp_script.c b/src/plugins/jobcomp/script/jobcomp_script.c index 9cd1775229c547721618f8e9f00bdd60bdd76bf4..0037dfd0c2b1426960d08f7749eff5c9417324f9 100644 --- a/src/plugins/jobcomp/script/jobcomp_script.c +++ b/src/plugins/jobcomp/script/jobcomp_script.c @@ -1,6 +1,6 @@ /*****************************************************************************\ * jobcomp_script.c - Script running slurm job completion logging plugin. - * $Id: jobcomp_script.c 19095 2009-12-01 22:59:18Z da $ + * $Id: jobcomp_script.c 19896 2010-03-26 21:49:42Z jette $ ***************************************************************************** * Produced at Center for High Performance Computing, North Dakota State * University @@ -214,7 +214,10 @@ static struct jobcomp_info * _jobcomp_info_create (struct job_record *job) j->jobstate = xstrdup (job_state_string (state)); j->partition = xstrdup (job->partition); - j->limit = job->time_limit; + if ((job->time_limit == NO_VAL) && job->part_ptr) + j->limit = job->part_ptr->max_time; + else + j->limit = job->time_limit; j->start = job->start_time; j->end = job->end_time; j->submit = job->details ? job->details->submit_time:job->start_time; diff --git a/src/plugins/sched/backfill/backfill.c b/src/plugins/sched/backfill/backfill.c index b55ed20a3120cf9822d00cdbb0383513c64ac43f..8c194fa6ea7522a369a05b842e11fa205d942186 100644 --- a/src/plugins/sched/backfill/backfill.c +++ b/src/plugins/sched/backfill/backfill.c @@ -356,8 +356,9 @@ extern void *backfill_agent(void *args) break; now = time(NULL); - if (!_more_work() || _job_is_completing() || - (difftime(now, last_backfill_time) < backfill_interval)) + if ((difftime(now, last_backfill_time) < backfill_interval) || + _job_is_completing() || + !_more_work()) /* _more_work() test must be last */ continue; last_backfill_time = now; diff --git a/src/plugins/select/bluegene/plugin/block_sys.c b/src/plugins/select/bluegene/plugin/block_sys.c index 267860d630f1bfe2c3039f6fd7ad7fc104dfe0c4..264756d2434cee551323f232bc11d7a4a684b8b6 100755 --- a/src/plugins/select/bluegene/plugin/block_sys.c +++ b/src/plugins/select/bluegene/plugin/block_sys.c @@ -1,7 +1,7 @@ /*****************************************************************************\ * block_sys.c - component used for wiring up the blocks * - * $Id: block_sys.c 19280 2010-01-20 17:45:13Z da $ + * $Id: block_sys.c 19849 2010-03-23 19:10:13Z da $ ***************************************************************************** * Copyright (C) 2004 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). @@ -1097,7 +1097,6 @@ extern int load_state_file(List curr_block_list, char *dir_name) non_usable_nodes = bitmap2node_name(bitmap); FREE_NULL_BITMAP(bitmap); - removable_set_bps(non_usable_nodes); node_bitmap = bit_alloc(node_record_count); ionode_bitmap = bit_alloc(bg_conf->numpsets); @@ -1199,14 +1198,27 @@ extern int load_state_file(List curr_block_list, char *dir_name) if((bg_conf->layout_mode == LAYOUT_OVERLAP) || bg_record->full_block) { reset_ba_system(false); - removable_set_bps(non_usable_nodes); } + removable_set_bps(non_usable_nodes); + /* we want the bps that aren't + * in this record to mark them as used + */ + if(set_all_bps_except(bg_record->nodes) + != SLURM_SUCCESS) + fatal("something happened in " + "the load of %s. " + "Did you use smap to " + "make the " + "bluegene.conf file?", + bg_record->bg_block_id); results = list_create(NULL); name = set_bg_block(results, bg_record->start, geo, bg_record->conn_type); + reset_all_removed_bps(); + if(!name) { error("I was unable to " "make the " diff --git a/src/slurmctld/job_mgr.c b/src/slurmctld/job_mgr.c index 45ac1c8264b01179be66a8fb472f6cc690803288..a91b69c7880338c6fab31773a6d86ba3fcebcfaf 100644 --- a/src/slurmctld/job_mgr.c +++ b/src/slurmctld/job_mgr.c @@ -3854,50 +3854,36 @@ void job_time_limit(void) extern int job_update_cpu_cnt(struct job_record *job_ptr, int node_inx) { - uint16_t cpu_cnt=0, i=0; - int curr_node_inx; + int offset; + + xassert(job_ptr); + #ifdef HAVE_BG /* This function doesn't apply to a bluegene system since the - cpu count isn't set up on that system. */ + * cpu count isn't set up on that system. */ return SLURM_SUCCESS; #endif - xassert(job_ptr); - if(!job_ptr->job_resrcs || !job_ptr->job_resrcs->node_bitmap) { - error("job_update_cpu_cnt: " - "no job_resrcs or node_bitmap for job %u", + if((offset = job_resources_node_inx_to_cpu_array_inx( + job_ptr->job_resrcs, node_inx)) < 0) { + error("job_update_cpu_cnt: problem getting offset of job %u", job_ptr->job_id); return SLURM_ERROR; } - /* Figure out what the first bit is in the job to get the - correct offset. unlike the job_ptr->node_bitmap which gets - cleared, job_ptr->job_resrcs->node_bitmap never gets cleared. - */ - curr_node_inx = bit_ffs(job_ptr->job_resrcs->node_bitmap); - if(curr_node_inx != -1) { - for (i=0; i<job_ptr->job_resrcs->cpu_array_cnt; i++) { - cpu_cnt = job_ptr->job_resrcs->cpu_array_value[i]; - if(curr_node_inx >= node_inx) - break; - curr_node_inx += job_ptr->job_resrcs->cpu_array_reps[i]; - } - /* info("removing %u from %u", cpu_cnt, job_ptr->cpu_cnt); */ - job_ptr->cpu_cnt -= cpu_cnt; - if((int)job_ptr->cpu_cnt < 0) { - error("job_update_cpu_cnt: " - "cpu_cnt underflow on job_id %u", - job_ptr->job_id); - job_ptr->cpu_cnt = 0; - return SLURM_ERROR; - } - } else { - error("job_update_cpu_cnt: " - "no nodes set yet in job %u", job_ptr->job_id); + /* info("cpu for %d is %d out of %d", */ + /* node_inx, job_ptr->job_resrcs->cpu_array_value[offset], */ + /* job_ptr->cpu_cnt); */ + + if (job_ptr->job_resrcs->cpu_array_value[offset] > job_ptr->cpu_cnt) { + error("job_update_cpu_cnt: cpu_cnt underflow on job_id %u", + job_ptr->job_id); + job_ptr->cpu_cnt = 0; return SLURM_ERROR; } + + job_ptr->cpu_cnt -= job_ptr->job_resrcs->cpu_array_value[offset]; return SLURM_SUCCESS; } - /* Terminate a job that has exhausted its time limit */ static void _job_timed_out(struct job_record *job_ptr) { @@ -4288,9 +4274,10 @@ void pack_job(struct job_record *dump_job_ptr, uint16_t show_flags, Buf buffer) pack_time(begin_time, buffer); /* Actual or expected start time */ - if(dump_job_ptr->start_time >= begin_time) + if((dump_job_ptr->start_time) || /* estimated start time set OR */ + (begin_time <= time(NULL))) /* earliest start time in past */ pack_time(dump_job_ptr->start_time, buffer); - else + else /* earliest start time in the future */ pack_time(begin_time, buffer); pack_time(dump_job_ptr->end_time, buffer); diff --git a/src/slurmctld/read_config.c b/src/slurmctld/read_config.c index 1f2a29e4ca43e6e3961eca2831a5f7596e3c7194..01fb1a24b9c8209c89e28eab69f1e3b3e35ef2ca 100644 --- a/src/slurmctld/read_config.c +++ b/src/slurmctld/read_config.c @@ -130,8 +130,11 @@ static void _build_bitmaps_pre_select(void) while ((part_ptr = (struct part_record *) list_next(part_iterator))) { FREE_NULL_BITMAP(part_ptr->node_bitmap); - if ((part_ptr->nodes == NULL) || (part_ptr->nodes[0] == '\0')) + if ((part_ptr->nodes == NULL) || (part_ptr->nodes[0] == '\0')) { + /* Partitions need a bitmap, even if empty */ + part_ptr->node_bitmap = bit_alloc(node_record_count); continue; + } if (node_name2bitmap(part_ptr->nodes, false, &part_ptr->node_bitmap)) { diff --git a/src/slurmctld/step_mgr.c b/src/slurmctld/step_mgr.c index aeed83aba96aea3f1db87524a98c66ebe9f8539f..27881cdc29024413ee96ef84eec603b4e5eb6a0d 100644 --- a/src/slurmctld/step_mgr.c +++ b/src/slurmctld/step_mgr.c @@ -522,16 +522,17 @@ _pick_step_nodes (struct job_record *job_ptr, false, &selected_nodes); if (error_code) { - info("_pick_step_nodes: invalid node list %s", - step_spec->node_list); + info("_pick_step_nodes: invalid node list (%s) " + "for job step %u", + step_spec->node_list, job_ptr->job_id); bit_free(selected_nodes); goto cleanup; } if (!bit_super_set(selected_nodes, job_ptr->node_bitmap)) { - info("_pick_step_nodes: selected node is not " - "in job %u", step_spec->node_list, - job_ptr->job_id); + info("_pick_step_nodes: selected nodes (%s) " + "not in job %u", + step_spec->node_list, job_ptr->job_id); bit_free(selected_nodes); goto cleanup; } diff --git a/src/slurmd/slurmstepd/mgr.c b/src/slurmd/slurmstepd/mgr.c index 20ea46bc92b362c218f731a1eabdc90e43c5afea..fc9f0e7d2aa91756ac2f82582d792d089d420fed 100644 --- a/src/slurmd/slurmstepd/mgr.c +++ b/src/slurmd/slurmstepd/mgr.c @@ -1,6 +1,6 @@ /*****************************************************************************\ * src/slurmd/slurmstepd/mgr.c - job manager functions for slurmstepd - * $Id: mgr.c 19712 2010-03-09 16:45:32Z jette $ + * $Id: mgr.c 19858 2010-03-23 21:29:05Z jette $ ***************************************************************************** * Copyright (C) 2002-2007 The Regents of the University of California. * Copyright (C) 2008-2009 Lawrence Livermore National Security. @@ -563,13 +563,18 @@ _send_exit_msg(slurmd_job_t *job, uint32_t *tid, int n, int status) _random_sleep(job); /* - * XXX: Should srun_list be associated with each task? + * Notify each srun and sattach. + * No message for poe or batch jobs */ i = list_iterator_create(job->sruns); while ((srun = list_next(i))) { resp.address = srun->resp_addr; - if (resp.address.sin_family != 0) - slurm_send_only_node_msg(&resp); + if ((resp.address.sin_family == 0) && + (resp.address.sin_port == 0) && + (resp.address.sin_addr.s_addr == 0)) + continue; /* no srun or sattach here */ + if (slurm_send_only_node_msg(&resp) != SLURM_SUCCESS) + verbose("Failed to send MESSAGE_TASK_EXIT: %m"); } list_iterator_destroy(i); @@ -1608,7 +1613,8 @@ _send_launch_failure (launch_tasks_request_msg_t *msg, slurm_addr *cli, int rc) resp.return_code = rc ? rc : -1; resp.count_of_pids = 0; - slurm_send_only_node_msg(&resp_msg); + if (slurm_send_only_node_msg(&resp_msg) != SLURM_SUCCESS) + error("Failed to send RESPONSE_LAUNCH_TASKS: %m"); xfree(name); return; } @@ -1642,7 +1648,8 @@ _send_launch_resp(slurmd_job_t *job, int rc) resp.task_ids[i] = job->task[i]->gtid; } - slurm_send_only_node_msg(&resp_msg); + if (slurm_send_only_node_msg(&resp_msg) != SLURM_SUCCESS) + error("failed to send RESPONSE_LAUNCH_TASKS: %m"); xfree(resp.local_pids); xfree(resp.task_ids); @@ -1842,8 +1849,10 @@ static void _set_prio_process (slurmd_job_t *job) if (setpriority( PRIO_PROCESS, 0, prio_process )) error( "setpriority(PRIO_PROCESS): %m" ); - - debug2( "_set_prio_process: setpriority %d succeeded", prio_process); + else { + debug2( "_set_prio_process: setpriority %d succeeded", + prio_process); + } } static int diff --git a/src/smap/partition_functions.c b/src/smap/partition_functions.c index 8cd5add15c5f716870b252ac3daa5691b5af37d6..d6e30362f4728a6d54ef3652e78145f9967be650 100644 --- a/src/smap/partition_functions.c +++ b/src/smap/partition_functions.c @@ -138,8 +138,6 @@ extern void get_slurm_part() j = 0; part = new_part_ptr->partition_array[i]; - if (!part.nodes || (part.nodes[0] == '\0')) - continue; /* empty partition */ if(nodes_req) { int overlap = 0; bitstr_t *loc_bitmap = bit_alloc(bit_size(nodes_req)); diff --git a/src/sview/part_info.c b/src/sview/part_info.c index f7298aeed6674a4651acefdde8a20a81d3d76634..bcb4150cf197990bc335ad629c4a34a11b8c7742 100644 --- a/src/sview/part_info.c +++ b/src/sview/part_info.c @@ -1451,8 +1451,6 @@ static List _create_part_info_list(partition_info_msg_t *part_info_ptr, for (i=0; i<part_info_ptr->record_count; i++) { part_ptr = &(part_info_ptr->partition_array[i]); - if (!part_ptr->nodes || (part_ptr->nodes[0] == '\0')) - continue; /* empty partition */ sview_part_info = _create_sview_part_info(part_ptr); list_append(info_list, sview_part_info); diff --git a/testsuite/expect/Makefile.in b/testsuite/expect/Makefile.in index cac543021c1434738e496f848c3f6a9782b2c385..82c7891844dd5040a4a1d41f561d3d00aac1c3c3 100644 --- a/testsuite/expect/Makefile.in +++ b/testsuite/expect/Makefile.in @@ -589,6 +589,7 @@ EXTRA_DIST = \ test21.24 \ test21.25 \ test21.26 \ + test21.27 \ test22.1 \ test22.2 \ test23.1 \ diff --git a/testsuite/expect/test21.27 b/testsuite/expect/test21.27 index ee6dafb9c1bf390c2df9385a7dd534b29ffb01df..0adc4cf537bfd3759546bcffbbd3716e4e63a20f 100755 --- a/testsuite/expect/test21.27 +++ b/testsuite/expect/test21.27 @@ -137,7 +137,7 @@ exec $sacctmgr $sho $pro } if {$matches != 6} { - send_user "\nFAILURE: sacctmgr did not find enough problems\n" + send_user "\nFAILURE: sacctmgr found $matches of 6 problems\n" incr exit_code 1 }