diff --git a/NEWS b/NEWS
index ce0ca5c4a44e72309e265567fad69b5ce7f32c01..ec1a12c2a62cebdb5f4b15519879be4e64cc6ad6 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,8 @@ documents those changes that are of interest to users and admins.
 
 * Changes in SLURM 0.7.0-pre3
 =============================
+ -- Restructure node states: DRAINING and DRAINED states are replaced 
+    with a DRAIN flag. COMPLETING state is changed to a COMPLETING flag. 
 
 * Changes in SLURM 0.7.0-pre2
 =============================
diff --git a/doc/man/man1/scontrol.1 b/doc/man/man1/scontrol.1
index d712853a23db0f3a8ccc210f81ffc2a601b2507f..d5bd0dbf93cf0bccaf5d6594c4a23dee9aa3498d 100644
--- a/doc/man/man1/scontrol.1
+++ b/doc/man/man1/scontrol.1
@@ -272,10 +272,7 @@ Use quotes to enclose a reason having more than one word.
 .TP
 \fIState\fP=<state>
 Identify the state to be assigned to the node. Possible values are  "NoResp", 
-"RESUME", "DOWN", "IDLE", "DRAIN", "DRAINED", "DRAINING", and "ALLOCATED". 
-To drain a node specify "DRAIN", "DRAINED", or "DRAINING".
-SLURM will automatically set it to the appropriate value of either 
-"DRAINING" or "DRAINED" depending if the node is allocated or not.
+"DRAIN" "RESUME", "DOWN", "IDLE", "ALLOC", and "ALLOCATED". 
 "RESUME is not an actual node state, but will return a DRAINED, DRAINING, 
 or DOWN node to service, either IDLE or ALLOCATED state as appropriate. 
 The "NoResp" state will only set the "NoResp" flag for a node without
diff --git a/doc/man/man1/sinfo.1 b/doc/man/man1/sinfo.1
index a152dfd1dddb518f9022a75895d7a8075bb4f010..9ef3ed14e6ea6863d556a230d5dee12c3b6bea20 100644
--- a/doc/man/man1/sinfo.1
+++ b/doc/man/man1/sinfo.1
@@ -1,4 +1,4 @@
-.TH SINFO "1" "July 2005" "sinfo 0.5" "Slurm components"
+.TH SINFO "1" "October 2005" "sinfo 0.7" "Slurm components"
 
 .SH "NAME"
 sinfo \- view information about SLURM nodes and partitions.
@@ -189,23 +189,23 @@ Specification of the order in which records should be reported.
 This uses the same field specifciation as the <output_format>.
 Multiple sorts may be performed by listing multiple sort fields
 separated by commas.  The field specifications may be preceeded
-by "+" or "-" for assending (default) and desending order
+by "+" or "\-" for assending (default) and desending order
 respectively.  The partition field specification, "P", may be
 preceeded by a "#" to report partitions in the same order that
 they appear in SLURM's  configuration file, \fBslurm.conf\fR.
-For example, a sort value of "+P,-m" requests that records
+For example, a sort value of "+P,\-m" requests that records
 be printed in order of increasing partition name and within a
 partition by decreasing memory size.  The default value of sort
-is "#P,-t" (partitions ordered as configured then decreasing
-node state).  If the \fB--Node\fB option is selected, the
+is "#P,\-t" (partitions ordered as configured then decreasing
+node state).  If the \fB\-\-Node\fB option is selected, the
 default sort value is "N" (increasing node name).
 .TP
 \fB\-t <states>\fR , \fB\-\-states=<states>\fR
 List nodes only having the given state(s).  Multiple states
 may be comma separated and the comparison is case insensitive.
 Possible values include (case insensitive): ALLOC, ALLOCATED,
-COMP, COMPLETING, DOWN, DRAIN, DRAINED, DRAINING, IDLE, UNK,
-and UNKNOWN.  By default nodes in the specified state are
+COMP, COMPLETING, DOWN, DRAIN, DRAINED, DRNG, DRAINING, IDLE, 
+UNK, and UNKNOWN.  By default nodes in the specified state are
 reported whether they are responding or not.  The \fB\-\-dead\fR 
 and \fB\-\-responding\fR options may be used to filtering nodes by 
 the responding flag.
@@ -297,9 +297,13 @@ be placed in the \fBDOWN\fR state (except in the case of
 ALLOCATED
 The node has been allocated to one or more jobs.
 .TP
+ALLOCATED+
+The node is allocated to one or more active jobs plus
+one or more jobs are in the process of COMPLETING.
+.TP
 COMPLETING
-One or more jobs have been allocated this node and are in
-the process of COMPLETING. This node state will be removed when
+All jobs associated with this node are in the process of 
+COMPLETING.  This node state will be removed when
 all of the job's processes have terminated and the SLURM
 epilog program (if any) has terminated. See the \fBEpilog\fR
 parameter description in the \fBslurm.conf\fR man page for
diff --git a/doc/man/man1/smap.1 b/doc/man/man1/smap.1
index a2b54288f802db34f591b8c8d270c0a854851fdb..fc5d72ad21f88073902489b1cf264c4e08d7a2ec 100644
--- a/doc/man/man1/smap.1
+++ b/doc/man/man1/smap.1
@@ -1,4 +1,4 @@
-.TH SMAP "1" "September 2005" "smap 0.6" "Slurm components"
+.TH SMAP "1" "October 2005" "smap 0.7" "Slurm components"
 
 .SH "NAME"
 smap \- graphically view information about SLURM jobs, partitions, and set 
@@ -31,12 +31,12 @@ configure mode.  Typing 'exit' will end the configuration mode and exit smap.
 Note that unallocated nodes are indicated by a '.' and DOWN or DRAINED 
 nodes by a '#'.
 \fB\-R <RACK_MIDPLANE_ID/XYZ>\fR, \fB\-\-resolve=<RACK_MIDPLANE_ID/XYZ>\fR
-Returns the XYZ coords for a Rack/Midplane id or vice-versa.
+Returns the XYZ coords for a Rack/Midplane id or vice\-versa.
 
-To get the XYZ coord for a Rack/Midplane id input -R R101 where 10 is the rack
+To get the XYZ coord for a Rack/Midplane id input \-R R101 where 10 is the rack
 and 1 is the midplane.  
 
-To get the Rack/Midplane id from a XYZ coord input -R 101 where X=1 Y=1 Z=1 with
+To get the Rack/Midplane id from a XYZ coord input \-R 101 where X=1 Y=1 Z=1 with
 no leading 'R'.  
 .RS
 .TP 15
@@ -168,7 +168,7 @@ a a a a b b c c
  a a a a . . e e              Y
 a a a a . . e e               |
                               |
-   a a a a . . d d            0----X
+   a a a a . . d d            0\-\-\-\-X
   a a a a . . d d            /
  a a a a . . . .            /
 a a a a . . . #            Z
@@ -200,12 +200,12 @@ Mode Type: \fBCOPROCESS\fR or \fBVIRTUAL\fR.
 \fBINPUT COMMANDS\fR
 .TP
 .I resolve <RACK_MIDPLANE_ID/XYZ>\fR
-Returns the XYZ coords for a Rack/Midplane id or vice-versa.
+Returns the XYZ coords for a Rack/Midplane id or vice\-versa.
 
-To get the XYZ coord for a Rack/Midplane id input -R R101 where 10 is the rack
+To get the XYZ coord for a Rack/Midplane id input \-R R101 where 10 is the rack
 and 1 is the midplane.  
 
-To get the Rack/Midplane id from a XYZ coord input -R 101 where X=1 Y=1 Z=1 with
+To get the Rack/Midplane id from a XYZ coord input \-R 101 where X=1 Y=1 Z=1 with
 no leading 'R'.  
 
 .RS
@@ -226,7 +226,7 @@ The default value is TORUS.
 .I \fBSmall\fR
 Equivalent to "Connection=Small".
 If a small connection is specified the midplanes chosen will create 4
-smaller partitions within the midplane each consisting of 128 c-nodes.
+smaller partitions within the midplane each consisting of 128 c\-nodes.
 .TP
 .I \fBMesh\fR
 Equivalent to "Connection=Mesh".
@@ -268,7 +268,7 @@ Delete the specified block or (default) the last partition created.
 .TP
 .I \fBdown <node_range>\fR
 Down a specific node or range of nodes. 
-i.e. 000, 000-111 [000x111]
+i.e. 000, 000\-111 [000x111]
 
 .TP
 .I \fBsave <file_name>\fR
@@ -285,16 +285,20 @@ Clear all partitions created.
 Node state codes are shortened as required for the field size.
 If the node state code is followed by "*", this indicates the
 node is presently not responding and will not be allocated
-any new work.  If the node remains non-responsive, it will
+any new work.  If the node remains non\-responsive, it will
 be placed in the \fBDOWN\fR state (except in the case of
 \fBDRAINED\fR, \fBDRAINING\fR, or \fBCOMPLETING\fR nodes).
 .TP 12
 ALLOCATED
 The node has been allocated to one or more jobs.
 .TP
+ALLOCATED+
+The node is allocated to one or more active jobs plus
+one or more jobs are in the process of COMPLETING.
+.TP
 COMPLETING
-One or more jobs have been allocated this node and are in
-the process of COMPLETING. This node state will be removed when
+All jobs associated with this node are in the process of 
+COMPLETING.  This node state will be removed when
 all of the job's processes have terminated and the SLURM
 epilog program (if any) has terminated. See the \fBEpilog\fR
 parameter description in the \fBslurm.conf\fR man page for
@@ -347,7 +351,7 @@ CG  COMPLETING
 Job is in the process of completing. Some processes on some nodes may still be active.
 .TP
 F   FAILED
-Job terminated with non-zero exit code or other failure condition.
+Job terminated with non\-zero exit code or other failure condition.
 .TP
 NF  NODE_FAIL
 Job terminated due to failure of one or more allocated nodes.
@@ -371,7 +375,7 @@ The location of the SLURM configuration file.
 .SH "COPYING"
 Copyright (C) 2004 The Regents of the University of California.
 Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
-UCRL-CODE-2002-040.
+UCRL\-CODE\-2002\-040.
 .LP
 This file is part of SLURM, a resource management program.
 For details, see <http://www.llnl.gov/linux/slurm/>.
diff --git a/doc/man/man3/slurm_reconfigure.3 b/doc/man/man3/slurm_reconfigure.3
index 773227dd42afe869193bebde0e8cccf997787d1f..7d1a0fa0824e15449414a488ed030f94b2526206 100644
--- a/doc/man/man3/slurm_reconfigure.3
+++ b/doc/man/man3/slurm_reconfigure.3
@@ -1,4 +1,4 @@
-.TH "Slurm API" "3" "July 2004" "Morris Jette" "Slurm administrative calls"
+.TH "Slurm API" "3" "October 2005" "Morris Jette" "Slurm administrative calls"
 .SH "NAME"
 slurm_delete_partition, slurm_init_part_desc_msg,
 slurm_reconfigure, slurm_shutdown, slurm_update_job, 
@@ -101,9 +101,7 @@ its hardware configuration may not be changed by this function. If the hardware
 configuration of a node changes, update the Slurm configuration file and execute 
 the \fBslurm_reconfigure\fR function. This function may only be successfully 
 executed by user root. If used by some autonomous program, the state value 
-most likely to be used is \fBNODE_STATE_DRAINING\fR. SLURM will automatically 
-determine if some program is active on the node and set its state to either 
-\fBNODE_STATE_DRAINING\fR or \fBNODE_STATE_DRAINED\fR as appropriate.
+most likely to be used is \fBNODE_STATE_DRAIN\fR. 
 The node state flag \fBNODE_STATE_NO_RESPOND\fR may be specified without 
 changing the underlying node state. Note that the node's 
 \fBNODE_STATE_NO_RESPOND\fR flag will be cleared as soon as the slurmd 
diff --git a/slurm/slurm.h.in b/slurm/slurm.h.in
index 993edf1f4fb0b393b4cb9b90df3084eedef1da27..fcbefd2db869acff5999e2c6c4696177ea5c2e5d 100644
--- a/slurm/slurm.h.in
+++ b/slurm/slurm.h.in
@@ -203,23 +203,27 @@ enum task_dist_states {
 	SLURM_DIST_BLOCK	/* distribute tasks filling node by node */
 };
 
-/* last entry must be STATE_END, keep in sync with node_state_string    */
-/* 	if a node ceases to respond, its last state is ORed with 	*/
-/* 	NODE_STATE_NO_RESPOND	*/
+/* The last entry in node_states must be STATE_END, keep in sync with 
+ * node_state_string. values may be ORed with NODE_STATE_FLAGS below. 
+ * Node states typically alternate between NODE_STATE_IDLE and 
+ * NODE_STATE_ALLOCATED. The NODE_STATE_COMPLETING flag will be set 
+ * when jobs are in the process of terminating. */
 enum node_states {
-	NODE_STATE_DOWN,	/* node is not responding */
 	NODE_STATE_UNKNOWN,	/* node's initial state, unknown */
+	NODE_STATE_DOWN,	/* node is not responding */
 	NODE_STATE_IDLE,	/* node idle and available for use */
 	NODE_STATE_ALLOCATED,	/* node has been allocated to a job */
-	NODE_STATE_DRAINED,	/* node idle and not to be allocated work */
-	NODE_STATE_DRAINING,	/* node in use, but not to be allocated work */
-	NODE_STATE_COMPLETING,	/* node is completing allocated job */
 	NODE_STATE_END		/* last entry in table */
 };
-#define NODE_RESUME 0x400	/* Restore a DRAINED, DRAINING, or DOWN
-				 * node to service (e.g. IDLE or ALLOCATED).
-				 * Used for slurm_update_node request */
-#define NODE_STATE_NO_RESPOND (0x8000)
+#define NODE_STATE_BASE       0x00ff
+#define NODE_STATE_FLAGS      0xff00
+#define NODE_RESUME           0x0100	/* Restore a DRAINED, DRAINING, or 
+					 * DOWN node to service (e.g. IDLE or 
+					 * ALLOCATED). Used in 
+					 * slurm_update_node() request */
+#define NODE_STATE_DRAIN      0x0200	/* node not be be allocated work */
+#define NODE_STATE_COMPLETING 0x0400	/* node is completing allocated job */
+#define NODE_STATE_NO_RESPOND 0x0800	/* node is not responding */
 
 /* used to define the size of the credential.signature size
  * used to define the key size of the io_stream_header_t
diff --git a/src/api/node_info.c b/src/api/node_info.c
index cee6d3b7e46bde7a7b667a4ef61892fca2208336..3a59be12eca169254d56dfb50536481aa94c3ee8 100644
--- a/src/api/node_info.c
+++ b/src/api/node_info.c
@@ -78,10 +78,22 @@ slurm_print_node_info_msg ( FILE * out, node_info_msg_t * node_info_msg_ptr,
 void
 slurm_print_node_table ( FILE * out, node_info_t * node_ptr, int one_liner )
 {
+	uint16_t my_state = node_ptr->node_state;
+	char *comp_str = "", *drain_str = "";
+
+	if (my_state & NODE_STATE_COMPLETING) {
+		my_state &= (~NODE_STATE_COMPLETING);
+		comp_str = "+COMPLETING";
+	}
+	if (my_state & NODE_STATE_DRAIN) {
+		my_state &= (~NODE_STATE_DRAIN);
+		drain_str = "+DRAIN";
+	}
+
 	/****** Line 1 ******/
-	fprintf ( out, "NodeName=%s State=%s CPUs=%u ", 
-		node_ptr->name, node_state_string(node_ptr->node_state), 
-		node_ptr->cpus);
+	fprintf ( out, "NodeName=%s State=%s%s%s CPUs=%u ", 
+		node_ptr->name, node_state_string(my_state),
+		comp_str, drain_str, node_ptr->cpus);
 	fprintf ( out, "RealMemory=%u TmpDisk=%u", 
 		node_ptr->real_memory, node_ptr->tmp_disk);
 	if (one_liner)
diff --git a/src/common/slurm_protocol_defs.c b/src/common/slurm_protocol_defs.c
index 07e6052121e92404e26e057ae5a4af6e84699a18..cdb2d1c5d89341ca14ed15ee86d7a6880b655366 100644
--- a/src/common/slurm_protocol_defs.c
+++ b/src/common/slurm_protocol_defs.c
@@ -530,90 +530,100 @@ char *job_state_string_compact(enum job_states inx)
 
 char *node_state_string(enum node_states inx)
 {
-	bool no_resp_flag;
+	bool drain_flag   = (inx & NODE_STATE_DRAIN);
+	bool comp_flag    = (inx & NODE_STATE_NO_RESPOND);
+	bool no_resp_flag = (inx & NODE_STATE_NO_RESPOND);
 
-	if (inx & NODE_STATE_NO_RESPOND) {
-		no_resp_flag = true;
-		inx = (uint16_t) (inx & (~NODE_STATE_NO_RESPOND));
-	} else
-		no_resp_flag = false;
+	inx = (uint16_t) (inx & NODE_STATE_BASE);
 
-	switch (inx) {
-		case NODE_STATE_DOWN:
-			if (no_resp_flag)
-				return "DOWN*";
-			return "DOWN";
-		case NODE_STATE_UNKNOWN:
-			if (no_resp_flag)
-				return "UNKNOWN*";
-			return "UNKNOWN";
-		case NODE_STATE_IDLE:
-			if (no_resp_flag)
-				return "IDLE*";
-			return "IDLE";
-		case NODE_STATE_ALLOCATED:
-			if (no_resp_flag)
-				return "ALLOCATED*";
-			return "ALLOCATED";
-		case NODE_STATE_DRAINED:
-			if (no_resp_flag)
-				return "DRAINED*";
-			return "DRAINED";
-		case NODE_STATE_DRAINING:
+	if (inx == NODE_STATE_DOWN) {
+		if (no_resp_flag)
+			return "DOWN*";
+		return "DOWN";
+	}
+	if (drain_flag) {
+		if (comp_flag || (inx == NODE_STATE_ALLOCATED)) {
 			if (no_resp_flag)
 				return "DRAINING*";
 			return "DRAINING";
-		case NODE_STATE_COMPLETING:
+		} else {
 			if (no_resp_flag)
-				return "COMPLETING*";
-			return "COMPLETING";
-		default:
-			return "?";
+				return "DRAINED*";
+			return "DRAINED";
+		}
+	}
+	if (inx == NODE_STATE_ALLOCATED) {
+		if (no_resp_flag)
+			return "ALLOCATED*";
+		if (comp_flag)
+			return "ALLOCATED+";
+		return "ALLOCATED";
+	}
+	if (comp_flag) {
+		if (no_resp_flag)
+			return "COMPLETING*";
+		return "COMPLETING";
 	}
+	if (inx == NODE_STATE_IDLE) {
+		if (no_resp_flag)
+			return "IDLE*";
+		return "IDLE";
+	}
+	if (inx == NODE_STATE_UNKNOWN) {
+		if (no_resp_flag)
+			return "UNKNOWN*";
+		return "UNKNOWN";
+	}
+	return "?";
 }
 
 char *node_state_string_compact(enum node_states inx)
 {
-	bool no_resp_flag;
+	bool drain_flag   = (inx & NODE_STATE_DRAIN);
+	bool comp_flag    = (inx & NODE_STATE_NO_RESPOND);
+	bool no_resp_flag = (inx & NODE_STATE_NO_RESPOND);
 
-	if (inx & NODE_STATE_NO_RESPOND) {
-		no_resp_flag = true;
-		inx = (uint16_t) (inx & (~NODE_STATE_NO_RESPOND));
-	} else
-		no_resp_flag = false;
+	inx = (uint16_t) (inx & NODE_STATE_BASE);
 
-	switch (inx) {
-		case NODE_STATE_DOWN:
-			if (no_resp_flag)
-				return "DOWN*";
-			return "DOWN";
-		case NODE_STATE_UNKNOWN:
-			if (no_resp_flag)
-				return "UNK*";
-			return "UNK";
-		case NODE_STATE_IDLE:
-			if (no_resp_flag)
-				return "IDLE*";
-			return "IDLE";
-		case NODE_STATE_ALLOCATED:
-			if (no_resp_flag)
-				return "ALLOC*";
-			return "ALLOC";
-		case NODE_STATE_DRAINED:
-			if (no_resp_flag)
-				return "DRAIN*";
-			return "DRAIN";
-		case NODE_STATE_DRAINING:
+	if (inx == NODE_STATE_DOWN) {
+		if (no_resp_flag)
+			return "DOWN*";
+		return "DOWN";
+	}
+	if (drain_flag) {
+		if (comp_flag || (inx == NODE_STATE_ALLOCATED)) {
 			if (no_resp_flag)
 				return "DRNG*";
 			return "DRNG";
-		case NODE_STATE_COMPLETING:
+		} else {
 			if (no_resp_flag)
-				return "COMP*";
-			return "COMP";
-		default:
-			return "?";
+				return "DRAIN*";
+			return "DRAIN";
+		}
 	}
+	if (inx == NODE_STATE_ALLOCATED) {
+		if (no_resp_flag)
+			return "ALLOC*";
+		if (comp_flag)
+			return "ALLOC+";
+		return "ALLOC";
+	}
+	if (comp_flag) {
+		if (no_resp_flag)
+			return "COMP*";
+		return "COMP";
+	}
+	if (inx == NODE_STATE_IDLE) {
+		if (no_resp_flag)
+			return "IDLE*";
+		return "IDLE";
+	}
+	if (inx == NODE_STATE_UNKNOWN) {
+		if (no_resp_flag)
+			return "UNK*";
+		return "UNK";
+	}
+	return "?";
 }
 
 /*
diff --git a/src/partition_allocator/partition_allocator.c b/src/partition_allocator/partition_allocator.c
index 8ea8db90b0a456f5abb2a6165aeb27e95a8f32ee..e485323f36fa0ab338cd2a89a702c3ed34847f43 100644
--- a/src/partition_allocator/partition_allocator.c
+++ b/src/partition_allocator/partition_allocator.c
@@ -1051,16 +1051,13 @@ extern void init_grid(node_info_msg_t * node_info_ptr)
 				if(node_info_ptr!=NULL) {
 					node_ptr = 
 						&node_info_ptr->node_array[i];
-					node_base_state = 
-						(node_ptr->node_state) 
-						& (~NODE_STATE_NO_RESPOND);
+					node_base_state = node_ptr->node_state 
+						& NODE_STATE_BASE;
 					pa_system_ptr->grid[x][y][z].color = 7;
 					if ((node_base_state 
 					     == NODE_STATE_DOWN) || 
-					    (node_base_state 
-					     == NODE_STATE_DRAINED) || 
-					    (node_base_state 
-					     == NODE_STATE_DRAINING)) {
+					    (node_ptr->node_state &
+					     NODE_STATE_DRAIN)) {
 						pa_system_ptr->
 							grid[x][y][z].color 
 							= 0;
@@ -1093,13 +1090,10 @@ extern void init_grid(node_info_msg_t * node_info_ptr)
 	for (x = 0; x < DIM_SIZE[X]; x++) {
 		if(node_info_ptr!=NULL) {
 			node_ptr = &node_info_ptr->node_array[i];
-			node_base_state = 
-				(node_ptr->node_state) 
-				& (~NODE_STATE_NO_RESPOND);
+			node_base_state = node_ptr->node_state & NODE_STATE_BASE;
 			pa_system_ptr->grid[x].color = 7;
 			if ((node_base_state == NODE_STATE_DOWN) || 
-			    (node_base_state == NODE_STATE_DRAINED) || 
-			    (node_base_state == NODE_STATE_DRAINING)) {
+			    (node_ptr->node_state & NODE_STATE_DRAIN)) {
 				pa_system_ptr->grid[x].color = 0;
 				pa_system_ptr->grid[x].letter = '#';
 				if(_initialized) {
@@ -1114,8 +1108,7 @@ extern void init_grid(node_info_msg_t * node_info_ptr)
 		} else {
 			pa_system_ptr->grid[x].color = 7;
 			pa_system_ptr->grid[x].letter = '.';
-			pa_system_ptr->grid[x].state = 
-				NODE_STATE_IDLE;
+			pa_system_ptr->grid[x].state = NODE_STATE_IDLE;
 		}
 		pa_system_ptr->grid[x].indecies = i++;
 	}
diff --git a/src/plugins/sched/backfill/backfill.c b/src/plugins/sched/backfill/backfill.c
index c910662e03239f694f5d5645d588e74d1cf15611..57781a9c182c37f6383e2617a07b3b308d967ae5 100644
--- a/src/plugins/sched/backfill/backfill.c
+++ b/src/plugins/sched/backfill/backfill.c
@@ -544,11 +544,12 @@ _get_avail_node_cnt(struct job_record *job_ptr)
 		if (bit_test(job_ptr->node_bitmap, i) == 0)
 			continue;
 		node_ptr = node_record_table_ptr + i;
-		base_state = node_ptr->node_state & (~NODE_STATE_NO_RESPOND);
-		if ( (base_state != NODE_STATE_DRAINING) &&
-		     (base_state != NODE_STATE_DRAINED)  &&
-		     (base_state != NODE_STATE_DOWN) )
-			cnt++;
+		if (node_ptr->node_state & NODE_STATE_DRAIN)
+			continue;
+		base_state = node_ptr->node_state & NODE_STATE_BASE;
+		if (base_state == NODE_STATE_DOWN)
+			continue;	
+		cnt++;
 	}
 
 	return cnt;
diff --git a/src/scontrol/scontrol.c b/src/scontrol/scontrol.c
index fa68c7dd8b122e0cab2d92d651674320f7ed59ea..6c154dac5c4b06700c40f827165218661718ab6c 100644
--- a/src/scontrol/scontrol.c
+++ b/src/scontrol/scontrol.c
@@ -518,7 +518,7 @@ _print_completing_job(job_info_t *job_ptr, node_info_msg_t *node_info_msg)
 {
 	int i;
 	node_info_t *node_info;
-	uint16_t node_state;
+	uint16_t node_state, base_state;
 	hostlist_t all_nodes, comp_nodes, down_nodes;
 	char node_buf[1024];
 
@@ -528,11 +528,12 @@ _print_completing_job(job_info_t *job_ptr, node_info_msg_t *node_info_msg)
 
 	node_info = node_info_msg->node_array;
 	for (i=0; i<node_info_msg->record_count; i++) {
-		node_state = node_info[i].node_state & (~NODE_STATE_NO_RESPOND);
-		if ((node_state == NODE_STATE_COMPLETING) && 
+		node_state = node_info[i].node_state;
+		base_state = node_info[i].node_state & NODE_STATE_BASE;
+		if ((node_state & NODE_STATE_COMPLETING) && 
 		    (_in_node_bit_list(i, job_ptr->node_inx)))
 			hostlist_push_host(comp_nodes, node_info[i].name);
-		else if ((node_state == NODE_STATE_DOWN) &&
+		else if ((base_state == NODE_STATE_DOWN) &&
 			 (hostlist_find(all_nodes, node_info[i].name) != -1))
 			hostlist_push_host(down_nodes, node_info[i].name);
 	}
@@ -1570,6 +1571,10 @@ _update_node (int argc, char *argv[])
 		}
 		else if (strncasecmp(argv[i], "State=NoResp", 12) == 0)
 			node_msg.node_state = NODE_STATE_NO_RESPOND;
+		else if (strncasecmp(argv[i], "State=DRAIN", 11) == 0)
+			node_msg.node_state = NODE_STATE_DRAIN;
+		else if (strncasecmp(argv[i], "State=RES", 9) == 0)
+			 node_msg.node_state = NODE_RESUME;
 		else if (strncasecmp(argv[i], "State=", 6) == 0) {
 			state_val = (uint16_t) NO_VAL;
 			for (j = 0; j <= NODE_STATE_END; j++) {
@@ -1578,23 +1583,13 @@ _update_node (int argc, char *argv[])
 					state_val = (uint16_t) j;
 					break;
 				}
-				if ((j == 0) && 
-				    (strcasecmp ("DRAIN", &argv[i][6]) == 0)) {
-					state_val = NODE_STATE_DRAINING;
-					break;
-				}
-				if ((j == 0) &&
-				    (strncasecmp ("RES", &argv[i][6], 3) == 0)) {
-					state_val = NODE_RESUME;
-					break;
-				}
 				if (strcmp(node_state_string(j),"END") == 0) {
 					exit_code = 1;
 					fprintf(stderr, "Invalid input: %s\n", 
 						argv[i]);
 					fprintf (stderr, "Request aborted\n");
 					fprintf (stderr, "Valid states are: ");
-					fprintf (stderr, "NoResp DRAIN ");
+					fprintf (stderr, "NoResp DRAIN RES ");
 					for (k = 0; k < NODE_STATE_END; k++) {
 						fprintf (stderr, "%s ", 
 						         node_state_string(k));
@@ -1613,8 +1608,7 @@ _update_node (int argc, char *argv[])
 		}
 	}
 
-	if (((node_msg.node_state == NODE_STATE_DRAINING) ||
-	     (node_msg.node_state == NODE_STATE_DRAINING)) &&
+	if ((node_msg.node_state == NODE_STATE_DRAIN)  &&
 	    (node_msg.reason == NULL)) {
 		fprintf (stderr, "You must specify a reason when DRAINING a node\n");
 		fprintf (stderr, "Request aborted\n");
diff --git a/src/sinfo/opts.c b/src/sinfo/opts.c
index 46c933f9ac0733115325d80964cee5c74ec08f60..58263086e73603344e438c6d3f4008ab12631081 100644
--- a/src/sinfo/opts.c
+++ b/src/sinfo/opts.c
@@ -216,7 +216,7 @@ extern void parse_command_line(int argc, char *argv[])
 	_parse_format( params.format );
 
 	if (params.list_reasons && (params.state_list == NULL)) {
-		params.states = xstrdup ("down,drain,draining");
+		params.states = xstrdup ("down,drain");
 		if (!(params.state_list = _build_state_list (params.states)))
 			fatal ("Unable to build state list for -R!");
 	}
@@ -256,7 +256,7 @@ _next_tok (char *sep, char **str)
 }
 
 /*
- * _build_state_list - build a list of job states
+ * _build_state_list - build a list of node states
  * IN str - comma separated list of job states
  * RET List of enum job_states values
  */
@@ -288,7 +288,7 @@ _build_state_list (char *state_str)
 }
 
 /*
- * _build_all_states_list - build a list containing all possible job states
+ * _build_all_states_list - build a list containing all possible node states
  * RET List of enum job_states values
  */
 static List 
@@ -299,11 +299,20 @@ _build_all_states_list( void )
 	uint16_t *state_id;
 
 	my_list = list_create( NULL );
-	for (i = 0; i<NODE_STATE_END; i++) {
+	for (i = 0; i < NODE_STATE_END; i++) {
 		state_id = xmalloc( sizeof( uint16_t ) );
 		*state_id = (uint16_t) i;
 		list_append( my_list, state_id );
 	}
+
+	state_id = xmalloc( sizeof( uint16_t ) );
+	*state_id = NODE_STATE_DRAIN;
+	list_append( my_list, state_id );
+
+	state_id = xmalloc( sizeof( uint16_t ) );
+	*state_id = NODE_STATE_COMPLETING;
+	list_append( my_list, state_id );
+
 	return my_list;
 }
 
@@ -321,6 +330,14 @@ _node_state_list (void)
 		xstrcat (all_states, node_state_string_compact(i));
 	}
 
+	xstrcat (all_states, ",");
+	xstrcat (all_states, 
+		node_state_string_compact(NODE_STATE_DRAIN));
+
+	xstrcat (all_states, ",");
+	xstrcat (all_states, 
+		node_state_string_compact(NODE_STATE_COMPLETING));
+
 	for (i = 0; i < strlen (all_states); i++)
 		all_states[i] = tolower (all_states[i]);
 
@@ -336,7 +353,6 @@ _node_state_equal (int i, const char *str)
 	if (  (strncasecmp (node_state_string_compact(i), str, len) == 0) 
 	   || (strncasecmp (node_state_string(i),         str, len) == 0)) 
 		return (true);
-
 	return (false);
 }
 
@@ -355,6 +371,12 @@ _node_state_id (char *str)
 			return (i);
 	}
 
+	if  (_node_state_equal (NODE_STATE_DRAIN, str))
+		return NODE_STATE_DRAIN;
+
+	if (_node_state_equal (NODE_STATE_COMPLETING, str))
+		return NODE_STATE_COMPLETING;
+
 	return (-1);
 }
 
diff --git a/src/sinfo/sinfo.c b/src/sinfo/sinfo.c
index 4786f448bf751d9a836322255807a7f037b3780f..6168f66a489572bfad09b56a29ff2f4282563c61 100644
--- a/src/sinfo/sinfo.c
+++ b/src/sinfo/sinfo.c
@@ -359,15 +359,22 @@ static bool _filter_out(node_info_t *node_ptr)
 	if (params.state_list) {
 		int *node_state;
 		bool match = false;
+		uint16_t base_state = node_ptr->node_state & 
+			(~NODE_STATE_NO_RESPOND);
 		ListIterator iterator;
+
 		iterator = list_iterator_create(params.state_list);
 		while ((node_state = list_next(iterator))) {
-			if ( (node_ptr->node_state == *node_state) || 
-					((node_ptr->node_state & 
-					 (~NODE_STATE_NO_RESPOND)) == 
-					 *node_state) ) {
-				match = true;
-				break;
+			if (*node_state & NODE_STATE_FLAGS) {
+				if (*node_state & node_ptr->node_state) {
+					match = true;
+					break;
+				}
+			} else {
+				if (base_state == *node_state) { 
+					match = true;
+					break;
+				}
 			}
 		}
 		list_iterator_destroy(iterator);
@@ -473,6 +480,8 @@ static bool _match_part_data(sinfo_data_t *sinfo_ptr,
 static void _update_sinfo(sinfo_data_t *sinfo_ptr, partition_info_t* part_ptr, 
 		node_info_t *node_ptr)
 {
+	uint16_t base_state;
+
 	if (sinfo_ptr->nodes_tot == 0) {	/* first node added */
 		sinfo_ptr->node_state = node_ptr->node_state;
 		sinfo_ptr->features   = node_ptr->features;
@@ -507,10 +516,11 @@ static void _update_sinfo(sinfo_data_t *sinfo_ptr, partition_info_t* part_ptr,
 			sinfo_ptr->max_weight = node_ptr->weight;
 	}
 
-	if ((node_ptr->node_state == NODE_STATE_ALLOCATED) ||
-	    (node_ptr->node_state == NODE_STATE_COMPLETING))
+	base_state = node_ptr->node_state & NODE_STATE_BASE;
+	if ((base_state == NODE_STATE_ALLOCATED)
+	||  (node_ptr->node_state & NODE_STATE_COMPLETING))
 		sinfo_ptr->nodes_alloc++;
-	else if (node_ptr->node_state == NODE_STATE_IDLE)
+	else if (base_state == NODE_STATE_IDLE)
 		sinfo_ptr->nodes_idle++;
 	else 
 		sinfo_ptr->nodes_other++;
@@ -537,11 +547,13 @@ static void _create_sinfo(List sinfo_list, partition_info_t* part_ptr,
 	sinfo_ptr->part_info = part_ptr;
 
 	if (node_ptr) {
+		uint16_t base_state = node_ptr->node_state & 
+			NODE_STATE_BASE;
 		sinfo_ptr->node_state = node_ptr->node_state;
-		if ((node_ptr->node_state == NODE_STATE_ALLOCATED) ||
-		    (node_ptr->node_state == NODE_STATE_COMPLETING))
+		if ((base_state == NODE_STATE_ALLOCATED)
+		||  (node_ptr->node_state & NODE_STATE_COMPLETING))
 			sinfo_ptr->nodes_alloc++;
-		else if (node_ptr->node_state == NODE_STATE_IDLE)
+		else if (base_state == NODE_STATE_IDLE)
 			sinfo_ptr->nodes_idle++;
 		else 
 			sinfo_ptr->nodes_other++;
diff --git a/src/slurmctld/node_mgr.c b/src/slurmctld/node_mgr.c
index 7e9a1e7d733931cf9e5f624f8e7a70a0e00547db..acf3df8ab6220739f013f3786f159a09a4a702f3 100644
--- a/src/slurmctld/node_mgr.c
+++ b/src/slurmctld/node_mgr.c
@@ -370,16 +370,17 @@ extern int load_all_node_state ( bool state_only )
 	safe_unpack_time (&time_stamp, buffer);
 
 	while (remaining_buf (buffer) > 0) {
+		uint16_t base_state;
 		safe_unpackstr_xmalloc (&node_name, &name_len, buffer);
 		safe_unpackstr_xmalloc (&reason, &name_len, buffer);
 		safe_unpack16 (&node_state,  buffer);
 		safe_unpack32 (&cpus,        buffer);
 		safe_unpack32 (&real_memory, buffer);
 		safe_unpack32 (&tmp_disk,    buffer);
-		node_state &= (~NODE_STATE_NO_RESPOND);
+		base_state = node_state & NODE_STATE_BASE;
 
 		/* validity test as possible */
-		if ((cpus == 0) || (node_state  >= NODE_STATE_END)) {
+		if ((cpus == 0) || (base_state  >= NODE_STATE_END)) {
 			error ("Invalid data for node %s: cpus=%u, state=%u",
 				node_name, cpus, node_state);
 			error ("No more node data will be processed from the "
@@ -398,11 +399,12 @@ extern int load_all_node_state ( bool state_only )
 			xfree(reason);
 		} else if (state_only) {
 			node_cnt++;
-			if ((node_ptr->node_state == NODE_STATE_UNKNOWN) &&
-			    ((node_state == NODE_STATE_DOWN) ||
-			     (node_state == NODE_STATE_DRAINED) ||
-			     (node_state == NODE_STATE_DRAINING)))
-				node_ptr->node_state    = node_state;
+			if (node_ptr->node_state == NODE_STATE_UNKNOWN) {
+				if (node_state & NODE_STATE_DRAIN)
+					 node_ptr->node_state = NODE_STATE_DRAIN;
+				else if (base_state == NODE_STATE_DOWN)
+					node_ptr->node_state = NODE_STATE_DOWN;
+			}
 			if (node_ptr->reason == NULL)
 				node_ptr->reason = reason;
 			else
@@ -846,8 +848,7 @@ int update_node ( update_node_msg_t * update_node_msg )
 		}
 
 		if (state_val != (uint16_t) NO_VAL) {
-			base_state = node_ptr->node_state & 
-			             (~NODE_STATE_NO_RESPOND);
+			base_state = node_ptr->node_state; 
 			if (!_valid_node_state_change(base_state, &state_val)) {
 				info ("Invalid node state transition requested "
 					"for node %s from=%s to=%s",
@@ -860,7 +861,8 @@ int update_node ( update_node_msg_t * update_node_msg )
 		}
 		if (state_val != (uint16_t) NO_VAL) {
 			if (state_val == NODE_STATE_DOWN) {
-				/* We must set node down before killing its jobs */
+				/* We must set node DOWN before killing 
+				 * its jobs */
 				_make_node_down(node_ptr);
 				kill_running_job_by_node_name (this_node_name,
 							       false);
@@ -874,14 +876,10 @@ int update_node ( update_node_msg_t * update_node_msg )
 				bit_set   (avail_node_bitmap, node_inx);
 				bit_clear (idle_node_bitmap, node_inx);
 			}
-			else if ((state_val == NODE_STATE_DRAINED) ||
-			         (state_val == NODE_STATE_DRAINING)) {
-				if ((node_ptr->run_job_cnt + 
-					 	node_ptr->comp_job_cnt) == 0)
-					state_val = NODE_STATE_DRAINED;
-				else
-					state_val = NODE_STATE_DRAINING;
+			else if (state_val == NODE_STATE_DRAIN) {
 				bit_clear (avail_node_bitmap, node_inx);
+				state_val = node_ptr->node_state |
+					NODE_STATE_DRAIN;
 			}
 			else {
 				info ("Invalid node state specified %d", 
@@ -908,10 +906,9 @@ int update_node ( update_node_msg_t * update_node_msg )
 				this_node_name, node_ptr->reason);
 		}
 
-		base_state = node_ptr->node_state & (~NODE_STATE_NO_RESPOND);
-		if ((base_state != NODE_STATE_DRAINED)  && 
-		    (base_state != NODE_STATE_DRAINING) &&
-		    (base_state != NODE_STATE_DOWN))
+		base_state = node_ptr->node_state & NODE_STATE_BASE;
+		if ((base_state != NODE_STATE_DOWN)
+		&&  ((node_ptr->node_state & NODE_STATE_DRAIN) == 0))
 			xfree(node_ptr->reason);
 
 		free (this_node_name);
@@ -935,7 +932,6 @@ extern int drain_nodes ( char *nodes, char *reason )
 	struct node_record *node_ptr;
 	char  *this_node_name ;
 	hostlist_t host_list;
-	uint16_t base_state, no_resp_flag, state_val;
 
 	if ((nodes == NULL) || (nodes[0] == '\0')) {
 		error ("drain_nodes: invalid node name  %s", nodes);
@@ -959,23 +955,16 @@ extern int drain_nodes ( char *nodes, char *reason )
 			break;
 		}
 
-		base_state = node_ptr->node_state & (~NODE_STATE_NO_RESPOND);
-		no_resp_flag = node_ptr->node_state &  NODE_STATE_NO_RESPOND;
-		if ((base_state == NODE_STATE_DRAINED)
-		||  (base_state == NODE_STATE_DRAINING)) {
+		if (node_ptr->node_state & NODE_STATE_DRAIN) {
 			/* state already changed, nothing to do */
 			free (this_node_name);
 			continue;
 		}
 
-		if ((node_ptr->run_job_cnt + node_ptr->comp_job_cnt) == 0)
-			state_val = NODE_STATE_DRAINED;
-		else
-			state_val = NODE_STATE_DRAINING;
-		node_ptr->node_state = state_val | no_resp_flag;
+		node_ptr->node_state |= NODE_STATE_DRAIN;
 		bit_clear (avail_node_bitmap, node_inx);
-		info ("drain_nodes: node %s state set to %s",
-			this_node_name, node_state_string(state_val));
+		info ("drain_nodes: node %s state set to DRAIN",
+			this_node_name);
 
 		xfree(node_ptr->reason);
 		node_ptr->reason = xstrdup(reason);
@@ -989,36 +978,37 @@ extern int drain_nodes ( char *nodes, char *reason )
 /* Return true if admin request to change node state from old to new is valid */
 static bool _valid_node_state_change(uint16_t old, uint16_t *new)
 {
+	uint16_t base_state, node_flags;
 	if (old == *new)
 		return true;
 
+	base_state = (old) & NODE_STATE_BASE;
+	node_flags = (old) & NODE_STATE_FLAGS;
 	switch (*new) {
 		case NODE_STATE_DOWN:
-		case NODE_STATE_DRAINED:
-		case NODE_STATE_DRAINING:
+		case NODE_STATE_DRAIN:
 			return true;
 			break;
 
 		case NODE_RESUME:
-			if ((old == NODE_STATE_DRAINED) ||
-			    (old == NODE_STATE_DOWN)) {
-				*new = NODE_STATE_IDLE;
+			if (base_state == NODE_STATE_DOWN) {
+				*new = NODE_STATE_IDLE | node_flags;
 				return true;
 			}
-			if (old == NODE_STATE_DRAINING) {
-				*new = NODE_STATE_ALLOCATED;
+			if (node_flags & NODE_STATE_DRAIN) {
+				*new = old & (~NODE_STATE_DRAIN);
 				return true;
 			}
 			break;
 
 		case NODE_STATE_IDLE:
-			if ((old == NODE_STATE_DRAINED) ||
-			    (old == NODE_STATE_DOWN))
+			if ((base_state == NODE_STATE_DOWN)
+			||  (base_state == NODE_STATE_IDLE))
 				return true;
 			break;
 
 		case NODE_STATE_ALLOCATED:
-			if (old == NODE_STATE_DRAINING)
+			if (base_state == NODE_STATE_ALLOCATED)
 				return true;
 			break;
 
@@ -1051,6 +1041,7 @@ validate_node_specs (char *node_name, uint32_t cpus,
 	struct config_record *config_ptr;
 	struct node_record *node_ptr;
 	char *reason_down = NULL;
+	uint16_t base_state, node_flags;
 
 	node_ptr = find_node_record (node_name);
 	if (node_ptr == NULL)
@@ -1102,18 +1093,18 @@ validate_node_specs (char *node_name, uint32_t cpus,
 		reset_job_priority();
 		node_ptr->node_state &= (uint16_t) (~NODE_STATE_NO_RESPOND);
 	}
+	base_state = node_ptr->node_state & NODE_STATE_BASE;
+	node_flags = node_ptr->node_state & NODE_STATE_FLAGS;
 	if (error_code) {
-		if ((node_ptr->node_state != NODE_STATE_DRAINING) &&
-		    (node_ptr->node_state != NODE_STATE_DRAINED)  &&
-		    (node_ptr->node_state != NODE_STATE_DOWN)) {
+		if ((base_state != NODE_STATE_DOWN)
+		&&  ((node_flags & NODE_STATE_DRAIN) == 0)) {
 			last_node_update = time (NULL);
 			error ("Setting node %s state to DOWN", node_name);
 			set_node_down(node_name, reason_down);
 		}
 		_sync_bitmaps(node_ptr, job_count);
 	} else if (status == ESLURMD_PROLOG_FAILED) {
-		if ((node_ptr->node_state != NODE_STATE_DRAINING) &&
-		    (node_ptr->node_state != NODE_STATE_DRAINED)) {
+		if ((node_flags & NODE_STATE_DRAIN) == 0) {
 			last_node_update = time (NULL);
 			error ("Prolog failure on node %s, state to DOWN",
 				node_name);
@@ -1125,40 +1116,35 @@ validate_node_specs (char *node_name, uint32_t cpus,
 			reset_job_priority();
 			debug("validate_node_specs: node %s has registered", 
 				node_name);
-			if (job_count)
-				node_ptr->node_state = NODE_STATE_ALLOCATED;
-			else
-				node_ptr->node_state = NODE_STATE_IDLE;
-			xfree(node_ptr->reason);
-		} else if (node_ptr->node_state == NODE_STATE_DRAINING) {
-			if (job_count == 0) {
-				last_node_update = time (NULL);
-				node_ptr->node_state = NODE_STATE_DRAINED;
-			}
-		} else if (node_ptr->node_state == NODE_STATE_DRAINED) {
-			if (job_count != 0) {
-				last_node_update = time (NULL);
-				node_ptr->node_state = NODE_STATE_DRAINING;
+			if (job_count) {
+				node_ptr->node_state = NODE_STATE_ALLOCATED |
+					node_flags;
+			} else {
+				node_ptr->node_state = NODE_STATE_IDLE |
+					node_flags;
 			}
-		} else if ((node_ptr->node_state == NODE_STATE_DOWN) &&
+			xfree(node_ptr->reason);
+		} else if ((base_state == NODE_STATE_DOWN) &&
 		           (slurmctld_conf.ret2service == 1)) {
 			last_node_update = time (NULL);
-			if (job_count)
-				node_ptr->node_state = NODE_STATE_ALLOCATED;
-			else
-				node_ptr->node_state = NODE_STATE_IDLE;
-			info ("validate_node_specs: node %s returned to service", 
-			      node_name);
+			if (job_count) {
+				node_ptr->node_state = NODE_STATE_ALLOCATED |
+					node_flags;
+			} else {
+				node_ptr->node_state = NODE_STATE_IDLE |
+					node_flags;
+			}
+			info ("node %s returned to service", node_name);
 			xfree(node_ptr->reason);
 			reset_job_priority();
-		} else if ((node_ptr->node_state == NODE_STATE_ALLOCATED) &&
+		} else if ((base_state == NODE_STATE_ALLOCATED) &&
 			   (job_count == 0)) {	/* job vanished */
 			last_node_update = time (NULL);
-			node_ptr->node_state = NODE_STATE_IDLE;
-		} else if ((node_ptr->node_state == NODE_STATE_COMPLETING) &&
+			node_ptr->node_state = NODE_STATE_IDLE | node_flags;
+		} else if ((node_flags & NODE_STATE_COMPLETING) &&
 			   (job_count == 0)) {	/* job already done */
 			last_node_update = time (NULL);
-			node_ptr->node_state = NODE_STATE_IDLE;
+			node_ptr->node_state &= (~NODE_STATE_COMPLETING);
 		}
 		_sync_bitmaps(node_ptr, job_count);
 	}
@@ -1192,6 +1178,7 @@ extern int validate_nodes_via_front_end(uint32_t job_count,
 	hostlist_t return_hostlist = NULL, reg_hostlist = NULL;
 	hostlist_t prolog_hostlist = NULL;
 	char host_str[64];
+	uint16_t base_state, node_flags;
 
 	/* First validate the job info */
 	node_ptr = &node_record_table_ptr[0];	/* All msg send to node zero,
@@ -1282,8 +1269,7 @@ extern int validate_nodes_via_front_end(uint32_t job_count,
 		}
 
 		if (status == ESLURMD_PROLOG_FAILED) {
-			if ((node_ptr->node_state != NODE_STATE_DRAINING) &&
-			    (node_ptr->node_state != NODE_STATE_DRAINED)) {
+			if (!(node_ptr->node_state & NODE_STATE_DRAIN)) {
 				updated_job = true;
 				if (prolog_hostlist)
 					(void) hostlist_push_host(
@@ -1295,7 +1281,9 @@ extern int validate_nodes_via_front_end(uint32_t job_count,
 				set_node_down(node_ptr->name, "Prolog failed");
 			}
 		} else {
-			if (node_ptr->node_state == NODE_STATE_UNKNOWN) {
+			base_state = node_ptr->node_state & NODE_STATE_BASE;
+			node_flags = node_ptr->node_state & NODE_STATE_FLAGS;
+			if (base_state == NODE_STATE_UNKNOWN) {
 				updated_job = true;
 				if (reg_hostlist)
 					(void) hostlist_push_host(
@@ -1303,28 +1291,27 @@ extern int validate_nodes_via_front_end(uint32_t job_count,
 				else
 					reg_hostlist = hostlist_create(
 						node_ptr->name);
-				if (jobs_on_node)
-					node_ptr->node_state = NODE_STATE_ALLOCATED;
-				else
-					node_ptr->node_state = NODE_STATE_IDLE;
+				if (jobs_on_node) {
+					node_ptr->node_state = 
+						NODE_STATE_ALLOCATED | 
+						node_flags;
+				} else
+					node_ptr->node_state = 
+						NODE_STATE_IDLE |
+						node_flags;
 				xfree(node_ptr->reason);
-			} else if (node_ptr->node_state == NODE_STATE_DRAINING) {
-				if (jobs_on_node== 0) {
-					updated_job = true;
-					node_ptr->node_state = NODE_STATE_DRAINED;
-				}
-			} else if (node_ptr->node_state == NODE_STATE_DRAINED) {
-				if (jobs_on_node != 0) {
-					updated_job = true;
-					node_ptr->node_state = NODE_STATE_DRAINING;
-				}
-			} else if ((node_ptr->node_state == NODE_STATE_DOWN) &&
+			} else if ((base_state == NODE_STATE_DOWN) &&
 			           (slurmctld_conf.ret2service == 1)) {
 				updated_job = true;
-				if (jobs_on_node)
-					node_ptr->node_state = NODE_STATE_ALLOCATED;
-				else
-					node_ptr->node_state = NODE_STATE_IDLE;
+				if (jobs_on_node) {
+					node_ptr->node_state = 
+						NODE_STATE_ALLOCATED |
+						node_flags;
+				} else {
+					node_ptr->node_state = 
+						NODE_STATE_IDLE |
+						node_flags;
+				}
 				if (return_hostlist)
 					(void) hostlist_push_host(
 						return_hostlist, node_ptr->name);
@@ -1332,14 +1319,15 @@ extern int validate_nodes_via_front_end(uint32_t job_count,
 					return_hostlist = hostlist_create(
 						node_ptr->name);
 				xfree(node_ptr->reason);
-			} else if ((node_ptr->node_state == NODE_STATE_ALLOCATED) &&
+			} else if ((base_state == NODE_STATE_ALLOCATED) &&
 				   (jobs_on_node == 0)) {	/* job vanished */
 				updated_job = true;
-				node_ptr->node_state = NODE_STATE_IDLE;
-			} else if ((node_ptr->node_state == NODE_STATE_COMPLETING) &&
-				   (jobs_on_node == 0)) {	/* job already done */
+				node_ptr->node_state = NODE_STATE_IDLE |
+					node_flags;
+			} else if ((node_flags & NODE_STATE_COMPLETING) &&
+			           (jobs_on_node == 0)) {  /* job already done */
 				updated_job = true;
-				node_ptr->node_state = NODE_STATE_IDLE;
+				node_ptr->node_state &= (~NODE_STATE_COMPLETING);
 			}
 			_sync_bitmaps(node_ptr, jobs_on_node);
 		}
@@ -1377,21 +1365,16 @@ extern int validate_nodes_via_front_end(uint32_t job_count,
 /* Sync idle, share, and avail_node_bitmaps for a given node */
 static void _sync_bitmaps(struct node_record *node_ptr, int job_count)
 {
+	uint16_t base_state;
 	int node_inx = node_ptr - node_record_table_ptr;
 
 	if (job_count == 0) {
 		bit_set (idle_node_bitmap, node_inx);
 		bit_set (share_node_bitmap, node_inx);
-		if (node_ptr->node_state == NODE_STATE_DRAINING)
-			node_ptr->node_state = NODE_STATE_DRAINED;
-	} else {
-		if (node_ptr->node_state == NODE_STATE_DRAINED)
-			node_ptr->node_state = NODE_STATE_DRAINING;
 	}
-
-	if ((node_ptr->node_state == NODE_STATE_DOWN)     ||
-	    (node_ptr->node_state == NODE_STATE_DRAINING) ||
-	    (node_ptr->node_state == NODE_STATE_DRAINED))
+	base_state = node_ptr->node_state & NODE_STATE_BASE;
+	if ((base_state == NODE_STATE_DOWN)
+	||  (node_ptr->node_state & NODE_STATE_DRAIN))
 		bit_clear (avail_node_bitmap, node_inx);
 	else
 		bit_set   (avail_node_bitmap, node_inx);
@@ -1425,7 +1408,7 @@ void node_did_resp (char *name)
 static void _node_did_resp(struct node_record *node_ptr)
 {
 	int node_inx;
-	uint16_t resp_state;
+	uint16_t resp_state, base_state, node_flags;
 
 	node_inx = node_ptr - node_record_table_ptr;
 	node_ptr->last_response = time (NULL);
@@ -1436,27 +1419,29 @@ static void _node_did_resp(struct node_record *node_ptr)
 		reset_job_priority();
 		node_ptr->node_state &= (uint16_t) (~NODE_STATE_NO_RESPOND);
 	}
-	if (node_ptr->node_state == NODE_STATE_UNKNOWN) {
+	base_state = node_ptr->node_state & NODE_STATE_BASE;
+	node_flags = node_ptr->node_state & NODE_STATE_FLAGS;
+	if (base_state == NODE_STATE_UNKNOWN) {
 		last_node_update = time (NULL);
-		node_ptr->node_state = NODE_STATE_IDLE;
+		node_ptr->node_state = NODE_STATE_IDLE | node_flags;
 	}
-	if ((node_ptr->node_state == NODE_STATE_DOWN) &&
+	if ((base_state == NODE_STATE_DOWN) &&
 	    (slurmctld_conf.ret2service == 1) &&
 	    (node_ptr->reason != NULL) && 
 	    (strcmp(node_ptr->reason, "Not responding") == 0)) {
 		last_node_update = time (NULL);
-		node_ptr->node_state = NODE_STATE_IDLE;
+		node_ptr->node_state = NODE_STATE_IDLE | node_flags;
 		info("node_did_resp: node %s returned to service", 
 			node_ptr->name);
 		xfree(node_ptr->reason);
 	}
-	if (node_ptr->node_state == NODE_STATE_IDLE) {
+	base_state = node_ptr->node_state & NODE_STATE_BASE;
+	if (base_state == NODE_STATE_IDLE) {
 		bit_set (idle_node_bitmap, node_inx);
 		bit_set (share_node_bitmap, node_inx);
 	}
-	if ((node_ptr->node_state == NODE_STATE_DOWN)     ||
-	    (node_ptr->node_state == NODE_STATE_DRAINING) ||
-	    (node_ptr->node_state == NODE_STATE_DRAINED))
+	if ((base_state == NODE_STATE_DOWN)
+	||  (node_flags & NODE_STATE_DRAIN))
 		bit_clear (avail_node_bitmap, node_inx);
 	else
 		bit_set   (avail_node_bitmap, node_inx);
@@ -1524,7 +1509,6 @@ static void _node_not_resp (struct node_record *node_ptr, time_t msg_time)
 void set_node_down (char *name, char *reason)
 {
 	struct node_record *node_ptr;
-	uint16_t base_state;
 
 	node_ptr = find_node_record (name);
 	if (node_ptr == NULL) {
@@ -1532,10 +1516,7 @@ void set_node_down (char *name, char *reason)
 		return;
 	}
 
-	base_state = node_ptr->node_state & (~NODE_STATE_NO_RESPOND);
-	if ((base_state != NODE_STATE_DRAINING) &&
-	    (base_state != NODE_STATE_DRAINED))
-		_make_node_down(node_ptr);
+	_make_node_down(node_ptr);
 	(void) kill_running_job_by_node_name(name, false);
 	if (node_ptr->reason == NULL)
 		node_ptr->reason = xstrdup(reason);
@@ -1559,7 +1540,7 @@ bool is_node_down (char *name)
 		return false;
 	}
 
-	base_state = node_ptr->node_state & (~NODE_STATE_NO_RESPOND);
+	base_state = node_ptr->node_state & NODE_STATE_BASE;
 	if (base_state == NODE_STATE_DOWN)
 		return true;
 	return false;
@@ -1699,7 +1680,7 @@ extern void make_node_alloc(struct node_record *node_ptr,
 		            struct job_record *job_ptr)
 {
 	int inx = node_ptr - node_record_table_ptr;
-	uint16_t no_resp_flag, base_state;
+	uint16_t node_flags;
 
 	last_node_update = time (NULL);
 
@@ -1710,10 +1691,8 @@ extern void make_node_alloc(struct node_record *node_ptr,
 		(node_ptr->no_share_job_cnt)++;
 	}
 
-	base_state   = node_ptr->node_state & (~NODE_STATE_NO_RESPOND);
-	no_resp_flag = node_ptr->node_state &   NODE_STATE_NO_RESPOND ;
-	if (base_state != NODE_STATE_COMPLETING)
-		node_ptr->node_state = NODE_STATE_ALLOCATED | no_resp_flag;
+	node_flags = node_ptr->node_state & NODE_STATE_FLAGS;
+	node_ptr->node_state = NODE_STATE_ALLOCATED | node_flags;
 	xfree(node_ptr->reason);
 }
 
@@ -1725,7 +1704,7 @@ extern void make_node_comp(struct node_record *node_ptr,
 			   struct job_record *job_ptr)
 {
 	int inx = node_ptr - node_record_table_ptr;
-	uint16_t no_resp_flag, base_state;
+	uint16_t node_flags, base_state;
 
 	xassert(node_ptr);
 	last_node_update = time (NULL);
@@ -1744,41 +1723,40 @@ extern void make_node_comp(struct node_record *node_ptr,
 			bit_set(share_node_bitmap, inx);
 	}
 
-	base_state   = node_ptr->node_state & (~NODE_STATE_NO_RESPOND);
-	no_resp_flag = node_ptr->node_state &   NODE_STATE_NO_RESPOND;
-	if (base_state != NODE_STATE_DOWN)
-		(node_ptr->comp_job_cnt)++;	/* Don't verify  RPC */
+	base_state = node_ptr->node_state & NODE_STATE_BASE;
+	if (base_state != NODE_STATE_DOWN)  {
+		/* Don't verify  RPC if DOWN */
+		(node_ptr->comp_job_cnt)++;
+		node_ptr->node_state |= NODE_STATE_COMPLETING;
+	} 
+	node_flags = node_ptr->node_state & NODE_STATE_FLAGS;
 
-	if ((base_state == NODE_STATE_DRAINING) && 
+	if ((node_ptr->node_state & NODE_STATE_DRAIN) && 
 	    (node_ptr->run_job_cnt  == 0) &&
 	    (node_ptr->comp_job_cnt == 0)) {
 		bit_set(idle_node_bitmap, inx);
-		node_ptr->node_state = NODE_STATE_DRAINED | no_resp_flag;
+		node_ptr->node_state = NODE_STATE_IDLE | node_flags;
 	}
 
-	if ((base_state == NODE_STATE_DOWN) ||
-	    (base_state == NODE_STATE_DRAINED) ||
-	    (base_state == NODE_STATE_DRAINING)) {
-		debug3("make_node_comp: Node %s being left in state %s", 
-		       node_ptr->name, 
-		       node_state_string((enum node_states)
-					 node_ptr->node_state));
-	} else {
-		node_ptr->node_state = NODE_STATE_COMPLETING | no_resp_flag;
-		xfree(node_ptr->reason);
-	}
+	if (base_state == NODE_STATE_DOWN) {
+		debug3("make_node_comp: Node %s being left DOWN", 
+		       node_ptr->name);
+	} else if (node_ptr->run_job_cnt)
+		node_ptr->node_state = NODE_STATE_ALLOCATED | node_flags;
+	else
+		node_ptr->node_state = NODE_STATE_IDLE | node_flags;
 }
 
 /* _make_node_down - flag specified node as down */
 static void _make_node_down(struct node_record *node_ptr)
 {
 	int inx = node_ptr - node_record_table_ptr;
-	uint16_t no_resp_flag;
+	uint16_t node_flags;
 
 	xassert(node_ptr);
 	last_node_update = time (NULL);
-	no_resp_flag = node_ptr->node_state & NODE_STATE_NO_RESPOND;
-	node_ptr->node_state = NODE_STATE_DOWN | no_resp_flag;
+	node_flags = node_ptr->node_state & NODE_STATE_FLAGS;
+	node_ptr->node_state = NODE_STATE_DOWN | node_flags;
 	bit_clear (avail_node_bitmap, inx);
 	bit_set   (idle_node_bitmap,  inx);
 	bit_set   (share_node_bitmap, inx);
@@ -1793,7 +1771,7 @@ void make_node_idle(struct node_record *node_ptr,
 		    struct job_record *job_ptr)
 {
 	int inx = node_ptr - node_record_table_ptr;
-	uint16_t no_resp_flag, base_state;
+	uint16_t node_flags, base_state;
 
 	xassert(node_ptr);
 
@@ -1837,30 +1815,26 @@ void make_node_idle(struct node_record *node_ptr,
 	}
 
 	last_node_update = time (NULL);
-	base_state   = node_ptr->node_state & (~NODE_STATE_NO_RESPOND);
-	no_resp_flag = node_ptr->node_state & NODE_STATE_NO_RESPOND;
-	if ((base_state == NODE_STATE_DRAINING) && 
-	    (node_ptr->run_job_cnt == 0) && 
-	    (node_ptr->comp_job_cnt == 0)) {
-		node_ptr->node_state = NODE_STATE_DRAINED;
+	if (node_ptr->comp_job_cnt == 0)
+		node_ptr->node_state &= (~NODE_STATE_COMPLETING);
+	base_state = node_ptr->node_state & NODE_STATE_BASE;
+	node_flags = node_ptr->node_state & NODE_STATE_FLAGS;
+	if (base_state == NODE_STATE_DOWN) {
+		debug3("make_node_idle: Node %s being left DOWN",
+			node_ptr->name);
+	} else if ((node_ptr->node_state & NODE_STATE_DRAIN) &&
+	           (node_ptr->run_job_cnt == 0) &&
+	           (node_ptr->comp_job_cnt == 0)) {
+		node_ptr->node_state = NODE_STATE_IDLE | node_flags;
 		bit_set(idle_node_bitmap, inx);
 		bit_clear(avail_node_bitmap, inx);
-		debug3("make_node_idle: Node %s is %s", 
-		       node_ptr->name, 
-		       node_state_string((enum node_states)base_state));
-	} else if ((base_state == NODE_STATE_DOWN)     ||
-	           (base_state == NODE_STATE_DRAINING) ||
-	           (base_state == NODE_STATE_DRAINED)) {
-		debug3("make_node_idle: Node %s being left in state %s", 
-		       node_ptr->name, 
-		       node_state_string((enum node_states)base_state));
-	} else if (node_ptr->comp_job_cnt) {
-		node_ptr->node_state = NODE_STATE_COMPLETING | no_resp_flag;
+		debug3("make_node_idle: Node %s is DRAINED", 
+		       node_ptr->name);
 	} else if (node_ptr->run_job_cnt) {
-		node_ptr->node_state = NODE_STATE_ALLOCATED | no_resp_flag;
+		node_ptr->node_state = NODE_STATE_ALLOCATED | node_flags;
 	} else {
-		node_ptr->node_state = NODE_STATE_IDLE | no_resp_flag;
-		if (no_resp_flag == 0)
+		node_ptr->node_state = NODE_STATE_IDLE | node_flags;
+		if ((node_flags & NODE_STATE_NO_RESPOND) == 0)
 			bit_set(idle_node_bitmap, inx);
 	}
 }
diff --git a/src/slurmctld/node_scheduler.c b/src/slurmctld/node_scheduler.c
index b9bc8d5e6f02142a2b7ee3d3acf15add92a82e23..c7abd4492f38d559f9b48ce9c0fb286488ee607e 100644
--- a/src/slurmctld/node_scheduler.c
+++ b/src/slurmctld/node_scheduler.c
@@ -152,7 +152,7 @@ extern void deallocate_nodes(struct job_record *job_ptr, bool timeout)
 	kill_job_msg_t *kill_job;
 	agent_arg_t *agent_args;
 	int buf_rec_size = 0, down_node_cnt = 0;
-	uint16_t base_state, no_resp_flag;
+	uint16_t base_state;
 
 	xassert(job_ptr);
 	xassert(job_ptr->details);
@@ -177,8 +177,7 @@ extern void deallocate_nodes(struct job_record *job_ptr, bool timeout)
 		struct node_record *node_ptr = &node_record_table_ptr[i];
 		if (bit_test(job_ptr->node_bitmap, i) == 0)
 			continue;
-		base_state = node_ptr->node_state & (~NODE_STATE_NO_RESPOND);
-		no_resp_flag = node_ptr->node_state & NODE_STATE_NO_RESPOND;
+		base_state = node_ptr->node_state & NODE_STATE_BASE;
 		if (base_state == NODE_STATE_DOWN) {
 			/* Issue the KILL RPC, but don't verify response */
 			down_node_cnt++;
@@ -556,7 +555,7 @@ _pick_best_nodes(struct node_set *node_set_ptr, int node_set_size,
 					share_node_bitmap);
 				for (ni = 0; ni < node_record_count; ni++) {
 					if (node_record_table_ptr[ni].node_state
-					==  NODE_STATE_COMPLETING)
+					&  NODE_STATE_COMPLETING)
 						bit_clear(node_set_ptr[i].my_bitmap, ni);
 				}
 				/* pick_light_load = false;  Non-overlapping blocks */
@@ -1372,7 +1371,7 @@ extern void re_kill_job(struct job_record *job_ptr)
 		if ((job_ptr->node_bitmap == NULL) ||
 		    (bit_test(job_ptr->node_bitmap, i) == 0))
 			continue;
-		if ((node_ptr->node_state & (~NODE_STATE_NO_RESPOND))
+		if ((node_ptr->node_state & NODE_STATE_BASE) 
 				== NODE_STATE_DOWN) {
 			/* Consider job already completed */
 			bit_clear(job_ptr->node_bitmap, i);
diff --git a/src/slurmctld/ping_nodes.c b/src/slurmctld/ping_nodes.c
index ad40cec4f446f8b5295dcec8c08ef3b568f6d036..a6341b49c251257cff1c5d01749077c2fb93af6b 100644
--- a/src/slurmctld/ping_nodes.c
+++ b/src/slurmctld/ping_nodes.c
@@ -163,12 +163,11 @@ void ping_nodes (void)
 		if (node_ptr->last_response >= still_live_time)
 			continue;
 
-		base_state   = node_ptr->node_state & (~NODE_STATE_NO_RESPOND);
-		no_resp_flag = node_ptr->node_state &   NODE_STATE_NO_RESPOND;
-		if ((node_ptr->last_response != (time_t)0) &&
-		    (node_ptr->last_response <= node_dead_time) &&
-		    ((base_state != NODE_STATE_DOWN) &&
-		     (base_state != NODE_STATE_DRAINED))) {
+		base_state   = node_ptr->node_state & NODE_STATE_BASE;
+		no_resp_flag = node_ptr->node_state & NODE_STATE_NO_RESPOND;
+		if ((node_ptr->last_response != (time_t)0)
+		&&  (node_ptr->last_response <= node_dead_time)
+		&&  (base_state != NODE_STATE_DOWN)) {
 			if (down_hostlist)
 				(void) hostlist_push_host(down_hostlist,
 					node_ptr->name);
diff --git a/src/slurmctld/read_config.c b/src/slurmctld/read_config.c
index ba36dfeebc197de33b01556bab207e56411e1690..9207c47615878d934004992cfe105b668f0cf8f1 100644
--- a/src/slurmctld/read_config.c
+++ b/src/slurmctld/read_config.c
@@ -167,37 +167,19 @@ static int _build_bitmaps(void)
 
 		if (node_record_table_ptr[i].name[0] == '\0')
 			continue;	/* defunct */
-		base_state   = node_record_table_ptr[i].node_state & 
-			       (~NODE_STATE_NO_RESPOND);
+		base_state = node_record_table_ptr[i].node_state & 
+				NODE_STATE_BASE; 
 		no_resp_flag = node_record_table_ptr[i].node_state & 
-			       NODE_STATE_NO_RESPOND;
+				NODE_STATE_NO_RESPOND;
 		job_cnt = node_record_table_ptr[i].run_job_cnt +
 		          node_record_table_ptr[i].comp_job_cnt;
 
-		if ((base_state == NODE_STATE_DRAINED) &&
-		    (job_cnt > 0)) {
-			error("Bad node drain state for %s", 
-				node_record_table_ptr[i].name);
-			node_record_table_ptr[i].node_state =
-				NODE_STATE_DRAINING | no_resp_flag;
-		}
-		if ((base_state == NODE_STATE_DRAINING) &&
-		    (job_cnt == 0)) {
-			error("Bad node drain state for %s",
-				node_record_table_ptr[i].name);
-			node_record_table_ptr[i].node_state =
-				NODE_STATE_DRAINED | no_resp_flag;
-		}
-
-		if ((base_state == NODE_STATE_IDLE   ) ||
-		    (base_state == NODE_STATE_DOWN   ) ||
-		    (base_state == NODE_STATE_DRAINED))
+		if ((base_state == NODE_STATE_IDLE)
+		||  (base_state == NODE_STATE_DOWN))
 			bit_set(idle_node_bitmap, i);
-		if ((base_state != NODE_STATE_DOWN)     &&
-		    (base_state != NODE_STATE_UNKNOWN)  &&
-		    (base_state != NODE_STATE_DRAINING) &&
-		    (base_state != NODE_STATE_DRAINED)  &&
-		    (no_resp_flag == 0))
+		if ((base_state == NODE_STATE_IDLE)
+		||  (base_state == NODE_STATE_ALLOCATED)
+		&&  (no_resp_flag == 0))
 			bit_set(avail_node_bitmap, i);
 		if (node_record_table_ptr[i].config_ptr)
 			bit_set(node_record_table_ptr[i].config_ptr->
@@ -354,8 +336,9 @@ static int _parse_node_spec(char *in_line)
 				break;
 			}
 		}
-		if ((state_val == NO_VAL) ||
-		    (state_val == NODE_STATE_COMPLETING)) {
+		if ((i == 0) && (strncasecmp("DRAIN", state, 5) == 0))
+			state_val = NODE_STATE_IDLE | NODE_STATE_DRAIN;
+		if (state_val == NO_VAL) {
 			error("_parse_node_spec: invalid initial state %s for "
 				"node %s", state, node_name);
 			error_code = EINVAL;
@@ -464,8 +447,7 @@ static int _parse_node_spec(char *in_line)
 #endif
 			node_ptr->reason = xstrdup(reason);
 		} else {
-			error
-			    ("_parse_node_spec: reconfiguration for node %s",
+			error("_parse_node_spec: reconfiguration for node %s",
 			     this_node_name);
 			if ((state_val != NO_VAL) &&
 			    (state_val != NODE_STATE_UNKNOWN))
@@ -1080,14 +1062,17 @@ static int _sync_nodes_to_comp_job(void)
 static int _sync_nodes_to_active_job(struct job_record *job_ptr)
 {
 	int i, cnt = 0;
-	uint16_t base_state, no_resp_flag;
+	uint16_t base_state, node_flags;
 
 	for (i = 0; i < node_record_count; i++) {
 		if (bit_test(job_ptr->node_bitmap, i) == 0)
 			continue;
 
 		base_state = node_record_table_ptr[i].node_state & 
-			     (~NODE_STATE_NO_RESPOND);
+				NODE_STATE_BASE;
+		node_flags = node_record_table_ptr[i].node_state & 
+				NODE_STATE_FLAGS;
+ 
 		node_record_table_ptr[i].run_job_cnt++; /* NOTE:
 				* This counter moved to comp_job_cnt 
 				* by _sync_nodes_to_comp_job() */
@@ -1103,19 +1088,11 @@ static int _sync_nodes_to_active_job(struct job_record *job_ptr)
 			delete_all_step_records(job_ptr);
 			job_completion_logger(job_ptr);
 			cnt++;
-		} else {
-			no_resp_flag = node_record_table_ptr[i].node_state & 
-				       NODE_STATE_NO_RESPOND;
-			if ((base_state == NODE_STATE_UNKNOWN) || 
-			    (base_state == NODE_STATE_IDLE)) {
-				cnt++;
-				node_record_table_ptr[i].node_state =
-				    NODE_STATE_ALLOCATED | no_resp_flag;
-			} else if (base_state == NODE_STATE_DRAINED) {
-				cnt++;
-				node_record_table_ptr[i].node_state =
-				    NODE_STATE_DRAINING | no_resp_flag;
-			}
+		} else if ((base_state == NODE_STATE_UNKNOWN) || 
+			   (base_state == NODE_STATE_IDLE)) {
+			cnt++;
+			node_record_table_ptr[i].node_state =
+				NODE_STATE_ALLOCATED | node_flags;
 		} 
 	}
 	return cnt;
@@ -1145,8 +1122,8 @@ static void _validate_node_proc_count(void)
 				node_size = node_ptr->config_ptr->cpus;
 			else if (node_ptr->cpus < node_ptr->config_ptr->cpus)
 				continue;	/* node too small, will be DOWN */
-			else if ((node_ptr->node_state & (~NODE_STATE_NO_RESPOND))
-			     == NODE_STATE_DOWN)
+			else if ((node_ptr->node_state & NODE_STATE_BASE) 
+					== NODE_STATE_DOWN)
 				continue;
 			else
 				node_size = node_ptr->cpus;
diff --git a/src/slurmctld/sched_upcalls.c b/src/slurmctld/sched_upcalls.c
index 8e461f2ddc070b6c41dc810aa0a94cf3acffad7c..42ef602a87570aab97f93905f377993c4f6481c0 100644
--- a/src/slurmctld/sched_upcalls.c
+++ b/src/slurmctld/sched_upcalls.c
@@ -940,9 +940,6 @@ sched_get_node_state( sched_obj_list_t node_data,
 		{ NODE_STATE_UNKNOWN,	NODE_STATE_LABEL_DOWN },
 		{ NODE_STATE_IDLE,     	NODE_STATE_LABEL_IDLE },
 		{ NODE_STATE_ALLOCATED,	NODE_STATE_LABEL_ALLOCATED },
-		{ NODE_STATE_DRAINED,	NODE_STATE_LABEL_DRAINED },
-		{ NODE_STATE_DRAINING,	NODE_STATE_LABEL_DRAINING },
-		{ NODE_STATE_COMPLETING, NODE_STATE_LABEL_COMPLETING },
 		{ NODE_STATE_END,      	NODE_STATE_LABEL_UNKNOWN }
 	};
 
@@ -955,7 +952,15 @@ sched_get_node_state( sched_obj_list_t node_data,
 	if ( state & NODE_STATE_NO_RESPOND ) {
 		return NODE_STATE_LABEL_DOWN;
 	}
-	
+	if ( state & NODE_STATE_COMPLETING ) {
+		return NODE_STATE_LABEL_COMPLETING;
+	}
+	if ( state & NODE_STATE_DRAIN ) {
+		if ((state & NODE_STATE_COMPLETING)
+		||  ((state & NODE_STATE_BASE) == NODE_STATE_ALLOCATED))
+			return NODE_STATE_LABEL_DRAINING;
+		return NODE_STATE_LABEL_DRAINED;
+	}
 	for ( p = node_state_label_map;
 		  p->state != NODE_STATE_END;
 		  ++p ) {
diff --git a/src/smap/grid_functions.c b/src/smap/grid_functions.c
index b565df3837b9fca506ce3853ed20a734ec41e12a..d94f130312a23d6c162b9d7c28166ab55d00240d 100644
--- a/src/smap/grid_functions.c
+++ b/src/smap/grid_functions.c
@@ -43,9 +43,7 @@ extern int set_grid(int start, int end, int count)
 				if ((pa_system_ptr->grid[x][y][z].state 
 				     == NODE_STATE_DOWN)
 				    ||  (pa_system_ptr->grid[x][y][z].state 
-					 == NODE_STATE_DRAINED)
-				    ||  (pa_system_ptr->grid[x][y][z].state 
-					 == NODE_STATE_DRAINING))
+					 & NODE_STATE_DRAIN))
 					continue;
 				
 				pa_system_ptr->grid[x][y][z].letter = 
@@ -61,8 +59,7 @@ extern int set_grid(int start, int end, int count)
 		    ||  (pa_system_ptr->grid[x].indecies > end)) 
 			continue;
 		if ((pa_system_ptr->grid[x].state == NODE_STATE_DOWN)
-		    ||  (pa_system_ptr->grid[x].state == NODE_STATE_DRAINED)
-		    ||  (pa_system_ptr->grid[x].state == NODE_STATE_DRAINING))
+		    ||  (pa_system_ptr->grid[x].state & NODE_STATE_DRAIN))
 			continue;
 
 		pa_system_ptr->grid[x].letter =