From d9d5b71d661e32dc122bff465966b07da333afe2 Mon Sep 17 00:00:00 2001
From: Moe Jette <jette1@llnl.gov>
Date: Wed, 26 Feb 2003 00:13:10 +0000
Subject: [PATCH] Added much of infrastructure for COMPLETING job state.

---
 src/slurmctld/controller.c     |  1 +
 src/slurmctld/job_mgr.c        |  3 +--
 src/slurmctld/node_mgr.c       | 40 +++++++++++++++++++++++-----------
 src/slurmctld/node_scheduler.c |  6 ++---
 src/slurmctld/read_config.c    | 36 ++++++++++++++----------------
 src/slurmctld/slurmctld.h      | 19 +++++++++++-----
 6 files changed, 60 insertions(+), 45 deletions(-)

diff --git a/src/slurmctld/controller.c b/src/slurmctld/controller.c
index 6dd5b33cd9b..9afc0de9020 100644
--- a/src/slurmctld/controller.c
+++ b/src/slurmctld/controller.c
@@ -1954,6 +1954,7 @@ static void _slurm_rpc_node_registration(slurm_msg_t * msg)
 		   node_reg_stat_msg->node_name, 
 		   (long) (clock() - start_time));
 		slurm_send_rc_msg(msg, SLURM_SUCCESS);
+		schedule();	/* has own locks */
 	}
 }
 
diff --git a/src/slurmctld/job_mgr.c b/src/slurmctld/job_mgr.c
index ee13b659b29..c4c6b298af0 100644
--- a/src/slurmctld/job_mgr.c
+++ b/src/slurmctld/job_mgr.c
@@ -2614,8 +2614,7 @@ int update_job(job_desc_msg_t * job_specs, uid_t uid)
 /*
  * validate_jobs_on_node - validate that any jobs that should be on the node 
  *	are actually running, if not clean up the job records and/or node 
- *	records, call this function after validate_node_specs() sets the node 
- *	state properly 
+ *	records
  * IN node_name - node which should have jobs running
  * IN job_count - number of jobs which should be running on specified node
  * IN job_id_ptr - pointer to array of job_ids that should be on this node
diff --git a/src/slurmctld/node_mgr.c b/src/slurmctld/node_mgr.c
index 58089475b5d..5fd1e330b1c 100644
--- a/src/slurmctld/node_mgr.c
+++ b/src/slurmctld/node_mgr.c
@@ -460,10 +460,10 @@ int load_all_node_state ( void )
 
 	while (remaining_buf (buffer) > 0) {
 		safe_unpackstr_xmalloc (&node_name, &name_len, buffer);
-		safe_unpack16 (&node_state, buffer);
-		safe_unpack32 (&cpus, buffer);
+		safe_unpack16 (&node_state,  buffer);
+		safe_unpack32 (&cpus,        buffer);
 		safe_unpack32 (&real_memory, buffer);
-		safe_unpack32 (&tmp_disk, buffer);
+		safe_unpack32 (&tmp_disk,    buffer);
 
 		/* validity test as possible */
 		if ((cpus == 0) || 
@@ -1059,8 +1059,7 @@ validate_node_specs (char *node_name, uint32_t cpus,
 	error_code = 0;
 
 	if (cpus < config_ptr->cpus) {
-		error ("validate_node_specs: node %s has low cpu count %u", 
-		       node_name, cpus);
+		error ("Node %s has low cpu count %u", node_name, cpus);
 		error_code = EINVAL;
 	}
 	node_ptr->cpus = cpus;
@@ -1069,22 +1068,21 @@ validate_node_specs (char *node_name, uint32_t cpus,
 						(cpus - config_ptr->cpus);
 
 	if (real_memory < config_ptr->real_memory) {
-		error ("validate_node_specs: node %s has low real_memory size %u", 
+		error ("Node %s has low real_memory size %u", 
 		       node_name, real_memory);
 		error_code = EINVAL;
 	}
 	node_ptr->real_memory = real_memory;
 
 	if (tmp_disk < config_ptr->tmp_disk) {
-		error ("validate_node_specs: node %s has low tmp_disk size %u",
+		error ("Node %s has low tmp_disk size %u",
 		       node_name, tmp_disk);
 		error_code = EINVAL;
 	}
 	node_ptr->tmp_disk = tmp_disk;
 
 	if (error_code) {
-		error ("validate_node_specs: setting node %s state to DOWN",
-			node_name);
+		error ("Setting node %s state to DOWN", node_name);
 		set_node_down(node_name);
 	} else if (status == ESLURMD_PROLOG_FAILED) {
 		error ("Prolog failure on node %s, state to DOWN",
@@ -1101,7 +1099,7 @@ validate_node_specs (char *node_name, uint32_t cpus,
 		 * processor count at present */
 		if ((slurmctld_conf.fast_schedule == 0) &&
 		    (node_ptr->config_ptr->cpus != cpus)) {
-			error ("Node %s has processor count inconsistent with rest of partition",
+			error ("Node %s processor count inconsistent with rest of partition",
 				node_name);
 			return EINVAL;		/* leave node down */
 		}
@@ -1489,29 +1487,45 @@ void msg_to_slurmd (slurm_msg_type_t msg_type)
 }
 
 
+/* make_node_alloc - flag specified node as allocated to a job */
+void make_node_alloc(struct node_record *node_ptr)
+{
+	int inx = node_ptr - node_record_table_ptr;
+	uint16_t no_resp_flag;
+
+	last_node_update = time (NULL);
+	no_resp_flag = node_ptr->node_state & NODE_STATE_NO_RESPOND;
+	node_ptr->node_state = NODE_STATE_ALLOCATED | no_resp_flag;
+	(node_ptr->job_cnt)++;
+	bit_clear(idle_node_bitmap, inx);
+}
+
 /* make_node_comp - flag specified node as completing a job */
 void make_node_comp(struct node_record *node_ptr)
 {
 	uint16_t no_resp_flag, base_state;
 
+	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_DOWN) ||
 	    (base_state == NODE_STATE_DRAINED) ||
 	    (base_state == NODE_STATE_DRAINING)) {
-		debug3("Node %s being left in state %s", 
-		       node_state_string((enum node_states)node_ptr->name));
+		debug3("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;
 	}
 }
 
-/* make_node_idle - flag specified node as no longer being in use */
+/* make_node_idle - flag specified node as having completed a job */
 void make_node_idle(struct node_record *node_ptr)
 {
 	int inx = node_ptr - node_record_table_ptr;
 	uint16_t no_resp_flag, base_state;
 
+	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;
 	no_resp_flag = node_ptr->node_state & NODE_STATE_NO_RESPOND;
diff --git a/src/slurmctld/node_scheduler.c b/src/slurmctld/node_scheduler.c
index 5153ea25bca..41d9b4ed56a 100644
--- a/src/slurmctld/node_scheduler.c
+++ b/src/slurmctld/node_scheduler.c
@@ -94,10 +94,8 @@ void allocate_nodes(unsigned *bitmap)
 	last_node_update = time(NULL);
 
 	for (i = 0; i < node_record_count; i++) {
-		if (bit_test(bitmap, i) == 0)
-			continue;
-		node_record_table_ptr[i].node_state = NODE_STATE_ALLOCATED;
-		bit_clear(idle_node_bitmap, i);
+		if (bit_test(bitmap, i))
+			make_node_alloc(&node_record_table_ptr[i]);
 	}
 	return;
 }
diff --git a/src/slurmctld/read_config.c b/src/slurmctld/read_config.c
index 538709067b7..f72ec18c7f4 100644
--- a/src/slurmctld/read_config.c
+++ b/src/slurmctld/read_config.c
@@ -125,11 +125,11 @@ 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);
+		    node_record_table_ptr[i].node_state & 
+		    (~NODE_STATE_NO_RESPOND);
 		no_resp_flag =
-		    node_record_table_ptr[i].
-		    node_state & NODE_STATE_NO_RESPOND;
+		    node_record_table_ptr[i].node_state & 
+		    NODE_STATE_NO_RESPOND;
 		if (base_state == NODE_STATE_IDLE)
 			bit_set(idle_node_bitmap, i);
 		if ((base_state != NODE_STATE_DOWN) &&
@@ -284,9 +284,10 @@ static int _parse_node_spec(char *in_line)
 				break;
 			}
 		}
-		if (state_val == NO_VAL) {
+		if ((state_val == NO_VAL) ||
+		    (state_val == NODE_STATE_COMPLETING)) {
 			error
-			    ("_parse_node_spec: invalid state %s for node_name %s",
+			    ("_parse_node_spec: invalid initial state %s for node %s",
 			     state, node_name);
 			error_code = EINVAL;
 			goto cleanup;
@@ -374,8 +375,8 @@ static int _parse_node_spec(char *in_line)
 			node_record_point =
 			    create_node_record(config_point,
 					       this_node_name);
-			if ((state_val != NO_VAL)
-			    && (state_val != NODE_STATE_UNKNOWN))
+			if ((state_val != NO_VAL) &&
+			    (state_val != NODE_STATE_UNKNOWN))
 				node_record_point->node_state = state_val;
 			node_record_point->last_response = (time_t) 0;
 			if (node_addr)
@@ -827,32 +828,27 @@ static int _sync_nodes_to_jobs(void)
 	struct job_record *job_ptr;
 	ListIterator job_record_iterator;
 	int i, update_cnt = 0;
+	uint16_t no_resp_flag;
 
 	job_record_iterator = list_iterator_create(job_list);
 	while ((job_ptr =
 		(struct job_record *) list_next(job_record_iterator))) {
-		if ((job_ptr->job_state == JOB_PENDING)
-		    || (job_ptr->job_state == JOB_COMPLETE)
-		    || (job_ptr->job_state == JOB_FAILED)
-		    || (job_ptr->job_state == JOB_TIMEOUT))
+		if (job_ptr->job_state > JOB_COMPLETING)
 			continue;
 		if (job_ptr->node_bitmap == NULL)
 			continue;
 		for (i = 0; i < node_record_count; i++) {
 			if (bit_test(job_ptr->node_bitmap, i) == 0)
 				continue;
+			node_record_table_ptr[i].job_cnt++;
 			if (node_record_table_ptr[i].node_state ==
 			    NODE_STATE_ALLOCATED)
 				continue;	/* already in proper state */
 			update_cnt++;
-			if (node_record_table_ptr[i].
-			    node_state & NODE_STATE_NO_RESPOND)
-				node_record_table_ptr[i].node_state =
-				    NODE_STATE_ALLOCATED |
-				    NODE_STATE_NO_RESPOND;
-			else
-				node_record_table_ptr[i].node_state =
-				    NODE_STATE_ALLOCATED;
+			no_resp_flag = node_record_table_ptr[i].node_state & 
+				       NODE_STATE_NO_RESPOND;
+			node_record_table_ptr[i].node_state =
+				    NODE_STATE_ALLOCATED | no_resp_flag;
 		}
 	}
 	if (update_cnt)
diff --git a/src/slurmctld/slurmctld.h b/src/slurmctld/slurmctld.h
index d724305a7dc..482f85fbe87 100644
--- a/src/slurmctld/slurmctld.h
+++ b/src/slurmctld/slurmctld.h
@@ -122,7 +122,7 @@ struct config_record {
 	uint32_t real_memory;	/* MB real memory on the node */
 	uint32_t tmp_disk;	/* MB total storage in TMP_FS file system */
 	uint32_t weight;	/* arbitrary priority of node for 
-				   scheduling work on */
+				 * scheduling work on */
 	char *feature;		/* arbitrary list of features associated */
 	char *nodes;		/* name of nodes with this configuration */
 	bitstr_t *node_bitmap;	/* bitmap of nodes with this configuration */
@@ -134,8 +134,8 @@ struct node_record {
 	uint32_t magic;			/* magic cookie for data integrity */
 	char name[MAX_NAME_LEN];	/* name of the node. NULL==defunct */
 	uint16_t node_state;		/* enum node_states, ORed with 
-					   NODE_STATE_NO_RESPOND if not 
-					   responding */
+					 * NODE_STATE_NO_RESPOND if not 
+					 * responding */
 	time_t last_response;		/* last response from the node */
 	uint32_t cpus;			/* count of cpus on the node */
 	uint32_t real_memory;		/* MB real memory on the node */
@@ -144,15 +144,16 @@ struct node_record {
 	struct part_record *partition_ptr; /* partition for this node */
 	char comm_name[MAX_NAME_LEN];	/* communications path name to node */
 	slurm_addr slurm_addr;		/* network address */
+	uint16_t job_cnt;		/* count of jobs allocated to node */
 };
 
 extern struct node_record *node_record_table_ptr;  /* ptr to node records */
 extern time_t last_bitmap_update;	/* time of last node creation or 
-					   deletion */
+					 * deletion */
 extern time_t last_node_update;		/* time of last node record update */
 extern int node_record_count;		/* count in node_record_table_ptr */
 extern int *hash_table;			/* table of hashed indicies into 
-					   node_record_table_ptr */
+					 * node_record_table_ptr */
 extern bitstr_t *up_node_bitmap;	/* bitmap of nodes are up */
 extern bitstr_t *idle_node_bitmap;	/* bitmap of nodes are idle */
 extern struct config_record default_config_record;
@@ -236,7 +237,10 @@ struct job_record {
 	struct part_record *part_ptr;	/* pointer to the partition record */
 	uint16_t batch_flag;		/* 1 if batch job (with script) */
 	uint32_t user_id;		/* user the job runs as */
-	enum job_states job_state;	/* state of the job */
+	enum job_states job_state;	/* state of the job, NOTE: state
+					 * JOB_COMPLETING is set in pack_job 
+					 * when (job state > JOB_RUNNING) &&
+					 * (node_count > 0), its artificial */
 	uint16_t kill_on_node_fail;	/* 1 if job should be killed on 
 					   node failure */
 	uint16_t kill_on_step_done;	/* 1 if job should be killed when 
@@ -701,6 +705,9 @@ extern void load_part_uid_allow_list ( int force );
  */
 extern int load_all_part_state ( void );
 
+/* make_node_alloc - flag specified node as allocated to a job */
+extern void make_node_alloc(struct node_record *node_ptr);
+
 /* make_node_comp - flag specified node as completing a job */
 extern void make_node_comp(struct node_record *node_ptr);
 
-- 
GitLab