From 10a087185d2f9a1e91b77742c0e2efbbe41b79f0 Mon Sep 17 00:00:00 2001
From: Danny Auble <da@llnl.gov>
Date: Mon, 7 Jul 2008 21:22:10 +0000
Subject: [PATCH] added support for updating cluster when read in, no
 associations other than root work right now.

---
 src/common/assoc_mgr.c                        |  16 +-
 .../mysql/accounting_storage_mysql.c          |  79 +++++-----
 src/sacctmgr/cluster_functions.c              |   4 +-
 src/sacctmgr/sacctmgr.c                       | 149 ++++++++++++++++--
 4 files changed, 192 insertions(+), 56 deletions(-)

diff --git a/src/common/assoc_mgr.c b/src/common/assoc_mgr.c
index 49780f2f64e..21a5b2d2a70 100644
--- a/src/common/assoc_mgr.c
+++ b/src/common/assoc_mgr.c
@@ -534,26 +534,25 @@ extern int assoc_mgr_update_local_assocs(acct_update_object_t *update)
 				break;
 			}
 			debug("updating assoc %u", rec->id);
-			if(object->fairshare != (uint32_t)NO_VAL) {
+			if(object->fairshare != NO_VAL) {
 				rec->fairshare = object->fairshare;
 			}
 
-			if(object->max_jobs != (uint32_t)NO_VAL) {
+			if(object->max_jobs != NO_VAL) {
 				rec->max_jobs = object->max_jobs;
 			}
 
-			if(object->max_nodes_per_job != (uint32_t)NO_VAL) {
+			if(object->max_nodes_per_job != NO_VAL) {
 				rec->max_nodes_per_job =
 					object->max_nodes_per_job;
 			}
 
-			if(object->max_wall_duration_per_job !=
-			   (uint32_t)NO_VAL) {
+			if(object->max_wall_duration_per_job != NO_VAL) {
 				rec->max_wall_duration_per_job =
 					object->max_wall_duration_per_job;
 			}
 
-			if(object->max_cpu_secs_per_job != (uint32_t)NO_VAL) {
+			if(object->max_cpu_secs_per_job != NO_VAL) {
 				rec->max_cpu_secs_per_job = 
 					object->max_cpu_secs_per_job;
 			}
@@ -570,7 +569,6 @@ extern int assoc_mgr_update_local_assocs(acct_update_object_t *update)
 				
 			}
 			log_assoc_rec(rec);
-			/* FIX ME: do more updates here */
 			break;
 		case ACCT_ADD_ASSOC:
 			if(rec) {
@@ -579,6 +577,7 @@ extern int assoc_mgr_update_local_assocs(acct_update_object_t *update)
 			}
 			_set_assoc_parent_and_user(object);
 			list_append(local_association_list, object);
+			break;
 		case ACCT_REMOVE_ASSOC:
 			if(!rec) {
 				//rc = SLURM_ERROR;
@@ -672,7 +671,7 @@ extern int assoc_mgr_update_local_users(acct_update_object_t *update)
 			if(passwd_ptr) 
 				object->uid = passwd_ptr->pw_uid;
 			else
-				object->uid = (uint32_t)NO_VAL;
+				object->uid = NO_VAL;
 
 			list_append(local_user_list, object);
 		case ACCT_REMOVE_USER:
@@ -683,6 +682,7 @@ extern int assoc_mgr_update_local_users(acct_update_object_t *update)
 			list_delete_item(itr);
 			break;
 		case ACCT_ADD_COORD:
+			/* same as ACCT_REMOVE_COORD */
 		case ACCT_REMOVE_COORD:
 			if(!rec) {
 				//rc = SLURM_ERROR;
diff --git a/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c b/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c
index 5cc437aec76..63249622843 100644
--- a/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c
+++ b/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c
@@ -483,36 +483,36 @@ static int _modify_unset_users(mysql_conn_t *mysql_conn,
 		mod_assoc = xmalloc(sizeof(acct_association_rec_t));
 		mod_assoc->id = atoi(row[ASSOC_ID]);
 
-		if(!row[ASSOC_MJ] && assoc->max_jobs != (uint32_t)NO_VAL) {
+		if(!row[ASSOC_MJ] && assoc->max_jobs != NO_VAL) {
 			mod_assoc->max_jobs = assoc->max_jobs;
 			modified = 1;
 		} else
-			mod_assoc->max_jobs = (uint32_t)NO_VAL;
+			mod_assoc->max_jobs = NO_VAL;
 		
 		if(!row[ASSOC_MNPJ] &&
-		   assoc->max_nodes_per_job != (uint32_t)NO_VAL) {
+		   assoc->max_nodes_per_job != NO_VAL) {
 			mod_assoc->max_nodes_per_job =
 				assoc->max_nodes_per_job;
 			modified = 1;
 		} else 
-			mod_assoc->max_nodes_per_job = (uint32_t)NO_VAL;
+			mod_assoc->max_nodes_per_job = NO_VAL;
 
 		
 		if(!row[ASSOC_MWPJ] && 
-		   assoc->max_wall_duration_per_job != (uint32_t)NO_VAL) {
+		   assoc->max_wall_duration_per_job != NO_VAL) {
 			mod_assoc->max_wall_duration_per_job =
 				assoc->max_wall_duration_per_job;
 			modified = 1;
 		} else 
-			mod_assoc->max_wall_duration_per_job = (uint32_t)NO_VAL;
+			mod_assoc->max_wall_duration_per_job = NO_VAL;
 					
 		if(!row[ASSOC_MCPJ] && 
-		   assoc->max_cpu_secs_per_job != (uint32_t)NO_VAL) {
+		   assoc->max_cpu_secs_per_job != NO_VAL) {
 			mod_assoc->max_cpu_secs_per_job = 
 				assoc->max_cpu_secs_per_job;
 			modified = 1;
 		} else
-			mod_assoc->max_cpu_secs_per_job = (uint32_t)NO_VAL;
+			mod_assoc->max_cpu_secs_per_job = NO_VAL;
 		
 
 		if(modified) {
@@ -527,7 +527,7 @@ static int _modify_unset_users(mysql_conn_t *mysql_conn,
 				continue;
 			}
 
-			mod_assoc->fairshare = (uint32_t)NO_VAL;
+			mod_assoc->fairshare = NO_VAL;
 			if(row[ASSOC_PART][0]) { 
 				// see if there is a partition name
 				object = xstrdup_printf(
@@ -1922,7 +1922,7 @@ extern int acct_storage_p_add_clusters(mysql_conn_t *mysql_conn, uint32_t uid,
 			xstrfmtcat(vals, ", %u", object->default_fairshare);
 			xstrfmtcat(extra, ", fairshare=%u",
 				   object->default_fairshare);
-		} else if ((int)object->default_fairshare == -1) {
+		} else if ((int)object->default_fairshare == INFINITE) {
 			xstrcat(cols, ", fairshare");
 			xstrfmtcat(vals, ", NULL");
 			xstrfmtcat(extra, ", fairshare=NULL");		
@@ -1934,7 +1934,7 @@ extern int acct_storage_p_add_clusters(mysql_conn_t *mysql_conn, uint32_t uid,
 				   object->default_max_cpu_secs_per_job);
 			xstrfmtcat(extra, ", max_cpu_secs_per_job=%u",
 				   object->default_max_cpu_secs_per_job);
-		} else if((int)object->default_max_cpu_secs_per_job == -1) {
+		} else if((int)object->default_max_cpu_secs_per_job == INFINITE) {
 			xstrcat(cols, ", max_cpu_secs_per_job");
 			xstrfmtcat(vals, ", NULL");
 			xstrfmtcat(extra, ", max_cpu_secs_per_job=NULL");
@@ -1945,7 +1945,7 @@ extern int acct_storage_p_add_clusters(mysql_conn_t *mysql_conn, uint32_t uid,
 			xstrfmtcat(vals, ", %u", object->default_max_jobs);
 			xstrfmtcat(extra, ", max_jobs=%u",
 				   object->default_max_jobs);
-		} else if((int)object->default_max_jobs == -1) {
+		} else if((int)object->default_max_jobs == INFINITE) {
 			xstrcat(cols, ", max_jobs");
 			xstrfmtcat(vals, ", NULL");
 			xstrfmtcat(extra, ", max_jobs=NULL");		
@@ -1957,7 +1957,7 @@ extern int acct_storage_p_add_clusters(mysql_conn_t *mysql_conn, uint32_t uid,
 				   object->default_max_nodes_per_job);
 			xstrfmtcat(extra, ", max_nodes_per_job=%u",
 				   object->default_max_nodes_per_job);
-		} else if((int)object->default_max_nodes_per_job == -1) {
+		} else if((int)object->default_max_nodes_per_job == INFINITE) {
 			xstrcat(cols, ", max_nodes_per_job");
 			xstrfmtcat(vals, ", NULL");
 			xstrfmtcat(extra, ", max_nodes_per_job=NULL");
@@ -1970,7 +1970,7 @@ extern int acct_storage_p_add_clusters(mysql_conn_t *mysql_conn, uint32_t uid,
 			xstrfmtcat(extra, ", max_wall_duration_per_job=%u",
 				   object->default_max_wall_duration_per_job);
 		} else if((int)object->default_max_wall_duration_per_job
-			  == -1) {
+			  == INFINITE) {
 			xstrcat(cols, ", max_wall_duration_per_job");
 			xstrfmtcat(vals, ", NULL");
 			xstrfmtcat(extra, ", max_duration_per_job=NULL");
@@ -2537,6 +2537,7 @@ extern List acct_storage_p_modify_users(mysql_conn_t *mysql_conn, uint32_t uid,
 		xstrfmtcat(vals, ", admin_level=%u", user->admin_level);
 
 	if(!extra || !vals) {
+		errno = SLURM_NO_CHANGE_IN_DATA;
 		error("Nothing to change");
 		return NULL;
 	}
@@ -2673,6 +2674,7 @@ extern List acct_storage_p_modify_accts(mysql_conn_t *mysql_conn, uint32_t uid,
 		xstrfmtcat(vals, ", qos='%u'", acct->qos);
 
 	if(!extra || !vals) {
+		errno = SLURM_NO_CHANGE_IN_DATA;
 		error("Nothing to change");
 		return NULL;
 	}
@@ -2789,6 +2791,7 @@ extern List acct_storage_p_modify_clusters(mysql_conn_t *mysql_conn,
 	}
 
 	if(!vals) {
+		errno = SLURM_NO_CHANGE_IN_DATA;
 		error("Nothing to change");
 		return NULL;
 	}
@@ -3009,33 +3012,35 @@ extern List acct_storage_p_modify_associations(mysql_conn_t *mysql_conn,
 
 	if((int)assoc->fairshare >= 0) 
 		xstrfmtcat(vals, ", fairshare=%u", assoc->fairshare);
-	else if((int)assoc->fairshare == -1) 
+	else if((int)assoc->fairshare == INFINITE) {
 		xstrfmtcat(vals, ", fairshare=1");
-       		
+		assoc->fairshare = 1;
+	}
 	if((int)assoc->max_cpu_secs_per_job >= 0) 
 		xstrfmtcat(vals, ", max_cpu_secs_per_job=%u",
 			   assoc->max_cpu_secs_per_job);
-	else if((int)assoc->max_cpu_secs_per_job == -1) 
+	else if((int)assoc->max_cpu_secs_per_job == INFINITE) {
 		xstrfmtcat(vals, ", max_cpu_secs_per_job=NULL");
-
+	}
 	if((int)assoc->max_jobs >= 0) 
 		xstrfmtcat(vals, ", max_jobs=%u", assoc->max_jobs);
-	else if((int)assoc->max_jobs == -1)
+	else if((int)assoc->max_jobs == INFINITE) {
 		xstrfmtcat(vals, ", max_jobs=NULL");
-		
+	}
 	if((int)assoc->max_nodes_per_job >= 0) 
 		xstrfmtcat(vals, ", max_nodes_per_job=%u",
 			   assoc->max_nodes_per_job);
-	else if((int)assoc->max_nodes_per_job == -1)
+	else if((int)assoc->max_nodes_per_job == INFINITE) {
 		xstrfmtcat(vals, ", max_nodes_per_job=NULL");
-
+	}
 	if((int)assoc->max_wall_duration_per_job >= 0) 
 		xstrfmtcat(vals, ", max_wall_duration_per_job=%u",
 			   assoc->max_wall_duration_per_job);
-	else if((int)assoc->max_wall_duration_per_job == -1) 
+	else if((int)assoc->max_wall_duration_per_job == INFINITE) {
 		xstrfmtcat(vals, ", max_wall_duration_per_job=NULL");
-		
+	}
 	if(!extra || (!vals && !assoc->parent_acct)) {
+		errno = SLURM_NO_CHANGE_IN_DATA;
 		error("Nothing to change");
 		return NULL;
 	}
@@ -4609,25 +4614,25 @@ empty:
 		if(row2[ASSOC_REQ_MJ])
 			cluster->default_max_jobs = atoi(row2[ASSOC_REQ_MJ]);
 		else
-			cluster->default_max_jobs = -1;
+			cluster->default_max_jobs = INFINITE;
 		
 		if(row2[ASSOC_REQ_MNPJ])
 			cluster->default_max_nodes_per_job =
 				atoi(row2[ASSOC_REQ_MNPJ]);
 		else
-			cluster->default_max_nodes_per_job = -1;
+			cluster->default_max_nodes_per_job = INFINITE;
 		
 		if(row2[ASSOC_REQ_MWPJ])
 			cluster->default_max_wall_duration_per_job = 
 				atoi(row2[ASSOC_REQ_MWPJ]);
 		else
-			cluster->default_max_wall_duration_per_job = -1;
+			cluster->default_max_wall_duration_per_job = INFINITE;
 		
 		if(row2[ASSOC_REQ_MCPJ])
 			cluster->default_max_cpu_secs_per_job = 
 				atoi(row2[ASSOC_REQ_MCPJ]);
 		else 
-			cluster->default_max_cpu_secs_per_job = -1;
+			cluster->default_max_cpu_secs_per_job = INFINITE;
 		mysql_free_result(result2);
 	}
 	mysql_free_result(result);
@@ -4653,10 +4658,10 @@ extern List acct_storage_p_get_associations(mysql_conn_t *mysql_conn,
 	int i=0;
 	MYSQL_RES *result = NULL;
 	MYSQL_ROW row;
-	int parent_mj = -1;
-	int parent_mnpj = -1;
-	int parent_mwpj = -1;
-	int parent_mcpj = -1;
+	int parent_mj = INFINITE;
+	int parent_mnpj = INFINITE;
+	int parent_mwpj = INFINITE;
+	int parent_mcpj = INFINITE;
 	char *last_acct = NULL;
 	char *last_acct_parent = NULL;
 	char *last_cluster = NULL;
@@ -4894,22 +4899,22 @@ empty:
 				if(row2[ASSOC2_REQ_MJ])
 					parent_mj = atoi(row2[ASSOC2_REQ_MJ]);
 				else
-					parent_mj = -1;
+					parent_mj = INFINITE;
 				
 				if(row2[ASSOC2_REQ_MNPJ])
 					parent_mnpj = atoi(row2[ASSOC2_REQ_MNPJ]);
 				else
-					parent_mwpj = -1;
+					parent_mwpj = INFINITE;
 				
 				if(row2[ASSOC2_REQ_MWPJ])
 					parent_mwpj = atoi(row2[ASSOC2_REQ_MWPJ]);
 				else
-					parent_mwpj = -1;
+					parent_mwpj = INFINITE;
 				
 				if(row2[ASSOC2_REQ_MCPJ])
 					parent_mcpj = atoi(row2[ASSOC2_REQ_MCPJ]);
 				else 
-					parent_mcpj = -1;
+					parent_mcpj = INFINITE;
 			}
 			last_acct = row[ASSOC_REQ_ACCT];
 			last_cluster2 = row[ASSOC_REQ_CLUSTER];
@@ -5951,7 +5956,7 @@ extern int jobacct_storage_p_step_complete(mysql_conn_t *mysql_conn,
 		ave_cpu /= 100;
 	}
  
-	if(jobacct->min_cpu != (uint32_t)NO_VAL) {
+	if(jobacct->min_cpu != NO_VAL) {
 		ave_cpu2 = jobacct->min_cpu;
 		ave_cpu2 /= 100;
 	}
diff --git a/src/sacctmgr/cluster_functions.c b/src/sacctmgr/cluster_functions.c
index b4a1e94c9ac..fe6d007a963 100644
--- a/src/sacctmgr/cluster_functions.c
+++ b/src/sacctmgr/cluster_functions.c
@@ -657,7 +657,7 @@ extern int sacctmgr_modify_cluster(int argc, char *argv[])
 				 "Are you sure you want to continue?")) {
 			printf("Aborted\n");
 			destroy_acct_association_rec(assoc);
-			destroy_acct_association_cond(assoc);
+			destroy_acct_association_cond(assoc_cond);
 			return SLURM_SUCCESS;
 		}		
 	}
@@ -839,7 +839,7 @@ extern int sacctmgr_dump_cluster (int argc, char *argv[])
 
 	if(!file_name) {
 		file_name = xstrdup_printf("./%s.cfg", cluster_name);
-		printf(" No filename give using %s.\n", file_name);
+		printf(" No filename given, using %s.\n", file_name);
 	}
 
 	memset(&assoc_cond, 0, sizeof(acct_association_cond_t));
diff --git a/src/sacctmgr/sacctmgr.c b/src/sacctmgr/sacctmgr.c
index 1ca4c620dbf..1c5719fa960 100644
--- a/src/sacctmgr/sacctmgr.c
+++ b/src/sacctmgr/sacctmgr.c
@@ -705,11 +705,11 @@ static sacctmgr_file_opts_t *_parse_options(char *options)
 	char *option = NULL;
 	char quote_c = '\0';
 
-	file_opts->fairshare = NO_VAL;
-	file_opts->max_cpu_secs_per_job = NO_VAL;
-	file_opts->max_jobs = NO_VAL;
-	file_opts->max_nodes_per_job = NO_VAL;
-	file_opts->max_wall_duration_per_job = NO_VAL;
+	file_opts->fairshare = 1;
+	file_opts->max_cpu_secs_per_job = INFINITE;
+	file_opts->max_jobs = INFINITE;
+	file_opts->max_nodes_per_job = INFINITE;
+	file_opts->max_wall_duration_per_job = INFINITE;
 
 	while(options[i]) {
 		quote = 0;
@@ -935,6 +935,7 @@ static void _load_file (int argc, char *argv[])
 				rc = SLURM_ERROR;
 				break;
 			}
+
 			file_opts = _parse_options(line+start);
 			
 			if(!file_opts) {
@@ -943,8 +944,11 @@ static void _load_file (int argc, char *argv[])
 				break;
 			}
 			cluster_name = xstrdup(file_opts->name);
-			if(!sacctmgr_find_cluster_from_list(
-				   curr_cluster_list, cluster_name)) {
+
+			info("For cluster %s", cluster_name);
+
+			if(!(cluster = sacctmgr_find_cluster_from_list(
+				     curr_cluster_list, cluster_name))) {
 				List cluster_list =
 					list_create(destroy_acct_cluster_rec);
 				cluster = xmalloc(sizeof(acct_cluster_rec_t));
@@ -970,8 +974,135 @@ static void _load_file (int argc, char *argv[])
 					rc = SLURM_ERROR;
 					break;
 				}
+				set = 1;
+			} else {
+				int changed = 0;
+				acct_association_rec_t mod_assoc;
+				acct_association_cond_t assoc_cond;
+
+				memset(&mod_assoc, 0,
+				       sizeof(acct_association_rec_t));
+
+				mod_assoc.fairshare = NO_VAL;
+				mod_assoc.max_cpu_secs_per_job = NO_VAL;
+				mod_assoc.max_jobs = NO_VAL;
+				mod_assoc.max_nodes_per_job = NO_VAL;
+				mod_assoc.max_wall_duration_per_job = NO_VAL;
+
+				memset(&assoc_cond, 0,
+				       sizeof(acct_association_cond_t));
+
+				assoc_cond.fairshare = NO_VAL;
+				assoc_cond.max_cpu_secs_per_job = NO_VAL;
+				assoc_cond.max_jobs = NO_VAL;
+				assoc_cond.max_nodes_per_job = NO_VAL;
+				assoc_cond.max_wall_duration_per_job = NO_VAL;
+
+				if(cluster->default_fairshare !=
+				   file_opts->fairshare) {
+					mod_assoc.fairshare =
+						file_opts->fairshare;
+					changed = 1;
+					printf(" Changed Cluster default for "
+					       "fairshare from %d -> %d\n",
+					       cluster->default_fairshare,
+					       file_opts->fairshare);
+				}
+				if(cluster->default_max_cpu_secs_per_job != 
+				   file_opts->max_cpu_secs_per_job) {
+					mod_assoc.max_cpu_secs_per_job =
+						file_opts->max_cpu_secs_per_job;
+					changed = 1;
+					printf(" Changed Cluster default for "
+					       "MaxCPUSecsPerJob "
+					       "from %d -> %d\n",
+					       cluster->
+					       default_max_cpu_secs_per_job,
+					       file_opts->max_cpu_secs_per_job);
+				}
+				if(cluster->default_max_jobs !=
+				   file_opts->max_jobs) {
+					mod_assoc.max_jobs = 
+						file_opts->max_jobs;
+					changed = 1;
+					printf(" Changed Cluster default for "
+					       "MaxJobs from %d -> %d\n",
+					       cluster->default_max_jobs,
+					       file_opts->max_jobs);
+				}
+				if(cluster->default_max_nodes_per_job != 
+				   file_opts->max_nodes_per_job) {
+					mod_assoc.max_nodes_per_job =
+						file_opts->max_nodes_per_job;
+					changed = 1;
+					printf(" Changed Cluster default for "
+					       "MaxNodesPerJob "
+					       "from %d -> %d\n",
+					       cluster->
+					       default_max_nodes_per_job, 
+					       file_opts->max_nodes_per_job);
+				}
+				if(cluster->default_max_wall_duration_per_job !=
+				   file_opts->max_wall_duration_per_job) {
+					mod_assoc.max_wall_duration_per_job =
+						file_opts->
+						max_wall_duration_per_job;
+					changed = 1;
+					printf(" Changed Cluster default for "
+					       "MaxWallDurationPerJob "
+					       "from %d -> %d\n",
+					       cluster->
+					       default_max_wall_duration_per_job,
+					       file_opts->
+					       max_wall_duration_per_job);
+				}
+
+				if(changed) {
+					List ret_list = NULL;
+					
+					assoc_cond.cluster_list = 
+						list_create(NULL); 
+					assoc_cond.acct_list = 
+						list_create(NULL); 
+					
+					list_push(assoc_cond.cluster_list,
+						  cluster->name);
+					list_push(assoc_cond.acct_list, "root");
+					
+					notice_thread_init();
+					ret_list =
+						acct_storage_g_modify_associations(
+							db_conn, my_uid,
+							&assoc_cond, 
+							&mod_assoc);
+					notice_thread_fini();
+					
+					list_destroy(assoc_cond.cluster_list);
+					list_destroy(assoc_cond.acct_list);
+
+					if(ret_list && list_count(ret_list)) {
+						char *object = NULL;
+						ListIterator itr = 
+							list_iterator_create(
+								ret_list);
+						printf(" Modified cluster "
+						       "defaults for "
+						       "associations...\n");
+						while((object = 
+						       list_next(itr))) {
+							printf("  %s\n",
+							       object);
+						}
+						list_iterator_destroy(itr);
+					}
+ 
+					if(ret_list) {
+						list_destroy(ret_list);
+						set = 1;
+					}
+				}
 			}
-			info("For cluster %s", cluster_name);
+				     
 			_destroy_sacctmgr_file_opts(file_opts);
 			
 			memset(&assoc_cond, 0, sizeof(acct_association_cond_t));
@@ -991,7 +1122,7 @@ static void _load_file (int argc, char *argv[])
 			continue;
 		} else if(!cluster_name) {
 			printf(" error: You need to specify a cluster name "
-			       "first with 'Cluster - name' in your file\n");
+			       "first with 'Cluster - $NAME' in your file\n");
 			break;
 		}
 
-- 
GitLab