From 09f409fb343c1b048c8e8735ccaa6dd4c0d5cb08 Mon Sep 17 00:00:00 2001
From: Mehdi Dogguy <mehdi@debian.org>
Date: Mon, 8 Sep 2014 21:33:19 +0200
Subject: [PATCH] Imported Upstream version 2.1.5

---
 META                                          |   4 +-
 NEWS                                          |  47 +++++-
 RELEASE_NOTES                                 |   3 +-
 RELEASE_NOTES_LLNL                            |  28 +++-
 contribs/perlapi/libslurm-perl/Makefile.PL.in | 110 +++++++++++-
 contribs/perlapi/libslurm-perl/Slurm.pm       | 111 +++++++++++-
 contribs/perlapi/libslurm-perl/Slurm.xs       | 105 +++++++++++-
 contribs/perlapi/libslurm-perl/alloc.c        |  25 +--
 contribs/perlapi/libslurm-perl/job.c          |  31 +++-
 contribs/perlapi/libslurm-perl/msg.h          |  59 ++++---
 contribs/perlapi/libslurm-perl/node.c         |  53 +++++-
 contribs/perlapi/libslurm-perl/typemap        |   5 +-
 contribs/spank_direct_io.c                    | 114 +++++++++++++
 contribs/torque/pbsnodes.pl                   |   3 +-
 contribs/torque/qstat.pl                      |  26 ++-
 doc/html/configurator.html.in                 |   4 +-
 doc/man/Makefile.am                           |   2 +
 doc/man/Makefile.in                           |   2 +
 doc/man/man1/sacctmgr.1                       |   6 +-
 doc/man/man1/salloc.1                         |  20 +--
 doc/man/man1/sbatch.1                         |  20 +--
 doc/man/man1/scontrol.1                       |   3 +-
 doc/man/man1/squeue.1                         |  53 +++++-
 doc/man/man1/srun.1                           |  28 ++--
 doc/man/man3/slurm_free_job_info_msg.3        |  39 ++++-
 .../man3/slurm_job_cpus_allocated_on_node.3   |   1 +
 .../slurm_job_cpus_allocated_on_node_id.3     |   1 +
 doc/man/man5/slurmdbd.conf.5                  |   2 +-
 doc/man/man8/slurmctld.8                      |  12 +-
 doc/man/man8/spank.8                          |   2 +-
 slurm.spec                                    |   6 +-
 slurm/slurm.h.in                              |   8 +-
 src/api/job_info.c                            |  34 ++--
 src/api/step_io.c                             |  18 +-
 src/api/step_launch.c                         |  60 ++++---
 src/common/jobacct_common.c                   |  20 ++-
 src/common/slurm_errno.c                      |   2 +-
 src/common/slurm_protocol_defs.c              |   5 +-
 .../mysql/accounting_storage_mysql.c          |   4 +-
 .../mysql/mysql_jobacct_process.c             |   4 +-
 src/plugins/sched/wiki2/hostlist.c            |   8 +-
 .../select/bluegene/plugin/bg_job_place.c     |  24 ++-
 .../select/bluegene/plugin/bg_job_run.c       |   9 +-
 .../bluegene/plugin/bg_record_functions.c     |  26 ++-
 .../bluegene/plugin/bg_record_functions.h     |   3 +-
 src/plugins/select/bluegene/plugin/bluegene.c |  13 +-
 .../select/bluegene/plugin/select_bluegene.c  |   2 +-
 .../select/bluegene/plugin/state_test.c       |  39 ++++-
 .../select/bluegene/plugin/state_test.h       |   4 +-
 src/plugins/select/bluegene/wrap_rm_api.h     |   3 +-
 src/plugins/select/cons_res/job_test.c        |  18 +-
 src/scontrol/update_job.c                     |   9 +-
 src/sinfo/opts.c                              |   2 +-
 src/sinfo/sinfo.c                             |  46 +++--
 src/slurmctld/gang.c                          |   7 +
 src/slurmctld/node_mgr.c                      |   6 +
 src/slurmctld/proc_req.c                      |   6 +-
 src/slurmd/slurmd/req.c                       |   4 +-
 src/slurmd/slurmd/slurmd.c                    |  12 +-
 src/slurmd/slurmstepd/io.c                    |   9 +-
 src/slurmd/slurmstepd/mgr.c                   |  11 +-
 src/slurmd/slurmstepd/req.c                   |   3 +
 src/slurmd/slurmstepd/slurmstepd.h            |   4 +-
 src/slurmd/slurmstepd/ulimits.c               |   3 +-
 src/squeue/squeue.c                           |   2 +-
 src/srun/opt.c                                |  13 +-
 src/srun/srun.c                               |   3 +-
 src/sview/job_info.c                          |  34 ++--
 src/sview/part_info.c                         |  25 ++-
 src/sview/resv_info.c                         |  20 ++-
 src/sview/sview.c                             |   2 +
 src/sview/sview.h                             |   2 +
 testsuite/expect/Makefile.am                  |   1 +
 testsuite/expect/test1.27                     |   1 -
 testsuite/expect/test1.84                     |   7 +-
 testsuite/expect/test17.13                    |   1 -
 testsuite/expect/test21.27                    | 158 ++++++++++++++++++
 77 files changed, 1297 insertions(+), 323 deletions(-)
 create mode 100644 contribs/spank_direct_io.c
 create mode 100644 doc/man/man3/slurm_job_cpus_allocated_on_node.3
 create mode 100644 doc/man/man3/slurm_job_cpus_allocated_on_node_id.3
 create mode 100755 testsuite/expect/test21.27

diff --git a/META b/META
index 396df5ed8..fcab221ab 100644
--- a/META
+++ b/META
@@ -3,9 +3,9 @@
   Api_revision:  0
   Major:         2
   Meta:          1
-  Micro:         4
+  Micro:         5
   Minor:         1
   Name:          slurm
   Release:       1
   Release_tags:  dist
-  Version:       2.1.4
+  Version:       2.1.5
diff --git a/NEWS b/NEWS
index 514bc7e6d..cc822f2f7 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,51 @@
 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.5
+========================
+ -- BLUEGENE - Fixed display of draining nodes for sinfo -R.
+ -- Fixes to scontrol and sview when setting a job to an impossible start time.
+ -- Added -h to srun for help.
+ -- Fix for sacctmgr man page to remove erroneous 'with' statements.
+ -- Fix for unpacking jobs with accounting statistics, previously it appears
+    only steps were unpacked correctly, for the most case sacct would only
+    display this information making this fix a very minor one.
+ -- Changed scontrol and sview output for jobs with unknown end times from
+    'NONE' to 'Unknown'.
+ -- Fixed mysql plugin to reset classification when adding a
+    previously deleted cluster.
+ -- Permit a batch script to reset umask and have that propagate to tasks
+    spawed by subsequent srun. Previously the umask in effect when sbatch was
+    executed was propagated to tasks spawed by srun.
+ -- Modify slurm_job_cpus_allocated_on_node_id() and 
+    slurm_job_cpus_allocated_on_node() functions to not write explanation of 
+    failures to stderr. Only return -1 and set errno.
+ -- Correction in configurator.html script. Prolog and Epilog were reversed.
+ -- BLUEGENE - Fixed race condition where if a nodecard has an error on an
+    un-booted block when a job comes to use it before the state checking
+    thread notices it which could cause the slurmctld to lock up on a
+    non-dynamic system.
+ -- Correct TaskEpilog logic. Previously could kill other user tasks on that
+    node which remained running.
+ -- Fix accounting Purge to remove correct period of time.  Previously would
+    remove n+1 leaving an extra time period around.
+ -- In select/cons_res with FastSchedule=0 and Procs=# defined for the node, 
+    but no specific socket/core/thread count configured, avoid fatal error if 
+    the number of cores on a node is less than the number of Procs configured.
+ -- Added ability for the perlapi to utilize opaque data types returned from
+    the C api.
+ -- BLUEGENE - made the perlapi get correct values for cpus per node,
+    Previously it would give the number of cpus per cnode instead of midplane.
+ -- BLEUGENE - Fixed issue where if a block being selected for a job to use
+    and during the process a hardware failure happens, previously the block
+    would still be allowed to be used which would fail or requeue the job
+    depending on the configuration.
+ -- For SPANK job environment, avoid duplicate "SPANK_" prefix for environment
+    set by sbatch jobs.
+ -- Make squeue select jobs on hidden partitions when requesting more than one.
+ -- Avoid automatically cancelling job steps when all of the tasks on some node
+    have gracefully terminated.
+
 * Changes in SLURM 2.1.4
 ========================
  -- Fix for purge script in accounting to use correct options.
@@ -4890,4 +4935,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 19625 2010-02-27 00:23:00Z jette $
+$Id: NEWS 19780 2010-03-17 23:56:43Z jette $
diff --git a/RELEASE_NOTES b/RELEASE_NOTES
index 61e117ed0..150807404 100644
--- a/RELEASE_NOTES
+++ b/RELEASE_NOTES
@@ -1,5 +1,5 @@
 RELEASE NOTES FOR SLURM VERSION 2.1
-05 January 2010 (through SLURM 2.1.0)
+8 March 2010
 
 
 IMPORTANT NOTE:
@@ -70,6 +70,7 @@ CONFIGURATION FILE CHANGES (see "man slurm.conf" for details)
 COMMAND CHANGES (see man pages for details)
 * Added "sacctmgr show problems" command to display problems in the accounting
   database (e.g. accounts with no users, users with no UID, etc.).
+* Add support for job step time limits.
 * Several redundant squeue output and sorting options have been removed:
   "%o" (use %D"), "%b" (use "%S"), "%X", %Y, and "%Z" (use "%z").
 * Standardized on the use of the '-Q' flag for all commands that offer the
diff --git a/RELEASE_NOTES_LLNL b/RELEASE_NOTES_LLNL
index 5f744e669..d87380e00 100644
--- a/RELEASE_NOTES_LLNL
+++ b/RELEASE_NOTES_LLNL
@@ -1,22 +1,38 @@
 LLNL CHAOS-SPECIFIC RELEASE NOTES FOR SLURM VERSION 2.1
-16 October 2009
+8 March 2010
 
 This lists only the most significant changes from SLURM v2.0 to v2.1
 with respect to Chaos systems. See the file RELEASE_NOTES for other
 changes.
 
 For system administrators:
-* The pam_slurm Pluggable Authentication Module for SLURM previously
-  distributed separately has been moved within the main SLURM distribution
+* The pam_slurm Pluggable Authentication Module for SLURM, previously
+  distributed separately, has been moved within the main SLURM distribution
   and is packaged as a separate RPM.
-* Added command "sacctmgr show problems" to display problems in the accounting 
+* Added MaxTasksPerNode configuration parameter to control how many tasks that
+  the slurmd daemon can launch. The default value is 128 (same as Slurm v2.0 
+  value).
+* Changed "scontrol show job" command:
+  - ReqProcs (number of processors requested) is replaced by NumCPUs (number
+    of cpus requested or actually allocated)
+  - ReqNodes (number of nodes requested) is replaced by NumNodes (number of
+    nodes requested or actually allocated).
+  - Added a --detail option to "scontrol show job" to display the cpu/memory
+    allocation information on a node-by-node basis.
+  - Reorganized the output into functional groupings.
+* Added command "sacctmgr show problems" to display problems in the accounting
   database (e.g. accounts with no users, users with no UID, etc.).
-* Completely disable logging of sched/wiki and sched/wiki2 (Maui & Moab) 
-  message traffic unless DebugFlag=Wiki is configured.
+* A mechanism has been added for SPANK plugins to set environment variables
+  for Prolog, Epilog, PrologSLurmctld and EpilogSlurmctld programs using the
+  functions spank_get_job_env, spank_set_job_env, and spank_unset_job_env. See
+  "man spank" for more information.
 
 Mostly for users:
 * Added -"-signal=<int>@<time>" option to salloc, sbatch and srun commands to
   notify programs before reaching the end of their time limit.
+* Add support for job step time limits.
+* Sbatch response changed from "sbatch: Submitted batch job #" written to
+  stderr to "Submitted batch job #" written to stdout.
 * Added a --detail option to "scontrol show job" to display the cpu/memory
   allocation informaton on a node-by-node basis.
 * Add new job wait reason, ReqNodeNotAvail: Required node is not available 
diff --git a/contribs/perlapi/libslurm-perl/Makefile.PL.in b/contribs/perlapi/libslurm-perl/Makefile.PL.in
index 1ff96f031..caf55fdd0 100644
--- a/contribs/perlapi/libslurm-perl/Makefile.PL.in
+++ b/contribs/perlapi/libslurm-perl/Makefile.PL.in
@@ -102,9 +102,21 @@ if (eval {require ExtUtils::Constant; 1}) {
 	my $macros = [qw /
 		INFINITE
 		NO_VAL
+		MAX_TASKS_PER_NODE
 		SLURM_BATCH_SCRIPT
 		SHOW_ALL
+                SHOW_DETAIL
 		JOB_COMPLETING
+                JOB_CONFIGURING
+		READY_JOB_FATAL
+		READY_JOB_ERROR
+		READY_NODE_STATE
+		READY_JOB_STATE
+		NICE_OFFSET
+
+		MAIL_JOB_BEGIN
+		MAIL_JOB_END
+		MAIL_JOB_FAIL
 
 		NODE_STATE_BASE
 		NODE_STATE_FLAGS
@@ -113,10 +125,69 @@ if (eval {require ExtUtils::Constant; 1}) {
 		NODE_STATE_COMPLETING
 		NODE_STATE_NO_RESPOND
 		NODE_STATE_POWER_SAVE
-
-		MAIL_JOB_BEGIN
-		MAIL_JOB_END
-		MAIL_JOB_FAIL
+		NODE_STATE_FAIL
+		NODE_STATE_POWER_UP
+		NODE_STATE_MAINT
+
+		SLURM_SSL_SIGNATURE_LENGTH
+
+		OPEN_MODE_APPEND
+		OPEN_MODE_TRUNCATE
+
+		MEM_PER_CPU
+		SHARED_FORCE
+
+		PRIVATE_DATA_JOBS
+		PRIVATE_DATA_NODES
+		PRIVATE_DATA_PARTITIONS
+		PRIVATE_DATA_USAGE
+		PRIVATE_DATA_USERS
+		PRIVATE_DATA_ACCOUNTS
+		PRIVATE_DATA_RESERVATIONS
+
+		PRIORITY_RESET_NONE
+		PRIORITY_RESET_NOW
+		PRIORITY_RESET_DAILY
+		PRIORITY_RESET_WEEKLY
+		PRIORITY_RESET_MONTHLY
+		PRIORITY_RESET_QUARTERLY
+		PRIORITY_RESET_YEARLY
+
+		RESERVE_FLAG_MAINT
+		RESERVE_FLAG_NO_MAINT
+		RESERVE_FLAG_DAILY
+		RESERVE_FLAG_NO_DAILY
+		RESERVE_FLAG_WEEKLY
+		RESERVE_FLAG_NO_WEEKLY
+		RESERVE_FLAG_IGN_JOBS
+		RESERVE_FLAG_NO_IGN_JOB
+		RESERVE_FLAG_OVERLAP
+		RESERVE_FLAG_SPEC_NODES
+
+		DEBUG_FLAG_SELECT_TYPE
+		DEBUG_FLAG_STEPS
+		DEBUG_FLAG_TRIGGERS
+		DEBUG_FLAG_CPU_BIND
+		DEBUG_FLAG_WIKI
+
+		PREEMPT_MODE_OFF
+		PREEMPT_MODE_SUSPEND
+		PREEMPT_MODE_REQUEUE
+		PREEMPT_MODE_CHECKPOINT
+		PREEMPT_MODE_CANCEL
+		PREEMPT_MODE_GANG
+
+		TRIGGER_RES_TYPE_JOB
+		TRIGGER_RES_TYPE_NODE
+		TRIGGER_TYPE_UP
+		TRIGGER_TYPE_DOWN
+		TRIGGER_TYPE_FAIL
+		TRIGGER_TYPE_TIME
+		TRIGGER_TYPE_FINI
+		TRIGGER_TYPE_RECONFIG
+		TRIGGER_TYPE_BLOCK_ERR
+		TRIGGER_TYPE_IDLE
+		TRIGGER_TYPE_DRAINED
 
 		SLURM_SUCCESS
 		SLURM_ERROR
@@ -128,9 +199,10 @@ if (eval {require ExtUtils::Constant; 1}) {
 		JOB_SUSPENDED
 		JOB_COMPLETE
 		JOB_CANCELLED
-		JOB_TIMEOUT
 		JOB_FAILED
+		JOB_TIMEOUT
 		JOB_NODE_FAIL
+                JOB_END
 		/];
 	$enums{job_state_reason} = [qw /
 		WAIT_NO_REASON
@@ -218,6 +290,10 @@ if (eval {require ExtUtils::Constant; 1}) {
 		NODE_STATE_DOWN
 		NODE_STATE_IDLE
 		NODE_STATE_ALLOCATED
+                NODE_STATE_ERROR
+	        NODE_STATE_MIXED
+	        NODE_STATE_FUTURE
+	        NODE_STATE_END
 		/];
 	$enums{ctx_keys} = [qw /
 		SLURM_STEP_CTX_STEPID
@@ -241,6 +317,30 @@ if (eval {require ExtUtils::Constant; 1}) {
 		CR_CORE_MEMORY
 		CR_CPU_MEMORY
 		/];
+	$enums{select_jobdata_type} = [qw /
+                SELECT_JOBDATA_GEOMETRY
+	        SELECT_JOBDATA_ROTATE
+	        SELECT_JOBDATA_CONN_TYPE
+	        SELECT_JOBDATA_BLOCK_ID
+	        SELECT_JOBDATA_NODES
+	        SELECT_JOBDATA_IONODES
+	        SELECT_JOBDATA_NODE_CNT
+	        SELECT_JOBDATA_ALTERED
+	        SELECT_JOBDATA_MAX_CPUS
+	        SELECT_JOBDATA_BLRTS_IMAGE
+	        SELECT_JOBDATA_LINUX_IMAGE
+	        SELECT_JOBDATA_MLOADER_IMAGE
+	        SELECT_JOBDATA_RAMDISK_IMAGE
+	        SELECT_JOBDATA_REBOOT
+	        SELECT_JOBDATA_RESV_ID
+                /];
+	$enums{select_nodedata_type} = [qw /
+                SELECT_NODEDATA_BITMAP_SIZE
+	        SELECT_NODEDATA_SUBGRP_SIZE
+	        SELECT_NODEDATA_SUBCNT
+	        SELECT_NODEDATA_BITMAP
+	        SELECT_NODEDATA_STR
+                /];
 	my @names = @$macros;
 	foreach (values(%enums)) {
 		foreach my $key (@$_) {
diff --git a/contribs/perlapi/libslurm-perl/Slurm.pm b/contribs/perlapi/libslurm-perl/Slurm.pm
index 766edf321..6a0f0dbe9 100644
--- a/contribs/perlapi/libslurm-perl/Slurm.pm
+++ b/contribs/perlapi/libslurm-perl/Slurm.pm
@@ -17,9 +17,21 @@ BEGIN {
 $constants{macros} = [qw /
 		INFINITE
 		NO_VAL
+		MAX_TASKS_PER_NODE
 		SLURM_BATCH_SCRIPT
 		SHOW_ALL
+                SHOW_DETAIL
 		JOB_COMPLETING
+                JOB_CONFIGURING
+		READY_JOB_FATAL
+		READY_JOB_ERROR
+		READY_NODE_STATE
+		READY_JOB_STATE
+		NICE_OFFSET
+
+		MAIL_JOB_BEGIN
+		MAIL_JOB_END
+		MAIL_JOB_FAIL
 
 		NODE_STATE_BASE
 		NODE_STATE_FLAGS
@@ -27,10 +39,70 @@ $constants{macros} = [qw /
 		NODE_STATE_DRAIN
 		NODE_STATE_COMPLETING
 		NODE_STATE_NO_RESPOND
-
-		MAIL_JOB_BEGIN
-		MAIL_JOB_END
-		MAIL_JOB_FAIL
+		NODE_STATE_POWER_SAVE
+		NODE_STATE_FAIL
+		NODE_STATE_POWER_UP
+		NODE_STATE_MAINT
+
+		SLURM_SSL_SIGNATURE_LENGTH
+
+		OPEN_MODE_APPEND
+		OPEN_MODE_TRUNCATE
+
+		MEM_PER_CPU
+		SHARED_FORCE
+
+		PRIVATE_DATA_JOBS
+		PRIVATE_DATA_NODES
+		PRIVATE_DATA_PARTITIONS
+		PRIVATE_DATA_USAGE
+		PRIVATE_DATA_USERS
+		PRIVATE_DATA_ACCOUNTS
+		PRIVATE_DATA_RESERVATIONS
+
+		PRIORITY_RESET_NONE
+		PRIORITY_RESET_NOW
+		PRIORITY_RESET_DAILY
+		PRIORITY_RESET_WEEKLY
+		PRIORITY_RESET_MONTHLY
+		PRIORITY_RESET_QUARTERLY
+		PRIORITY_RESET_YEARLY
+
+		RESERVE_FLAG_MAINT
+		RESERVE_FLAG_NO_MAINT
+		RESERVE_FLAG_DAILY
+		RESERVE_FLAG_NO_DAILY
+		RESERVE_FLAG_WEEKLY
+		RESERVE_FLAG_NO_WEEKLY
+		RESERVE_FLAG_IGN_JOBS
+		RESERVE_FLAG_NO_IGN_JOB
+		RESERVE_FLAG_OVERLAP
+		RESERVE_FLAG_SPEC_NODES
+
+		DEBUG_FLAG_SELECT_TYPE
+		DEBUG_FLAG_STEPS
+		DEBUG_FLAG_TRIGGERS
+		DEBUG_FLAG_CPU_BIND
+		DEBUG_FLAG_WIKI
+
+		PREEMPT_MODE_OFF
+		PREEMPT_MODE_SUSPEND
+		PREEMPT_MODE_REQUEUE
+		PREEMPT_MODE_CHECKPOINT
+		PREEMPT_MODE_CANCEL
+		PREEMPT_MODE_GANG
+
+		TRIGGER_RES_TYPE_JOB
+		TRIGGER_RES_TYPE_NODE
+		TRIGGER_TYPE_UP
+		TRIGGER_TYPE_DOWN
+		TRIGGER_TYPE_FAIL
+		TRIGGER_TYPE_TIME
+		TRIGGER_TYPE_FINI
+		TRIGGER_TYPE_RECONFIG
+		TRIGGER_TYPE_BLOCK_ERR
+		TRIGGER_TYPE_IDLE
+		TRIGGER_TYPE_DRAINED
 
 		SLURM_SUCCESS
 		SLURM_ERROR
@@ -45,6 +117,7 @@ $constants{job_states} = [qw /
 		JOB_TIMEOUT
 		JOB_FAILED
 		JOB_NODE_FAIL
+                JOB_END
 		/];
 
 
@@ -142,6 +215,10 @@ $constants{node_states} = [qw /
 		NODE_STATE_DOWN
 		NODE_STATE_IDLE
 		NODE_STATE_ALLOCATED
+                NODE_STATE_ERROR
+	        NODE_STATE_MIXED
+	        NODE_STATE_FUTURE
+	        NODE_STATE_END
 		/];
 
 $constants{ctx_keys} = [qw /
@@ -168,6 +245,32 @@ $constants{select_type_plugin_info} = [qw /
 		CR_CPU_MEMORY
 		/];
 
+$constants{select_jobdata_type} = [qw /
+                SELECT_JOBDATA_GEOMETRY
+	        SELECT_JOBDATA_ROTATE
+	        SELECT_JOBDATA_CONN_TYPE
+	        SELECT_JOBDATA_BLOCK_ID
+	        SELECT_JOBDATA_NODES
+	        SELECT_JOBDATA_IONODES
+	        SELECT_JOBDATA_NODE_CNT
+	        SELECT_JOBDATA_ALTERED
+	        SELECT_JOBDATA_MAX_CPUS
+	        SELECT_JOBDATA_BLRTS_IMAGE
+	        SELECT_JOBDATA_LINUX_IMAGE
+	        SELECT_JOBDATA_MLOADER_IMAGE
+	        SELECT_JOBDATA_RAMDISK_IMAGE
+	        SELECT_JOBDATA_REBOOT
+	        SELECT_JOBDATA_RESV_ID
+                /];
+
+$constants{select_nodedata_type} = [qw /
+                SELECT_NODEDATA_BITMAP_SIZE
+	        SELECT_NODEDATA_SUBGRP_SIZE
+	        SELECT_NODEDATA_SUBCNT
+	        SELECT_NODEDATA_BITMAP
+	        SELECT_NODEDATA_STR
+                /];
+
 foreach my $const(values(%constants)) {
     push @{$constants{all}}, @$const;
 }
diff --git a/contribs/perlapi/libslurm-perl/Slurm.xs b/contribs/perlapi/libslurm-perl/Slurm.xs
index 724ad4b0c..0d271ae3b 100644
--- a/contribs/perlapi/libslurm-perl/Slurm.xs
+++ b/contribs/perlapi/libslurm-perl/Slurm.xs
@@ -468,11 +468,108 @@ slurm_update_job(slurm_t self, HV* job_info = NULL)
 	OUTPUT:
 		RETVAL
 
-#int
-#slurm_get_select_jobinfo(slurm_t self, select_jobinfo_t *jobinfo, int data_type, void* data)
+int
+slurm_get_select_jobinfo_int_type(slurm_t self, SV* jobinfo = NULL, int data_type)
+	CODE:
+		if(jobinfo) {
+			uint32_t data;
+			RETVAL = slurm_get_select_jobinfo(
+				(select_jobinfo_t *)SV2ptr(jobinfo),
+				 data_type, &data);
+			RETVAL = data;
+		} else {
+			RETVAL = -1;
+		}
+	OUTPUT:
+		RETVAL
 
-#int
-#slurm_get_select_nodeinfo(slurm_t self, select_nodeinfo_t *nodeinfo, int data_type, int state, void* data)
+char *
+slurm_get_select_jobinfo_char_type(slurm_t self, SV* jobinfo = NULL, int data_type)
+	CODE:
+		if(jobinfo) {
+			char *data = NULL;
+			slurm_get_select_jobinfo(
+				(select_jobinfo_t *)SV2ptr(jobinfo),
+				data_type, &data);
+			RETVAL = data;
+		} else {
+			RETVAL = NULL;
+		}
+	OUTPUT:
+		RETVAL
+
+U16
+slurm_get_select_nodeinfo_subcnt(slurm_t self, SV *nodeinfo, int state)
+	CODE:
+		if(nodeinfo) {
+			uint16_t tmp16;
+			RETVAL = slurm_get_select_nodeinfo(
+				(select_nodeinfo_t *)SV2ptr(nodeinfo),
+				 SELECT_NODEDATA_SUBCNT, state, &tmp16);
+			if(RETVAL != -1) {
+				RETVAL = tmp16;
+			}
+		} else {
+			RETVAL = -1;
+		}
+	OUTPUT:
+		RETVAL
+
+U16
+slurm_get_select_nodeinfo_subgrp_size(slurm_t self, SV *nodeinfo)
+	CODE:
+		if(nodeinfo) {
+			uint16_t tmp16;
+			RETVAL = slurm_get_select_nodeinfo(
+				(select_nodeinfo_t *)SV2ptr(nodeinfo),
+				SELECT_NODEDATA_SUBGRP_SIZE, 0, &tmp16);
+			if(RETVAL != -1) {
+				RETVAL = tmp16;
+			}
+		} else {
+			RETVAL = -1;
+		}
+	OUTPUT:
+		RETVAL
+
+char *
+slurm_get_select_nodeinfo_cpuids(slurm_t self, SV *nodeinfo)
+	CODE:
+		if(nodeinfo) {
+			char *tmp_char = NULL;
+			slurm_get_select_nodeinfo(
+				(select_nodeinfo_t *)SV2ptr(nodeinfo),
+				SELECT_NODEDATA_STR, 0, &tmp_char);
+			RETVAL = tmp_char;
+                } else {
+			RETVAL = NULL;
+		}
+	OUTPUT:
+		RETVAL
+
+int
+slurm_job_cpus_allocated_on_node_id(slurm_t self, SV* job_res = NULL, int node_id)
+	CODE:
+		if(job_res) {
+			RETVAL = slurm_job_cpus_allocated_on_node_id(
+				(job_resources_t *)SV2ptr(job_res), node_id);
+		} else {
+			RETVAL = 0;
+		}
+	OUTPUT:
+		RETVAL
+
+int
+slurm_job_cpus_allocated_on_node(slurm_t self, SV* job_res = NULL, char *node_name)
+	CODE:
+		if(job_res) {
+			RETVAL = slurm_job_cpus_allocated_on_node(
+				(job_resources_t *)SV2ptr(job_res), node_name);
+		} else {
+			RETVAL = 0;
+		}
+	OUTPUT:
+		RETVAL
 
 
 ######################################################################
diff --git a/contribs/perlapi/libslurm-perl/alloc.c b/contribs/perlapi/libslurm-perl/alloc.c
index 4d95b2354..e21822181 100644
--- a/contribs/perlapi/libslurm-perl/alloc.c
+++ b/contribs/perlapi/libslurm-perl/alloc.c
@@ -26,7 +26,7 @@ hv_to_job_desc_msg(HV* hv, job_desc_msg_t* job_desc_msg)
 	I32 klen;
 	STRLEN vlen;
 	int num_keys, i;
-	
+
 	slurm_init_job_desc_msg(job_desc_msg);
 
 	FETCH_FIELD(hv, job_desc_msg, contiguous, uint16_t, FALSE);
@@ -38,7 +38,7 @@ hv_to_job_desc_msg(HV* hv, job_desc_msg_t* job_desc_msg)
 			num_keys = HvKEYS(environ_hv);
 			job_desc_msg->env_size = num_keys;
 			Newz(0, job_desc_msg->environment, num_keys + 1, char*);
-			
+
 			hv_iterinit(environ_hv);
 			i = 0;
 			while((val = hv_iternextsv(environ_hv, &env_key, &klen))) {
@@ -150,13 +150,14 @@ hv_to_job_desc_msg(HV* hv, job_desc_msg_t* job_desc_msg)
 	FETCH_FIELD(hv, job_desc_msg, mloaderimage, charp, FALSE);
 	FETCH_FIELD(hv, job_desc_msg, ramdiskimage, charp, FALSE);
 	/* TODO: select_jobinfo */
-	/* Don't know how to manage memory of select_jobinfo, since it's storage size is unknown. */
-	/* Maybe we can do it if select_g_copy_jobinfo and select_g_free_jobinfo are exported. */
+	/* The api does not currently export the
+	 * slurm_set_select_jobinfo.  If it ever does we should be
+	 * able to handle this. */
 	return 0;
 }
 
 /*
- * free allocated environment variable memory for job_desc_msg_t 
+ * free allocated environment variable memory for job_desc_msg_t
  */
 static void
 _free_environment(char** environ)
@@ -188,7 +189,7 @@ resource_allocation_response_msg_to_hv(resource_allocation_response_msg_t* resp_
 {
 	AV* avp;
 	int i;
-	
+
 	STORE_FIELD(hv, resp_msg, job_id, uint32_t);
 	if(resp_msg->node_list)
 		STORE_FIELD(hv, resp_msg, node_list, charp);
@@ -199,7 +200,7 @@ resource_allocation_response_msg_to_hv(resource_allocation_response_msg_t* resp_
 			av_store(avp, i, newSVuv(resp_msg->cpus_per_node[i]));
 		}
 		hv_store_sv(hv, "cpus_per_node", newRV_noinc((SV*)avp));
-		
+
 		avp = newAV();
 		for(i = 0; i < resp_msg->num_cpu_groups; i ++) {
 			av_store(avp, i, newSVuv(resp_msg->cpu_count_reps[i]));
@@ -208,7 +209,8 @@ resource_allocation_response_msg_to_hv(resource_allocation_response_msg_t* resp_
 	}
 	STORE_FIELD(hv, resp_msg, node_cnt, uint32_t);
 	STORE_FIELD(hv, resp_msg, error_code, uint32_t);
-	/* TODO: select_jobinfo */
+	STORE_FIELD(hv, resp_msg, select_jobinfo, ptr);
+
 	return 0;
 }
 
@@ -220,7 +222,7 @@ job_alloc_info_response_msg_to_hv(job_alloc_info_response_msg_t *resp_msg, HV* h
 {
 	AV* avp;
 	int i;
-	
+
 	STORE_FIELD(hv, resp_msg, job_id, uint32_t);
 	if(resp_msg->node_list)
 		STORE_FIELD(hv, resp_msg, node_list, charp);
@@ -231,7 +233,7 @@ job_alloc_info_response_msg_to_hv(job_alloc_info_response_msg_t *resp_msg, HV* h
 			av_store(avp, i, newSVuv(resp_msg->cpus_per_node[i]));
 		}
 		hv_store_sv(hv, "cpus_per_node", newRV_noinc((SV*)avp));
-		
+
 		avp = newAV();
 		for(i = 0; i < resp_msg->num_cpu_groups; i ++) {
 			av_store(avp, i, newSVuv(resp_msg->cpu_count_reps[i]));
@@ -248,7 +250,7 @@ job_alloc_info_response_msg_to_hv(job_alloc_info_response_msg_t *resp_msg, HV* h
 		hv_store_sv(hv, "node_addr", newRV_noinc((SV*)avp));
 	}
 	STORE_FIELD(hv, resp_msg, error_code, uint32_t);
-	/* TODO: select_jobinfo */
+	STORE_FIELD(hv, resp_msg, select_jobinfo, ptr);
 	return 0;
 }
 
@@ -263,4 +265,3 @@ submit_response_msg_to_hv(submit_response_msg_t *resp_msg, HV* hv)
 	STORE_FIELD(hv, resp_msg, error_code, uint32_t);
 	return 0;
 }
-
diff --git a/contribs/perlapi/libslurm-perl/job.c b/contribs/perlapi/libslurm-perl/job.c
index 1e8454dd3..10ffef934 100644
--- a/contribs/perlapi/libslurm-perl/job.c
+++ b/contribs/perlapi/libslurm-perl/job.c
@@ -33,6 +33,8 @@ job_info_to_hv(job_info_t* job_info, HV* hv)
 	STORE_FIELD(hv, job_info, cpus_per_task, uint16_t);
 	if(job_info->dependency)
 		STORE_FIELD(hv, job_info, dependency, charp);
+	if(job_info->eligible_time)
+		STORE_FIELD(hv, job_info, eligible_time, time_t);
 	STORE_FIELD(hv, job_info, end_time, time_t);
 	if(job_info->exc_nodes)
 		STORE_FIELD(hv, job_info, exc_nodes, charp);
@@ -64,6 +66,8 @@ job_info_to_hv(job_info_t* job_info, HV* hv)
 		STORE_FIELD(hv, job_info, name, charp);
 	if(job_info->network)
 		STORE_FIELD(hv, job_info, network, charp);
+	if(job_info->nice)
+		STORE_FIELD(hv, job_info, nice, uint16_t);
 	if(job_info->nodes)
 		STORE_FIELD(hv, job_info, nodes, charp);
 	avp = newAV();
@@ -77,12 +81,21 @@ job_info_to_hv(job_info_t* job_info, HV* hv)
 	STORE_FIELD(hv, job_info, ntasks_per_core, uint16_t);
 	STORE_FIELD(hv, job_info, ntasks_per_node, uint16_t);
 	STORE_FIELD(hv, job_info, ntasks_per_socket, uint16_t);
+#ifdef HAVE_BG
+	slurm_get_select_jobinfo(job_info->select_jobinfo,
+				 SELECT_JOBDATA_NODE_CNT,
+				 &job_info->num_nodes);
+
+#endif
 	STORE_FIELD(hv, job_info, num_nodes, uint32_t);
+
 	STORE_FIELD(hv, job_info, num_procs, uint32_t);
 	if(job_info->partition)
 		STORE_FIELD(hv, job_info, partition, charp);
 	STORE_FIELD(hv, job_info, pre_sus_time, time_t);
 	STORE_FIELD(hv, job_info, priority, uint32_t);
+	if(job_info->qos)
+		STORE_FIELD(hv, job_info, qos, charp);
 	if(job_info->req_nodes)
 		STORE_FIELD(hv, job_info, req_nodes, charp);
 	avp = newAV();
@@ -97,8 +110,8 @@ job_info_to_hv(job_info_t* job_info, HV* hv)
 	STORE_FIELD(hv, job_info, restart_cnt, uint16_t);
 	if(job_info->resv_name)
 		STORE_FIELD(hv, job_info, resv_name, charp);
-	/* TODO: select_jobinfo */
-	/* TODO: select_job_res */
+	STORE_FIELD(hv, job_info, select_jobinfo, ptr);
+	STORE_FIELD(hv, job_info, job_resrcs, ptr);
 	STORE_FIELD(hv, job_info, shared, uint16_t);
 	STORE_FIELD(hv, job_info, start_time, time_t);
 	if(job_info->state_desc)
@@ -112,7 +125,7 @@ job_info_to_hv(job_info_t* job_info, HV* hv)
 		STORE_FIELD(hv, job_info, wckey, charp);
 	if(job_info->work_dir)
 		STORE_FIELD(hv, job_info, work_dir, charp);
-			
+
 	return 0;
 }
 
@@ -186,18 +199,20 @@ job_step_info_to_hv(job_step_info_t* step_info, HV* hv)
  * convert job_step_info_response_msg_t to perl HV
  */
 int
-job_step_info_response_msg_to_hv(job_step_info_response_msg_t* job_step_info_msg, HV* hv)
+job_step_info_response_msg_to_hv(
+	job_step_info_response_msg_t* job_step_info_msg, HV* hv)
 {
 	int i;
 	AV* avp;
 	HV* hvp;
-	
+
 	STORE_FIELD(hv, job_step_info_msg, last_update, time_t);
 	/* job_step_count implied in job_steps */
 	avp = newAV();
 	for(i = 0; i < job_step_info_msg->job_step_count; i ++) {
 		hvp = newHV();
-		if (job_step_info_to_hv(job_step_info_msg->job_steps + i, hvp) < 0) {
+		if (job_step_info_to_hv(
+			    job_step_info_msg->job_steps + i, hvp) < 0) {
 			SvREFCNT_dec(hvp);
 			SvREFCNT_dec(avp);
 			return -1;
@@ -234,11 +249,11 @@ slurm_step_layout_to_hv(slurm_step_layout_t* step_layout, HV* hv)
 	avp = newAV();
 	for(i = 0; i < step_layout->node_cnt; i ++) {
 		avp2 = newAV();
-		for(j = 0; j < step_layout->tasks[i]; j ++) 
+		for(j = 0; j < step_layout->tasks[i]; j ++)
 			av_store(avp2, i, newSVuv(step_layout->tids[i][j]));
 		av_store(avp, i, newRV_noinc((SV*)avp2));
 	}
 	hv_store_sv(hv, "tids", newRV_noinc((SV*)avp));
-	
+
 	return 0;
 }
diff --git a/contribs/perlapi/libslurm-perl/msg.h b/contribs/perlapi/libslurm-perl/msg.h
index 6dc418d10..10b21cd5e 100644
--- a/contribs/perlapi/libslurm-perl/msg.h
+++ b/contribs/perlapi/libslurm-perl/msg.h
@@ -1,5 +1,5 @@
 /*
- * msg2hv.h - prototypes of msg-hv converting functions 
+ * msg2hv.h - prototypes of msg-hv converting functions
  */
 
 #ifndef _MSG_H
@@ -10,7 +10,7 @@
 typedef char* charp;
 
 /*
- * store an uint16_t into AV 
+ * store an uint16_t into AV
  */
 inline static int av_store_uint16_t(AV* av, int index, uint16_t val)
 {
@@ -24,7 +24,7 @@ inline static int av_store_uint16_t(AV* av, int index, uint16_t val)
 		sv = newSViv(NO_VAL);
 	else
 		sv = newSViv(val);
-	
+
 	if (av_store(av, (I32)index, sv) == NULL) {
 		SvREFCNT_dec(sv);
 		return -1;
@@ -33,7 +33,7 @@ inline static int av_store_uint16_t(AV* av, int index, uint16_t val)
 }
 
 /*
- * store an uint32_t into AV 
+ * store an uint32_t into AV
  */
 inline static int av_store_uint32_t(AV* av, int index, uint32_t val)
 {
@@ -47,7 +47,7 @@ inline static int av_store_uint32_t(AV* av, int index, uint32_t val)
 		sv = newSViv(NO_VAL);
 	else
 		sv = newSViv(val);
-	
+
 	if (av_store(av, (I32)index, sv) == NULL) {
 		SvREFCNT_dec(sv);
 		return -1;
@@ -56,12 +56,12 @@ inline static int av_store_uint32_t(AV* av, int index, uint32_t val)
 }
 
 /*
- * store an int into AV 
+ * store an int into AV
  */
 inline static int av_store_int(AV* av, int index, int val)
 {
 	SV* sv = newSViv(val);
-	
+
 	if (av_store(av, (I32)index, sv) == NULL) {
 		SvREFCNT_dec(sv);
 		return -1;
@@ -70,7 +70,7 @@ inline static int av_store_int(AV* av, int index, int val)
 }
 
 /*
- * store a string into HV 
+ * store a string into HV
  */
 inline static int hv_store_charp(HV* hv, const char *key, charp val)
 {
@@ -87,7 +87,7 @@ inline static int hv_store_charp(HV* hv, const char *key, charp val)
 }
 
 /*
- * store an unsigned 32b int into HV 
+ * store an unsigned 32b int into HV
  */
 inline static int hv_store_uint32_t(HV* hv, const char *key, uint32_t val)
 {
@@ -110,7 +110,7 @@ inline static int hv_store_uint32_t(HV* hv, const char *key, uint32_t val)
 }
 
 /*
- * store an unsigned 16b int into HV 
+ * store an unsigned 16b int into HV
  */
 inline static int hv_store_uint16_t(HV* hv, const char *key, uint16_t val)
 {
@@ -124,7 +124,7 @@ inline static int hv_store_uint16_t(HV* hv, const char *key, uint16_t val)
 		sv = newSViv(NO_VAL);
 	else
 		sv = newSVuv(val);
-	
+
 	if (!key || hv_store(hv, key, (I32)strlen(key), sv, 0) == NULL) {
 		SvREFCNT_dec(sv);
 		return -1;
@@ -133,7 +133,7 @@ inline static int hv_store_uint16_t(HV* hv, const char *key, uint16_t val)
 }
 
 /*
- * store an unsigned 8b int into HV 
+ * store an unsigned 8b int into HV
  */
 inline static int hv_store_uint8_t(HV* hv, const char *key, uint8_t val)
 {
@@ -147,7 +147,7 @@ inline static int hv_store_uint8_t(HV* hv, const char *key, uint8_t val)
 		sv = newSViv(NO_VAL);
 	else
 		sv = newSVuv(val);
-	
+
 	if (!key || hv_store(hv, key, (I32)strlen(key), sv, 0) == NULL) {
 		SvREFCNT_dec(sv);
 		return -1;
@@ -155,12 +155,12 @@ inline static int hv_store_uint8_t(HV* hv, const char *key, uint8_t val)
 	return 0;
 }
 /*
- * store a signed int into HV 
+ * store a signed int into HV
  */
 inline static int hv_store_int(HV* hv, const char *key, int val)
 {
 	SV* sv = newSViv(val);
-	
+
 	if (!key || hv_store(hv, key, (I32)strlen(key), sv, 0) == NULL) {
 		SvREFCNT_dec(sv);
 		return -1;
@@ -169,7 +169,7 @@ inline static int hv_store_int(HV* hv, const char *key, int val)
 }
 
 /*
- * store a bool into HV 
+ * store a bool into HV
  */
 inline static int hv_store_bool(HV* hv, const char *key, bool val)
 {
@@ -180,12 +180,12 @@ inline static int hv_store_bool(HV* hv, const char *key, bool val)
 }
 
 /*
- * store a time_t into HV 
+ * store a time_t into HV
  */
 inline static int hv_store_time_t(HV* hv, const char *key, time_t val)
 {
 	SV* sv = newSVuv(val);
-	
+
 	if (!key || hv_store(hv, key, (I32)strlen(key), sv, 0) == NULL) {
 		SvREFCNT_dec(sv);
 		return -1;
@@ -194,7 +194,7 @@ inline static int hv_store_time_t(HV* hv, const char *key, time_t val)
 }
 
 /*
- * store a SV into HV 
+ * store a SV into HV
  */
 inline static int hv_store_sv(HV* hv, const char *key, SV* sv)
 {
@@ -204,12 +204,33 @@ inline static int hv_store_sv(HV* hv, const char *key, SV* sv)
 	return 0;
 }
 
+/*
+ * store a PTR into HV
+ */
+inline static int hv_store_ptr(HV* hv, const char *key, void* ptr)
+{
+	SV* sv = NULL;
+
+	if(ptr) {
+		sv = NEWSV(0, 0);
+		sv_setref_pv(sv, key, ptr);
+	}
+
+	if (!key || hv_store(hv, key, (I32)strlen(key), sv, 0) == NULL) {
+		SvREFCNT_dec(sv);
+		return -1;
+	}
+
+	return 0;
+}
+
 #define SV2uint32_t(sv) SvUV(sv)
 #define SV2uint16_t(sv) SvUV(sv)
 #define SV2uint8_t(sv)  SvUV(sv)
 #define SV2time_t(sv)   SvUV(sv)
 #define SV2charp(sv)    SvPV_nolen(sv)
 #define SV2bool(sv)     SvTRUE(sv)
+#define SV2ptr(sv)      SvIV(SvRV(sv))
 
 
 #define FETCH_FIELD(hv, ptr, field, type, required) \
diff --git a/contribs/perlapi/libslurm-perl/node.c b/contribs/perlapi/libslurm-perl/node.c
index 70869e421..3b326923f 100644
--- a/contribs/perlapi/libslurm-perl/node.c
+++ b/contribs/perlapi/libslurm-perl/node.c
@@ -9,12 +9,29 @@
 #include <slurm/slurm.h>
 #include "msg.h"
 
+#ifdef HAVE_BG
+/* These are just helper functions from slurm proper that don't get
+ * exported regularly.  Copied from src/common/slurm_protocol_defs.h.
+ */
+#define IS_NODE_ALLOCATED(_X)		\
+	((_X->node_state & NODE_STATE_BASE) == NODE_STATE_ALLOCATED)
+#define IS_NODE_COMPLETING(_X)	\
+	(_X->node_state & NODE_STATE_COMPLETING)
+#endif
+
 /*
- * convert node_info_t to perl HV 
+ * convert node_info_t to perl HV
  */
 int
-node_info_to_hv(node_info_t* node_info, HV* hv)
+node_info_to_hv(node_info_t* node_info, uint16_t node_scaling, HV* hv)
 {
+	uint16_t err_cpus = 0, alloc_cpus = 0;
+#ifdef HAVE_BG
+	int cpus_per_node = 1;
+
+	if(node_scaling)
+		cpus_per_node = node_info->cpus / node_scaling;
+#endif
 	if(node_info->arch)
 		STORE_FIELD(hv, node_info, arch, charp);
 	STORE_FIELD(hv, node_info, cores, uint16_t);
@@ -37,13 +54,36 @@ node_info_to_hv(node_info_t* node_info, HV* hv)
 	STORE_FIELD(hv, node_info, threads, uint16_t);
 	STORE_FIELD(hv, node_info, tmp_disk, uint32_t);
 
-	/* TODO: select_nodeinfo */
+	slurm_get_select_nodeinfo(node_info->select_nodeinfo,
+				  SELECT_NODEDATA_SUBCNT,
+				  NODE_STATE_ALLOCATED,
+				  &alloc_cpus);
+#ifdef HAVE_BG
+	if(!alloc_cpus
+	   && (IS_NODE_ALLOCATED(node_info) || IS_NODE_COMPLETING(node_info)))
+		alloc_cpus = node_info->cpus;
+	else
+		alloc_cpus *= cpus_per_node;
+#endif
+
+	slurm_get_select_nodeinfo(node_info->select_nodeinfo,
+				  SELECT_NODEDATA_SUBCNT,
+				  NODE_STATE_ERROR,
+				  &err_cpus);
+#ifdef HAVE_BG
+	err_cpus *= cpus_per_node;
+#endif
+
+	hv_store_uint16_t(hv, "alloc_cpus", alloc_cpus);
+	hv_store_uint16_t(hv, "err_cpus", err_cpus);
+
+	STORE_FIELD(hv, node_info, select_nodeinfo, ptr);
 
 	STORE_FIELD(hv, node_info, weight, uint32_t);
 	return 0;
 }
 /*
- * convert node_info_msg_t to perl HV 
+ * convert node_info_msg_t to perl HV
  */
 int
 node_info_msg_to_hv(node_info_msg_t* node_info_msg, HV* hv)
@@ -58,7 +98,8 @@ node_info_msg_to_hv(node_info_msg_t* node_info_msg, HV* hv)
 	avp = newAV();
 	for(i = 0; i < node_info_msg->record_count; i ++) {
 		hvp =newHV();
-		if (node_info_to_hv(node_info_msg->node_array + i, hvp) < 0) {
+		if (node_info_to_hv(node_info_msg->node_array + i,
+				    node_info_msg->node_scaling, hvp) < 0) {
 			SvREFCNT_dec((SV*)hvp);
 			SvREFCNT_dec((SV*)avp);
 			return -1;
@@ -70,7 +111,7 @@ node_info_msg_to_hv(node_info_msg_t* node_info_msg, HV* hv)
 }
 
 /*
- * convert perl HV to update_node_msg_t 
+ * convert perl HV to update_node_msg_t
  */
 int
 hv_to_update_node_msg(HV* hv, update_node_msg_t *update_msg)
diff --git a/contribs/perlapi/libslurm-perl/typemap b/contribs/perlapi/libslurm-perl/typemap
index 338dbb2de..22ad007ff 100644
--- a/contribs/perlapi/libslurm-perl/typemap
+++ b/contribs/perlapi/libslurm-perl/typemap
@@ -4,7 +4,10 @@ slurm_step_ctx_t * T_STEPCTX
 signo_t		T_SIGNO
 slurm_cred_t	* T_PTRREF
 switch_jobinfo_t * T_PTRREF
-
+job_resources_t * T_PTRREF
+select_jobinfo_t * T_PTRREF
+select_nodeinfo_t * T_PTRREF
+jobacctinfo_t * T_PTRREF
 #####################################
 OUTPUT
 
diff --git a/contribs/spank_direct_io.c b/contribs/spank_direct_io.c
new file mode 100644
index 000000000..139acbefd
--- /dev/null
+++ b/contribs/spank_direct_io.c
@@ -0,0 +1,114 @@
+/*****************************************************************************
+ *
+ *  Copyright (C) 2010 Lawrence Livermore National Security, LLC.
+ *  Produced at Lawrence Livermore National Laboratory.
+ *  Written by Morris Jette <jette1@llnl.gov>.
+ *
+ *  UCRL-CODE-235358
+ * 
+ *  This file is part of chaos-spankings, a set of spank plugins for SLURM.
+ * 
+ *  This is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This is distributed in the hope that it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ ****************************************************************************
+ * Two options are added for salloc, sbatch, and srun: --cache-io and
+ * --direct-io. These options will set a SPANK_DIRECT_IO environment variable
+ * for the job's Prolog and Epilog scripts. If neither option (or their
+ * corresponding environment variables) are set, then SPANK_DIRECT_IO
+ * will not exist. NOTE: Command line options take precidence over the 
+ * environment variables.
+ *
+ * --cache-io  or SLURM_CACHE_IO  env var will set SPANK_DIRECT_IO=0
+ * --direct-io or SLURM_DIRECT_IO env var will set SPANK_DIRECT_IO=1
+ ****************************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <slurm/spank.h>
+
+/*
+ * All spank plugins must define this macro for the SLURM plugin loader.
+ */
+SPANK_PLUGIN(direct-io, 1)
+
+#define CACHE_IO	0x1
+#define DIRECT_IO	0x2
+
+static int io_style = 0;
+
+static int _opt_process (int val, const char *optarg, int remote);
+
+/*
+ *  Provide a --cache-io/--direct-io option for srun:
+ */
+struct spank_option spank_option_array[] =
+{
+	{ "cache-io",     NULL, "Cache I/O", 
+		0, CACHE_IO, (spank_opt_cb_f) _opt_process },
+	{ "direct-io",    NULL, "Write I/O directly to disk, without caching", 
+		0, DIRECT_IO,  (spank_opt_cb_f) _opt_process },
+	SPANK_OPTIONS_TABLE_END
+};
+
+int slurm_spank_init(spank_t sp, int ac, char **av)
+{
+	int i, j, rc = ESPANK_SUCCESS;
+
+	for (i=0; spank_option_array[i].name; i++) {
+		j = spank_option_register(sp, &spank_option_array[i]);
+		if (j != ESPANK_SUCCESS) {
+			slurm_error("Could not register Spank option %s",
+				    spank_option_array[i].name);
+			rc = j;
+		}
+	}
+
+	return rc;
+}
+
+/*
+ *  Called from both srun and slurmd.
+ */
+int slurm_spank_init_post_opt (spank_t sp, int ac, char **av)
+{
+	int rc = ESPANK_SUCCESS;
+
+	if (spank_remote (sp))
+		return (0);
+
+	if (io_style == CACHE_IO) {
+		slurm_debug("cache_io option");
+		rc = spank_set_job_env("O_DIRECT", "0", 1);
+	} else if (io_style == DIRECT_IO) {
+		slurm_debug("direct_io option");
+		rc = spank_set_job_env("O_DIRECT", "1", 1);
+	} else if (getenv("SLURM_CACHE_IO")) {
+		slurm_debug("cache_io env var");
+		rc = spank_set_job_env("O_DIRECT", "0", 1);
+	} else if (getenv("SLURM_DIRECT_IO")) {
+		slurm_debug("direct_io env var");
+		rc = spank_set_job_env("O_DIRECT", "1", 1);
+	}
+	if (rc != ESPANK_SUCCESS)
+		slurm_error("spank_setjob_env: %s", spank_strerror(rc));
+
+	return (0);
+}
+
+static int _opt_process (int val, const char *optarg, int remote)
+{
+	io_style = val;
+	return (0);
+}
diff --git a/contribs/torque/pbsnodes.pl b/contribs/torque/pbsnodes.pl
index d7ac4e815..0590f225f 100755
--- a/contribs/torque/pbsnodes.pl
+++ b/contribs/torque/pbsnodes.pl
@@ -96,7 +96,8 @@ Main:
 	    my $rCProc    = $node->{'cpus'};
 	    my $features  = $node->{'features'};
 	    my $rAMem     = $node->{'real_memory'};
-	    my $rAProc    = ($node->{'cpus'}) - ($node->{'used_cpus'});
+	    my $rAProc    = ($node->{'cpus'} -
+		    ($node->{'alloc_cpus'} + $node->{'err_cpus'}));
 	    my $state = lc(Slurm::node_state_string($node->{'node_state'}));
 
 #these aren't really defined in slurm, so I am not sure what to get them from
diff --git a/contribs/torque/qstat.pl b/contribs/torque/qstat.pl
index 536c22f23..fa55eb9f9 100755
--- a/contribs/torque/qstat.pl
+++ b/contribs/torque/qstat.pl
@@ -126,6 +126,7 @@ chomp $hostname;
 # 	}
 # }
 my $now_time = time();
+my $job_flags = SHOW_ALL | SHOW_DETAIL;
 
 if(defined($queueList)) {
 	my @queueIds = split(/,/, $queueList) if $queueList;
@@ -150,7 +151,7 @@ if(defined($queueList)) {
 		$rc = 0;
 	}
 } elsif($queueStatus) {
-	my $jresp = Slurm->load_jobs(1);
+	my $jresp = Slurm->load_jobs($job_flags);
 	die "Problem loading jobs.\n" if(!$jresp);
 	my $resp = Slurm->load_partitions(1);
 	die "Problem loading partitions.\n" if(!$resp);
@@ -179,7 +180,7 @@ if(defined($queueList)) {
 	my @jobIds = @ARGV;
 	my @userIds = split(/,/, $userList) if $userList;
 
-	my $resp = Slurm->load_jobs(1);
+	my $resp = Slurm->load_jobs($job_flags);
 	if(!$resp) {
 		die "Problem loading jobs.\n";
 	}
@@ -416,14 +417,9 @@ sub get_exec_host
 		my $inx = 0;
 		my $cpu_cnt = 0;
 		while((my $host = Slurm::Hostlist::shift($hl))) {
-			push(@allocNodes,
-			     "$host/" . $job->{'cpus_per_node'}[$inx]);
-
-			$cpu_cnt++;
-			if($cpu_cnt >= $job->{'cpu_count_reps'}[$inx]) {
-				$cpu_cnt = 0;
-				$inx++;
-			}
+			push(@allocNodes, "$host/" .
+			     Slurm->job_cpus_allocated_on_node_id(
+				     $job->{'job_resrcs'}, $inx++));
 		}
 		$execHost = join '+', @allocNodes;
 	}
@@ -457,24 +453,24 @@ sub print_job_select
 	if (!defined $header_printed) {
 		print "\n${hostname}:\n";
 
-		printf("%-20s %-8s %-8s %-20s %-6s %-5s %-3s %-6s %-5s %-1s %-5s\n",
+		printf("%-20s %-8s %-8s %-20s %-6s %-5s %-5s %-6s %-5s %-1s %-5s\n",
 		       "", "", "", "", "", "", "", "Req'd", "Req'd", "", "Elap");
 		printf(
-			"%-20s %-8s %-8s %-20s %-6s %-5s %-3s %-6s %-5s %-1s %-5s\n",
+			"%-20s %-8s %-8s %-20s %-6s %-5s %-5s %-6s %-5s %-1s %-5s\n",
 			"Job ID", "Username", "Queue", "Jobname", "SessID", "NDS",
 			"TSK",    "Memory",   "Time",  "S",       "Time"
 			);
 		printf(
-			"%-20s %-8s %-8s %-20s %-6s %-5s %-3s %-6s %-5s %-1s %-5s\n",
+			"%-20s %-8s %-8s %-20s %-6s %-5s %-5s %-6s %-5s %-1s %-5s\n",
 			'-' x 20, '-' x 8, '-' x 8, '-' x 20, '-' x 6, '-' x 5,
-			'-' x 3,  '-' x 6, '-' x 5, '-',      '-' x 5
+			'-' x 5,  '-' x 6, '-' x 5, '-',      '-' x 5
 			);
 		$header_printed = 1;
 	}
 	$execHost = get_exec_host($job) if $nodes;
 
 	printf("%-20.20s %-8.8s %-8.8s %-20.20s " .
-	       "%-6.6s %5.5s %3.3s %6.6s %-5.5s %-1s %-5.5s",
+	       "%-6.6s %5.5s %5.5s %6.6s %-5.5s %-1s %-5.5s",
 	       $job->{'job_id'},
 	       $job->{'user_name'},
 	       $job->{'partition'},
diff --git a/doc/html/configurator.html.in b/doc/html/configurator.html.in
index 666441144..179cc54df 100644
--- a/doc/html/configurator.html.in
+++ b/doc/html/configurator.html.in
@@ -670,8 +670,8 @@ root on every node of a user's job before the job's tasks
 will be initiated there and after that job has terminated.
 These parameters are optional.
 <DL>
-<DT> <input type="text" name="epilog" value="" size=40> <B>Prolog</B>
-<DT> <input type="text" name="prolog" value="" size=40> <B>Epilog</B>
+<DT> <input type="text" name="prolog" value="" size=40> <B>Prolog</B>
+<DT> <input type="text" name="epilog" value="" size=40> <B>Epilog</B>
 </DL>
 
 <P>
diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am
index 3e229630d..767b8f096 100644
--- a/doc/man/Makefile.am
+++ b/doc/man/Makefile.am
@@ -76,6 +76,8 @@ man3_MANS = man3/slurm_hostlist_create.3 \
 	man3/slurm_init_part_desc_msg.3 \
 	man3/slurm_init_resv_desc_msg.3 \
 	man3/slurm_init_update_node_msg.3 \
+	man3/slurm_job_cpus_allocated_on_node.3 \
+	man3/slurm_job_cpus_allocated_on_node_id.3 \
 	man3/slurm_job_step_create.3 \
 	man3/slurm_job_step_launch_t_init.3 \
 	man3/slurm_job_step_layout_get.3 \
diff --git a/doc/man/Makefile.in b/doc/man/Makefile.in
index 8c2ca4d31..e52b6df7b 100644
--- a/doc/man/Makefile.in
+++ b/doc/man/Makefile.in
@@ -370,6 +370,8 @@ man3_MANS = man3/slurm_hostlist_create.3 \
 	man3/slurm_init_part_desc_msg.3 \
 	man3/slurm_init_resv_desc_msg.3 \
 	man3/slurm_init_update_node_msg.3 \
+	man3/slurm_job_cpus_allocated_on_node.3 \
+	man3/slurm_job_cpus_allocated_on_node_id.3 \
 	man3/slurm_job_step_create.3 \
 	man3/slurm_job_step_launch_t_init.3 \
 	man3/slurm_job_step_layout_get.3 \
diff --git a/doc/man/man1/sacctmgr.1 b/doc/man/man1/sacctmgr.1
index b5d817e3a..b649d091c 100644
--- a/doc/man/man1/sacctmgr.1
+++ b/doc/man/man1/sacctmgr.1
@@ -93,11 +93,11 @@ Add an entity.
 Identical to the \fBadd\fR command.
 
 .TP
-\fBdelete\fR <\fIENTITY\fR> with <\fISPECS\fR>
+\fBdelete\fR <\fIENTITY\fR> where <\fISPECS\fR>
 Delete the specified entities.
 
 .TP
-\fBdump\fR <\fIENTITY\fR> with <\fIFile=FILENAME\fR>
+\fBdump\fR <\fIENTITY\fR> <\fIFile=FILENAME\fR>
 Dump cluster data to the specified file.
 
 .TP
@@ -121,7 +121,7 @@ Identical to the \fBshow\fR command.
 Load cluster data to the specified file.
 
 .TP
-\fBmodify\fR <\fIENTITY\fR> \fbwith\fR <\fISPECS\fR> \fbset\fR <\fISPECS\fR>
+\fBmodify\fR <\fIENTITY\fR> \fbwhere\fR <\fISPECS\fR> \fbset\fR <\fISPECS\fR>
 Modify an entity.
 
 .TP
diff --git a/doc/man/man1/salloc.1 b/doc/man/man1/salloc.1
index c89852dc1..af07a8434 100644
--- a/doc/man/man1/salloc.1
+++ b/doc/man/man1/salloc.1
@@ -57,15 +57,15 @@ options if desired:
     \fB\-\-cores\-per\-socket\fR=<\fIcores\fR>
     \fB\-\-threads\-per\-core\fR=<\fIthreads\fR>
 .fi
-When the task/affinity plugin is enabled,
-specifying an allocation in this manner also instructs SLURM to use
-a CPU affinity mask to guarantee the request is filled as specified.
-NOTE: Support for these options are configuration dependent.
-The task/affinity plugin must be configured.
-In addition either select/linear or select/cons_res plugin must be
-configured.
-If select/cons_res is configured, it must have a parameter of CR_Core,
-CR_Core_Memory, CR_Socket, or CR_Socket_Memory.
+If task/affinity plugin is enabled, then specifying an allocation in this
+manner also sets a default \fB\-\-cpu_bind\fR option of \fIthreads\fR
+if the \fB\-B\fR option specifies a thread count, otherwise an option of
+\fIcores\fR if a core count is specified, otherwise an option of \fIsockets\fR.
+If SelectType is configured to select/cons_res, it must have a parameter of
+CR_Core, CR_Core_Memory, CR_Socket, or CR_Socket_Memory for this option
+to be honored.
+This option is not supported on BlueGene systems (select/bluegene plugin
+is configured).
 
 .TP
 \fB\-\-begin\fR=<\fItime\fR>
@@ -187,7 +187,7 @@ than one allowed CPU) could be used for the tasks in order to provide
 multiple CPUs for the multithreaded tasks.
 
 By default, a job step has access to every CPU allocated to the job.
-To ensure that distinct CPUs are allocated to each job step, us the
+To ensure that distinct CPUs are allocated to each job step, use the
 \fB\-\-exclusive\fR option.
 
 If the job step allocation includes an allocation with a number of
diff --git a/doc/man/man1/sbatch.1 b/doc/man/man1/sbatch.1
index 065570231..e5fe97639 100644
--- a/doc/man/man1/sbatch.1
+++ b/doc/man/man1/sbatch.1
@@ -56,15 +56,15 @@ options if desired:
     \fB\-\-cores\-per\-socket\fR=<\fIcores\fR>
     \fB\-\-threads\-per\-core\fR=<\fIthreads\fR>
 .fi
-When the task/affinity plugin is enabled,
-specifying an allocation in this manner also instructs SLURM to use
-a CPU affinity mask to guarantee the request is filled as specified.
-NOTE: Support for these options are configuration dependent.
-The task/affinity plugin must be configured.
-In addition either select/linear or select/cons_res plugin must be
-configured.
-If select/cons_res is configured, it must have a parameter of CR_Core,
-CR_Core_Memory, CR_Socket, or CR_Socket_Memory.
+If task/affinity plugin is enabled, then specifying an allocation in this
+manner also sets a default \fB\-\-cpu_bind\fR option of \fIthreads\fR
+if the \fB\-B\fR option specifies a thread count, otherwise an option of
+\fIcores\fR if a core count is specified, otherwise an option of \fIsockets\fR.
+If SelectType is configured to select/cons_res, it must have a parameter of
+CR_Core, CR_Core_Memory, CR_Socket, or CR_Socket_Memory for this option
+to be honored.
+This option is not supported on BlueGene systems (select/bluegene plugin
+is configured).
 
 .TP
 \fB\-\-begin\fR=<\fItime\fR>
@@ -194,7 +194,7 @@ than one allowed CPU) could be used for the tasks in order to provide
 multiple CPUs for the multithreaded tasks.
 
 By default, a job step has access to every CPU allocated to the job.
-To ensure that distinct CPUs are allocated to each job step, us the
+To ensure that distinct CPUs are allocated to each job step, use the
 \fB\-\-exclusive\fR option.
 
 If the job step allocation includes an allocation with a number of
diff --git a/doc/man/man1/scontrol.1 b/doc/man/man1/scontrol.1
index 89504f06a..e29f6a70e 100644
--- a/doc/man/man1/scontrol.1
+++ b/doc/man/man1/scontrol.1
@@ -65,6 +65,7 @@ are unavailable to user's group.
 .TP
 \fBabort\fP
 Instruct the Slurm controller to terminate immediately and generate a core file.
+See "man slurmctld" for information about where the core file will be written.
 
 .TP
 \fBcheckpoint\fP \fICKPT_OP\fP \fIID\fP
@@ -975,4 +976,4 @@ details.
 \fBslurm_takeover\fR(3),
 \fBslurm_update_job\fR(3), \fBslurm_update_node\fR(3),
 \fBslurm_update_partition\fR(3),
-\fBslurm.conf\fR(5)
+\fBslurm.conf\fR(5), \fBslurmctld\fR(8)
diff --git a/doc/man/man1/squeue.1 b/doc/man/man1/squeue.1
index b89a31a0d..d528284d2 100644
--- a/doc/man/man1/squeue.1
+++ b/doc/man/man1/squeue.1
@@ -101,23 +101,28 @@ Valid \fItype\fR specifications include:
 .TP 4
 \fB%a\fR
 Account associated with the job.
+(Valid for jobs only)
 .TP
 \fB%A\fR
 Number of tasks created by a job step.
 This reports the value of the \fBsrun \-\-ntasks\fR option.
+(Valid for job steps only)
 .TP
 \fB%c\fR
 Minimum number of CPUs (processors) per node requested by the job.
 This reports the value of the \fBsrun \-\-mincpus\fR option with a
 default value of zero.
+(Valid for jobs only)
 .TP
 \fB%C\fR
 Number of CPUs (processors) requested by the job or allocated to
 it if already running.  As a job is completing this number will
 reflect the current number of CPUs allocated.
+(Valid for jobs only)
 .TP
 \fB%d\fR
 Minimum size of temporary disk space (in MB) requested by the job.
+(Valid for jobs only)
 .TP
 \fB%D\fR
 Number of nodes allocated to the job or the minimum number of nodes
@@ -127,58 +132,75 @@ minimum and maximum node counts) or the the job specifies a processor
 count instead of a node count and the cluster contains nodes with varying
 processor counts. As a job is completing this number will reflect the
 current number of nodes allocated.
+(Valid for jobs only)
 .TP
 \fB%e\fR
-Time at which the job ended or is expected to end (based upon its time limit)
+Time at which the job ended or is expected to end (based upon its time limit).
+(Valid for jobs only)
 .TP
 \fB%E\fR
 Job dependency. This job will not begin execution until the dependent job
 completes.  A value of zero implies this job has no dependencies.
+(Valid for jobs only)
 .TP
 \fB%f\fR
 Features required by the job.
+(Valid for jobs only)
 .TP
 \fB%g\fR
 Group name of the job.
+(Valid for jobs only)
 .TP
 \fB%G\fR
 Group ID of the job.
+(Valid for jobs only)
 .TP
 \fB%h\fR
 Can the nodes allocated to the job be shared with other jobs.
+(Valid for jobs only)
 .TP
 \fB%H\fR
 Minimum number of sockets per node requested by the job.
 This reports the value of the \fBsrun \-\-sockets\-per\-node\fR option.
+(Valid for jobs only)
 .TP
 \fB%i\fR
 Job or job step id.
+(Valid for jobs and job steps)
 .TP
 \fB%I\fR
 Minimum number of cores per socket requested by the job.
 This reports the value of the \fBsrun \-\-cores\-per\-socket\fR option.
+(Valid for jobs only)
 .TP
 \fB%j\fR
 Job or job step name.
+(Valid for jobs and job steps)
 .TP
 \fB%J\fR
 Minimum number of threads per core requested by the job.
 This reports the value of the \fBsrun \-\-threads\-per\-core\fR option.
+(Valid for jobs only)
 .TP
 \fB%k\fR
 Comment associated with the job.
+(Valid for jobs only)
+.TP
 \fB%l\fR
 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.
+(Valid for jobs and job steps)
 .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.
+(Valid for jobs only)
 .TP
 \fB%m\fR
-Minimum size of memory (in MB) requested by the job
+Minimum size of memory (in MB) requested by the job.
+(Valid for jobs only)
 .TP
 \fB%M\fR
 Time used by the job or job step in days\-hours:minutes:seconds.
@@ -187,36 +209,45 @@ For job steps this field shows the elapsed time since execution began
 and thus will be inaccurate for job steps which have been suspended.
 Clock skew between nodes in the cluster will cause the time to be inaccurate.
 If the time is obviously wrong (e.g. negative), it displays as "INVALID".
+(Valid for jobs and job steps)
 .TP
 \fB%n\fR
 List of node names (or base partitions on BlueGene systems) explicitly
-requested by the job
+requested by the job.
+(Valid for jobs only)
 .TP
 \fB%N\fR
 List of nodes allocated to the job or job step. In the case of a
 \fICOMPLETING\fR job, the list of nodes will comprise only those
 nodes that have not yet been returned to service.
+(Valid for jobs and job steps)
 .TP
 \fB%O\fR
 Are contiguous nodes requested by the job.
+(Valid for jobs only)
 .TP
 \fB%p\fR
 Priority of the job (converted to a floating point number between 0.0 and 1.0).
 Also see \fB%Q\fR.
+(Valid for jobs only)
 .TP
 \fB%P\fR
 Partition of the job or job step.
+(Valid for jobs and job steps)
 .TP
 \fB%q\fR
 Quality of service associated with the job.
+(Valid for jobs only)
 .TP
 \fB%Q\fR
 Priority of the job (generally a very large unsigned integer).
 Also see \fB%p\fR.
+(Valid for jobs only)
 .TP
 \fB%r\fR
 The reason a job is in its current state.
 See the \fBJOB REASON CODES\fR section below for more information.
+(Valid for jobs only)
 .TP
 \fB%R\fR
 For pending jobs: the reason a job is waiting for execution
@@ -225,17 +256,19 @@ For terminated jobs with failure: an explanation as to why the
 job failed is printed within parenthesis.
 For all other job states: the list of allocate nodes.
 See the \fBJOB REASON CODES\fR section below for more information.
+(Valid for jobs only)
 .TP
 \fB%s\fR
 Node selection plugin specific data for a job. Possible data includes:
 Geometry requirement of resource allocation (X,Y,Z dimensions),
 Connection type (TORUS, MESH, or NAV == torus else mesh),
 Permit rotation of geometry (yes or no),
-Node use (VIRTUAL or COPROCESSOR),
-etc.
+Node use (VIRTUAL or COPROCESSOR), etc.
+(Valid for jobs only)
 .TP
 \fB%S\fR
 Actual or expected start time of the job or job step.
+(Valid for jobs and job steps)
 .TP
 \fB%t\fR
 Job state, compact form:
@@ -243,28 +276,34 @@ PD (pending), R (running), CA (cancelled), CF(configuring),
 CG (completing), CD (completed),
 F (failed), TO (timeout), and NF (node failure).
 See the \fBJOB STATE CODES\fR section below for more information.
+(Valid for jobs only)
 .TP
 \fB%T\fR
 Job state, extended form:
 PENDING, RUNNING, SUSPENDED, CANCELLED, COMPLETING, COMPLETED, CONFIGURING,
 FAILED, TIMEOUT, and NODE_FAIL.
 See the \fBJOB STATE CODES\fR section below for more information.
+(Valid for jobs only)
 .TP
 \fB%u\fR
 User name for a job or job step.
+(Valid for jobs and job steps)
 .TP
 \fB%U\fR
 User ID for a job or job step.
+(Valid for jobs and job steps)
 .TP
 \fB%v\fR
 Reservation for the job.
+(Valid for jobs only)
 .TP
 \fB%x\fR
 List of node names explicitly excluded by the job.
+(Valid for jobs only)
 .TP
 \fB%z\fR
-Number of requested sockets, cores, and threads (S:C:T) per node for
-the job.
+Number of requested sockets, cores, and threads (S:C:T) per node for the job.
+(Valid for jobs only)
 .RE
 
 .TP
diff --git a/doc/man/man1/srun.1 b/doc/man/man1/srun.1
index c0fb11a5f..1f51e4df0 100644
--- a/doc/man/man1/srun.1
+++ b/doc/man/man1/srun.1
@@ -46,15 +46,15 @@ options if desired:
     \fB\-\-cores\-per\-socket\fR=<\fIcores\fR>
     \fB\-\-threads\-per\-core\fR=<\fIthreads\fR>
 .fi
-When the task/affinity plugin is enabled,
-specifying an allocation in this manner also instructs SLURM to use
-a CPU affinity mask to guarantee the request is filled as specified.
-NOTE: Support for these options are configuration dependent.
-The task/affinity plugin must be configured.
-In addition either select/linear or select/cons_res plugin must be
-configured.
-If select/cons_res is configured, it must have a parameter of CR_Core,
-CR_Core_Memory, CR_Socket, or CR_Socket_Memory.
+If task/affinity plugin is enabled, then specifying an allocation in this
+manner also sets a default \fB\-\-cpu_bind\fR option of \fIthreads\fR
+if the \fB\-B\fR option specifies a thread count, otherwise an option of
+\fIcores\fR if a core count is specified, otherwise an option of \fIsockets\fR.
+If SelectType is configured to select/cons_res, it must have a parameter of
+CR_Core, CR_Core_Memory, CR_Socket, or CR_Socket_Memory for this option
+to be honored.
+This option is not supported on BlueGene systems (select/bluegene plugin
+is configured).
 
 .TP
 \fB\-\-begin\fR=<\fItime\fR>
@@ -191,7 +191,7 @@ than one allowed CPU) could be used for the tasks in order to provide
 multiple CPUs for the multithreaded tasks.
 
 By default, a job step has access to every CPU allocated to the job.
-To ensure that distinct CPUs are allocated to each job step, us the
+To ensure that distinct CPUs are allocated to each job step, use the
 \fB\-\-exclusive\fR option.
 
 If the job step allocation includes an allocation with a number of
@@ -280,7 +280,7 @@ If the number of tasks differs from the number of allocated locality domains
 this can result in sub\-optimal binding.
 .TP
 .B help
-Show this help message
+Show help message for cpu_bind
 .RE
 
 .TP
@@ -394,7 +394,7 @@ may be the group name or the numerical group ID.
 .\"A held job can now be released using scontrol to reset its priority.
 
 .TP
-\fB\-\-help\fR
+\fB\-h\fR, \fB\-\-help\fR
 Display help information and exit.
 
 .TP
@@ -1590,10 +1590,6 @@ repetition count. For example, "SLURM_TASKS_PER_NODE=2(x3),1"
 indicates that the first three nodes will each execute three
 tasks and the fourth node will execute one task.
 .TP
-\fBSLURM_UMASK\fR
-The umask (user file\-create mask) at the time of job submission.
-This value is propagated to the spawned processes.
-.TP
 \fBMPIRUN_NOALLOCATE\fR
 Do not allocate a block on Blue Gene systems only.
 .TP
diff --git a/doc/man/man3/slurm_free_job_info_msg.3 b/doc/man/man3/slurm_free_job_info_msg.3
index 7f8188c4a..ff401e2ca 100644
--- a/doc/man/man3/slurm_free_job_info_msg.3
+++ b/doc/man/man3/slurm_free_job_info_msg.3
@@ -35,7 +35,9 @@ int \fBslurm_load_job\fR (
 .br
 	job_info_msg_t **\fIjob_info_msg_pptr\fP,
 .br
-	uint32_t \fIjob_id\fP
+	uint32_t \fIjob_id\fP,
+.br
+	uint16_t \fIshow_flags\fP,
 .br
 );
 .LP
@@ -100,6 +102,22 @@ int \fBslurm_get_select_jobinfo\fR (
 .br
 	void *\fIdata\fP
 );
+.LP
+int \fBslurm_job_cpus_allocated_on_node_id\fR (
+.br
+	job_resources_t *\fIjob_resrcs_ptr\fP,
+.br
+	int \fInode_id\fP
+.br
+);
+.LP
+int \fBslurm_job_cpus_allocated_on_node\fR (
+.br
+	job_resources_t *\fIjob_resrcs_ptr\fP,
+.br
+	const char *\fInode_name\fP
+.br
+);
 
 .SH "FORTRAN EXTENSION"
 .LP
@@ -166,6 +184,16 @@ Specifies a process id of some process on the current node.
 Specifies a pointer to a single job records from the \fIjob_info_msg_ptr\fP
 data structure.
 .TP
+\fIjob_resrcs_ptr\fP
+Pointer to a job_resources_t structure previously using the function
+\fBslurm_load_job\fR with a \fIshow_flags\fP value of \fBSHOW_DETAIL\fP.
+.TP
+\fInode_id\fP
+Zero origin ID of a node allocated to a job.
+.TP
+\fInode_name\fP
+Name of a node allocated to a job.
+.TP
 \fIone_liner\fP
 Print one record per line if non\-zero.
 .TP
@@ -179,12 +207,15 @@ hidden and partitions that the user's group is unable to utilize
 are not reported by default.
 The \fBSHOW_ALL\fP flag will cause information about jobs in all
 partitions to be displayed.
+The \fBSHOW_DETAIL\fP flag will cause detailed resource allocation information
+to be reported (e.g. the could of CPUs allocated to a job on each node).
 .TP
 \fIupdate_time\fP
 For all of the following informational calls, if update_time is equal to or
 greater than the last time changes where made to that information, new
 information is not returned.  Otherwise all the configuration. job, node,
 or partition records are returned.
+
 .SH "DESCRIPTION"
 .LP
 \fBslurm_free_resource_allocation_response_msg\fR Free slurm resource
@@ -203,6 +234,10 @@ expected termination time of a specified SLURM job id. The time corresponds
 to the exhaustion of the job\'s or partition\'s time limit. NOTE: The data is
 cached locally and only retrieved from the SLURM controller once per minute.
 .LP
+\fBslurm_job_cpus_allocated_on_node\fR and 
+\fBslurm_job_cpus_allocated_on_node_id\fR return the number of CPUs allocated
+to a job on a specific node allocated to a job.
+.LP
 \fBslurm_load_job\fR Returns a job_info_msg_t that contains an update time,
 record count, and array of job_table records for some specific job ID.
 .LP
@@ -354,7 +389,7 @@ expressions into a collection of individual node names.
 
 .SH "COPYING"
 Copyright (C) 2002\-2006 The Regents of the University of California.
-Copyright (C) 2008 Lawrence Livermore National Security.
+Copyright (C) 2008\-2010 Lawrence Livermore National Security.
 Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
 CODE\-OCEC\-09\-009. All rights reserved.
 .LP
diff --git a/doc/man/man3/slurm_job_cpus_allocated_on_node.3 b/doc/man/man3/slurm_job_cpus_allocated_on_node.3
new file mode 100644
index 000000000..836ffa79b
--- /dev/null
+++ b/doc/man/man3/slurm_job_cpus_allocated_on_node.3
@@ -0,0 +1 @@
+.so man3/slurm_free_job_info_msg.3
diff --git a/doc/man/man3/slurm_job_cpus_allocated_on_node_id.3 b/doc/man/man3/slurm_job_cpus_allocated_on_node_id.3
new file mode 100644
index 000000000..836ffa79b
--- /dev/null
+++ b/doc/man/man3/slurm_job_cpus_allocated_on_node_id.3
@@ -0,0 +1 @@
+.so man3/slurm_free_job_info_msg.3
diff --git a/doc/man/man5/slurmdbd.conf.5 b/doc/man/man5/slurmdbd.conf.5
index e810068ce..df8fe7c76 100644
--- a/doc/man/man5/slurmdbd.conf.5
+++ b/doc/man/man5/slurmdbd.conf.5
@@ -127,7 +127,7 @@ returned by the \fIgethostname()\fR function cut at the first dot (e.g. use
 The port number that the Slurm Database Daemon (slurmdbd) listens
 to for work. The default value is SLURMDBD_PORT as established at system
 build time. If none is explicitly specified, it will be set to 6819.
-This value must be equal to the \fBSlurmDbdPort\fR parameter in the
+This value must be equal to the \fBAccountingStoragePort\fR parameter in the
 slurm.conf file.
 
 .TP
diff --git a/doc/man/man8/slurmctld.8 b/doc/man/man8/slurmctld.8
index f77b143e9..073e06ca5 100644
--- a/doc/man/man8/slurmctld.8
+++ b/doc/man/man8/slurmctld.8
@@ -1,4 +1,4 @@
-.TH SLURMCTLD "8" "June 2006" "slurmctld 12.0" "Slurm components"
+.TH SLURMCTLD "8" "June 2006" "slurmctld 2.0" "Slurm components"
 .SH "NAME"
 slurmctld \- The central management daemon of Slurm.
 .SH "SYNOPSIS"
@@ -51,6 +51,16 @@ compiled into slurmctld.
 The location of the SLURM configuration file. This is overridden by
 explicitly naming a configuration file on the command line.
 
+.SH "CORE FILE LOCATION"
+If slurmctld is started with the \fB\-D\fR option then the core file will be
+written to the current working directory.
+Otherwise if \fBSlurmctldLogFile\fR is a fully qualified path name (starting
+with a slash), the core file will be written to the same directory as the
+log file.
+Otherwise the core file will be written to the \fBStateSaveLocation\fR.
+The command "scontrol abort" can be used to abort the slurmctld daemon and
+generate a core file.
+
 .SH "NOTES"
 It may be useful to experiment with different \fBslurmctld\fR specific
 configuration parameters using a distinct configuration file
diff --git a/doc/man/man8/spank.8 b/doc/man/man8/spank.8
index 2e03b03c5..6fe599d9f 100644
--- a/doc/man/man8/spank.8
+++ b/doc/man/man8/spank.8
@@ -243,7 +243,7 @@ an argument.
 is a short description of the option suitable for \-\-help output.
 .TP
 .I has_arg
-0 if option takes an argument, 1 if option takes no argument, and
+0 if option takes no argument, 1 if option takes an argument, and
 2 if the option takes an optional argument. (See \fBgetopt_long\fR(3)).
 .TP
 .I val
diff --git a/slurm.spec b/slurm.spec
index 030596126..2d1945d1e 100644
--- a/slurm.spec
+++ b/slurm.spec
@@ -83,14 +83,14 @@
 %endif
 
 Name:    slurm
-Version: 2.1.4
+Version: 2.1.5
 Release: 1%{?dist}
 
 Summary: Simple Linux Utility for Resource Management
 
 License: GPL
 Group: System Environment/Base
-Source: slurm-2.1.4.tar.bz2
+Source: slurm-2.1.5.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.4
+%setup -n slurm-2.1.5
 
 %build
 %configure --program-prefix=%{?_program_prefix:%{_program_prefix}} \
diff --git a/slurm/slurm.h.in b/slurm/slurm.h.in
index 5cc894ce7..f72214ce4 100644
--- a/slurm/slurm.h.in
+++ b/slurm/slurm.h.in
@@ -1376,7 +1376,7 @@ typedef struct slurm_ctl_conf {
 	char *switch_type;	/* switch or interconnect type */
 	char *task_epilog;	/* pathname of task launch epilog */
 	char *task_plugin;	/* task launch plugin */
-	uint16_t task_plugin_param;	/* see TASK_PARAM_* */
+	uint16_t task_plugin_param;	/* see CPU_BIND_* */
 	char *task_prolog;	/* pathname of task launch prolog */
 	char *tmp_fs;		/* pathname of temporary file system */
 	char *topology_plugin;	/* network topology plugin */
@@ -1925,8 +1925,8 @@ void slurm_print_key_pairs PARAMS((
  *                        get the number of cpus allocated to a job
  *			  on a node by node id
  * IN job_resrcs_ptr	- pointer to job_resources structure
- * IN node_id		- node id in allocation
- * RET cpus used or -1 on error
+ * IN node_id		- zero-origin node id in allocation
+ * RET number of CPUs allocated to job on this node or -1 on error
  */
 extern int slurm_job_cpus_allocated_on_node_id PARAMS(
 	(job_resources_t *job_resrcs_ptr, int node_id));
@@ -1937,7 +1937,7 @@ extern int slurm_job_cpus_allocated_on_node_id PARAMS(
  *			  on a node by node name
  * IN job_resrcs_ptr	- pointer to job_resources structure
  * IN node_name		- name of node
- * RET cpus used or -1 on error
+ * RET number of CPUs allocated to job on this node or -1 on error
  */
 extern int slurm_job_cpus_allocated_on_node PARAMS(
 	(job_resources_t *job_resrcs_ptr, const char *node_name));
diff --git a/src/api/job_info.c b/src/api/job_info.c
index 7afc8c30d..a68522cdb 100644
--- a/src/api/job_info.c
+++ b/src/api/job_info.c
@@ -276,7 +276,7 @@ slurm_sprint_job_info ( job_info_t * job_ptr, int one_liner )
 	xstrcat(out, tmp_line);
 	if ((job_ptr->time_limit == INFINITE) &&
 	    (job_ptr->end_time > time(NULL)))
-		sprintf(tmp_line, "NONE");
+		sprintf(tmp_line, "Unknown");
 	else {
 		slurm_make_time_str ((time_t *)&job_ptr->end_time, time_str,
 				     sizeof(time_str));
@@ -507,7 +507,7 @@ slurm_sprint_job_info ( job_info_t * job_ptr, int one_liner )
 			}
 
 			snprintf(tmp_line, sizeof(tmp_line), "%d",
-				 job_resrcs->cpu_array_value[i]);
+				 job_resrcs->cpus[i]);
 			xstrcat(out, tmp_line);
 			length += strlen(tmp_line);
 		    	if (job_resrcs->cpu_array_reps[i] > 1) {
@@ -1039,10 +1039,8 @@ extern int slurm_job_cpus_allocated_on_node_id(
 	int start_node=-1; /* start with -1 less so the array reps
 			    * lines up correctly */
 
-	if (!job_resrcs_ptr) {
-		error("slurm_cpus_used_on_node_id: job_resources not set");
-		return -1;
-	}
+	if (!job_resrcs_ptr || node_id < 0)
+		slurm_seterrno_ret(EINVAL);
 
 	for (i = 0; i < job_resrcs_ptr->cpu_array_cnt; i++) {
 		start_node += job_resrcs_ptr->cpu_array_reps[i];
@@ -1050,6 +1048,9 @@ extern int slurm_job_cpus_allocated_on_node_id(
 			break;
 	}
 
+	if (i >= job_resrcs_ptr->cpu_array_cnt)
+		return (0); /* nodeid not in this job */
+
 	return job_resrcs_ptr->cpu_array_value[i];
 }
 
@@ -1058,22 +1059,11 @@ extern int slurm_job_cpus_allocated_on_node(
 {
 	int node_id;
 
-	if (!job_resrcs_ptr) {
-		error("slurm_cpus_used_on_node: job_resources not set");
-		return -1;
-	} else if(!node) {
-		error("slurm_cpus_used_on_node: no node given");
-		return -1;
-	} else if(!job_resrcs_ptr->node_hl) {
-		error("slurm_cpus_used_on_node: "
-		      "hostlist not set in job_resources");
-		return -1;
-	} else if((node_id = hostlist_find(job_resrcs_ptr->node_hl, node))
-		  == -1) {
-		error("slurm_cpus_used_on_node: "
-		      "node %s is not in this allocation", node);
-		return -1;
-	}
+	if (!job_resrcs_ptr || !node || !job_resrcs_ptr->node_hl)
+		slurm_seterrno_ret(EINVAL);
+
+	if ((node_id = hostlist_find(job_resrcs_ptr->node_hl, node)) == -1)
+		return (0); /* No cpus allocated on this node */
 
 	return slurm_job_cpus_allocated_on_node_id(job_resrcs_ptr, node_id);
 }
diff --git a/src/api/step_io.c b/src/api/step_io.c
index 76e417510..fec4222ec 100644
--- a/src/api/step_io.c
+++ b/src/api/step_io.c
@@ -1,6 +1,6 @@
 /****************************************************************************\
  *  step_io.c - process stdin, stdout, and stderr for parallel jobs.
- *  $Id: step_io.c 19095 2009-12-01 22:59:18Z da $
+ *  $Id: step_io.c 19745 2010-03-12 20:52:45Z jette $
  *****************************************************************************
  *  Copyright (C) 2006 The Regents of the University of California.
  *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
@@ -352,9 +352,21 @@ _server_read(eio_obj_t *obj, List objs)
 		if ((n = read(obj->fd, buf, s->in_remaining)) < 0) {
 			if (errno == EINTR)
 				goto again;
-			if (errno == EAGAIN || errno == EWOULDBLOCK)
+			if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
 				return SLURM_SUCCESS;
-			debug3("_server_read error: %m");
+			if (errno == ECONNRESET) {
+				/* The slurmstepd writes the message (header
+				 * plus data) in a single write(). We read the
+				 * header above OK, but the data can't be read.
+				 * I've confirmed the full write completes and
+				 * the file is closed at slurmstepd shutdown.
+				 * The reason for this error is unknown. -Moe */
+				debug("Stdout/err from task %u may be "
+				      "incomplete due to a network error",
+				      s->header.gtaskid);
+			} else {
+				debug3("_server_read error: %m");
+			}
 		}
 		if (n <= 0) { /* got eof or unhandled error */
 			if (s->cio->sls)
diff --git a/src/api/step_launch.c b/src/api/step_launch.c
index 599f1c275..224817822 100644
--- a/src/api/step_launch.c
+++ b/src/api/step_launch.c
@@ -443,10 +443,9 @@ void slurm_step_launch_wait_finish(slurm_step_ctx_t *ctx)
 				 *   be made smart enough to really ensure
 				 *   that a killed step never starts.
 				 */
-				slurm_kill_job_step(
-					ctx->job_id,
-					ctx->step_resp->job_step_id,
-					SIGKILL);
+				slurm_kill_job_step(ctx->job_id,
+						    ctx->step_resp->job_step_id,
+						    SIGKILL);
 				if (!sls->user_managed_io) {
 					client_io_handler_abort(sls->
 								io.normal);
@@ -471,12 +470,12 @@ void slurm_step_launch_wait_finish(slurm_step_ctx_t *ctx)
 		     ctx->job_id, ctx->step_resp->job_step_id);
 
 	/* task_exit_signal != 0 when srun receives a message that a task
-	   exited with a SIGTERM or SIGKILL.  Without this test, a hang in srun
-	   might occur when a node gets a hard power failure, and TCP does not
-	   indicate that the I/O connection closed.  The I/O thread could
-	   block waiting for an EOF message, even though the remote process
-	   has died.  In this case, use client_io_handler_abort to force the
-	   I/O thread to stop listening for stdout or stderr and shutdown.*/
+	 * exited with a SIGTERM or SIGKILL.  Without this test, a hang in srun
+	 * might occur when a node gets a hard power failure, and TCP does not
+	 * indicate that the I/O connection closed.  The I/O thread could
+	 * block waiting for an EOF message, even though the remote process
+	 * has died.  In this case, use client_io_handler_abort to force the
+	 * I/O thread to stop listening for stdout or stderr and shutdown. */
 	if (task_exit_signal && !sls->user_managed_io) {
 		client_io_handler_abort(sls->io.normal);
 	}
@@ -1052,32 +1051,13 @@ _step_missing_handler(struct step_launch_state *sls, slurm_msg_t *missing_msg)
 		node = hostlist_next(fail_itr);
 		node_id = hostset_find(all_nodes, node);
 		if (node_id < 0) {
-			error(  "Internal error: bad SRUN_STEP_MISSING message. "
-				"Node %s not part of this job step", node);
+			error("Internal error: bad SRUN_STEP_MISSING message. "
+			      "Node %s not part of this job step", node);
 			free(node);
 			continue;
 		}
 		free(node);
 
-		/* If this is true, an I/O error has already occurred on the
-		   stepd for the current node, and the job should abort */
-		if (bit_test(sls->node_io_error, node_id)) {
-			error("Aborting, step missing and io error on node %d",
-			      node_id);
-			sls->abort = true;
-			pthread_cond_broadcast(&sls->cond);
-			break;
-		}
-
-		/*
-		 * A test is already is progress. Ignore message for this node.
-		 */
-		if (sls->io_deadline[node_id] != NO_VAL) {
-			debug("Test in progress for node %d, ignoring message",
-			      node_id);
-			continue;
-		}
-
 		/*
 		 * If all tasks for this node have either not started or already
 		 * exited, ignore the missing step message for this node.
@@ -1096,6 +1076,24 @@ _step_missing_handler(struct step_launch_state *sls, slurm_msg_t *missing_msg)
 		if (!active)
 			continue;
 
+		/* If this is true, an I/O error has already occurred on the
+		 * stepd for the current node, and the job should abort */
+		if (bit_test(sls->node_io_error, node_id)) {
+			error("Aborting, step missing and io error on node %d",
+			      node_id);
+			sls->abort = true;
+			pthread_cond_broadcast(&sls->cond);
+			break;
+		}
+
+		/*
+		 * A test is already is progress. Ignore message for this node.
+		 */
+		if (sls->io_deadline[node_id] != NO_VAL) {
+			debug("Test in progress for node %d, ignoring message",
+			      node_id);
+			continue;
+		}
 
 		sls->io_deadline[node_id] = time(NULL) + sls->io_timeout;
 
diff --git a/src/common/jobacct_common.c b/src/common/jobacct_common.c
index 218dc5a19..462740130 100644
--- a/src/common/jobacct_common.c
+++ b/src/common/jobacct_common.c
@@ -444,7 +444,9 @@ extern int unpack_jobacct_job_rec(void **job, uint16_t rpc_version, Buf buffer)
 		safe_unpack32(&job_ptr->resvid, buffer);
 		safe_unpack32(&job_ptr->req_cpus, buffer);
 		safe_unpack32(&job_ptr->requid, buffer);
-		_pack_sacct(&job_ptr->sacct, rpc_version, buffer);
+		if(_unpack_sacct(&job_ptr->sacct, rpc_version, buffer)
+		   != SLURM_SUCCESS)
+			goto unpack_error;
 		safe_unpack32(&job_ptr->show_full, buffer);
 		safe_unpack_time(&job_ptr->start, buffer);
 		safe_unpack16(&uint16_tmp, buffer);
@@ -498,7 +500,9 @@ extern int unpack_jobacct_job_rec(void **job, uint16_t rpc_version, Buf buffer)
 		safe_unpack16(&job_ptr->qos, buffer);
 		safe_unpack32(&job_ptr->req_cpus, buffer);
 		safe_unpack32(&job_ptr->requid, buffer);
-		_pack_sacct(&job_ptr->sacct, rpc_version, buffer);
+		if(_unpack_sacct(&job_ptr->sacct, rpc_version, buffer)
+		   != SLURM_SUCCESS)
+			goto unpack_error;
 		safe_unpack32(&job_ptr->show_full, buffer);
 		safe_unpack_time(&job_ptr->start, buffer);
 		safe_unpack16(&uint16_tmp, buffer);
@@ -552,7 +556,9 @@ extern int unpack_jobacct_job_rec(void **job, uint16_t rpc_version, Buf buffer)
 		safe_unpack16(&job_ptr->qos, buffer);
 		safe_unpack32(&job_ptr->req_cpus, buffer);
 		safe_unpack32(&job_ptr->requid, buffer);
-		_pack_sacct(&job_ptr->sacct, rpc_version, buffer);
+		if(_unpack_sacct(&job_ptr->sacct, rpc_version, buffer)
+		   != SLURM_SUCCESS)
+			goto unpack_error;
 		safe_unpack32(&job_ptr->show_full, buffer);
 		safe_unpack_time(&job_ptr->start, buffer);
 		safe_unpack16(&uint16_tmp, buffer);
@@ -659,7 +665,9 @@ extern int unpack_jobacct_step_rec(jobacct_step_rec_t **step,
 		safe_unpackstr_xmalloc(&step_ptr->nodes, &uint32_tmp, buffer);
 		safe_unpack32(&step_ptr->ntasks, buffer);
 		safe_unpack32(&step_ptr->requid, buffer);
-		_unpack_sacct(&step_ptr->sacct, rpc_version, buffer);
+		if(_unpack_sacct(&step_ptr->sacct, rpc_version, buffer)
+		   != SLURM_SUCCESS)
+			goto unpack_error;
 		safe_unpack_time(&step_ptr->start, buffer);
 		safe_unpack16(&uint16_tmp, buffer);
 		step_ptr->state = uint16_tmp;
@@ -683,7 +691,9 @@ extern int unpack_jobacct_step_rec(jobacct_step_rec_t **step,
 		safe_unpack32(&step_ptr->ncpus, buffer);
 		safe_unpackstr_xmalloc(&step_ptr->nodes, &uint32_tmp, buffer);
 		safe_unpack32(&step_ptr->requid, buffer);
-		_unpack_sacct(&step_ptr->sacct, rpc_version, buffer);
+		if(_unpack_sacct(&step_ptr->sacct, rpc_version, buffer)
+		   != SLURM_SUCCESS)
+			goto unpack_error;
 		safe_unpack_time(&step_ptr->start, buffer);
 		safe_unpack16(&uint16_tmp, buffer);
 		step_ptr->state = uint16_tmp;
diff --git a/src/common/slurm_errno.c b/src/common/slurm_errno.c
index b33190ba4..e4b9b8b00 100644
--- a/src/common/slurm_errno.c
+++ b/src/common/slurm_errno.c
@@ -284,7 +284,7 @@ static slurm_errtab_t slurm_errtab[] = {
 	{ ESLURMD_CREDENTIAL_REPLAYED,
 	  "Job credential replayed"                             },
 	{ ESLURMD_CREATE_BATCH_DIR_ERROR,
-	  "Slurmd could not create a batch directory"		},
+	  "Slurmd could not create a batch directory or file"	},
 	{ ESLURMD_MODIFY_BATCH_DIR_ERROR,
 	  "Slurmd could not chown or chmod a batch directory"	},
 	{ ESLURMD_CREATE_BATCH_SCRIPT_ERROR,
diff --git a/src/common/slurm_protocol_defs.c b/src/common/slurm_protocol_defs.c
index 1355fa464..fb382893e 100644
--- a/src/common/slurm_protocol_defs.c
+++ b/src/common/slurm_protocol_defs.c
@@ -2030,9 +2030,12 @@ extern bool valid_spank_job_env(char **spank_job_env,
 			        uint32_t spank_job_env_size, uid_t uid)
 {
 	int i;
+	char *entry;
 
 	for (i=0; i<spank_job_env_size; i++) {
-		char *entry = spank_job_env[i];
+		if (!strncmp(spank_job_env[i], "SPANK_", 6))
+			continue;
+		entry = spank_job_env[i];
 		spank_job_env[i] = xstrdup_printf ("SPANK_%s", entry);
 		xfree (entry);
 	}
diff --git a/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c b/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c
index 5c4693379..d5be23ee5 100644
--- a/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c
+++ b/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c
@@ -4226,10 +4226,10 @@ extern int acct_storage_p_add_clusters(mysql_conn_t *mysql_conn, uint32_t uid,
 			   "name, classification) "
 			   "values (%d, %d, \"%s\", %u) "
 			   "on duplicate key update deleted=0, mod_time=%d, "
-			   "control_host='', control_port=0;",
+			   "control_host='', control_port=0, classification=%u",
 			   cluster_table,
 			   now, now, object->name, object->classification,
-			   now);
+			   now, object->classification);
 		debug3("%d(%d) query\n%s",
 		       mysql_conn->conn, __LINE__, query);
 		rc = mysql_db_query(mysql_conn->db_conn, query);
diff --git a/src/plugins/accounting_storage/mysql/mysql_jobacct_process.c b/src/plugins/accounting_storage/mysql/mysql_jobacct_process.c
index 696b557c5..af64285b2 100644
--- a/src/plugins/accounting_storage/mysql/mysql_jobacct_process.c
+++ b/src/plugins/accounting_storage/mysql/mysql_jobacct_process.c
@@ -1742,13 +1742,15 @@ extern int mysql_jobacct_process_archive(mysql_conn_t *mysql_conn,
 		      last_submit);
 		return SLURM_ERROR;
 	}
+
+	/* get to the beginning of the current month */
 	time_tm.tm_sec = 0;
 	time_tm.tm_min = 0;
 	time_tm.tm_hour = 0;
 	time_tm.tm_mday = 1;
 	time_tm.tm_isdst = -1;
 	last_submit = mktime(&time_tm);
-	last_submit--;
+
 	debug("archive: adjusted last submit is (%d)", last_submit);
 
 	if(arch_cond->archive_script)
diff --git a/src/plugins/sched/wiki2/hostlist.c b/src/plugins/sched/wiki2/hostlist.c
index ed78f17c2..341fd15df 100644
--- a/src/plugins/sched/wiki2/hostlist.c
+++ b/src/plugins/sched/wiki2/hostlist.c
@@ -170,9 +170,7 @@ static char * _task_list(struct job_record *job_ptr)
 	xassert(job_resrcs_ptr);
 #ifdef HAVE_BG
 	if(job_ptr->node_cnt) {
-		task_cnt = ((job_resrcs_ptr->cpu_array_value[0]
-			     * job_resrcs_ptr->cpu_array_reps[0])
-			    / job_ptr->node_cnt);
+		task_cnt = job_resrcs_ptr->cpu_array_value[0];
 	} else
 		task_cnt = 1;
 #endif
@@ -279,9 +277,7 @@ static char * _task_list_exp(struct job_record *job_ptr)
 	xassert(job_resrcs_ptr);
 #ifdef HAVE_BG
 	if(job_ptr->node_cnt) {
-		task_cnt = ((job_resrcs_ptr->cpu_array_value[0]
-			     * job_resrcs_ptr->cpu_array_reps[0])
-			    / job_ptr->node_cnt);
+		task_cnt = job_resrcs_ptr->cpu_array_value[0];
 	} else
 		task_cnt = 1;
 #endif
diff --git a/src/plugins/select/bluegene/plugin/bg_job_place.c b/src/plugins/select/bluegene/plugin/bg_job_place.c
index be35075bd..2b4476a99 100644
--- a/src/plugins/select/bluegene/plugin/bg_job_place.c
+++ b/src/plugins/select/bluegene/plugin/bg_job_place.c
@@ -991,15 +991,18 @@ static int _find_best_block_match(List block_list,
 		if (bg_record) {
 			if(!is_test) {
 				if(check_block_bp_states(
-					   bg_record->bg_block_id)
-				   == SLURM_ERROR) {
-					error("_find_best_block_match: Marking "
-					      "block %s in an error state "
-					      "because of bad bps.",
+					   bg_record->bg_block_id, 1)
+				   != SLURM_SUCCESS) {
+					/* check_block_bp_states will
+					   already set things in an
+					   error state, so we don't
+					   have to do that here.
+					*/
+					error("_find_best_block_match: Picked "
+					      "block had some issues with "
+					      "hardware, trying a different "
+					      "one.",
 					      bg_record->bg_block_id);
-					put_block_in_error_state(
-						bg_record, BLOCK_ERROR_STATE,
-						"Block had bad BPs");
 					continue;
 				}
 			}
@@ -1316,7 +1319,10 @@ static void _build_select_struct(struct job_record *job_ptr,
 		fatal("bit_copy malloc failure");
 
 	job_resrcs_ptr->cpu_array_cnt = 1;
-	job_resrcs_ptr->cpu_array_value[0] = bg_conf->cpu_ratio;
+	if(job_ptr->num_procs < bg_conf->cpus_per_bp)
+		job_resrcs_ptr->cpu_array_value[0] = job_ptr->num_procs;
+	else
+		job_resrcs_ptr->cpu_array_value[0] = bg_conf->cpus_per_bp;
 	job_resrcs_ptr->cpu_array_reps[0] = node_cnt;
 	total_cpus = bg_conf->cpu_ratio * node_cnt;
 
diff --git a/src/plugins/select/bluegene/plugin/bg_job_run.c b/src/plugins/select/bluegene/plugin/bg_job_run.c
index 5ec99adef..b702ca459 100644
--- a/src/plugins/select/bluegene/plugin/bg_job_run.c
+++ b/src/plugins/select/bluegene/plugin/bg_job_run.c
@@ -2,7 +2,7 @@
  *  bg_job_run.c - blue gene job execution (e.g. initiation and termination)
  *  functions.
  *
- *  $Id: bg_job_run.c 19292 2010-01-21 01:17:17Z da $
+ *  $Id: bg_job_run.c 19700 2010-03-08 18:50:55Z da $
  *****************************************************************************
  *  Copyright (C) 2004-2006 The Regents of the University of California.
  *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
@@ -574,7 +574,7 @@ static void _start_agent(bg_update_t *bg_update_ptr)
 		sleep(2);
 		lock_slurmctld(job_write_lock);
 		if((rc = job_requeue(0, bg_update_ptr->job_ptr->job_id, -1))) {
-			error("couldn't requeue job %u, failing it: %s",
+			error("1 couldn't requeue job %u, failing it: %s",
 			      bg_update_ptr->job_ptr->job_id,
 			      slurm_strerror(rc));
 			job_fail(bg_update_ptr->job_ptr->job_id);
@@ -657,7 +657,7 @@ static void _start_agent(bg_update_t *bg_update_ptr)
 		sleep(2);
 		lock_slurmctld(job_write_lock);
 		if((rc = job_requeue(0, bg_update_ptr->job_ptr->job_id, -1))) {
-			error("couldn't requeue job %u, failing it: %s",
+			error("2 couldn't requeue job %u, failing it: %s",
 			      bg_update_ptr->job_ptr->job_id,
 			      slurm_strerror(rc));
 			job_fail(bg_update_ptr->job_ptr->job_id);
@@ -873,7 +873,8 @@ static void _start_agent(bg_update_t *bg_update_ptr)
 			lock_slurmctld(job_write_lock);
 			if((rc = job_requeue(
 				    0, bg_update_ptr->job_ptr->job_id, -1))) {
-				error("couldn't requeue job %u, failing it: %s",
+				error("3 couldn't requeue job %u, "
+				      "failing it: %s",
 				      bg_update_ptr->job_ptr->job_id,
 				      slurm_strerror(rc));
 				job_fail(bg_update_ptr->job_ptr->job_id);
diff --git a/src/plugins/select/bluegene/plugin/bg_record_functions.c b/src/plugins/select/bluegene/plugin/bg_record_functions.c
index 5411275e4..774370597 100644
--- a/src/plugins/select/bluegene/plugin/bg_record_functions.c
+++ b/src/plugins/select/bluegene/plugin/bg_record_functions.c
@@ -1025,7 +1025,13 @@ extern int format_node_name(bg_record_t *bg_record, char *buf, int buf_size)
 	return SLURM_SUCCESS;
 }
 
-extern int down_nodecard(char *bp_name, bitoff_t io_start)
+/*
+ * This could potentially lock the node lock in the slurmctld with
+ * slurm_drain_node, or slurm_fail_job so if slurmctld_locked is called we
+ * will call the functions without locking the locks again.
+ */
+extern int down_nodecard(char *bp_name, bitoff_t io_start,
+			 bool slurmctld_locked)
 {
 	List requests = NULL;
 	List delete_list = NULL;
@@ -1106,9 +1112,13 @@ extern int down_nodecard(char *bp_name, bitoff_t io_start)
 		if(!blocks_overlap(bg_record, &tmp_record))
 			continue;
 
-		if(bg_record->job_running > NO_JOB_RUNNING)
-			slurm_fail_job(bg_record->job_running);
+		if(bg_record->job_running > NO_JOB_RUNNING) {
+			if(slurmctld_locked)
+				job_fail(bg_record->job_running);
+			else
+				slurm_fail_job(bg_record->job_running);
 
+		}
 		/* If Running Dynamic mode and the the block is
 		   smaller than the create size just continue on.
 		*/
@@ -1154,7 +1164,10 @@ extern int down_nodecard(char *bp_name, bitoff_t io_start)
 		debug("No block under 1 midplane available for this nodecard.  "
 		      "Draining the whole node.");
 		if(!node_already_down(bp_name)) {
-			slurm_drain_nodes(bp_name, reason);
+			if(slurmctld_locked)
+				drain_nodes(bp_name, reason);
+			else
+				slurm_drain_nodes(bp_name, reason);
 		}
 		rc = SLURM_SUCCESS;
 		goto cleanup;
@@ -1282,7 +1295,10 @@ extern int down_nodecard(char *bp_name, bitoff_t io_start)
 					 "select_bluegene: "
 					 "nodecard down [SLURM@%s]",
 					 time_str);
-				slurm_drain_nodes(bp_name, reason);
+				if(slurmctld_locked)
+					drain_nodes(bp_name, reason);
+				else
+					slurm_drain_nodes(bp_name, reason);
 			}
 			rc = SLURM_SUCCESS;
 			goto cleanup;
diff --git a/src/plugins/select/bluegene/plugin/bg_record_functions.h b/src/plugins/select/bluegene/plugin/bg_record_functions.h
index f07ddf903..26ae7daea 100644
--- a/src/plugins/select/bluegene/plugin/bg_record_functions.h
+++ b/src/plugins/select/bluegene/plugin/bg_record_functions.h
@@ -140,7 +140,8 @@ extern int handle_small_record_request(List records, blockreq_t *blockreq,
 				       bg_record_t *bg_record, bitoff_t start);
 
 extern int format_node_name(bg_record_t *bg_record, char *buf, int buf_size);
-extern int down_nodecard(char *bp_name, bitoff_t io_start);
+extern int down_nodecard(char *bp_name, bitoff_t io_start,
+			 bool slurmctld_locked);
 extern int up_nodecard(char *bp_name, bitstr_t *ionode_bitmap);
 extern int put_block_in_error_state(bg_record_t *bg_record,
 				    int state, char *reason);
diff --git a/src/plugins/select/bluegene/plugin/bluegene.c b/src/plugins/select/bluegene/plugin/bluegene.c
index 812278d34..93f5ddfc6 100644
--- a/src/plugins/select/bluegene/plugin/bluegene.c
+++ b/src/plugins/select/bluegene/plugin/bluegene.c
@@ -1,7 +1,7 @@
 /*****************************************************************************\
  *  bluegene.c - blue gene node configuration processing module.
  *
- *  $Id: bluegene.c 19173 2009-12-15 22:36:32Z da $
+ *  $Id: bluegene.c 19755 2010-03-16 19:15:43Z da $
  *****************************************************************************
  *  Copyright (C) 2004 The Regents of the University of California.
  *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
@@ -485,6 +485,17 @@ extern int bg_free_block(bg_record_t *bg_record, bool wait, bool locked)
 					      bg_record->bg_block_id);
 					break;
 				} else if(rc == INCOMPATIBLE_STATE) {
+#ifndef HAVE_BGL
+					/* If the state is error and
+					   we get an incompatible
+					   state back here, it means
+					   we set it ourselves so
+					   break out.
+					*/
+					if(bg_record->state
+					   == RM_PARTITION_ERROR)
+						break;
+#endif
 					debug2("bridge_destroy_partition"
 					       "(%s): %s State = %d",
 					       bg_record->bg_block_id,
diff --git a/src/plugins/select/bluegene/plugin/select_bluegene.c b/src/plugins/select/bluegene/plugin/select_bluegene.c
index 2046a9397..81676cc93 100644
--- a/src/plugins/select/bluegene/plugin/select_bluegene.c
+++ b/src/plugins/select/bluegene/plugin/select_bluegene.c
@@ -992,7 +992,7 @@ extern int select_p_update_sub_node (update_block_msg_t *block_desc_ptr)
 					/* find first bit in nc */
 					int start_io =
 						(int)nc_pos * bg_conf->io_ratio;
-					down_nodecard(node_name, start_io);
+					down_nodecard(node_name, start_io, 0);
 					last_pos = nc_pos;
 				}
 			}
diff --git a/src/plugins/select/bluegene/plugin/state_test.c b/src/plugins/select/bluegene/plugin/state_test.c
index 4449fbe69..600de3398 100644
--- a/src/plugins/select/bluegene/plugin/state_test.c
+++ b/src/plugins/select/bluegene/plugin/state_test.c
@@ -2,7 +2,7 @@
  *  state_test.c - Test state of Bluegene base partitions and switches.
  *  DRAIN nodes in SLURM that are not usable.
  *
- *  $Id: state_test.c 19095 2009-12-01 22:59:18Z da $
+ *  $Id: state_test.c 19755 2010-03-16 19:15:43Z da $
  *****************************************************************************
  *  Copyright (C) 2004-2007 The Regents of the University of California.
  *  Copyright (C) 2008-2009 Lawrence Livermore National Security.
@@ -141,11 +141,17 @@ static void _configure_node_down(rm_bp_id_t bp_id, my_bluegene_t *my_bg)
 	}
 }
 
-static int _test_down_nodecards(rm_BP_t *bp_ptr)
+/*
+ * This could potentially lock the node lock in the slurmctld with
+ * slurm_drain_node, so if nodes_locked is called we will call the
+ * drainning function without locking the lock again.
+ */
+static int _test_down_nodecards(rm_BP_t *bp_ptr, bool slurmctld_locked)
 {
 	rm_bp_id_t bp_id = NULL;
 	rm_nodecard_id_t nc_name = NULL;
 	int num = 0;
+	int marked_down = 0;
 	int i=0;
 	int rc = SLURM_SUCCESS;
 	rm_nodecard_list_t *ncard_list = NULL;
@@ -244,6 +250,11 @@ static int _test_down_nodecards(rm_BP_t *bp_ptr)
 		if(state == RM_NODECARD_UP)
 			continue;
 
+		/* Here we want to keep track of any nodecard that
+		   isn't up and return error if this is not 0 since
+		   we could be checking to see if we could run here. */
+		marked_down++;
+
 		if ((rc = bridge_get_data(ncard,
 					  RM_NodeCardID,
 					  &nc_name)) != STATUS_OK) {
@@ -298,7 +309,8 @@ static int _test_down_nodecards(rm_BP_t *bp_ptr)
 /* 		bit_nset(ionode_bitmap, io_start, io_start+io_cnt); */
 		/* we have to handle each nodecard separately to make
 		   sure we don't create holes in the system */
-		if(down_nodecard(node_name, io_start) == SLURM_SUCCESS) {
+		if(down_nodecard(node_name, io_start, slurmctld_locked)
+		   == SLURM_SUCCESS) {
 			debug("nodecard %s on %s is in an error state",
 			      nc_name, node_name);
 		}
@@ -359,6 +371,9 @@ clean_up:
 /* 		FREE_NULL_BITMAP(ionode_bitmap); */
 	free(bp_id);
 
+	/* If we marked any nodecard down we need to state it here */
+	if((rc == SLURM_SUCCESS) && marked_down)
+		rc = SLURM_ERROR;
 	return rc;
 }
 
@@ -390,7 +405,7 @@ static void _test_down_nodes(my_bluegene_t *my_bg)
 			}
 		}
 
-		_test_down_nodecards(my_bp);
+		_test_down_nodecards(my_bp, 0);
 	}
 }
 
@@ -496,7 +511,13 @@ extern void test_mmcs_failures(void)
 #endif
 }
 
-extern int check_block_bp_states(char *bg_block_id)
+
+/*
+ * This could potentially lock the node lock in the slurmctld with
+ * slurm_drain_node, so if slurmctld_locked is called we will call the
+ * drainning function without locking the lock again.
+ */
+extern int check_block_bp_states(char *bg_block_id, bool slurmctld_locked)
 {
 	int rc = SLURM_SUCCESS;
 #ifdef HAVE_BG_FILES
@@ -543,7 +564,13 @@ extern int check_block_bp_states(char *bg_block_id)
 			}
 		}
 
-		_test_down_nodecards(bp_ptr);
+		/* If we find any nodecards in an error state just
+		   break here since we are seeing if we can run.  If
+		   any nodecard is down this can't happen.
+		*/
+		if((rc = _test_down_nodecards(bp_ptr, slurmctld_locked))
+		   != SLURM_SUCCESS)
+			break;
 	}
 
 cleanup:
diff --git a/src/plugins/select/bluegene/plugin/state_test.h b/src/plugins/select/bluegene/plugin/state_test.h
index bb59be0fa..329eaca7b 100644
--- a/src/plugins/select/bluegene/plugin/state_test.h
+++ b/src/plugins/select/bluegene/plugin/state_test.h
@@ -1,6 +1,6 @@
 /*****************************************************************************\
  *  state_test.h - header for Blue Gene node and switch state test.
- *  $Id: state_test.h 19095 2009-12-01 22:59:18Z da $
+ *  $Id: state_test.h 19700 2010-03-08 18:50:55Z da $
  *****************************************************************************
  *  Copyright (C) 2004 The Regents of the University of California.
  *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
@@ -54,6 +54,6 @@ extern void test_mmcs_failures(void);
  * Search MMCS for failed switches and nodes inside of block.
  * Failed resources are DRAINED in SLURM. This relies upon rm_get_partition(),
  */
-extern int check_block_bp_states(char *bg_block_id);
+extern int check_block_bp_states(char *bg_block_id, bool slurmctld_locked);
 
 #endif /* _STATE_TEST_H_ */
diff --git a/src/plugins/select/bluegene/wrap_rm_api.h b/src/plugins/select/bluegene/wrap_rm_api.h
index 02fe3de60..755f79a15 100644
--- a/src/plugins/select/bluegene/wrap_rm_api.h
+++ b/src/plugins/select/bluegene/wrap_rm_api.h
@@ -42,11 +42,12 @@
    * make certain they match the rm_api.h values on the Service Node */
   enum rm_partition_state {RM_PARTITION_FREE,
 			   RM_PARTITION_CONFIGURING,
-			   RM_PARTITION_READY,
 #ifdef HAVE_BGL
+			   RM_PARTITION_READY,
 			   RM_PARTITION_BUSY,
 #else
 			   RM_PARTITION_REBOOTING,
+			   RM_PARTITION_READY,
 #endif
 			   RM_PARTITION_DEALLOCATING,
 			   RM_PARTITION_ERROR,
diff --git a/src/plugins/select/cons_res/job_test.c b/src/plugins/select/cons_res/job_test.c
index 717b6e042..0fa4b6cd5 100644
--- a/src/plugins/select/cons_res/job_test.c
+++ b/src/plugins/select/cons_res/job_test.c
@@ -1661,7 +1661,7 @@ extern int cr_job_test(struct job_record *job_ptr, bitstr_t *bitmap,
 	bitstr_t *orig_map, *avail_cores, *free_cores;
 	bitstr_t *tmpcore = NULL, *reqmap = NULL;
 	bool test_only;
-	uint32_t c, i, n, csize, total_cpus, save_mem = 0;
+	uint32_t c, i, k, n, csize, total_cpus, save_mem = 0;
 	int32_t build_cnt;
 	job_resources_t *job_res;
 	struct part_res_record *p_ptr, *jp_ptr;
@@ -2041,11 +2041,21 @@ alloc_job:
 		if (bit_test(bitmap, n) == 0)
 			continue;
 		j = cr_get_coremap_offset(n);
-		for (; j < cr_get_coremap_offset(n+1); j++, c++) {
+		k = cr_get_coremap_offset(n+1);
+		for (; j < k; j++, c++) {
 			if (bit_test(free_cores, j)) {
 				if (c >= csize)	{
-					fatal("cons_res: cr_job_test "
-					      "core_bitmap index error");
+					error("cons_res: cr_job_test "
+					      "core_bitmap index error on "
+					      "node %s", 
+					      select_node_record[n].node_ptr->
+					      name);
+					drain_nodes(select_node_record[n].
+						    node_ptr->name,
+						    "Bad core count");
+					free_job_resources(&job_res);
+					FREE_NULL_BITMAP(free_cores);
+					return SLURM_ERROR;
 				}
 				bit_set(job_res->core_bitmap, c);
 			}
diff --git a/src/scontrol/update_job.c b/src/scontrol/update_job.c
index 8ded694c2..9cc255b13 100644
--- a/src/scontrol/update_job.c
+++ b/src/scontrol/update_job.c
@@ -525,10 +525,11 @@ scontrol_update_job (int argc, char *argv[])
 		}
 		else if (!strncasecmp(tag, "EligibleTime", MAX(taglen, 2)) ||
 			 !strncasecmp(tag, "StartTime",    MAX(taglen, 2))) {
-			job_msg.begin_time = parse_time(val, 0);
-			if(job_msg.begin_time < time(NULL))
-				job_msg.begin_time = time(NULL);
-			update_cnt++;
+			if((job_msg.begin_time = parse_time(val, 0))) {
+				if(job_msg.begin_time < time(NULL))
+					job_msg.begin_time = time(NULL);
+				update_cnt++;
+			}
 		}
 		else if (!strncasecmp(tag, "EndTime", MAX(taglen, 2))) {
 			job_msg.end_time = parse_time(val, 0);
diff --git a/src/sinfo/opts.c b/src/sinfo/opts.c
index ca28326c3..5b618ffa0 100644
--- a/src/sinfo/opts.c
+++ b/src/sinfo/opts.c
@@ -770,7 +770,7 @@ Usage: sinfo [OPTIONS]\n\
   -e, --exact                group nodes only on exact match of configuration\n\
   -h, --noheader             no headers on output\n\
   -hide                      do not show hidden or non-accessible partitions\n\
-  -i, --iterate=seconds      specify an interation period\n\
+  -i, --iterate=seconds      specify an iteration period\n\
   -l, --long                 long output - displays more information\n\
   -n, --nodes=NODES          report on specific node(s)\n\
   -N, --Node                 Node-centric format\n\
diff --git a/src/sinfo/sinfo.c b/src/sinfo/sinfo.c
index 2118afaf0..49c6c4049 100644
--- a/src/sinfo/sinfo.c
+++ b/src/sinfo/sinfo.c
@@ -430,28 +430,29 @@ static bool _filter_out(node_info_t *node_ptr)
 		uint16_t base_state;
 		ListIterator iterator;
 		uint16_t cpus = 0;
+		node_info_t tmp_node, *tmp_node_ptr = &tmp_node;
 
 		iterator = list_iterator_create(params.state_list);
 		while ((node_state = list_next(iterator))) {
-			if (*node_state ==
-			    (NODE_STATE_DRAIN | NODE_STATE_ALLOCATED)) {
+			tmp_node_ptr->node_state = *node_state;
+			if (*node_state == NODE_STATE_DRAIN) {
+				/* We search for anything that has the
+				 * drain flag set */
+				if (IS_NODE_DRAIN(node_ptr)) {
+					match = true;
+					break;
+				}
+			} else if (IS_NODE_DRAINING(tmp_node_ptr)) {
 				/* We search for anything that gets mapped to
 				 * DRAINING in node_state_string */
-				if (!IS_NODE_DRAIN(node_ptr))
-					continue;
-				if (IS_NODE_ALLOCATED(node_ptr)
-				    || IS_NODE_COMPLETING(node_ptr)) {
+				if (IS_NODE_DRAINING(node_ptr)) {
 					match = true;
 					break;
 				}
-			} else if (*node_state ==
-				   (NODE_STATE_DRAIN | NODE_STATE_IDLE)) {
+			} else if (IS_NODE_DRAINED(tmp_node_ptr)) {
 				/* We search for anything that gets mapped to
 				 * DRAINED in node_state_string */
-				if (!IS_NODE_DRAIN(node_ptr))
-					continue;
-				if (!IS_NODE_ALLOCATED(node_ptr)
-				    && !IS_NODE_COMPLETING(node_ptr)) {
+				if (IS_NODE_DRAINED(node_ptr)) {
 					match = true;
 					break;
 				}
@@ -835,8 +836,13 @@ static int _handle_subgrps(List sinfo_list, uint16_t part_num,
 
 	for(i=0; i<state_cnt; i++) {
 		if(iterator) {
+			node_info_t tmp_node, *tmp_node_ptr = &tmp_node;
 			while ((node_state = list_next(iterator))) {
-				if(*node_state == state[i])
+				tmp_node_ptr->node_state = *node_state;
+				if((((state[i] == NODE_STATE_ALLOCATED)
+				     && IS_NODE_DRAINING(tmp_node_ptr))
+				    || (*node_state == NODE_STATE_DRAIN))
+				   || (*node_state == state[i]))
 					break;
 			}
 			list_iterator_reset(iterator);
@@ -872,8 +878,8 @@ static int _handle_subgrps(List sinfo_list, uint16_t part_num,
 			node_scaling -= size;
 			node_ptr->node_state &= NODE_STATE_FLAGS;
 			node_ptr->node_state |= state[i];
-/* 			info("%s got %s of %u", node_ptr->name, */
-/* 			     node_state_string(node_ptr->node_state), size); */
+			/* info("1 %s got %s of %u", node_ptr->name, */
+			/*      node_state_string(node_ptr->node_state), size); */
 			_insert_node_ptr(sinfo_list, part_num, part_ptr,
 					 node_ptr, size);
 /* 			set = 1; */
@@ -895,7 +901,11 @@ static int _handle_subgrps(List sinfo_list, uint16_t part_num,
 	/* now handle the idle */
 	if(iterator) {
 		while ((node_state = list_next(iterator))) {
-			if(*node_state == NODE_STATE_IDLE)
+			node_info_t tmp_node, *tmp_node_ptr = &tmp_node;
+			tmp_node_ptr->node_state = *node_state;
+			if(((*node_state == NODE_STATE_DRAIN)
+			    || IS_NODE_DRAINED(tmp_node_ptr))
+			   || (*node_state == NODE_STATE_IDLE))
 				break;
 		}
 		list_iterator_destroy(iterator);
@@ -904,8 +914,8 @@ static int _handle_subgrps(List sinfo_list, uint16_t part_num,
 	}
 	node_ptr->node_state &= NODE_STATE_FLAGS;
 	node_ptr->node_state |= NODE_STATE_IDLE;
-/* 	info("%s got %s of %u", node_ptr->name, */
-/* 	     node_state_string(node_ptr->node_state), size); */
+	/* info("2 %s got %s of %u", node_ptr->name, */
+	/*      node_state_string(node_ptr->node_state), node_scaling); */
 	if((int)node_scaling > 0)
 		_insert_node_ptr(sinfo_list, part_num, part_ptr,
 				 node_ptr, node_scaling);
diff --git a/src/slurmctld/gang.c b/src/slurmctld/gang.c
index 56816f00d..2df65a714 100644
--- a/src/slurmctld/gang.c
+++ b/src/slurmctld/gang.c
@@ -689,6 +689,7 @@ static void _preempt_job_dequeue(void)
 	uint32_t job_id, *tmp_id;
 	uint16_t preempt_mode = slurm_get_preempt_mode();
 
+	xassert(preempt_job_list);
 	preempt_mode &= (~PREEMPT_MODE_GANG);
 	while ((tmp_id = list_pop(preempt_job_list))) {
 		job_id = *tmp_id;
@@ -1343,6 +1344,12 @@ extern int gs_reconfig(void)
 	struct gs_part *p_ptr, *old_part_list, *newp_ptr;
 	struct job_record *job_ptr;
 
+	if (!timeslicer_thread_id) {
+		/* gs_init() will be called later from read_slurm_conf()
+		 * if we are enabling gang scheduling via reconfiguration */
+		return SLURM_SUCCESS;
+	}
+
 	debug3("gang: entering gs_reconfig");
 	pthread_mutex_lock(&data_mutex);
 
diff --git a/src/slurmctld/node_mgr.c b/src/slurmctld/node_mgr.c
index 1531e783a..0cb2f6886 100644
--- a/src/slurmctld/node_mgr.c
+++ b/src/slurmctld/node_mgr.c
@@ -1246,6 +1246,12 @@ extern int validate_node_specs(slurm_node_registration_status_msg_t *reg_msg)
 				reg_msg->node_name, threads1);
 			error_code = EINVAL;
 			reason_down = "Low socket*core*thread count";
+		} else if ((slurmctld_conf.fast_schedule == 0) &&
+			   ((cr_flag == 1) || gang_flag) && (cores1 < cores2)) {
+			error("Node %s has low socket*core count %u",
+			      reg_msg->node_name, cores1);
+			error_code = EINVAL;
+			reason_down = "Low socket*core count";
 		} else if ((slurmctld_conf.fast_schedule == 0) &&
 			   ((cr_flag == 1) || gang_flag) &&
 			   ((sockets1 > sockets2) || (cores1 > cores2) ||
diff --git a/src/slurmctld/proc_req.c b/src/slurmctld/proc_req.c
index c4a8a7fbe..42faf0ca4 100644
--- a/src/slurmctld/proc_req.c
+++ b/src/slurmctld/proc_req.c
@@ -1320,10 +1320,10 @@ static void _slurm_rpc_complete_batch_script(slurm_msg_t * msg)
 		if (error_code == SLURM_SUCCESS) {
 			update_node_msg_t update_node_msg;
 			memset(&update_node_msg, 0, sizeof(update_node_msg_t));
-			update_node_msg.node_names =
-				comp_msg->node_name;
+			update_node_msg.node_names = comp_msg->node_name;
 			update_node_msg.node_state = NODE_STATE_DRAIN;
-			update_node_msg.reason = "step complete failure";
+			update_node_msg.reason = "batch job complete failure";
+			update_node_msg.weight = NO_VAL;
 			error_code = update_node(&update_node_msg);
 			if (comp_msg->job_rc != SLURM_SUCCESS)
 				job_requeue = true;
diff --git a/src/slurmd/slurmd/req.c b/src/slurmd/slurmd/req.c
index 1728bf73e..879b93ddb 100644
--- a/src/slurmd/slurmd/req.c
+++ b/src/slurmd/slurmd/req.c
@@ -773,8 +773,10 @@ _check_job_credential(launch_tasks_request_msg_t *req, uid_t uid,
 			error("step credential has no CPUs selected");
 		else {
 			i = conf->cpus / (i_last_bit - i_first_bit);
-			if (i > 1)
+			if (i > 1) {
+				info("scaling CPU count by factor of %d", i);
 				alloc_lps *= i;
+			}
 		}
 	} else
 		alloc_lps = 1;
diff --git a/src/slurmd/slurmd/slurmd.c b/src/slurmd/slurmd/slurmd.c
index 7b187a3e3..472f31aed 100644
--- a/src/slurmd/slurmd/slurmd.c
+++ b/src/slurmd/slurmd/slurmd.c
@@ -1,6 +1,6 @@
 /*****************************************************************************\
  *  src/slurmd/slurmd/slurmd.c - main slurm node server daemon
- *  $Id: slurmd.c 19424 2010-02-05 16:32:13Z jette $
+ *  $Id: slurmd.c 19759 2010-03-16 20:32:26Z jette $
  *****************************************************************************
  *  Copyright (C) 2002-2007 The Regents of the University of California.
  *  Copyright (C) 2008-2009 Lawrence Livermore National Security.
@@ -681,6 +681,8 @@ _read_config(void)
 {
 	char *path_pubkey = NULL;
 	slurm_ctl_conf_t *cf = NULL;
+	bool cr_flag = false, gang_flag = false;
+
 	slurm_conf_reinit(conf->conffile);
 	cf = slurm_conf_lock();
 
@@ -698,6 +700,11 @@ _read_config(void)
 	if (!conf->logfile)
 		conf->logfile = xstrdup(cf->slurmd_logfile);
 
+	if (!strcmp(cf->select_type, "select/cons_res"))
+		cr_flag = true;
+	if (cf->preempt_mode & PREEMPT_MODE_GANG)
+		gang_flag = true;
+
 	slurm_conf_unlock();
 	/* node_name may already be set from a command line parameter */
 	if (conf->node_name == NULL)
@@ -741,7 +748,8 @@ _read_config(void)
 		    &conf->block_map_size,
 		    &conf->block_map, &conf->block_map_inv);
 
-	if((cf->fast_schedule == 0) || (conf->actual_cpus < conf->conf_cpus)) {
+	if (((cf->fast_schedule == 0) && !cr_flag && !gang_flag) || 
+	    (conf->actual_cpus < conf->conf_cpus)) {
 		conf->cpus    = conf->actual_cpus;
 		conf->sockets = conf->actual_sockets;
 		conf->cores   = conf->actual_cores;
diff --git a/src/slurmd/slurmstepd/io.c b/src/slurmd/slurmstepd/io.c
index 47b718247..9df61a36d 100644
--- a/src/slurmd/slurmstepd/io.c
+++ b/src/slurmd/slurmstepd/io.c
@@ -1,6 +1,6 @@
 /*****************************************************************************\
  * src/slurmd/slurmstepd/io.c - Standard I/O handling routines for slurmstepd
- * $Id: io.c 19428 2010-02-05 18:27:09Z da $
+ * $Id: io.c 19754 2010-03-16 17:05:43Z jette $
  *****************************************************************************
  *  Copyright (C) 2002 The Regents of the University of California.
  *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
@@ -487,7 +487,11 @@ again:
 			return SLURM_SUCCESS;
 		}
 	}
-	debug5("Wrote %d bytes to socket", n);
+	if (n < client->out_remaining) {
+		error("Only wrote %d of %d bytes to socket", 
+		      n, client->out_remaining);
+	} else
+		debug5("Wrote %d bytes to socket", n);
 	client->out_remaining -= n;
 	if (client->out_remaining > 0)
 		return SLURM_SUCCESS;
@@ -1423,6 +1427,7 @@ io_close_local_fds(slurmd_job_t *job)
 			}
 		}
 	}
+	list_iterator_destroy(clients);
 }
 
 
diff --git a/src/slurmd/slurmstepd/mgr.c b/src/slurmd/slurmstepd/mgr.c
index 0da2d5e4a..20ea46bc9 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 19152 2009-12-10 22:29:52Z da $
+ *  $Id: mgr.c 19712 2010-03-09 16:45:32Z jette $
  *****************************************************************************
  *  Copyright (C) 2002-2007 The Regents of the University of California.
  *  Copyright (C) 2008-2009 Lawrence Livermore National Security.
@@ -1009,7 +1009,8 @@ _fork_all_tasks(slurmd_job_t *job)
 
 	xassert(job != NULL);
 
-	if (slurm_container_create(job) == SLURM_ERROR) {
+	if ((job->cont_id == 0) &&
+	    (slurm_container_create(job) != SLURM_SUCCESS)) {
 		error("slurm_container_create: %m");
 		return SLURM_ERROR;
 	}
@@ -1553,6 +1554,7 @@ _make_batch_script(batch_job_launch_msg_t *msg, char *path)
 	}
 
 	if (fputs(msg->script, fp) < 0) {
+		(void) fclose(fp);
 		error("fputs: %m");
 		goto error;
 	}
@@ -1573,6 +1575,7 @@ _make_batch_script(batch_job_launch_msg_t *msg, char *path)
 	return xstrdup(script);
 
   error:
+	(void) unlink(script);
 	return NULL;
 
 }
@@ -1967,7 +1970,8 @@ _run_script_as_user(const char *name, const char *path, slurmd_job_t *job,
 		return -1;
 	}
 
-	if (slurm_container_create(job) != SLURM_SUCCESS)
+	if ((job->cont_id == 0) &&
+	    (slurm_container_create(job) != SLURM_SUCCESS))
 		error("slurm_container_create: %m");
 
 	if ((cpid = fork()) < 0) {
@@ -2034,7 +2038,6 @@ _run_script_as_user(const char *name, const char *path, slurmd_job_t *job,
 	}
 	/* Insure that all child processes get killed, one last time */
 	killpg(cpid, SIGKILL);
-	slurm_container_signal(job->cont_id, SIGKILL);
 
 	return status;
 }
diff --git a/src/slurmd/slurmstepd/req.c b/src/slurmd/slurmstepd/req.c
index 07346807d..dd27fb255 100644
--- a/src/slurmd/slurmstepd/req.c
+++ b/src/slurmd/slurmstepd/req.c
@@ -280,9 +280,12 @@ _msg_socket_readable(eio_obj_t *obj)
 {
 	debug3("Called _msg_socket_readable");
 	if (obj->shutdown == true) {
+		/* All spawned tasks have been completed by this point */
 		if (obj->fd != -1) {
 			debug2("  false, shutdown");
 			_domain_socket_destroy(obj->fd);
+			/* slurmd considers the job step done now that
+			 * the domain name socket is destroyed */
 			obj->fd = -1;
 			_wait_for_connections();
 		} else {
diff --git a/src/slurmd/slurmstepd/slurmstepd.h b/src/slurmd/slurmstepd/slurmstepd.h
index 1aaf100bf..cca54f063 100644
--- a/src/slurmd/slurmstepd/slurmstepd.h
+++ b/src/slurmd/slurmstepd/slurmstepd.h
@@ -1,6 +1,6 @@
 /*****************************************************************************\
  * src/slurmd/slurmstepd/slurmstepd.h - slurmstepd general header file
- * $Id: slurmstepd.h 16867 2009-03-12 16:35:42Z jette $
+ * $Id: slurmstepd.h 19693 2010-03-06 00:36:35Z jette $
  *****************************************************************************
  *  Copyright (C) 2005 The Regents of the University of California.
  *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
@@ -42,7 +42,7 @@
 
 #include "src/common/bitstring.h"
 
-#define STEPD_MESSAGE_COMP_WAIT 15 /* seconds */
+#define STEPD_MESSAGE_COMP_WAIT 3 /* seconds */
 #define MAX_RETRIES    3
 
 extern int slurmstepd_blocked_signals[];
diff --git a/src/slurmd/slurmstepd/ulimits.c b/src/slurmd/slurmstepd/ulimits.c
index cb0305baf..1bf700f1a 100644
--- a/src/slurmd/slurmstepd/ulimits.c
+++ b/src/slurmd/slurmstepd/ulimits.c
@@ -1,6 +1,6 @@
 /*****************************************************************************\
  * src/slurmd/slurmstepd/ulimits.c - set user limits for job
- * $Id: ulimits.c 18027 2009-07-01 19:16:44Z da $
+ * $Id: ulimits.c 19673 2010-03-04 18:40:34Z jette $
  *****************************************************************************
  *  Copyright (C) 2002 The Regents of the University of California.
  *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
@@ -129,6 +129,7 @@ set_umask(slurmd_job_t *job)
 		return SLURM_ERROR;
 	}
 
+	unsetenvp(job->env, "SLURM_UMASK");
 	mask = strtol(val, (char **)NULL, 8);
 	umask(mask);
 	return SLURM_SUCCESS;
diff --git a/src/squeue/squeue.c b/src/squeue/squeue.c
index 223536fd1..654ca548c 100644
--- a/src/squeue/squeue.c
+++ b/src/squeue/squeue.c
@@ -138,7 +138,7 @@ _print_job ( void )
 	uint16_t show_flags = 0;
 	uint32_t job_id = 0;
 
-	if (params.all_flag)
+	if (params.all_flag || (params.job_list && list_count(params.job_list)))
 		show_flags |= SHOW_ALL;
 
 	/* We require detail data when CPUs are requested */
diff --git a/src/srun/opt.c b/src/srun/opt.c
index fc508004a..f730ac6fd 100644
--- a/src/srun/opt.c
+++ b/src/srun/opt.c
@@ -819,7 +819,7 @@ static void set_options(const int argc, char **argv)
 		{"wckey",            required_argument, 0, LONG_OPT_WCKEY},
 		{NULL,               0,                 0, 0}
 	};
-	char *opt_string = "+aA:bB:c:C:d:D:e:Eg:Hi:IjJ:kKlL:m:n:N:"
+	char *opt_string = "+aA:bB:c:C:d:D:e:Eg:hHi:IjJ:kKlL:m:n:N:"
 		"o:Op:P:qQr:Rst:T:uU:vVw:W:x:XZ";
 #ifdef HAVE_PTY_H
 	char *tmp_str;
@@ -1208,6 +1208,7 @@ static void set_options(const int argc, char **argv)
 			pmi_server_max_threads(opt.max_threads);
 			opt.msg_timeout     = 15;
 			break;
+		case 'h':
 		case LONG_OPT_HELP:
 			_help();
 			exit(0);
@@ -2325,10 +2326,10 @@ static void _help(void)
 "      --resv-ports            reserve communication ports\n"
 "\n"
 "Affinity/Multi-core options: (when the task/affinity plugin is enabled)\n"
-"  -B  --extra-node-info=S[:C[:T]]            Expands to:\n"
-"       --sockets-per-node=S   number of sockets per node to allocate\n"
-"       --cores-per-socket=C   number of cores per socket to allocate\n"
-"       --threads-per-core=T   number of threads per core to allocate\n"
+"  -B, --extra-node-info=S[:C[:T]]           Expands to:\n"
+"      --sockets-per-node=S    number of sockets per node to allocate\n"
+"      --cores-per-socket=C    number of cores per socket to allocate\n"
+"      --threads-per-core=T    number of threads per core to allocate\n"
 "                              each field can be 'min' or wildcard '*'\n"
 "                              total cpus requested = (N x S x C x T)\n"
 "\n"
@@ -2380,7 +2381,7 @@ static void _help(void)
 "\n"
 "Help options:\n"
 "  -h, --help                  show this help message\n"
-"  -u, --usage                 display brief usage message\n"
+"      --usage                 display brief usage message\n"
 "\n"
 "Other options:\n"
 "  -V, --version               output version information and exit\n"
diff --git a/src/srun/srun.c b/src/srun/srun.c
index b073d691c..c2f826dd3 100644
--- a/src/srun/srun.c
+++ b/src/srun/srun.c
@@ -324,6 +324,7 @@ int srun(int ac, char **av)
 		job = job_create_allocation(resp);
 
 		opt.exclusive = false;	/* not applicable for this step */
+		opt.time_limit = NO_VAL;/* not applicable for step, only job */
 		if (!opt.job_name_set_cmd && opt.job_name_set_env) {
 			/* use SLURM_JOB_NAME env var */
 			opt.job_name_set_cmd = true;
@@ -1273,7 +1274,7 @@ _task_finish(task_exit_msg_t *msg)
 	xfree(hosts);
 
 	_update_task_exit_state(msg->num_tasks, msg->task_id_list,
-			!normal_exit);
+				!normal_exit);
 
 	if (task_state_first_abnormal_exit(task_state) && _kill_on_bad_exit())
   		_terminate_job_step(job->step_ctx);
diff --git a/src/sview/job_info.c b/src/sview/job_info.c
index 9ebb15c3b..e5ac0b43a 100644
--- a/src/sview/job_info.c
+++ b/src/sview/job_info.c
@@ -619,9 +619,8 @@ static const char *_set_job_msg(job_desc_msg_t *job_msg, const char *new_text,
 	char* geometry_tmp = xstrdup(new_text);
 	char* original_ptr = geometry_tmp;
 #endif
-	/* need to clear errno here (just in case) */
-	errno = 0;
-
+	/* need to clear global_edit_error here (just in case) */
+	global_edit_error = 0;
 	if(!job_msg)
 		return NULL;
 
@@ -932,10 +931,13 @@ static const char *_set_job_msg(job_desc_msg_t *job_msg, const char *new_text,
 #endif
 	case SORTID_TIME_ELIGIBLE:
 	case SORTID_TIME_START:
+		type = "start time";
 		job_msg->begin_time = parse_time((char *)new_text, 0);
+		if(!job_msg->begin_time)
+			goto return_error;
+
 		if(job_msg->begin_time < time(NULL))
 			job_msg->begin_time = time(NULL);
-		type = "start time";
 		break;
 	default:
 		type = "unknown";
@@ -954,7 +956,7 @@ return_error:
 #ifdef HAVE_BG
 	xfree(original_ptr);
 #endif
-	errno = 1;
+	global_edit_error = 1;
 	return type;
 }
 
@@ -992,11 +994,21 @@ static gboolean _admin_focus_out_job(GtkEntry *entry,
 				     job_desc_msg_t *job_msg)
 {
 	if(global_entry_changed) {
+		const char *col_name = NULL;
 		int type = gtk_entry_get_max_length(entry);
 		const char *name = gtk_entry_get_text(entry);
 		type -= DEFAULT_ENTRY_LENGTH;
 
-		_set_job_msg(job_msg, name, type);
+		col_name = _set_job_msg(job_msg, name, type);
+		if(global_edit_error) {
+			if(global_edit_error_msg)
+				g_free(global_edit_error_msg);
+			global_edit_error_msg = g_strdup_printf(
+				"Job %d %s can't be set to %s",
+				job_msg->job_id,
+				col_name,
+				name);
+		}
 		global_entry_changed = 0;
 	}
 	return false;
@@ -1508,7 +1520,7 @@ static void _layout_job_record(GtkTreeView *treeview,
 				   tmp_char);
 	if ((job_ptr->time_limit == INFINITE) &&
 	    (job_ptr->end_time > time(NULL)))
-		sprintf(tmp_char, "NONE");
+		sprintf(tmp_char, "Unknown");
 	else
 		slurm_make_time_str((time_t *)&job_ptr->end_time, tmp_char,
 				    sizeof(tmp_char));
@@ -1625,7 +1637,7 @@ static void _update_job_record(sview_job_info_t *sview_job_info_ptr,
 	gtk_tree_store_set(treestore, iter, SORTID_TIME_START, tmp_char, -1);
 	if ((job_ptr->time_limit == INFINITE) &&
 	    (job_ptr->end_time > time(NULL)))
-		sprintf(tmp_char, "NONE");
+		sprintf(tmp_char, "Unknown");
 	else
 		slurm_make_time_str((time_t *)&job_ptr->end_time, tmp_char,
 				    sizeof(tmp_char));
@@ -2744,7 +2756,7 @@ extern void admin_edit_job(GtkCellRendererText *cell,
 	}
 
 	type = _set_job_msg(job_msg, new_text, column);
-	if(errno)
+	if(global_edit_error)
 		goto print_error;
 
 	if(got_edit_signal) {
@@ -3534,7 +3546,9 @@ extern void admin_job(GtkTreeModel *model, GtkTreeIter *iter, char *type)
 			if(got_edit_signal)
 				goto end_it;
 
-			if(!global_send_update_msg) {
+			if(global_edit_error)
+				tmp_char_ptr = global_edit_error_msg;
+			else if(!global_send_update_msg) {
 				tmp_char_ptr = g_strdup_printf(
 					"No change detected.");
 			} else if(slurm_update_job(job_msg) == SLURM_SUCCESS) {
diff --git a/src/sview/part_info.c b/src/sview/part_info.c
index 9deab6e41..f7298aeed 100644
--- a/src/sview/part_info.c
+++ b/src/sview/part_info.c
@@ -360,7 +360,7 @@ static const char *_set_part_msg(update_part_msg_t *part_msg,
 	char *type = "";
 	int temp_int = 0;
 
-	errno = 0;
+	global_edit_error = 0;
 
 	if(!part_msg)
 		return NULL;
@@ -389,7 +389,7 @@ static const char *_set_part_msg(update_part_msg_t *part_msg,
 			temp_int = time_str2mins((char *)new_text);
 
 		type = "timelimit";
-		if(temp_int <= 0 && temp_int != INFINITE)
+		if((temp_int <= 0) && (temp_int != INFINITE))
 			goto return_error;
 		part_msg->max_time = (uint32_t)temp_int;
 		break;
@@ -478,7 +478,7 @@ static const char *_set_part_msg(update_part_msg_t *part_msg,
 	return type;
 
 return_error:
-	errno = 1;
+	global_edit_error = 1;
 	return type;
 
 }
@@ -517,10 +517,21 @@ static gboolean _admin_focus_out_part(GtkEntry *entry,
 				      update_part_msg_t *part_msg)
 {
 	if(global_entry_changed) {
+		const char *col_name = NULL;
 		int type = gtk_entry_get_max_length(entry);
 		const char *name = gtk_entry_get_text(entry);
 		type -= DEFAULT_ENTRY_LENGTH;
-		_set_part_msg(part_msg, name, type);
+		col_name = _set_part_msg(part_msg, name, type);
+		if(global_edit_error) {
+			if(global_edit_error_msg)
+				g_free(global_edit_error_msg);
+			global_edit_error_msg = g_strdup_printf(
+				"Partition %s %s can't be set to %s",
+				part_msg->name,
+				col_name,
+				name);
+		}
+
 		global_entry_changed = 0;
 	}
 	return false;
@@ -1763,7 +1774,7 @@ extern void admin_edit_part(GtkCellRendererText *cell,
 	}
 
 	type = _set_part_msg(part_msg, new_text, column);
-	if(errno)
+	if(global_edit_error)
 		goto print_error;
 	if(got_edit_signal) {
 		temp = got_edit_signal;
@@ -2402,7 +2413,9 @@ extern void admin_part(GtkTreeModel *model, GtkTreeIter *iter, char *type)
 	response = gtk_dialog_run (GTK_DIALOG(popup));
 
 	if (response == GTK_RESPONSE_OK) {
-		if(!global_send_update_msg) {
+		if(global_edit_error)
+			temp = global_edit_error_msg;
+		else if(!global_send_update_msg) {
 			temp = g_strdup_printf("No change detected.");
 		} else if(slurm_update_partition(part_msg) == SLURM_SUCCESS) {
 			temp = g_strdup_printf(
diff --git a/src/sview/resv_info.c b/src/sview/resv_info.c
index 7221233b5..913f7a995 100644
--- a/src/sview/resv_info.c
+++ b/src/sview/resv_info.c
@@ -232,8 +232,8 @@ static const char *_set_resv_msg(resv_desc_msg_t *resv_msg,
 	int temp_int = 0;
 	uint32_t f;
 
-	/* need to clear errno here (just in case) */
-	errno = 0;
+	/* need to clear global_edit_error here (just in case) */
+	global_edit_error = 0;
 
 	if(!resv_msg)
 		return NULL;
@@ -311,7 +311,7 @@ static const char *_set_resv_msg(resv_desc_msg_t *resv_msg,
 	return type;
 
 return_error:
-	errno = 1;
+	global_edit_error = 1;
 	return type;
 }
 
@@ -360,10 +360,20 @@ static gboolean _admin_focus_out_resv(GtkEntry *entry,
 				      resv_desc_msg_t *resv_msg)
 {
 	if(global_entry_changed) {
+		const char *col_name = NULL;
 		int type = gtk_entry_get_max_length(entry);
 		const char *name = gtk_entry_get_text(entry);
 		type -= DEFAULT_ENTRY_LENGTH;
-		_set_resv_msg(resv_msg, name, type);
+		col_name = _set_resv_msg(resv_msg, name, type);
+		if(global_edit_error) {
+			if(global_edit_error_msg)
+				g_free(global_edit_error_msg);
+			global_edit_error_msg = g_strdup_printf(
+				"Reservation %s %s can't be set to %s",
+				resv_msg->name,
+				col_name,
+				name);
+		}
 		global_entry_changed = 0;
 	}
 	return false;
@@ -868,7 +878,7 @@ extern void admin_edit_resv(GtkCellRendererText *cell,
 	g_free(temp);
 
 	type = _set_resv_msg(resv_msg, new_text, column);
-	if(errno)
+	if(global_edit_error)
 		goto print_error;
 
 	if(got_edit_signal) {
diff --git a/src/sview/sview.c b/src/sview/sview.c
index 7e20437f0..997667d04 100644
--- a/src/sview/sview.c
+++ b/src/sview/sview.c
@@ -62,6 +62,8 @@ int global_horizontal = 10;
 int global_vertical = 10;
 bool global_entry_changed = 0;
 bool global_send_update_msg = 0;
+bool global_edit_error = 0;
+gchar *global_edit_error_msg = NULL;
 bool admin_mode = FALSE;
 GtkWidget *main_notebook = NULL;
 GtkWidget *main_statusbar = NULL;
diff --git a/src/sview/sview.h b/src/sview/sview.h
index dee8e2d2f..eb0b34208 100644
--- a/src/sview/sview.h
+++ b/src/sview/sview.h
@@ -279,6 +279,8 @@ extern int global_horizontal;
 extern int global_vertical;
 extern bool global_entry_changed;
 extern bool global_send_update_msg;
+extern bool global_edit_error;
+extern gchar *global_edit_error_msg;
 extern bool admin_mode;
 extern GtkWidget *main_statusbar;
 extern GtkWidget *main_window;
diff --git a/testsuite/expect/Makefile.am b/testsuite/expect/Makefile.am
index 5e6d55a35..044904a01 100644
--- a/testsuite/expect/Makefile.am
+++ b/testsuite/expect/Makefile.am
@@ -324,6 +324,7 @@ EXTRA_DIST = \
 	test21.24			\
 	test21.25			\
 	test21.26			\
+	test21.27			\
 	test22.1			\
 	test22.2			\
 	test23.1			\
diff --git a/testsuite/expect/test1.27 b/testsuite/expect/test1.27
index 343ef0991..e7003cecd 100755
--- a/testsuite/expect/test1.27
+++ b/testsuite/expect/test1.27
@@ -60,7 +60,6 @@ array set good_vars {
     SLURM_TASK_PID 1
     SLURM_TOPOLOGY_ADDR 0
     SLURM_TOPOLOGY_ADDR_PATTERN 0
-    SLURM_UMASK 0
 }
 
 #
diff --git a/testsuite/expect/test1.84 b/testsuite/expect/test1.84
index 7cd0011c3..22ac8ae4e 100755
--- a/testsuite/expect/test1.84
+++ b/testsuite/expect/test1.84
@@ -97,10 +97,12 @@ expect {
 		wait
 	}
 }
-exec $bin_rm -f $file_in
 # On Blue Gene/L each node has 1024 CPUs, more than slurmd can launch
 if {$fat_nodes == 1} {
-	exit 0
+	if {$exit_code == 0} {
+		exec $bin_rm -f $file_in
+	}
+	exit $exit_code
 }
 
 #
@@ -157,6 +159,7 @@ if {$task_cnt != [expr $cpu_cnt / 2]} {
 }
 
 if {$exit_code == 0} {
+	exec $bin_rm -f $file_in
 	send_user "\nSUCCESS\n"
 }
 exit $exit_code
diff --git a/testsuite/expect/test17.13 b/testsuite/expect/test17.13
index 3184a7851..89478490b 100755
--- a/testsuite/expect/test17.13
+++ b/testsuite/expect/test17.13
@@ -58,7 +58,6 @@ array set good_vars {
     SLURM_PROCID 0
     SLURM_TASKS_PER_NODE 1
     SLURM_TASK_PID 1
-    SLURM_UMASK 0
 }
 
 #
diff --git a/testsuite/expect/test21.27 b/testsuite/expect/test21.27
new file mode 100755
index 000000000..ee6dafb9c
--- /dev/null
+++ b/testsuite/expect/test21.27
@@ -0,0 +1,158 @@
+#!/usr/bin/expect
+############################################################################
+# Purpose: Test of SLURM functionality
+#          sacctmgr show problems
+#
+#
+# Output:  "TEST: #.#" followed by "SUCCESS" if test was successful, OR
+#          "FAILURE: ..." otherwise with an explanation of the failure, OR
+#          anything else indicates a failure mode that must be investigated.
+############################################################################
+# Copyright (C) 2010 Lawrence Livermore National Security.
+# Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
+# Written by Joseph Donaghy <donaghy1@llnl.gov>
+# CODE-OCEC-09-009. All rights reserved.
+#
+# This file is part of SLURM, a resource management program.
+# For details, see <https://computing.llnl.gov/linux/slurm/>.
+# Please also read the included file: DISCLAIMER.
+#
+# SLURM is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# SLURM is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along
+# with SLURM; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA.
+############################################################################
+source ./globals
+
+set test_id     "21.27"
+
+set sho		show
+set add		create
+set del		delete
+set pro		problem
+set par		parent
+set clu		Cluster
+set cl1		pc1
+set cl2		pc2
+set acc		Account
+set ac1		pa1
+set ac2		pa2
+set ac3		pa3
+set usr		user
+set us1		usr1
+set us2		usr2
+set us3		gdm
+
+set access_err  0
+set timeout     120
+#set user_name   "id -u -n"
+
+print_header $test_id
+
+#
+# Check accounting config and bail if not found.
+#
+if { [test_account_storage] == 0 } {
+	send_user "\nWARNING: This test can't be run without a usable AccountStorageType\n"
+	exit 0
+}
+
+if { [string compare [check_accounting_admin_level] "Administrator"] } {
+	send_user "\nWARNING: This test can't be run without being an Accounting administrator.\nUse sacctmgr mod user \$USER_NAME admin=admin.\n"
+	exit 0
+}
+
+#
+# Delete 
+#
+exec $sacctmgr -i $del $usr $us1,$us2,$us3
+exec $sacctmgr -i $del $acc $ac1,$ac2,$ac3
+exec $sacctmgr -i $del $clu $cl1,$cl2
+
+#
+# Build test associations
+#
+exec $sacctmgr -i $add $clu $cl1
+exec $sacctmgr -i $add $acc $ac1 $clu=$cl1
+exec $sacctmgr -i $add $acc $ac2 $par=$ac1 $clu=$cl1
+exec $sacctmgr -i $add $usr $us1 $acc=$ac1 $clu=$cl1
+exec $sacctmgr -i $add $usr $us2 $acc=$ac1 $clu=$cl1
+exec $sacctmgr -i $add $usr $us3 $acc=$ac2 $clu=$cl1
+exec $sacctmgr -i $del $clu $cl1
+exec $sacctmgr -i $add $clu $cl2
+exec $sacctmgr -i $add $acc $ac3 $clu=$cl2
+exec $sacctmgr $sho $pro
+
+#
+# Test for problems
+#
+	set exit_code 0
+	set matches 0
+	set nothing 0
+
+	set my_pid [spawn $sacctmgr -p $sho $pro]
+	expect {
+		-re "$ac1..Account has no Associations" {
+			incr matches
+			exp_continue
+		}
+		-re "$ac2..Account has no Associations" {
+			incr matches
+			exp_continue
+		}
+		-re "$cl2.$ac3..Account has no users" {
+			incr matches
+			exp_continue
+		}
+		-re "$us3.User has no Associations" {
+			incr matches
+			exp_continue
+		}
+		-re "$us1.User does not have a uid" {
+			incr matches
+			exp_continue
+		}
+		-re "$us2.User does not have a uid" {
+			incr matches
+			exp_continue
+		}
+
+		timeout {
+			send_user "\nFAILURE: sacctmgr delete not responding\n"
+			slow_kill $my_pid
+			incr exit_code 1
+		}
+		eof {
+			wait
+		}
+	}
+
+	if {$matches != 6} {
+		send_user "\nFAILURE: sacctmgr did not find enough problems\n"
+		incr exit_code 1
+	}
+
+
+#
+# Delete 
+#
+exec $sacctmgr -i $del $usr $us1,$us2,$us3
+exec $sacctmgr -i $del $acc $ac1,$ac2,$ac3
+exec $sacctmgr -i $del $clu $cl1,$cl2
+
+if {$exit_code == 0} {
+	send_user "\nSUCCESS\n"
+} else {
+	send_user "\nFAILURE\n"
+}
+exit $exit_code
+
-- 
GitLab