From 4be7316339ef6a386b9d779366b4e68bea2e2f0a Mon Sep 17 00:00:00 2001
From: Danny Auble <da@schedmd.com>
Date: Tue, 31 Jul 2012 16:02:57 -0700
Subject: [PATCH] Fix for sacct --state=S

Move code to handle multiple clusters.  Previous code could have issues
where job_db_inx space could overlap.
---
 .../mysql/as_mysql_jobacct_process.c          | 187 ++++++++----------
 .../mysql/as_mysql_jobacct_process.h          |   6 +-
 2 files changed, 84 insertions(+), 109 deletions(-)

diff --git a/src/plugins/accounting_storage/mysql/as_mysql_jobacct_process.c b/src/plugins/accounting_storage/mysql/as_mysql_jobacct_process.c
index c2236161d4e..cc5261a55ae 100644
--- a/src/plugins/accounting_storage/mysql/as_mysql_jobacct_process.c
+++ b/src/plugins/accounting_storage/mysql/as_mysql_jobacct_process.c
@@ -205,18 +205,10 @@ enum {
 	STEP_REQ_COUNT
 };
 
-static void _state_time_string(mysql_conn_t *mysql_conn,
-			       slurmdb_job_cond_t *job_cond,
-			       char **extra, uint32_t state,
+static void _state_time_string(char **extra, uint32_t state,
 			       uint32_t start, uint32_t end)
 {
-	MYSQL_RES *result = NULL;
-	MYSQL_ROW row;
-	ListIterator itr = NULL;
-	char *query = NULL, *cluster_name = NULL;
 	int base_state = state & JOB_STATE_BASE;
-	int set = 0, added = 0;
-	List use_cluster_list = as_mysql_cluster_list;
 
 	if (!start && !end) {
 		xstrfmtcat(*extra, "t1.state='%u'", state);
@@ -250,96 +242,7 @@ static void _state_time_string(mysql_conn_t *mysql_conn,
 		}
 		break;
 	case JOB_SUSPENDED:
-		/* Since we could be looking in the past for suspended
-		 * jobs we need to first look for jobs in each of the
-		 * cluster's suspend_table to see if we can use that
-		 * first.
-		 */
-		if (job_cond->cluster_list
-		    && list_count(job_cond->cluster_list))
-			use_cluster_list = job_cond->cluster_list;
-		else
-			slurm_mutex_lock(&as_mysql_cluster_list_lock);
-
-		itr = list_iterator_create(use_cluster_list);
-		while ((cluster_name = list_next(itr))) {
-			query = xstrdup_printf(
-				"select job_db_inx from \"%s_%s\"",
-				cluster_name, suspend_table);
-			if (start) {
-				if (!end) {
-					xstrfmtcat(query,
-						   " where (%d between "
-						   "time_start and time_end)",
-						   start);
-				} else {
-					xstrfmtcat(query,
-						   " where (time_start && "
-						   "((%d between time_start "
-						   "and time_end) "
-						   "|| (time_start between "
-						   "%d and %d)))",
-						   start, start, end);
-				}
-			} else if (end) {
-				xstrfmtcat(query, " where (time_start && "
-					   "time_start < %d)", end);
-			}
-
-			debug3("%d(%s:%d) query\n%s",
-			       mysql_conn->conn, THIS_FILE, __LINE__, query);
-			result = mysql_db_query_ret(mysql_conn, query, 0);
-			xfree(query);
-			if (!result)
-				continue;
-			set = 0;
-			while ((row = mysql_fetch_row(result))) {
-				if (set)
-					xstrfmtcat(*extra,
-						   " || job_db_inx=%s", row[0]);
-				else {
-					if (added)
-						xstrcat(*extra, ") || (");
-					else {
-						added = 1;
-						xstrcat(*extra, "(");
-					}
-					set = 1;
-					xstrfmtcat(*extra,
-						   "(job_db_inx=%s", row[0]);
-				}
-			}
-			mysql_free_result(result);
-		}
-		if (use_cluster_list == as_mysql_cluster_list)
-			slurm_mutex_unlock(&as_mysql_cluster_list_lock);
-
-		/* If we didn't find anything we need to put something
-		   here to avoid a blank () in the calling sql.
-		*/
-		if (added)
-			xstrcat(*extra, "))");
-		else if (start) {
-			if (!end)
-				xstrfmtcat(*extra,
-					   "(t1.time_start && "
-					   "((!t1.time_end && t1.state=%d) || "
-					   "(%d between t1.time_start "
-					   "and t1.time_end)))",
-					   JOB_SUSPENDED, start);
-			else
-				xstrfmtcat(*extra,
-					   "(t1.time_start && "
-					   "((%d between t1.time_start "
-					   "and t1.time_end) "
-					   "|| (t1.time_start between "
-					   "%d and %d)))",
-					   start, start,
-					   end);
-		} else if (end)
-			xstrfmtcat(*extra, "(t1.time_start && "
-				   "t1.time_start < %d)", end);
-		break;
+		/* Handle this the same way we handle RUNNING. */
 	case JOB_RUNNING:
 		if (start) {
 			if (!end) {
@@ -348,7 +251,7 @@ static void _state_time_string(mysql_conn_t *mysql_conn,
 					   "((!t1.time_end && t1.state=%d) || "
 					   "(%d between t1.time_start "
 					   "and t1.time_end)))",
-					   JOB_RUNNING, start);
+					   base_state, start);
 			} else {
 				xstrfmtcat(*extra,
 					   "(t1.time_start && "
@@ -1074,16 +977,16 @@ extern int good_nodes_from_inx(List local_cluster_list,
 	return 1;
 }
 
-extern char *setup_job_cluster_cond_limits(mysql_conn_t *mysql_conn,
-					   slurmdb_job_cond_t *job_cond,
-					   char *cluster_name, char **extra)
+extern int setup_job_cluster_cond_limits(mysql_conn_t *mysql_conn,
+					 slurmdb_job_cond_t *job_cond,
+					 char *cluster_name, char **extra)
 {
 	int set = 0;
 	ListIterator itr = NULL;
 	char *object = NULL;
 
 	if (!job_cond)
-		return NULL;
+		return SLURM_SUCCESS;
 
 	/* this must be done before resvid_list since we set
 	   resvid_list up here */
@@ -1137,6 +1040,78 @@ no_resv:
 		xstrcat(*extra, ")");
 	}
 
+	if (job_cond->state_list && list_count(job_cond->state_list)) {
+		itr = list_iterator_create(job_cond->state_list);
+		while ((object = list_next(itr))) {
+			uint32_t state = (uint32_t)slurm_atoul(object);
+			state &= JOB_STATE_BASE;
+			if (state == JOB_SUSPENDED)
+				break;
+		}
+		list_iterator_destroy(itr);
+
+		if (object) {
+			MYSQL_RES *result = NULL;
+			MYSQL_ROW row;
+			char *query = xstrdup_printf(
+				"select job_db_inx from \"%s_%s\"",
+				cluster_name, suspend_table);
+			if (job_cond->usage_start) {
+				if (!job_cond->usage_end) {
+					xstrfmtcat(query,
+						   " where (!time_end "
+						   "|| (%d between "
+						   "time_start and time_end))",
+						   (int)job_cond->usage_start);
+				} else {
+					xstrfmtcat(query,
+						   " where (!time_end "
+						   "|| (time_start && "
+						   "((%d between time_start "
+						   "and time_end) "
+						   "|| (time_start between "
+						   "%d and %d))))",
+						   (int)job_cond->usage_start,
+						   (int)job_cond->usage_start,
+						   (int)job_cond->usage_end);
+				}
+			} else if (job_cond->usage_end) {
+				xstrfmtcat(query, " where (time_start && "
+					   "time_start < %d)",
+					   (int)job_cond->usage_end);
+			}
+
+			debug3("%d(%s:%d) query\n%s",
+			       mysql_conn->conn, THIS_FILE, __LINE__, query);
+			result = mysql_db_query_ret(mysql_conn, query, 0);
+			xfree(query);
+			if (!result)
+				return SLURM_ERROR;
+			set = 0;
+			while ((row = mysql_fetch_row(result))) {
+				if (set)
+					xstrfmtcat(*extra,
+						   " || t1.job_db_inx=%s",
+						   row[0]);
+				else {
+					set = 1;
+					if (*extra)
+						xstrfmtcat(
+							*extra,
+							" || (t1.job_db_inx=%s",
+							row[0]);
+					else
+						xstrfmtcat(*extra, " where "
+							   "(t1.job_db_inx=%s",
+							   row[0]);
+				}
+			}
+			mysql_free_result(result);
+			if (set)
+				xstrcat(*extra, ")");
+		}
+	}
+
 	return SLURM_SUCCESS;
 }
 
@@ -1355,8 +1330,8 @@ extern int setup_job_cond_limits(mysql_conn_t *mysql_conn,
 		while ((object = list_next(itr))) {
 			if (set)
 				xstrcat(*extra, " || ");
-			_state_time_string(mysql_conn, job_cond,
-					   extra, (uint32_t)slurm_atoul(object),
+
+			_state_time_string(extra, (uint32_t)slurm_atoul(object),
 					   job_cond->usage_start,
 					   job_cond->usage_end);
 			set = 1;
diff --git a/src/plugins/accounting_storage/mysql/as_mysql_jobacct_process.h b/src/plugins/accounting_storage/mysql/as_mysql_jobacct_process.h
index 47cdd3bf949..719d02306de 100644
--- a/src/plugins/accounting_storage/mysql/as_mysql_jobacct_process.h
+++ b/src/plugins/accounting_storage/mysql/as_mysql_jobacct_process.h
@@ -52,9 +52,9 @@ extern List setup_cluster_list_with_inx(mysql_conn_t *mysql_conn,
 extern int good_nodes_from_inx(List local_cluster_list,
 			       void **object, char *node_inx,
 			       int submit);
-extern char *setup_job_cluster_cond_limits(mysql_conn_t *mysql_conn,
-					   slurmdb_job_cond_t *job_cond,
-					   char *cluster_name, char **extra);
+extern int setup_job_cluster_cond_limits(mysql_conn_t *mysql_conn,
+					 slurmdb_job_cond_t *job_cond,
+					 char *cluster_name, char **extra);
 extern int setup_job_cond_limits(mysql_conn_t *mysql_conn,
 				 slurmdb_job_cond_t *job_cond,
 				 char **extra);
-- 
GitLab