From 090ae9ab06228eadbf54d01ba8b2fb6322e7a22c Mon Sep 17 00:00:00 2001
From: Moe Jette <jette1@llnl.gov>
Date: Tue, 7 May 2002 18:57:37 +0000
Subject: [PATCH] Created README, basic build information. Modified src/api
 functions to build without warnings, mostly unused 	variables that were
 declared. Changed un/packstr into separate unpackstr_ptr and
 unpackstr_xmalloc, 	the first returns a pointer into the buffer, the
 second allocates 	memory and copies the string into it. Converted
 integers in various job/node/partition structures into 	uint32_t for
 ease of passing across network with API.

---
 src/slurmctld/controller.c     |   8 +-
 src/slurmctld/job_mgr.c        |  11 +-
 src/slurmctld/job_scheduler.c  |   7 +-
 src/slurmctld/node_mgr.c       | 232 ++++++++++++++++++++++++---------
 src/slurmctld/node_scheduler.c |  96 ++++++++------
 src/slurmctld/partition_mgr.c  |  34 +++--
 src/slurmctld/read_config.c    |  43 +++---
 7 files changed, 277 insertions(+), 154 deletions(-)

diff --git a/src/slurmctld/controller.c b/src/slurmctld/controller.c
index f13d6d02781..594d0e30f16 100644
--- a/src/slurmctld/controller.c
+++ b/src/slurmctld/controller.c
@@ -15,9 +15,11 @@
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <syslog.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
+#include <unistd.h>
 
 #include "slurm.h"
 #include "slurmlib.h"
@@ -27,9 +29,10 @@
 int msg_from_root (void);
 void slurmctld_req (int sockfd);
 
+int 
 main (int argc, char *argv[]) {
 	int error_code;
-	int child_pid, cli_len, newsockfd, sockfd;
+	int cli_len, newsockfd, sockfd;
 	struct sockaddr_in cli_addr, serv_addr;
 	char node_name[MAX_NAME_LEN];
 	log_options_t opts = LOG_OPTS_STDERR_ONLY;
@@ -62,6 +65,7 @@ main (int argc, char *argv[]) {
 	serv_addr.sin_port = htons (SLURMCTLD_PORT);
 	error_code = bind (sockfd, (struct sockaddr *) &serv_addr, sizeof (serv_addr));
 	if ((error_code < 0) && (errno == EADDRINUSE)) {
+		printf("waiting to bind\n");
 		sleep (10);
 		error_code = bind (sockfd, (struct sockaddr *) &serv_addr, 
 			sizeof (serv_addr));
@@ -102,7 +106,7 @@ int
 dump_build (char **buffer_ptr, int *buffer_size)
 {
 	char *buffer;
-	int buffer_offset, buffer_allocated, i, record_size;
+	int buffer_offset, buffer_allocated;
 	char out_line[BUILD_SIZE * 2];
 
 	buffer_ptr[0] = NULL;
diff --git a/src/slurmctld/job_mgr.c b/src/slurmctld/job_mgr.c
index fddd854ba73..225583cd07c 100644
--- a/src/slurmctld/job_mgr.c
+++ b/src/slurmctld/job_mgr.c
@@ -9,6 +9,7 @@
 #  include <config.h>
 #endif
 
+#include <ctype.h>
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -217,7 +218,7 @@ dump_all_job (char **buffer_ptr, int *buffer_size, time_t * update_time,
 	ListIterator job_record_iterator;
 	struct job_record *job_record_point;
 	char *buffer;
-	int buffer_offset, buffer_allocated, error_code, i, record_size;
+	int buffer_offset, buffer_allocated, error_code;
 	char out_line[BUF_SIZE];
 
 	buffer_ptr[0] = NULL;
@@ -238,7 +239,8 @@ dump_all_job (char **buffer_ptr, int *buffer_size, time_t * update_time,
 		goto cleanup;
 
 	/* write individual job records */
-	while (job_record_point = (struct job_record *) list_next (job_record_iterator)) {
+	while ((job_record_point = 
+		(struct job_record *) list_next (job_record_iterator))) {
 		if (job_record_point->magic != JOB_MAGIC)
 			fatal ("dump_all_job: data integrity is bad");
 
@@ -536,10 +538,10 @@ int
 job_create (char *job_specs, char **new_job_id)
 {
 	char *req_features, *req_node_list, *job_name, *req_group;
-	char *req_partition, *script, *out_line, *job_id;
+	char *req_partition, *script, *job_id;
 	int contiguous, req_cpus, req_nodes, min_cpus, min_memory;
 	int i, min_tmp_disk, time_limit, procs_per_task, user_id;
-	int error_code, cpu_tally, dist, node_tally, key, shared;
+	int error_code, dist, key, shared;
 	struct part_record *part_ptr;
 	struct job_record *job_ptr;
 	struct job_details *detail_ptr;
@@ -1014,6 +1016,7 @@ parse_job_specs (char *job_specs, char **req_features, char **req_node_list,
 		xfree (shared_str);
 	req_features[0] = req_node_list[0] = req_group[0] = NULL;
 	job_id[0] = req_partition[0] = job_name[0] = script[0] = NULL;
+	return error_code;
 }
 
 
diff --git a/src/slurmctld/job_scheduler.c b/src/slurmctld/job_scheduler.c
index 9003e76de2c..9c8584d2bc2 100644
--- a/src/slurmctld/job_scheduler.c
+++ b/src/slurmctld/job_scheduler.c
@@ -45,8 +45,8 @@ int
 build_job_queue (struct job_queue **job_queue) 
 {
 	ListIterator job_record_iterator;
-	struct job_record *job_record_point;
-	int job_buffer_size, job_queue_size, i;
+	struct job_record *job_record_point = NULL;
+	int job_buffer_size, job_queue_size;
 	struct job_queue *my_job_queue;
 
 	/* build list pending jobs */
@@ -54,7 +54,8 @@ build_job_queue (struct job_queue **job_queue)
 	job_queue[0] = my_job_queue = NULL;
 	job_record_iterator = list_iterator_create (job_list);	
 	
-	while (job_record_point = (struct job_record *) list_next (job_record_iterator)) {
+	while ((job_record_point = 
+		(struct job_record *) list_next (job_record_iterator))) {
 		if (job_record_point->job_state != JOB_PENDING) 
 			continue;
 		if (job_record_point->magic != JOB_MAGIC)
diff --git a/src/slurmctld/node_mgr.c b/src/slurmctld/node_mgr.c
index 1fcee42df5a..c28fb9f9a65 100644
--- a/src/slurmctld/node_mgr.c
+++ b/src/slurmctld/node_mgr.c
@@ -9,22 +9,21 @@
 #  include <config.h>
 #endif
 
+#include <ctype.h>
 #include <errno.h>
 #include <stdio.h>
+#include <string.h>
 
-#include "list.h"
 #include "slurm.h"
 #include "slurmlib.h"
 
 #define BUF_SIZE 	1024
-#define NO_VAL	 	(-99)
 #define SEPCHARS 	" \n\t"
 
 List config_list = NULL;		/* list of config_record entries */
 struct node_record *node_record_table_ptr = NULL;	/* location of the node records */
 char *node_state_string[] =
-	{ "DOWN", "UNKNOWN", "IDLE", "STAGE_IN", "BUSY", "STAGE_OUT",
-"DRAINED", "DRAINING", "END" };
+	{ "DOWN", "UNKNOWN", "IDLE", "BUSY", "DRAINED", "DRAINING", "END" };
 int *hash_table = NULL;		/* table of hashed indicies into node_record */
 struct config_record default_config_record;
 struct node_record default_node_record;
@@ -38,15 +37,16 @@ bitstr_t *idle_node_bitmap = NULL;	/* bitmap of nodes are idle */
 int delete_config_record ();
 void dump_hash ();
 int hash_index (char *name);
-void rehash ();
 void split_node_name (char *name, char *prefix, char *suffix, int *index,
 		      int *digits);
 
 #if DEBUG_MODULE
 /* main is used here for testing purposes only */
+int 
 main (int argc, char *argv[]) 
 {
-	int error_code, node_count, i, total_procs;
+	int error_code, node_count, i;
+	uint32_t total_procs;
 	char *out_line;
 	bitstr_t *map1, *map2, *map3;
 	struct config_record *config_ptr;
@@ -141,17 +141,26 @@ main (int argc, char *argv[])
 	if (strcmp (out_line, "lx[01-02],lx04") != 0)
 		printf ("ERROR: bitmap2node_name results bad %s vs %s\n",
 			out_line, "lx[01-02],lx04");
-	build_node_list (map3, DIST_CYCLE, 6, &node_list, &total_procs);
-	printf("build_node_list: 6 procs/task over lx[01-02],lx04 has %d procs over %s\n",
+	build_node_list (map3, &node_list, &total_procs);
+	printf("build_node_list: lx[01-02],lx04 has %d procs over %s\n",
 		 total_procs, node_list);
 	bit_free (map3);
 	xfree (out_line);
 	xfree (node_list);
 
-	update_time = (time_t) 0;
 	error_code = validate_node_specs ("lx01", 12, 345, 67);
 	if (error_code)
 		printf ("ERROR: validate_node_specs error1\n");
+
+	printf("dumping node info\n");
+	update_time = (time_t) 0;
+	error_code = pack_all_node (&dump, &dump_size, &update_time);
+	if (error_code)
+		printf ("ERROR: pack_all_node error %d\n", error_code);
+	if (dump)
+		xfree(dump);
+
+	update_time = (time_t) 0;
 	error_code = dump_all_node (&dump, &dump_size, &update_time);
 	if (error_code)
 		printf ("ERROR: dump_all_node error %d\n", error_code);
@@ -199,7 +208,7 @@ main (int argc, char *argv[])
 
 /*
  * bitmap2node_name - given a bitmap, build a list of comma separated node names.
- *	names may include regular expressions
+ *	names may include regular expressions (e.g. "lx[01-10]")
  * input: bitmap - bitmap pointer
  *        node_list - place to put node list
  * output: node_list - set to node list or NULL on error 
@@ -210,13 +219,11 @@ main (int argc, char *argv[])
 int 
 bitmap2node_name (bitstr_t *bitmap, char **node_list) 
 {
-	int error_code, node_list_size, i;
-	struct node_record *node_ptr;
+	int node_list_size, i;
 	char prefix[MAX_NAME_LEN], suffix[MAX_NAME_LEN];
 	char format[MAX_NAME_LEN], temp[MAX_NAME_LEN];
 	char last_prefix[MAX_NAME_LEN], last_suffix[MAX_NAME_LEN];
-	int first_index, last_index, index, digits;
-	unsigned mask;
+	int first_index = 0, last_index = 0, index, digits;
 
 	node_list[0] = NULL;
 	node_list_size = 0;
@@ -304,11 +311,10 @@ bitmap2node_name (bitstr_t *bitmap, char **node_list)
 
 
 /*
- * build_node_list - build a node_list for a job laying out the actual
+ * build_node_list - build a node_list for a job including processor 
+  *	count on the node (e.g. "lx01[4],lx02[4],...")
  *	task distributions on the nodes
  * input: bitmap - bitmap of nodes to use
- *	dist - distribution of tasks, BLOCK or CYCLE
- *	procs_per_task - how many processor each task will consume
  *	node_list - place to store node list
  *	total_procs - place to store count of total processors allocated
  * output: node_list - comma separated list of nodes on which the tasks 
@@ -318,55 +324,37 @@ bitmap2node_name (bitstr_t *bitmap, char **node_list)
  * NOTE: the storage at node_list must be xfreed by the caller
  */
 void 
-build_node_list (bitstr_t *bitmap, enum task_dist dist, 
-		int procs_per_task, char **node_list, int *total_procs)
+build_node_list (bitstr_t *bitmap, char **node_list, uint32_t *total_procs)
 {
-	int i, j, node_list_size, max_procs, min_procs;
-	int node_proc_count, sum_procs;
+	int i, node_list_size;
+	int sum_procs;
+	char tmp_str[MAX_NAME_LEN+10];
 
 	*total_procs = 0;
 	node_list[0] = NULL;
 	node_list_size = 0;
 	if (bitmap == NULL)
 		fatal ("build_node_list: bitmap is NULL");
-	if (procs_per_task < 0)
-		fatal ("build_node_list: procs_per_task invalid (%d)", 
-			procs_per_task);
 
 	node_list[0] = xmalloc (BUF_SIZE);
 	strcpy (node_list[0], "");
 
 	sum_procs = 0;
-	max_procs = procs_per_task;
-	for (min_procs = procs_per_task; min_procs <= max_procs; 
-	     min_procs+= procs_per_task) {
- 		for (i = 0; i < node_record_count; i++) {
-			if (bit_test (bitmap, i) != 1)
-				continue;
-			node_proc_count = node_record_table_ptr[i].cpus;
-			if (node_proc_count < min_procs) 
-				continue;
-			if (min_procs == procs_per_task)
-				sum_procs += node_proc_count;
-			if (node_proc_count > max_procs)
-				max_procs = node_proc_count;
-
-			if (node_list_size <
-			    (strlen (node_list[0]) + 
-				(MAX_NAME_LEN+1) * node_proc_count)) {
-				node_list_size += BUF_SIZE;
-				xrealloc (node_list[0], node_list_size);
-			}
-			for (j = 0; j < node_proc_count; j += procs_per_task) {
-				if (strlen (node_list[0]) > 0)
-					strcat (node_list[0], ",");
-				strcat (node_list[0], node_record_table_ptr[i].name);
-				if (dist == DIST_CYCLE)
-					break;
-			}
+ 	for (i = 0; i < node_record_count; i++) {
+		if (bit_test (bitmap, i) != 1)
+			continue;
+		sprintf (tmp_str, "%s[%d]", 
+			node_record_table_ptr[i].name,
+			node_record_table_ptr[i].cpus);
+		if (node_list_size <
+		    (strlen (node_list[0]) + (MAX_NAME_LEN+10))) {
+			node_list_size += BUF_SIZE;
+			xrealloc (node_list[0], node_list_size);
 		}
-		if (dist == DIST_BLOCK)
-			break;
+		if (sum_procs > 0)
+			strcat (node_list[0], ",");
+		strcat (node_list[0], node_record_table_ptr[i].name);
+		sum_procs += node_record_table_ptr[i].cpus;
 	}
 	*total_procs = sum_procs;
 	xrealloc (node_list[0], strlen (node_list[0]) + 1);
@@ -538,7 +526,9 @@ dump_hash ()
 
 
 /* 
- * dump_all_node - dump all configuration and node information to a buffer
+ * dump_all_node - dump all configuration and node information in text format
+ *	to a buffer, the data format will be the same as that of a configuration 
+ *	file (and can be used as such)
  * input: buffer_ptr - location into which a pointer to the data is to be stored.
  *                     the data buffer is actually allocated by dump_node and the 
  *                     calling function must xfree the storage.
@@ -556,8 +546,8 @@ int
 dump_all_node (char **buffer_ptr, int *buffer_size, time_t * update_time) 
 {
 	char *buffer;
-	int buffer_offset, buffer_allocated, error_code, i, inx;
-	char out_line[BUF_SIZE], *feature, *partition;
+	int buffer_offset, buffer_allocated, error_code, inx;
+	char out_line[BUF_SIZE];
 
 	buffer_ptr[0] = NULL;
 	*buffer_size = 0;
@@ -578,7 +568,7 @@ dump_all_node (char **buffer_ptr, int *buffer_size, time_t * update_time)
 	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 ("dump_node: data integrity is bad");
+			fatal ("dump_all_node: data integrity is bad");
 
 		error_code = dump_node(&node_record_table_ptr[inx], out_line, BUF_SIZE);
 		if (error_code != 0) continue;
@@ -603,7 +593,9 @@ dump_all_node (char **buffer_ptr, int *buffer_size, time_t * update_time)
 
 
 /* 
- * dump_node - dump all configuration information about a specific node to a buffer
+ * dump_node - dump all configuration information about a specific node in text format
+ *	to a buffer, the data format will be the same as that of a configuration 
+ *	file (and can be used as such)
  * input:  dump_node_ptr - pointer to node for which information is requested
  *         out_line - buffer for node information 
  *         out_line_size - byte size of out_line
@@ -662,7 +654,6 @@ dump_node (struct node_record *dump_node_ptr, char *out_line, int out_line_size)
 struct node_record * 
 find_node_record (char *name) 
 {
-	struct node_record *node_record_point;	/* pointer to node_record */
 	int i;
 
 	/* try to find in hash table first */
@@ -1010,6 +1001,125 @@ node_unlock ()
 }
 
 
+/* 
+ * pack_all_node - dump all configuration and node information for all nodes in 
+ *	machine independent form (for network transmission)
+ * input: buffer_ptr - location into which a pointer to the data is to be stored.
+ *                     the data buffer is actually allocated by dump_node and the 
+ *                     calling function must xfree the storage.
+ *         buffer_size - location into which the size of the created buffer is in bytes
+ *         update_time - dump new data only if partition records updated since time 
+ *                       specified, otherwise return empty buffer
+ * output: buffer_ptr - the pointer is set to the allocated buffer.
+ *         buffer_size - set to size of the buffer in bytes
+ *         update_time - set to time partition records last updated
+ *         returns 0 if no error, errno otherwise
+ * global: node_record_table_ptr - pointer to global node table
+ * NOTE: the caller must xfree the buffer at *buffer_ptr when no longer required
+ */
+int 
+pack_all_node (char **buffer_ptr, int *buffer_size, time_t * update_time) 
+{
+	int buf_len, buffer_allocated, buffer_offset = 0, error_code, inx;
+	char *buffer;
+	void *buf_ptr;
+
+	buffer_ptr[0] = NULL;
+	*buffer_size = 0;
+	if (*update_time == last_node_update)
+		return 0;
+
+	buffer_allocated = (BUF_SIZE*16);
+	buffer = xmalloc(buffer_allocated);
+	buf_ptr = buffer;
+	buf_len = buffer_allocated;
+
+	/* write haeader: version and time */
+	pack32  ((uint32_t) NODE_STRUCT_VERSION, &buf_ptr, &buf_len);
+	pack32  ((uint32_t) last_node_update, &buf_ptr, &buf_len);
+
+	/* write node records */
+	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");
+
+		error_code = pack_node(&node_record_table_ptr[inx], &buf_ptr, &buf_len);
+		if (error_code != 0) continue;
+		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;
+	}
+
+	if (buffer)
+		xrealloc (buffer, buffer_offset);
+
+	buffer_ptr[0] = buffer;
+	*buffer_size = buffer_offset;
+	*update_time = last_node_update;
+	return 0;
+}
+
+
+/* 
+ * pack_node - dump all configuration information about a specific node in 
+ *	machine independent form (for network transmission)
+ * 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
+ *	return 0 if no error, 1 if out_line buffer too small
+ * 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
+ */
+int 
+pack_node (struct node_record *dump_node_ptr, void **buf_ptr, int *buf_len) 
+{
+	int state;
+	char *partition = NULL;
+	uint32_t feature_size, name_size, partition_size;
+
+	state = dump_node_ptr->node_state;
+	if (state < 0)
+		state = STATE_DOWN;
+	name_size = strlen(dump_node_ptr->name) + 1;
+
+	if (dump_node_ptr->config_ptr->feature)
+		feature_size = strlen(dump_node_ptr->config_ptr->feature) + 1;
+	else
+		feature_size = 0;
+
+	if (dump_node_ptr->partition_ptr) {
+		partition = dump_node_ptr->partition_ptr->name;
+		partition_size = strlen(dump_node_ptr->partition_ptr->name) + 1;
+	}
+	else
+		partition_size = 0;
+
+	if (name_size + feature_size + partition_size + 40 > *buf_len) {
+		error ("pack_node: buffer too small for node %s", dump_node_ptr->name);
+		return 1;
+	}
+
+	packstr (dump_node_ptr->name, name_size, buf_ptr, buf_len);
+	pack32  (state, buf_ptr, buf_len);
+	pack32  (dump_node_ptr->cpus, buf_ptr, buf_len);
+	pack32  (dump_node_ptr->real_memory, buf_ptr, buf_len);
+	pack32  (dump_node_ptr->tmp_disk, buf_ptr, buf_len);
+	pack32  (dump_node_ptr->config_ptr->weight, buf_ptr, buf_len);
+	packstr (dump_node_ptr->config_ptr->feature, feature_size, 
+		 buf_ptr, buf_len);
+	packstr (partition, partition_size, buf_ptr, buf_len);
+
+	return 0;
+}
+
+
 /* 
  * rehash - build a hash table of the node_record entries. this is a large hash table 
  * to permit the immediate finding of a record based only upon its name without regards 
@@ -1024,7 +1134,6 @@ node_unlock ()
 void 
 rehash () 
 {
-	struct node_record *node_record_point;	/* pointer to node_record */
 	int i, inx;
 
 	xrealloc (hash_table, (sizeof (int) * node_record_count));
@@ -1192,7 +1301,8 @@ update_node (char *node_names, char *spec)
  * global: node_record_table_ptr - pointer to global node table
  */
 int 
-validate_node_specs (char *node_name, int cpus, int real_memory, int tmp_disk) {
+validate_node_specs (char *node_name, uint32_t cpus, 
+			uint32_t real_memory, uint32_t tmp_disk) {
 	int error_code;
 	struct config_record *config_ptr;
 	struct node_record *node_ptr;
diff --git a/src/slurmctld/node_scheduler.c b/src/slurmctld/node_scheduler.c
index c02a15a9c19..33e612f6ed1 100644
--- a/src/slurmctld/node_scheduler.c
+++ b/src/slurmctld/node_scheduler.c
@@ -15,6 +15,7 @@
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <syslog.h>
 
 #include "slurm.h"
@@ -22,9 +23,9 @@
 #define BUF_SIZE 1024
 
 struct node_set {		/* set of nodes with same configuration that could be allocated */
-	int cpus_per_node;
-	int nodes;
-	int weight;
+	uint32_t cpus_per_node;
+	uint32_t nodes;
+	uint32_t weight;
 	int feature;
 	bitstr_t *my_bitmap;
 };
@@ -32,18 +33,20 @@ struct node_set {		/* set of nodes with same configuration that could be allocat
 int pick_best_quadrics (bitstr_t *bitmap, bitstr_t *req_bitmap, int req_nodes,
 		    int req_cpus, int consecutive);
 int pick_best_nodes (struct node_set *node_set_ptr, int node_set_size,
-		     bitstr_t **req_bitmap, int req_cpus, int req_nodes,
-		     int contiguous, int shared, int max_nodes);
+		     bitstr_t **req_bitmap, uint32_t req_cpus, uint32_t req_nodes,
+		     int contiguous, int shared, uint32_t max_nodes);
 int valid_features (char *requested, char *available);
 
 #if DEBUG_MODULE
 /* main is used here for testing purposes only */
+int 
 main (int argc, char *argv[]) 
 {
 	int error_code, line_num, i;
 	FILE *command_file;
 	char in_line[BUF_SIZE], *job_id, *node_list;
 	log_options_t opts = LOG_OPTS_STDERR_ONLY;
+	clock_t start_time;
 
 	log_init(argv[0], opts, SYSLOG_FACILITY_DAEMON, NULL);
 
@@ -101,6 +104,7 @@ main (int argc, char *argv[])
 	line_num = 0;
 	printf ("\n");
 	while (fgets (in_line, BUF_SIZE, command_file)) {
+		start_time = clock ();
 		job_id = node_list = NULL;
 		if (in_line[strlen (in_line) - 1] == '\n')
 			in_line[strlen (in_line) - 1] = (char) NULL;
@@ -109,21 +113,23 @@ main (int argc, char *argv[])
 		if (error_code) {
 			if (strncmp (in_line, "JobName=FAIL", 12) != 0)
 				printf ("ERROR:");
-			printf ("for job: %s\n", in_line, node_list);
-			printf ("node_scheduler: error %d from job_allocate on line %d\n\n", 
+			printf ("for job: %s\n", in_line);
+			printf ("node_scheduler: error %d from job_allocate on line %d\n", 
 				error_code, line_num);
 		}
 		else {
 			if (strncmp (in_line, "JobName=FAIL", 12) == 0)
 				printf ("ERROR: ");
-			printf ("for job: %s\n  nodes selected %s\n\n",
+			printf ("for job: %s\n  nodes selected %s\n",
 				in_line, node_list);
 			if (job_id)
 				xfree (job_id);
 			if (node_list)
 				xfree (node_list);
-		}		
-	}			
+		}
+		printf("time = %ld usec\n\n", (long) (clock() - start_time));
+	}
+	exit (0);		
 }
 #endif
 
@@ -141,7 +147,7 @@ allocate_nodes (unsigned *bitmap)
 	for (i = 0; i < node_record_count; i++) {
 		if (bit_test (bitmap, i) == 0)
 			continue;
-		node_record_table_ptr[i].node_state = STATE_STAGE_IN;
+		node_record_table_ptr[i].node_state = STATE_BUSY;
 		bit_clear (idle_node_bitmap, i);
 	}
 	return;
@@ -285,8 +291,8 @@ match_group (char *allow_groups, char *user_groups)
 
 
 /*
- * pick_best_quadrics - identify the nodes which best fit the req_nodes and req_cpus counts
- *	for a system with Quadrics elan interconnect.
+ * pick_best_quadrics - identify the nodes which best fit the req_nodes and 
+ *	req_cpus counts for a system with Quadrics elan interconnect.
  * 	"best" is defined as either single set of consecutive nodes satisfying 
  *	the request and leaving the minimum number of unused nodes OR 
  *	the fewest number of consecutive node sets
@@ -296,7 +302,8 @@ match_group (char *allow_groups, char *user_groups)
  *        req_nodes - number of nodes required
  *        req_cpus - number of cpus required
  *        consecutive - nodes must be consecutive is 1, otherwise 0
- * output: bitmap - nodes not required to satisfy the request are cleared, other left set
+ * output: bitmap - nodes not required to satisfy the request are cleared, 
+ *		other left set
  *         returns zero on success, EINVAL otherwise
  * globals: node_record_count - count of nodes configured
  *	node_record_table_ptr - pointer to global node table
@@ -314,8 +321,8 @@ pick_best_quadrics (bitstr_t *bitmap, bitstr_t *req_bitmap, int req_nodes,
 	int *consec_req;	/* are nodes from this set required (in req_bitmap) */
 	int consec_index, consec_size;
 	int rem_cpus, rem_nodes;	/* remaining resources required */
-	int best_fit_nodes, best_fit_cpus, best_fit_req, best_fit_location,
-		best_fit_sufficient;
+	int best_fit_nodes, best_fit_cpus, best_fit_req;
+	int best_fit_location = 0, best_fit_sufficient;
 
 	if (bitmap == NULL)
 		fatal ("pick_best_quadrics: bitmap pointer is NULL\n");
@@ -339,10 +346,11 @@ pick_best_quadrics (bitstr_t *bitmap, bitstr_t *req_bitmap, int req_nodes,
 				consec_start[consec_index] = index;
 			i = node_record_table_ptr[index].cpus;
 			if (req_bitmap && bit_test (req_bitmap, index)) {
-				if (consec_req[consec_index] == -1) /* first required node in set */
+				if (consec_req[consec_index] == -1) 
+					/* first required node in set */
 					consec_req[consec_index] = index; 
-				rem_cpus -= i;	/* reduce count of additional resources required */
-				rem_nodes--;	/* reduce count of additional resources required */
+				rem_cpus -= i;
+				rem_nodes--;
 			}
 			else {
 				bit_clear (bitmap, index);
@@ -351,7 +359,8 @@ pick_best_quadrics (bitstr_t *bitmap, bitstr_t *req_bitmap, int req_nodes,
 			}	
 		}
 		else if (consec_nodes[consec_index] == 0) {
-			consec_req[consec_index] = -1;	/* already picked up any required nodes */
+			consec_req[consec_index] = -1;	
+			/* already picked up any required nodes */
 			/* re-use this record */
 		}
 		else {
@@ -455,7 +464,6 @@ pick_best_quadrics (bitstr_t *bitmap, bitstr_t *req_bitmap, int req_nodes,
 		consec_nodes[best_fit_location] = 0;
 	}			
 
-      cleanup:
 	if (consec_cpus)
 		xfree (consec_cpus);
 	if (consec_nodes)
@@ -480,7 +488,8 @@ pick_best_quadrics (bitstr_t *bitmap, bitstr_t *req_bitmap, int req_nodes,
  *        req_nodes - count of nodes required by the job
  *        contiguous - set to 1 if allocated nodes must be contiguous, 0 otherwise
  *        shared - set to 1 if nodes may be shared, 0 otherwise
- *        max_nodes - maximum number of nodes permitted for job, -1 for none (partition limit)
+ *        max_nodes - maximum number of nodes permitted for job, 
+ *		INFIITE for no limit (partition limit)
  * output: req_bitmap - pointer to bitmap of selected nodes
  *         returns 0 on success, EAGAIN if request can not be satisfied now, 
  *		EINVAL if request can never be satisfied (insufficient contiguous nodes)
@@ -488,22 +497,21 @@ pick_best_quadrics (bitstr_t *bitmap, bitstr_t *req_bitmap, int req_nodes,
  */
 int
 pick_best_nodes (struct node_set *node_set_ptr, int node_set_size,
-		 bitstr_t **req_bitmap, int req_cpus, int req_nodes,
-		 int contiguous, int shared, int max_nodes) 
+		 bitstr_t **req_bitmap, uint32_t req_cpus, uint32_t req_nodes,
+		 int contiguous, int shared, uint32_t max_nodes) 
 {
-	int error_code, i, j, pick_code, size;
+	int error_code, i, j, pick_code;
 	int total_nodes, total_cpus;	/* total resources configured in partition */
 	int avail_nodes, avail_cpus;	/* resources available for use now */
 	bitstr_t *avail_bitmap, *total_bitmap;
 	int max_feature, min_feature;
-	int *cpus_per_node;
 	int avail_set, total_set, runable;
 
 	if (node_set_size == 0) {
 		info ("pick_best_nodes: empty node set for selection");
 		return EINVAL;
 	}
-	if ((max_nodes != -1) && (req_nodes > max_nodes)) {
+	if ((max_nodes != INFINITE) && (req_nodes > max_nodes)) {
 		info ("pick_best_nodes: more nodes required than possible in partition");
 		return EINVAL;
 	}
@@ -542,7 +550,7 @@ pick_best_nodes (struct node_set *node_set_ptr, int node_set_size,
 			min_feature = node_set_ptr[i].feature;
 	}
 
-	runable = 0;		/* assume not runable until otherwise demonstrated */
+	runable = 0;	/* assume not runable until otherwise demonstrated */
 	for (j = min_feature; j <= max_feature; j++) {
 		avail_set = total_set = 0;
 		for (i = 0; i < node_set_size; i++) {
@@ -593,9 +601,10 @@ pick_best_nodes (struct node_set *node_set_ptr, int node_set_size,
 				pick_best_quadrics (avail_bitmap, req_bitmap[0],
 						req_nodes, req_cpus,
 						contiguous);
-			if ((pick_code == 0) && (max_nodes != -1)
+			if ((pick_code == 0) && (max_nodes != INFINITE)
 			    && (bit_set_count (avail_bitmap) > max_nodes)) {
-				info ("pick_best_nodes: too many nodes selected");
+				info ("pick_best_nodes: too many nodes selected %u of %u",
+					bit_set_count (avail_bitmap), max_nodes);
 				error_code = EINVAL;
 				break;
 			}	
@@ -612,17 +621,18 @@ pick_best_nodes (struct node_set *node_set_ptr, int node_set_size,
 		    (total_nodes > req_nodes) && (total_cpus > req_cpus) &&
 		    ((req_bitmap[0] == NULL)
 		     || (bit_super_set (req_bitmap[0], total_bitmap) == 1))
-		    && ((max_nodes == -1) || (req_nodes <= max_nodes))) {
+		    && ((max_nodes == INFINITE) || (req_nodes <= max_nodes))) {
 			/* determine if job could possibly run */
 			/* (if configured nodes all available) */
 			pick_code =
 				pick_best_quadrics (total_bitmap, req_bitmap[0],
 						req_nodes, req_cpus,
 						contiguous);
-			if ((pick_code == 0) && (max_nodes != -1)
-			    && (bit_set_count (avail_bitmap) > max_nodes)) {
+			if ((pick_code == 0) && (max_nodes != INFINITE)
+			    && (bit_set_count (total_bitmap) > max_nodes)) {
 				error_code = EINVAL;
-				info ("pick_best_nodes: too many nodes selected");
+				info ("pick_best_nodes: %u nodes selected, max is %u",
+					bit_set_count (avail_bitmap), max_nodes);
 			}
 			if (pick_code == 0)
 				runable = 1;
@@ -659,12 +669,13 @@ pick_best_nodes (struct node_set *node_set_ptr, int node_set_size,
 int
 select_nodes (struct job_record *job_ptr) 
 {
-	int error_code, i, node_set_index, node_set_size;
+	int error_code, i, node_set_index, node_set_size = 0;
 	bitstr_t *req_bitmap, *scratch_bitmap;
-	ListIterator config_record_iterator;	/* for iterating through config_list */
+	ListIterator config_record_iterator;
 	struct config_record *config_record_point;
 	struct node_set *node_set_ptr;
 	struct part_record *part_ptr;
+	int tmp_feature, check_node_config;
 
 	req_bitmap = scratch_bitmap = NULL;
 	config_record_iterator = (ListIterator) NULL;
@@ -695,9 +706,8 @@ select_nodes (struct job_record *job_ptr)
 	if (config_record_iterator == NULL)
 		fatal ("select_nodes: ListIterator_create unable to allocate memory");
 
-	while (config_record_point =
-	       (struct config_record *) list_next (config_record_iterator)) {
-		int tmp_feature, check_node_config;
+	while ((config_record_point =
+	        (struct config_record *) list_next (config_record_iterator))) {
 
 		tmp_feature = valid_features (job_ptr->details->features,
 					config_record_point->feature);
@@ -819,8 +829,7 @@ select_nodes (struct job_record *job_ptr)
 		error ("bitmap2node_name error %d", error_code);
 		goto cleanup;
 	}
-	build_node_list (req_bitmap, job_ptr->details->dist, 
-		job_ptr->details->procs_per_task, 
+	build_node_list (req_bitmap, 
 		&job_ptr->details->node_list, 
 		&job_ptr->details->total_procs);
 	allocate_nodes (req_bitmap);
@@ -847,7 +856,8 @@ select_nodes (struct job_record *job_ptr)
 }
 
 
-/* valid_features - determine if the requested features are satisfied by those available
+/*
+ * valid_features - determine if the requested features are satisfied by those available
  * input: requested - requested features (by a job)
  *        available - available features (on a node)
  * output: returns 0 if request is not satisfied, otherwise an integer indicating 
@@ -862,7 +872,7 @@ valid_features (char *requested, char *available)
 	char *tmp_requested, *str_ptr1;
 	int bracket, found, i, option, position, result;
 	int last_op;		/* last operation 0 for or, 1 for and */
-	int save_op, save_result;	/* for bracket support */
+	int save_op = 0, save_result = 0;	/* for bracket support */
 
 	if (requested == NULL)
 		return 1;	/* no constraints */
diff --git a/src/slurmctld/partition_mgr.c b/src/slurmctld/partition_mgr.c
index 71ff1e151b5..ac95c380cf8 100644
--- a/src/slurmctld/partition_mgr.c
+++ b/src/slurmctld/partition_mgr.c
@@ -9,6 +9,7 @@
 #  include <config.h>
 #endif
 
+#include <ctype.h>
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -33,6 +34,7 @@ int list_find_part (void *part_entry, void *key);
 
 #if DEBUG_MODULE
 /* main is used here for module testing purposes only */
+int 
 main (int argc, char *argv[]) 
 {
 	int error_code, i;
@@ -40,18 +42,6 @@ main (int argc, char *argv[])
 	struct part_record *part_ptr;
 	char *dump;
 	int dump_size;
-	char req_name[MAX_NAME_LEN];	/* name of the partition */
-	char next_name[MAX_NAME_LEN];	/* name of the next partition */
-	int max_time;		/* -1 if unlimited */
-	int max_nodes;		/* -1 if unlimited */
-	int total_nodes;	/* total number of nodes in the partition */
-	int total_cpus;		/* total number of cpus in the partition */
-	char *nodes;		/* names of nodes in partition */
-	char *allow_groups;	/* NULL indicates all */
-	int key;		/* 1 if slurm distributed key is required for use of partition */
-	int state_up;		/* 1 if state is up */
-	int shared;		/* 1 if partition can be shared */
-	bitstr_t *node_bitmap;	/* bitmap of nodes in partition */
 	char update_spec[] =
 		"MaxTime=34 MaxNodes=56 Key=NO State=DOWN Shared=FORCE";
 	log_options_t opts = LOG_OPTS_STDERR_ONLY;
@@ -316,7 +306,7 @@ dump_all_part (char **buffer_ptr, int *buffer_size, time_t * update_time)
 	ListIterator part_record_iterator;	/* for iterating through part_record list */
 	struct part_record *part_record_point;	/* pointer to part_record */
 	char *buffer;
-	int buffer_offset, buffer_allocated, error_code, i, record_size;
+	int buffer_offset, buffer_allocated, error_code;
 	char out_line[BUF_SIZE];
 
 	buffer_ptr[0] = NULL;
@@ -337,8 +327,8 @@ dump_all_part (char **buffer_ptr, int *buffer_size, time_t * update_time)
 		goto cleanup;
 
 	/* write individual partition records */
-	while (part_record_point =
-	       (struct part_record *) list_next (part_record_iterator)) {
+	while ((part_record_point = 
+		(struct part_record *) list_next (part_record_iterator))) {
 		if (part_record_point->magic != PART_MAGIC)
 			fatal ("dump_all_part: data integrity is bad");
 
@@ -460,8 +450,8 @@ int init_part_conf ()
 
 	strcpy (default_part.name, "DEFAULT");
 	default_part.allow_groups = (char *) NULL;
-	default_part.max_time = -1;
-	default_part.max_nodes = -1;
+	default_part.max_time = INFINITE;
+	default_part.max_nodes = INFINITE;
 	default_part.key = 0;
 	default_part.state_up = 1;
 	default_part.shared = 0;
@@ -692,13 +682,19 @@ update_part (char *partition_name, char *spec)
 	if (max_time_val != NO_VAL) {
 		info ("update_part: setting max_time to %d for partition %s",
 			max_time_val, partition_name);
-		part_ptr->max_time = max_time_val;
+		if (max_time_val == -1)
+			part_ptr->max_time = INFINITE;
+		else
+			part_ptr->max_time = max_time_val;
 	}			
 
 	if (max_nodes_val != NO_VAL) {
 		info ("update_part: setting max_nodes to %d for partition %s",
 			max_nodes_val, partition_name);
-		part_ptr->max_nodes = max_nodes_val;
+		if (max_nodes_val == -1)
+			part_ptr->max_nodes = INFINITE;
+		else
+			part_ptr->max_nodes = max_nodes_val;
 	}			
 
 	if (key_val != NO_VAL) {
diff --git a/src/slurmctld/read_config.c b/src/slurmctld/read_config.c
index f58fa28ddcc..fbb4c0de700 100644
--- a/src/slurmctld/read_config.c
+++ b/src/slurmctld/read_config.c
@@ -18,6 +18,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <syslog.h>
+#include <unistd.h>
 
 #include "slurm.h"
 #include "list.h"
@@ -32,10 +33,10 @@ char *control_machine = NULL;
 
 #if DEBUG_MODULE
 /* main is used here for module testing purposes only */
+int 
 main (int argc, char *argv[]) {
-	int error_code, start_inx, end_inx, count_inx;
-	char out_line[BUF_SIZE];
-	char *format, *node_name, bitmap[128];
+	int error_code;
+	char bitmap[128];
 	char *partitions[] = { "login", "debug", "batch", "class", "end" };
 	struct part_record *part_ptr;
 	int cycles, i, found;
@@ -189,8 +190,8 @@ build_bitmaps () {
 	if (config_record_iterator == NULL)
 		fatal ("build_bitmaps: list_iterator_create unable to allocate memory");
 	
-	while (config_record_point =
-	       (struct config_record *) list_next (config_record_iterator)) {
+	while ((config_record_point =
+	       (struct config_record *) list_next (config_record_iterator))) {
 		if (config_record_point->node_bitmap)
 			bit_free (config_record_point->node_bitmap);
 
@@ -220,7 +221,8 @@ build_bitmaps () {
 	if (part_record_iterator == NULL)
 		fatal ("build_bitmaps: list_iterator_create unable to allocate memory");
 
-	while (part_record_point = (struct part_record *) list_next (part_record_iterator)) {
+	while ((part_record_point = 
+		(struct part_record *) list_next (part_record_iterator))) {
 		if (part_record_point->node_bitmap)
 			bit_free (part_record_point->node_bitmap);
 		part_record_point->node_bitmap = (bitstr_t *) bit_alloc (node_record_count);	
@@ -287,13 +289,13 @@ init_slurm_conf () {
 		backup_controller = NULL;
 	}
 
-	if (error_code = init_node_conf ())
+	if ((error_code = init_node_conf ()))
 		return error_code;
 
-	if (error_code = init_part_conf ())
+	if ((error_code = init_part_conf ()))
 		return error_code;
 
-	if (error_code = init_job_conf ())
+	if ((error_code = init_job_conf ()))
 		return error_code;
 
 	return 0;
@@ -315,12 +317,12 @@ parse_node_spec (char *in_line) {
 	int error_code, i, node_count;
 	int state_val, cpus_val, real_memory_val, tmp_disk_val, weight_val;
 	struct node_record *node_record_point;
-	struct config_record *config_point;
+	struct config_record *config_point = NULL;
 
 	node_name = state = feature = node_list = (char *) NULL;
 	cpus_val = real_memory_val = state_val = NO_VAL;
 	tmp_disk_val = weight_val = NO_VAL;
-	if (error_code = load_string (&node_name, "NodeName=", in_line))
+	if ((error_code = load_string (&node_name, "NodeName=", in_line)))
 		return error_code;
 	if (node_name == NULL)
 		return 0;	/* no node info */
@@ -441,12 +443,11 @@ parse_node_spec (char *in_line) {
  */
 int 
 parse_part_spec (char *in_line) {
-	int line_num;		/* line number in input file */
 	char *allow_groups, *nodes, *partition_name;
 	char *default_str, *key_str, *shared_str, *state_str;
-	int max_time_val, max_nodes_val, key_val, default_val, state_val,
-		shared_val;
-	int error_code, i;
+	int max_time_val, max_nodes_val, key_val, default_val;
+	int state_val, shared_val;
+	int error_code;
 	struct part_record *part_record_point;
 
 	partition_name = (char *) NULL;
@@ -454,8 +455,8 @@ parse_part_spec (char *in_line) {
 	max_time_val = max_nodes_val = key_val = default_val = state_val =
 		shared_val = NO_VAL;
 
-	if (error_code =
-	    load_string (&partition_name, "PartitionName=", in_line))
+	if ((error_code =
+	    load_string (&partition_name, "PartitionName=", in_line)))
 		return error_code;
 	if (partition_name == NULL)
 		return 0;	/* no partition info */
@@ -641,8 +642,6 @@ read_slurm_conf (char *file_name) {
 	FILE *slurm_spec_file;	/* pointer to input data file */
 	int line_num;		/* line number in input file */
 	char in_line[BUF_SIZE];	/* input line */
-	char scratch[BUF_SIZE];	/* scratch area for parsing the input line */
-	char *str_ptr1, *str_ptr2, *str_ptr3;
 	int i, j, error_code;
 
 	/* initialization */
@@ -695,13 +694,13 @@ read_slurm_conf (char *file_name) {
 		}		
 
 		/* node configuration parameters */
-		if (error_code = parse_node_spec (in_line)) {
+		if ((error_code = parse_node_spec (in_line))) {
 			fclose (slurm_spec_file);
 			return error_code;
 		}		
 
 		/* partition configuration parameters */
-		if (error_code = parse_part_spec (in_line)) {
+		if ((error_code = parse_part_spec (in_line))) {
 			fclose (slurm_spec_file);
 			return error_code;
 		}		
@@ -725,7 +724,7 @@ read_slurm_conf (char *file_name) {
 		return EINVAL;
 	}			
 	rehash ();
-	if (error_code = build_bitmaps ())
+	if ((error_code = build_bitmaps ()))
 		return error_code;
 	list_sort (config_list, &list_compare_config);
 
-- 
GitLab