diff --git a/doc/man/man1/slurmctld.1 b/doc/man/man1/slurmctld.1
index 6815073ab5802d4c98196a78dd7d2aa5db346d55..5f99463ec68a4a60f224b7574465aab757a182bc 100644
--- a/doc/man/man1/slurmctld.1
+++ b/doc/man/man1/slurmctld.1
@@ -33,6 +33,10 @@ Write log messages to the specified file.
 \fB-s <errlev>\fR
 Set syslog logging to the specified level.
 .TP
+\fB-r\fR
+Recover \fBslurmctld\fR state from its last checkpoint 
+(performed periodically and at time of graceful shutdown).
+.TP
 ARGUMENTS
 .TP
 \fIerrlev\fP
diff --git a/src/common/xstring.h b/src/common/xstring.h
index 8dfdb5bce6105c08b98425615c0de0ef96abc89e..6e0c0375dd66ce099a10a07dcc47ebf97f58eeff 100644
--- a/src/common/xstring.h
+++ b/src/common/xstring.h
@@ -1,7 +1,7 @@
 /*****************************************************************************\
  *  xstring.h - "safe" string processing functions with automatic memory 
-  *	management
-******************************************************************************
+ *	management
+ ******************************************************************************
  *  Copyright (C) 2002 The Regents of the University of California.
  *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
  *  Written by Jim Garlick <garlick@llnl.gov>, et. al.
diff --git a/src/slurmctld/controller.c b/src/slurmctld/controller.c
index 05392f38e401900023b9630aa974900356a4772a..b7fe84aa1e86a14cd9efaf8f1f850f857edadc48 100644
--- a/src/slurmctld/controller.c
+++ b/src/slurmctld/controller.c
@@ -67,6 +67,7 @@ pthread_t thread_id_main = (pthread_t)0;
 pthread_t thread_id_rpc = (pthread_t)0;
 extern slurm_ssl_key_ctx_t sign_ctx ;
 int daemonize = 0;
+int recover = 0;
 
 int msg_from_root (void);
 void slurmctld_req ( slurm_msg_t * msg );
@@ -75,6 +76,7 @@ void init_ctld_conf ( slurm_ctl_conf_t * build_ptr );
 void parse_commandline( int argc, char* argv[], slurm_ctl_conf_t * );
 void *process_rpc ( void * req );
 void report_locks_set ( void );
+inline static void save_all_state ( void );
 void *slurmctld_background ( void * no_data );
 void slurmctld_cleanup (void *context);
 void *slurmctld_rpc_mgr( void * no_data );
@@ -133,7 +135,7 @@ main (int argc, char *argv[])
 	}
 	init_locks ( );
 
-	if ( ( error_code = read_slurm_conf ()) ) 
+	if ( ( error_code = read_slurm_conf (recover)) ) 
 		fatal ("read_slurm_conf error %d reading %s", error_code, SLURM_CONFIG_FILE);
 	if ( ( error_code = getnodename (node_name, MAX_NAME_LEN) ) ) 
 		fatal ("getnodename errno %d", error_code);
@@ -203,7 +205,7 @@ main (int argc, char *argv[])
 				break;
 			case SIGHUP:	/* kill -1 */
 				info ("Reconfigure signal (SIGHUP) received\n");
-				error_code = read_slurm_conf ( );
+				error_code = read_slurm_conf (0);
 				if (error_code)
 					error ("read_slurm_conf error %d", error_code);
 				break;
@@ -362,12 +364,12 @@ slurmctld_background ( void * no_data )
 				report_locks_set ( );
 				last_checkpoint_time = now;
 				/* don't lock to insure checkpoint never blocks */
-				/* issue call to save state */
+				save_all_state ( );
 			}
 			else {
 				last_checkpoint_time = now;
 				lock_slurmctld (state_write_lock);
-				/* issue call to save state */
+				save_all_state ( );
 				unlock_slurmctld (state_write_lock);
 			}
 		}
@@ -377,6 +379,13 @@ slurmctld_background ( void * no_data )
 	pthread_exit ((void *)0);
 }
 
+/* save_all_state - save slurmctld state for later recovery */
+void
+save_all_state ( void )
+{
+	dump_all_node_state ( );
+}
+
 /* report_locks_set - report any slurmctld locks left set */
 void
 report_locks_set ( void )
@@ -1116,7 +1125,7 @@ slurm_rpc_reconfigure_controller ( slurm_msg_t * msg )
 /* must be user root */
 
 	/* do RPC call */
-	error_code = read_slurm_conf ( );
+	error_code = read_slurm_conf (0);
 
 	/* return result */
 	if (error_code)
@@ -1388,7 +1397,7 @@ parse_commandline( int argc, char* argv[], slurm_ctl_conf_t * conf_ptr )
 	char *log_file = NULL;
 
 	opterr = 0;
-	while ((c = getopt (argc, argv, "de:f:hl:L:s:")) != -1)
+	while ((c = getopt (argc, argv, "de:f:hl:L:rs:")) != -1)
 		switch (c)
 		{
 			case 'd':
@@ -1425,6 +1434,9 @@ parse_commandline( int argc, char* argv[], slurm_ctl_conf_t * conf_ptr )
 			case 'L':
 				log_file = optarg;
 				break;
+			case 'r':
+				recover = 1;
+				break;
 			case 's':
 				errlev = strtol (optarg, (char **) NULL, 10);
 				if ((errlev < LOG_LEVEL_QUIET) || 
@@ -1455,6 +1467,7 @@ usage (char *prog_name)
 	printf ("  -l <errlev>  Set logfile logging to the specified level\n");
 	printf ("  -L <file>    Set logfile to the supplied file name\n");
 	printf ("  -s <errlev>  Set syslog logging to the specified level\n");
+	printf ("  -r           Recover state from last checkpoint\n");
 	printf ("<errlev> is an integer between 0 and 7 with higher numbers providing more detail.\n");
 }
 
diff --git a/src/slurmctld/job_mgr.c b/src/slurmctld/job_mgr.c
index f24a104f5bd88f136dec9d501c9d886fff1f5bd4..d7f5eaae5a885dddccca0c25cd092f472d7715f8 100644
--- a/src/slurmctld/job_mgr.c
+++ b/src/slurmctld/job_mgr.c
@@ -74,8 +74,6 @@ void	delete_job_desc_files (uint32_t job_id);
 void	list_delete_job (void *job_entry);
 int	list_find_job_id (void *job_entry, void *key);
 int	list_find_job_old (void *job_entry, void *key);
-int 	mkdir2 (char * path, int modes);
-int 	rmdir2 (char * path);
 int	top_priority (struct job_record *job_ptr);
 int 	validate_job_desc ( job_desc_msg_t * job_desc_msg , int allocate ) ;
 int	write_data_to_file ( char * file_name, char * data ) ;
@@ -768,8 +766,6 @@ copy_job_desc_to_file ( job_desc_msg_t * job_desc , uint32_t job_id )
 	dir_name = xstrdup (slurmctld_conf . state_save_location);
 	if (dir_name == NULL)
 		fatal ("Memory exhausted");
-	if (stat (dir_name, &sbuf) == -1)	/* create base directory as needed */
-		(void) mkdir2 (dir_name, 0744);
 
 	/* Create job_id specific directory */
 	sprintf (job_dir, "/job.%d", job_id);
diff --git a/src/slurmctld/node_mgr.c b/src/slurmctld/node_mgr.c
index a3b63a622d886d0a770cdc9b5d794dc3353bafe2..5d60ceac52ba094bc3f35b7effbc3ae4e8ebcf61 100644
--- a/src/slurmctld/node_mgr.c
+++ b/src/slurmctld/node_mgr.c
@@ -35,16 +35,21 @@
 #include <errno.h>
 #include <stdio.h>
 #include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
 
 #include <src/common/hostlist.h>
+#include <src/common/xstring.h>
 #include <src/slurmctld/locks.h>
 #include <src/slurmctld/slurmctld.h>
 
-#define BUF_SIZE 	1024
+#define BUF_SIZE 	4096
 
 List config_list = NULL;		/* list of config_record entries */
 struct node_record *node_record_table_ptr = NULL;	/* location of the node records */
-int *hash_table = NULL;		/* table of hashed indicies into node_record */
+int *hash_table = NULL;			/* table of hashed indicies into node_record */
 struct config_record default_config_record;
 struct node_record default_node_record;
 time_t last_bitmap_update = (time_t) NULL;	/* time of last node creation or deletion */
@@ -55,7 +60,9 @@ bitstr_t *idle_node_bitmap = NULL;	/* bitmap of nodes are idle */
 
 int	delete_config_record ();
 void	dump_hash ();
+void 	dump_node_state (struct node_record *dump_node_ptr, void **buf_ptr, int *buf_len);
 int	hash_index (char *name);
+void 	pack_node (struct node_record *dump_node_ptr, void **buf_ptr, int *buf_len);
 void	split_node_name (char *name, char *prefix, char *suffix, int *index, int *digits);
 
 #if DEBUG_MODULE
@@ -516,6 +523,170 @@ dump_hash ()
 }
 
 
+/* 
+ * dump_all_node_state - save the state of all nodes to file
+ */
+int
+dump_all_node_state ( void )
+{
+	int buf_len, buffer_allocated, buffer_offset = 0, error_code = 0, inx, log_fd;
+	char *buffer;
+	char *old_file, *new_file, *reg_file;
+	void *buf_ptr;
+
+	old_file = xstrdup (slurmctld_conf.state_save_location);
+	xstrcat (old_file, "/node_state.old");
+	new_file = xstrdup (slurmctld_conf.state_save_location);
+	xstrcat (new_file, "/node_state");
+
+	buffer_allocated = (BUF_SIZE*16);
+	buffer = xmalloc(buffer_allocated);
+	buf_ptr = buffer;
+	buf_len = buffer_allocated;
+
+	/* write header: time */
+	pack32  ((uint32_t) time (NULL), &buf_ptr, &buf_len);
+
+	/* write node records to buffer */
+	for (inx = 0; inx < node_record_count; inx++) {
+		if ((node_record_table_ptr[inx].magic != NODE_MAGIC) ||
+		    (node_record_table_ptr[inx].config_ptr->magic != CONFIG_MAGIC))
+			fatal ("pack_all_node: data integrity is bad");
+
+		dump_node_state(&node_record_table_ptr[inx], &buf_ptr, &buf_len);
+		if (buf_len > BUF_SIZE) 
+			continue;
+		buffer_allocated += (BUF_SIZE*16);
+		buf_len += (BUF_SIZE*16);
+		buffer_offset = (char *)buf_ptr - buffer;
+		xrealloc(buffer, buffer_allocated);
+		buf_ptr = buffer + buffer_offset;
+	}
+
+	/* write the buffer to file */
+	old_file = xstrdup (slurmctld_conf.state_save_location);
+	xstrcat (old_file, "/node_state.old");
+	reg_file = xstrdup (slurmctld_conf.state_save_location);
+	xstrcat (reg_file, "/node_state");
+	new_file = xstrdup (slurmctld_conf.state_save_location);
+	xstrcat (new_file, "/node_state.new");
+	lock_state_files ();
+	log_fd = creat (new_file, 0600);
+	if (log_fd == 0) {
+		error ("Create error %d on file %s, can't save state", errno, new_file);
+		error_code = errno;
+	}
+	else {
+		buf_len = buffer_allocated - buf_len;
+		if (write (log_fd, buffer, buf_len) != buf_len) {
+			error ("Write error %d on file %s, can't save state", errno, new_file);
+			error_code = errno;
+		}
+		close (log_fd);
+	}
+	if (error_code) 
+		(void) unlink (new_file);
+	else {	/* file shuffle */
+		(void) unlink (old_file);
+		(void) link (reg_file, old_file);
+		(void) unlink (reg_file);
+		(void) link (new_file, reg_file);
+		(void) unlink (new_file);
+	}
+	xfree (old_file);
+	xfree (new_file);
+	unlock_state_files ();
+
+	xfree (buffer);
+	return error_code;
+}
+
+/*
+ * dump_node_state - dump the state of a specific node to a buffer
+ * input:  dump_node_ptr - pointer to node for which information is requested
+ *	buf_ptr - buffer for node information 
+ *	buf_len - byte size of buffer
+ * output: buf_ptr - advanced to end of data written
+ *	buf_len - byte size remaining in buffer
+ */
+void 
+dump_node_state (struct node_record *dump_node_ptr, void **buf_ptr, int *buf_len) 
+{
+	packstr (dump_node_ptr->name, buf_ptr, buf_len);
+	pack16  (dump_node_ptr->node_state, buf_ptr, buf_len);
+	pack32  (dump_node_ptr->config_ptr->cpus, buf_ptr, buf_len);
+	pack32  (dump_node_ptr->config_ptr->real_memory, buf_ptr, buf_len);
+	pack32  (dump_node_ptr->config_ptr->tmp_disk, buf_ptr, buf_len);
+}
+
+/*
+ * load_node_state - load the node state from file, recover from slurmctld restart.
+ *	execute this after loading the configuration file data.
+ */
+int
+load_node_state ( void )
+{
+	char *node_name, *state_file;
+	int buffer_allocated, buffer_used = 0, error_code = 0;
+	int state_fd;
+	uint16_t node_state, name_len;
+	uint32_t time, cpus, real_memory, tmp_disk;
+	struct node_record *node_ptr;
+	uint32_t buffer_size = 0;
+	char *buffer;
+	void *buf_ptr;
+
+	/* read the file */
+	state_file = xstrdup (slurmctld_conf.state_save_location);
+	xstrcat (state_file, "/node_state");
+	lock_state_files ();
+	state_fd = open (state_file, O_RDONLY);
+	if (state_fd < 0) {
+		info ("No node_state file (%s) to recover", state_file);
+		error_code = ENOENT;
+	}
+	else {
+		buffer_allocated = BUF_SIZE;
+		buffer = xmalloc(buffer_allocated);
+		buf_ptr = buffer;
+		while ((buffer_used = read (state_fd, buf_ptr, BUF_SIZE)) == BUF_SIZE) {
+			buffer_size += buffer_used;
+			buffer_allocated += BUF_SIZE;
+			xrealloc(buffer, buffer_allocated);
+			buf_ptr = (void *) (buffer + buffer_size);
+		}
+		buffer_size += buffer_used;
+		close (state_fd);
+		if (buffer_used < 0) 
+			error ("Read error %d on %s", errno, state_file);
+	}
+	xfree (state_file);
+	unlock_state_files ();
+
+	if (buffer_size > sizeof (uint32_t))
+		unpack32 (&time, &buf_ptr, &buffer_size);
+
+	while (buffer_size >= (4 *sizeof (uint32_t))) {
+		unpackstr_xmalloc (&node_name, &name_len, &buf_ptr, &buffer_size);
+		unpack16 (&node_state, &buf_ptr, &buffer_size);
+		unpack32 (&cpus, &buf_ptr, &buffer_size);
+		unpack32 (&real_memory, &buf_ptr, &buffer_size);
+		unpack32 (&tmp_disk, &buf_ptr, &buffer_size);
+
+		/* find record and perform update */
+		node_ptr = find_node_record (node_name);
+		if (node_ptr) {
+			node_ptr->node_state = node_state;
+			node_ptr->cpus = cpus;
+			node_ptr->real_memory = real_memory;
+			node_ptr->tmp_disk = tmp_disk;
+		}
+		if (node_name)
+			xfree (node_name);
+	}
+	return error_code;
+}
+
 /* 
  * find_node_record - find a record for node with specified name
  * input: name - name of the desired node 
@@ -785,7 +956,6 @@ node_name2bitmap (char *node_names, bitstr_t **bitmap)
  *         update_time - set to time partition records last updated
  * global: node_record_table_ptr - pointer to global node table
  * NOTE: the caller must xfree the buffer at *buffer_ptr when no longer required
- * NOTE: change NODE_STRUCT_VERSION in common/slurmlib.h whenever the format changes
  * NOTE: change slurm_load_node() in api/node_info.c whenever the data format changes
  */
 void 
@@ -809,7 +979,7 @@ pack_all_node (char **buffer_ptr, int *buffer_size, time_t * update_time)
 	buf_ptr = buffer;
 	buf_len = buffer_allocated;
 
-	/* write haeader: version and time */
+	/* write header: version and time */
 	nodes_packed = 0 ;
 	pack32  ((uint32_t) nodes_packed, &buf_ptr, &buf_len);
 	pack32  ((uint32_t) last_node_update, &buf_ptr, &buf_len);
@@ -821,17 +991,14 @@ pack_all_node (char **buffer_ptr, int *buffer_size, time_t * update_time)
 			fatal ("pack_all_node: data integrity is bad");
 
 		pack_node(&node_record_table_ptr[inx], &buf_ptr, &buf_len);
+		nodes_packed ++ ;
 		if (buf_len > BUF_SIZE) 
-		{
-			nodes_packed ++ ;
 			continue;
-		}
 		buffer_allocated += (BUF_SIZE*16);
 		buf_len += (BUF_SIZE*16);
 		buffer_offset = (char *)buf_ptr - buffer;
 		xrealloc(buffer, buffer_allocated);
 		buf_ptr = buffer + buffer_offset;
-		nodes_packed ++ ;
 	}
 
 	unlock_slurmctld (node_read_lock);
@@ -857,8 +1024,8 @@ pack_all_node (char **buffer_ptr, int *buffer_size, time_t * update_time)
  *	buf_len - byte size of buffer
  * output: buf_ptr - advanced to end of data written
  *	buf_len - byte size remaining in buffer
- * NOTE: if you make any changes here be sure to increment the value of NODE_STRUCT_VERSION
- *	and make the corresponding changes to load_node_config in api/node_info.c
+ * NOTE: if you make any changes here be sure to make the corresponding changes to 
+ *	load_node_config in api/node_info.c
  */
 void 
 pack_node (struct node_record *dump_node_ptr, void **buf_ptr, int *buf_len) 
diff --git a/src/slurmctld/partition_mgr.c b/src/slurmctld/partition_mgr.c
index b4bda9fd4c963f2d01f9f4c4eda7243fd782ab70..9728cde7ece2d1f7fd7e1939c85698530d86d3b0 100644
--- a/src/slurmctld/partition_mgr.c
+++ b/src/slurmctld/partition_mgr.c
@@ -50,6 +50,7 @@ struct part_record *default_part_loc = NULL;	/* location of default partition */
 time_t last_part_update;		/* time of last update to partition records */
 
 int	build_part_bitmap (struct part_record *part_record_point);
+void	dump_part_state (struct part_record *part_record_point, void **buf_ptr, int *buf_len);
 void	list_delete_part (void *part_entry);
 int	list_find_part (void *part_entry, void *key);
 
@@ -316,6 +317,148 @@ delete_part_record (char *name)
 }
 
 
+/* 
+ * dump_all_part_state - save the state of all partitions to file
+ */
+int
+dump_all_part_state ( void )
+{
+	ListIterator part_record_iterator;
+	struct part_record *part_record_point;
+	int buf_len, buffer_allocated, buffer_offset = 0;
+	char *buffer;
+	void *buf_ptr;
+	/* Locks: Read partition */
+	slurmctld_lock_t part_read_lock = { NO_LOCK, NO_LOCK, NO_LOCK, READ_LOCK };
+
+	lock_slurmctld (part_read_lock);
+
+	buffer_allocated = (BUF_SIZE*16);
+	buffer = xmalloc(buffer_allocated);
+	buf_ptr = buffer;
+	buf_len = buffer_allocated;
+
+	/* write header: time */
+	pack32  ((uint32_t) time (NULL), &buf_ptr, &buf_len);
+
+	/* write partition records to buffer */
+	part_record_iterator = list_iterator_create (part_list);		
+	while ((part_record_point = (struct part_record *) list_next (part_record_iterator))) {
+		if (part_record_point->magic != PART_MAGIC)
+			fatal ("pack_all_part: data integrity is bad");
+
+		dump_part_state (part_record_point, &buf_ptr, &buf_len);
+		if (buf_len > BUF_SIZE) 
+			continue;
+		buffer_allocated += (BUF_SIZE*16);
+		buf_len += (BUF_SIZE*16);
+		buffer_offset = (char *)buf_ptr - buffer;
+		xrealloc(buffer, buffer_allocated);
+		buf_ptr = buffer + buffer_offset;
+	}			
+	list_iterator_destroy (part_record_iterator);
+	unlock_slurmctld (part_read_lock);
+
+	/* write the buffer to file */
+	lock_state_files ();
+
+	unlock_state_files ();
+
+	xfree (buffer);
+	return 0;
+}
+
+/*
+ * dump_part_state - dump the state of a specific partition to a buffer
+ * input:  part_record_point - pointer to partition for which information is requested
+ *	buf_ptr - buffer for node information 
+ *	buf_len - byte size of buffer
+ * output: buf_ptr - advanced to end of data written
+ *	buf_len - byte size remaining in buffer
+ */
+void 
+dump_part_state (struct part_record *part_record_point, void **buf_ptr, int *buf_len) 
+{
+	uint16_t default_part_flag;
+
+	if (default_part_loc == part_record_point)
+		default_part_flag = 1;
+	else
+		default_part_flag = 0;
+
+	packstr (part_record_point->name, buf_ptr, buf_len);
+	pack32  (part_record_point->max_time, buf_ptr, buf_len);
+	pack32  (part_record_point->max_nodes, buf_ptr, buf_len);
+
+	pack16  (default_part_flag, buf_ptr, buf_len);
+	pack16  ((uint16_t)part_record_point->root_only, buf_ptr, buf_len);
+	pack16  ((uint16_t)part_record_point->shared, buf_ptr, buf_len);
+
+	pack16  ((uint16_t)part_record_point->state_up, buf_ptr, buf_len);
+	packstr (part_record_point->allow_groups, buf_ptr, buf_len);
+	packstr (part_record_point->nodes, buf_ptr, buf_len);
+}
+
+/*
+ * load_part_state - load the partition state from file, recover from slurmctld restart.
+ *	execute this after loading the configuration file data.
+ */
+int
+load_part_state ( void )
+{
+	char *part_name, *allow_groups, *nodes;
+	uint32_t dump_time, max_time, max_nodes;
+	uint16_t name_len, def_part_flag, root_only, shared, state_up;
+	struct part_record *part_ptr;
+	uint32_t buffer_size;
+	void *buf_ptr;
+
+	/* read the file */
+	lock_state_files ();
+	unpack32 (&dump_time, &buf_ptr, &buffer_size);
+
+	while (1) {
+		unpackstr_xmalloc (&part_name, &name_len, &buf_ptr, &buffer_size);
+		unpack32 (&max_time, &buf_ptr, &buffer_size);
+		unpack32 (&max_nodes, &buf_ptr, &buffer_size);
+		unpack16 (&def_part_flag, &buf_ptr, &buffer_size);
+		unpack16 (&root_only, &buf_ptr, &buffer_size);
+		unpack16 (&shared, &buf_ptr, &buffer_size);
+		unpack16 (&state_up, &buf_ptr, &buffer_size);
+		unpackstr_xmalloc (&allow_groups, &name_len, &buf_ptr, &buffer_size);
+		unpackstr_xmalloc (&nodes, &name_len, &buf_ptr, &buffer_size);
+
+		/* find record and perform update */
+		part_ptr = list_find_first (part_list, &list_find_part, part_name);
+
+		if (part_ptr == NULL) {
+			error ("load_part_state: partition %s removed from configuration file.",
+				part_name);
+		}
+		else {
+			part_ptr->max_time = max_time;
+			part_ptr->max_nodes = max_nodes;
+			if (def_part_flag) {
+				strcpy (default_part_name, part_name);
+				default_part_loc = part_ptr;	
+			}
+			part_ptr->root_only = root_only;
+			part_ptr->shared = shared;
+			part_ptr->state_up = state_up;
+			if (part_ptr->allow_groups)
+				xfree (part_ptr->allow_groups);
+			part_ptr->allow_groups = allow_groups;
+			if (part_ptr->nodes)
+				xfree (part_ptr->nodes);
+			part_ptr->allow_groups = nodes;
+		}		
+
+		if (part_name)
+			xfree (part_name);
+	}
+	unlock_state_files ();
+}
+
 /* 
  * find_part_record - find a record for partition with specified name
  * input: name - name of the desired partition 
@@ -475,17 +618,14 @@ pack_all_part (char **buffer_ptr, int *buffer_size, time_t * update_time)
 			fatal ("pack_all_part: data integrity is bad");
 
 		pack_part(part_record_point, &buf_ptr, &buf_len);
+		parts_packed ++ ;
 		if (buf_len > BUF_SIZE) 
-		{
-			parts_packed ++ ;
 			continue;
-		}
 		buffer_allocated += (BUF_SIZE*16);
 		buf_len += (BUF_SIZE*16);
 		buffer_offset = (char *)buf_ptr - buffer;
 		xrealloc(buffer, buffer_allocated);
 		buf_ptr = buffer + buffer_offset;
-		parts_packed ++ ;
 	}			
 
 	list_iterator_destroy (part_record_iterator);
diff --git a/src/slurmctld/read_config.c b/src/slurmctld/read_config.c
index bce28bb8cb3a1e59d9852cb6f11e89579726148e..297fffbeafa67f36b3383899d9875483298a1c62 100644
--- a/src/slurmctld/read_config.c
+++ b/src/slurmctld/read_config.c
@@ -1,5 +1,5 @@
 /*****************************************************************************\
- * read_config.c - read the overall slurm configuration file
+ *  read_config.c - read the overall slurm configuration file
  *****************************************************************************
  *  Copyright (C) 2002 The Regents of the University of California.
  *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
@@ -34,6 +34,8 @@
 #include <stdio.h>
 #include <string.h>
 #include <syslog.h>
+#include <sys/types.h>
+#include <sys/stat.h>
 #include <unistd.h>
 
 #include <src/common/hostlist.h>
@@ -73,7 +75,7 @@ main (int argc, char *argv[]) {
 		exit (1);
 	}			
 
-	error_code = read_slurm_conf ( );
+	error_code = read_slurm_conf (0);
 	if (error_code) {
 		printf ("ERROR %d from read_slurm_conf\n", error_code);
 		exit (error_code);
@@ -149,7 +151,7 @@ main (int argc, char *argv[]) {
 		sleep (5);
 	}
 	for (i = 0; i < cycles; i++) {
-		error_code = read_slurm_conf ( );
+		error_code = read_slurm_conf (0);
 		if (error_code) {
 			printf ("ERROR %d from read_slurm_conf\n",
 				error_code);
@@ -361,6 +363,7 @@ parse_config_spec (char *in_line)
 	char *job_credential_private_key = NULL , *job_credential_public_certificate = NULL;
 	long first_job_id = 0;
 	struct servent *servent;
+	struct stat sbuf;
 
 	error_code = slurm_parser(in_line,
 		"BackupController=", 's', &backup_controller, 
@@ -455,6 +458,8 @@ parse_config_spec (char *in_line)
 		if ( slurmctld_conf.state_save_location )
 			xfree (slurmctld_conf.state_save_location);
 		slurmctld_conf.state_save_location = state_save_location;
+		if (stat (state_save_location, &sbuf) == -1)	/* create directory as needed */
+			(void) mkdir2 (state_save_location, 0744);
 	}
 
 	if ( tmp_fs ) {
@@ -831,10 +836,11 @@ parse_part_spec (char *in_line) {
 /*
  * read_slurm_conf - load the slurm configuration from the configured file. 
  * read_slurm_conf can be called more than once if so desired.
+ * input: recover - set to use state saved from last slurmctld shutdown
  * output: return - 0 if no error, otherwise an error code
  */
 int 
-read_slurm_conf ( ) {
+read_slurm_conf (int recover) {
 	clock_t start_time;
 	FILE *slurm_spec_file;	/* pointer to input data file */
 	int line_num;		/* line number in input file */
@@ -940,6 +946,11 @@ read_slurm_conf ( ) {
 		
 	rehash ();
 	set_slurmd_addr ();
+
+	if (recover) {
+		(void) load_node_state ();
+	}
+
 	if ((error_code = build_bitmaps ())) {
 		unlock_slurmctld (config_write_lock);
 		return error_code;
diff --git a/src/slurmctld/slurmctld.h b/src/slurmctld/slurmctld.h
index ef4d0a3d56c664d821e2dc81d539220993a0021c..0982e9d35630a710f848550cfa92e299b493dd00 100644
--- a/src/slurmctld/slurmctld.h
+++ b/src/slurmctld/slurmctld.h
@@ -259,6 +259,12 @@ extern int delete_part_record (char *name);
 /* delete_step_record - delete record for job step for specified job_ptr and step_id */
 extern int delete_step_record (struct job_record *job_ptr, uint32_t step_id);
 
+/* dump_all_node_state - save the state of all nodes to file */
+extern int dump_all_node_state ( void );
+
+/* dump_all_part_state - save the state of all partitions to file */
+extern int dump_all_part_state ( void );
+
 /* dump_job_desc - dump the incoming job submit request message */
 extern void dump_job_desc(job_desc_msg_t * job_specs);
 
@@ -342,12 +348,21 @@ extern void list_delete_part (void *part_entry);
 /* list_find_part - find an entry in the partition list */
 extern int list_find_part (void *part_entry, void *key);
 
+/* load_node_state - load the node state from file, recover from slurmctld restart */
+extern int load_node_state ( void );
+
+/* load_part_state - load the partition state from file, recover from slurmctld restart */
+extern int load_node_state ( void );
+
 /* match_feature - determine if the desired feature (seek) is one of those available */
 extern int  match_feature (char *seek, char *available);
 
 /* match_group - determine if the user is a member of any groups permitted to use this partition */
 extern int match_group (char *allow_groups, char *user_groups);
 
+/* mkdir2 - issues system calls for mkdir (if root) */
+int mkdir2 (char * path, int modes);
+
 /* node_name2bitmap - given a node name regular expression, build a bitmap representation */
 extern int node_name2bitmap (char *node_names, bitstr_t **bitmap);
 
@@ -389,11 +404,6 @@ extern void pack_all_part (char **buffer_ptr, int *buffer_size, time_t * update_
  */
 extern void pack_job (struct job_record *dump_job_ptr, void **buf_ptr, int *buf_len);
 
-/* pack_node - dump all configuration information about a specific node in 
- *	machine independent form (for network transmission)
- */
-extern void pack_node (struct node_record *dump_node_ptr, void **buf_ptr, int *buf_len); 
-
 /* 
  * pack_part - dump all configuration information about a specific partition in 
  *	machine independent form (for network transmission)
@@ -407,7 +417,7 @@ extern void pack_part (struct part_record *part_record_point, void **buf_ptr, in
 void purge_old_job (void);
 
 /* read_slurm_conf - load the slurm configuration from the configured file */
-extern int  read_slurm_conf ( );
+extern int  read_slurm_conf (int recover);
 
 /* rehash - build a hash table of the node_record entries */
 extern void rehash ();
@@ -415,6 +425,9 @@ extern void rehash ();
 /* reset_job_bitmaps - reestablish bitmaps for existing jobs */
 extern void reset_job_bitmaps ();
 
+/* rmdir2 - issues system call to rmdir (if root) */
+extern int rmdir2 (char * path);
+
 /* schedule - attempt to schedule all pending jobs */
 void schedule();