From 6e3c4e14bba501f5280f7d31c6e5364b01ba998f Mon Sep 17 00:00:00 2001
From: Moe Jette <jette1@llnl.gov>
Date: Mon, 6 Nov 2006 22:54:12 +0000
Subject: [PATCH] Permit the modification of a pending job's geometry or rotate
 parameters. NOTE: select_g_alloc_jobinfo() now sets geometry and rotate to
 NO_VAL rather than 0 and 1 respectively. This is needed to tell when the user
 specified new values for the paramters or if they are still in the initial
 settings.

---
 src/common/node_select.c  | 26 +++++++++-----
 src/scontrol/update_job.c | 33 ++++--------------
 src/slurmctld/job_mgr.c   | 72 ++++++++++++++++++++++++++++++++-------
 3 files changed, 84 insertions(+), 47 deletions(-)

diff --git a/src/common/node_select.c b/src/common/node_select.c
index 476d4b95108..38fb3ac2880 100644
--- a/src/common/node_select.c
+++ b/src/common/node_select.c
@@ -588,12 +588,14 @@ static char *_job_conn_type_string(uint16_t inx)
 	else if (inx == SELECT_SMALL)
 		return "small";
 	else
-		return "nav";
+		return "n/a";
 }
 
 static char *_job_rotate_string(uint16_t inx)
 {
-	if (inx)
+	if (inx == (uint16_t) NO_VAL)
+		return "n/a";
+	else if (inx)
 		return "yes";
 	else
 		return "no";
@@ -610,12 +612,12 @@ extern int select_g_alloc_jobinfo (select_jobinfo_t *jobinfo)
 	xassert(jobinfo != NULL);
 	
 	*jobinfo = xmalloc(sizeof(struct select_jobinfo));
-	for (i=0; i<SYSTEM_DIMENSIONS; i++)
-			(*jobinfo)->start[i] = (uint16_t) NO_VAL;
-	for (i=0; i<SYSTEM_DIMENSIONS; i++)
-			(*jobinfo)->geometry[i] = 0;
+	for (i=0; i<SYSTEM_DIMENSIONS; i++) {
+		(*jobinfo)->start[i]    = (uint16_t) NO_VAL;
+		(*jobinfo)->geometry[i] = (uint16_t) NO_VAL;
+	}
 	(*jobinfo)->conn_type = SELECT_NAV;
-	(*jobinfo)->rotate = 1;
+	(*jobinfo)->rotate = (uint16_t) NO_VAL;
 	(*jobinfo)->node_use = SELECT_NAV;
 	(*jobinfo)->bg_block_id = NULL;
 	(*jobinfo)->magic = JOBINFO_MAGIC;
@@ -639,7 +641,11 @@ extern int select_g_set_jobinfo (select_jobinfo_t jobinfo,
 	uint16_t *uint16 = (uint16_t *) data;
 	uint32_t *uint32 = (uint32_t *) data;
 	char *tmp_char = (char *) data;
-	
+
+	if (jobinfo == NULL) {
+		error("select_g_set_jobinfo: jobinfo not set");
+		return SLURM_ERROR;
+	}
 	if (jobinfo->magic != JOBINFO_MAGIC) {
 		error("select_g_set_jobinfo: jobinfo magic bad");
 		return SLURM_ERROR;
@@ -705,6 +711,10 @@ extern int select_g_get_jobinfo (select_jobinfo_t jobinfo,
 	uint32_t *uint32 = (uint32_t *) data;
 	char **tmp_char = (char **) data;
 
+	if (jobinfo == NULL) {
+		error("select_g_get_jobinfo: jobinfo not set");
+		return SLURM_ERROR;
+	}
 	if (jobinfo->magic != JOBINFO_MAGIC) {
 		error("select_g_get_jobinfo: jobinfo magic bad");
 		return SLURM_ERROR;
diff --git a/src/scontrol/update_job.c b/src/scontrol/update_job.c
index c12ac3d490b..b4182bce848 100644
--- a/src/scontrol/update_job.c
+++ b/src/scontrol/update_job.c
@@ -388,15 +388,13 @@ scontrol_update_job (int argc, char *argv[])
 
 			if (original_ptr)
 				xfree(original_ptr);
-			if (rc != 0) {
-				for (j=0; j<SYSTEM_DIMENSIONS; j++)
-					geo[j] = (uint16_t) NO_VAL;
+			if (rc != 0)
 				exit_code = 1;
-			} else
+			else {
+				for (j=0; j<SYSTEM_DIMENSIONS; j++)
+					job_msg.geometry[j] = geo[j];
 				update_cnt++;
-			select_g_set_jobinfo(job_msg.select_jobinfo,
-					     SELECT_DATA_GEOMETRY,
-					     (void *) &geo);
+			}
 		}
 
 		else if (strncasecmp(argv[i], "Rotate=", 7) == 0) {
@@ -408,26 +406,7 @@ scontrol_update_job (int argc, char *argv[])
 			else
 				rotate = (uint16_t) strtol(&argv[i][7], 
 							   (char **) NULL, 10);
-			select_g_set_jobinfo(job_msg.select_jobinfo,
-					     SELECT_DATA_ROTATE,
-					     (void *) &rotate);
-			update_cnt++;
-		}
-		else if (strncasecmp(argv[i], "Connection=", 11) == 0) {
-			uint16_t conn_type;
-			if (strcasecmp(&argv[i][11], "torus") == 0)
-				conn_type = SELECT_TORUS;
-			else if (strcasecmp(&argv[i][11], "mesh") == 0)
-				conn_type = SELECT_MESH;
-			else if (strcasecmp(&argv[i][11], "nav") == 0)
-				conn_type = SELECT_NAV;
-			else
-				conn_type = 
-					(uint16_t) strtol(&argv[i][11], 
-							(char **) NULL, 10);
-			select_g_set_jobinfo(job_msg.select_jobinfo,
-					     SELECT_DATA_CONN_TYPE,
-					     (void *) &conn_type);
+			job_msg.rotate = rotate;
 			update_cnt++;
 		}
 #endif
diff --git a/src/slurmctld/job_mgr.c b/src/slurmctld/job_mgr.c
index cf284fbf062..46049981b43 100644
--- a/src/slurmctld/job_mgr.c
+++ b/src/slurmctld/job_mgr.c
@@ -1662,6 +1662,7 @@ static int _job_create(job_desc_msg_t * job_desc, int allocate, int will_run,
 	uint32_t total_nodes, max_procs;
 #if SYSTEM_DIMENSIONS
 	uint16_t geo[SYSTEM_DIMENSIONS];
+	uint16_t rotate;
 #endif
 
 	debug2("before alteration asking for nodes %u-%u procs %u", 
@@ -1769,13 +1770,17 @@ static int _job_create(job_desc_msg_t * job_desc, int allocate, int will_run,
 
 #if SYSTEM_DIMENSIONS
 	select_g_get_jobinfo(job_desc->select_jobinfo,
-			     SELECT_DATA_GEOMETRY,
-			     &geo);
-	if ((geo[0] != (uint16_t) NO_VAL) && (geo[0] != 0)) {
-		int i, tot = 1;
+			     SELECT_DATA_GEOMETRY, &geo);
+	if (geo[0] == (uint16_t) NO_VAL) {
 		for (i=0; i<SYSTEM_DIMENSIONS; i++) {
-			tot *= geo[i];
+			geo[i] = 0;
 		}
+		select_g_set_jobinfo(job_desc->select_jobinfo,
+				     SELECT_DATA_GEOMETRY, &geo);
+	} else if (geo[0] != 0) {
+		uint32_t i, tot = 1;
+		for (i=0; i<SYSTEM_DIMENSIONS; i++)
+			tot *= geo[i];
 		if (job_desc->min_nodes > tot) {
 			info("MinNodes(%d) > GeometryNodes(%d)", 
 				job_desc->min_nodes, tot);
@@ -1784,6 +1789,13 @@ static int _job_create(job_desc_msg_t * job_desc, int allocate, int will_run,
 		}
 		job_desc->min_nodes = tot;
 	}
+	select_g_get_jobinfo(job_desc->select_jobinfo,
+			     SELECT_DATA_ROTATE, &rotate);
+	if (rotate == (uint16_t) NO_VAL) {
+		rotate = (uint16_t) 1;
+		select_g_set_jobinfo(job_desc->select_jobinfo,
+				     SELECT_DATA_ROTATE, &rotate);
+	}
 #endif
 
 	if (job_desc->max_nodes == NO_VAL)
@@ -3468,13 +3480,6 @@ int update_job(job_desc_msg_t * job_specs, uid_t uid)
 		}
 	}
 
-	if (job_specs->kill_on_node_fail != (uint16_t) NO_VAL) {
-		job_ptr->kill_on_node_fail = job_specs->kill_on_node_fail;
-		info("update_job: setting kill_on_node_fail to %u for "
-			"job_id %u", job_specs->kill_on_node_fail, 
-			job_specs->job_id);
-	}
-
 	if (job_specs->features) {
 		if ((!IS_JOB_PENDING(job_ptr)) || (detail_ptr == NULL))
 			error_code = ESLURM_DISABLED;
@@ -3583,6 +3588,49 @@ int update_job(job_desc_msg_t * job_specs, uid_t uid)
 			error_code = ESLURM_DISABLED;
 	}
 
+#ifdef HAVE_BG
+{
+	uint16_t rotate = (uint16_t) NO_VAL;
+	uint16_t geometry[SYSTEM_DIMENSIONS] = {(uint16_t) NO_VAL};
+
+	select_g_get_jobinfo(job_specs->select_jobinfo,
+			SELECT_DATA_ROTATE, &rotate);
+	if (rotate != (uint16_t) NO_VAL) {
+		if (!IS_JOB_PENDING(job_ptr))
+			error_code = ESLURM_DISABLED;
+		else {
+			info("update_job: setting rotate to %u for "
+				"jobid %u", rotate, job_ptr->job_id);
+			select_g_set_jobinfo(job_ptr->select_jobinfo,
+				SELECT_DATA_ROTATE, &rotate);
+		}
+	}
+
+	select_g_get_jobinfo(job_specs->select_jobinfo,
+			SELECT_DATA_GEOMETRY, geometry);
+	if (geometry[0] != (uint16_t) NO_VAL) {
+		if (!IS_JOB_PENDING(job_ptr))
+			error_code = ESLURM_DISABLED;
+		else if (super_user) {
+			uint32_t i, tot = 1;
+			for (i=0; i<SYSTEM_DIMENSIONS; i++)
+				tot *= geometry[i];
+			info("update_job: setting rotate to %ux%ux%u "
+				"min_nodes=%u for jobid %u", 
+				geometry[0], geometry[1], 
+				geometry[2], tot, job_ptr->job_id);
+			select_g_set_jobinfo(job_ptr->select_jobinfo,
+				SELECT_DATA_GEOMETRY, geometry);
+			detail_ptr->min_nodes = tot;
+		} else {
+			error("Attempt to change geometry for job %u",
+				job_specs->job_id);
+			error_code = ESLURM_ACCESS_DENIED;
+		}
+	}
+}
+#endif
+
 	return error_code;
 }
 
-- 
GitLab