From 005af7d8d2a9514d75cea485feab024fede9fddb Mon Sep 17 00:00:00 2001
From: Danny Auble <da@llnl.gov>
Date: Mon, 17 Mar 2008 16:42:06 +0000
Subject: [PATCH] svn merge -r13604:13619
 https://eris.llnl.gov/svn/slurm/branches/acct_da

---
 src/common/assoc_mgr.c                        |  12 +-
 src/common/slurm_accounting_storage.c         |  11 +-
 src/common/slurm_accounting_storage.h         |   4 +-
 src/common/slurmdbd_defs.c                    |   2 +
 src/common/slurmdbd_defs.h                    |   1 +
 .../mysql/accounting_storage_mysql.c          | 906 +++++++++++++++++-
 .../mysql/mysql_jobacct_process.c             |  20 +-
 .../mysql/mysql_jobacct_process.h             |   3 +
 .../pgsql/accounting_storage_pgsql.c          | 129 ++-
 .../pgsql/pgsql_jobacct_process.h             |   2 +
 .../slurmdbd/accounting_storage_slurmdbd.c    |  15 +-
 src/sacctmgr/cluster_functions.c              |  45 +-
 src/slurmdbd/proc_req.c                       |   1 +
 13 files changed, 1051 insertions(+), 100 deletions(-)

diff --git a/src/common/assoc_mgr.c b/src/common/assoc_mgr.c
index cf3a20c3639..82cd0368801 100644
--- a/src/common/assoc_mgr.c
+++ b/src/common/assoc_mgr.c
@@ -120,17 +120,7 @@ static int _get_local_user_list(void *db_conn, int enforce)
 		} else {
 			return SLURM_SUCCESS;
 		}		
-	} else {
-		acct_user_rec_t *user = NULL;
-		struct passwd *passwd_ptr = NULL;
-		ListIterator itr = list_iterator_create(local_user_list);
-		while((user = list_next(itr))) {
-			passwd_ptr = getpwnam(user->name);
-			if(passwd_ptr) 
-				user->uid = passwd_ptr->pw_uid;
-		}
-		list_iterator_destroy(itr);
-	}
+	} 
 
 	slurm_mutex_unlock(&local_user_lock);
 	return SLURM_SUCCESS;
diff --git a/src/common/slurm_accounting_storage.c b/src/common/slurm_accounting_storage.c
index 77e6a8780d6..18eb5fe7c47 100644
--- a/src/common/slurm_accounting_storage.c
+++ b/src/common/slurm_accounting_storage.c
@@ -354,9 +354,8 @@ extern void destroy_acct_cluster_rec(void *object)
 	if(acct_cluster) {
 		if(acct_cluster->accounting_list)
 			list_destroy(acct_cluster->accounting_list);
-		xfree(acct_cluster->backup);
+		xfree(acct_cluster->control_host);
 		xfree(acct_cluster->name);
-		xfree(acct_cluster->primary);
 		xfree(acct_cluster);
 	}
 }
@@ -679,9 +678,9 @@ extern void pack_acct_cluster_rec(void *in, Buf buffer)
 		}
 		list_iterator_destroy(itr);
 	}
-	packstr(object->backup, buffer);
+	packstr(object->control_host, buffer);
+	pack32(object->control_port, buffer);
 	packstr(object->name, buffer);
-	packstr(object->primary, buffer);
 }
 
 extern int unpack_acct_cluster_rec(void **object, Buf buffer)
@@ -701,9 +700,9 @@ extern int unpack_acct_cluster_rec(void **object, Buf buffer)
 		unpack_cluster_accounting_rec((void *)&acct_info, buffer);
 		list_append(object_ptr->accounting_list, acct_info);
 	}
-	safe_unpackstr_xmalloc(&object_ptr->backup, &uint32_tmp, buffer);
+	safe_unpackstr_xmalloc(&object_ptr->control_host, &uint32_tmp, buffer);
+	safe_unpack32(&object_ptr->control_port, buffer);
 	safe_unpackstr_xmalloc(&object_ptr->name, &uint32_tmp, buffer);
-	safe_unpackstr_xmalloc(&object_ptr->primary, &uint32_tmp, buffer);
 
 	return SLURM_SUCCESS;
 
diff --git a/src/common/slurm_accounting_storage.h b/src/common/slurm_accounting_storage.h
index 8c097834706..258f3668898 100644
--- a/src/common/slurm_accounting_storage.h
+++ b/src/common/slurm_accounting_storage.h
@@ -99,9 +99,9 @@ typedef struct {
 
 typedef struct {
 	List accounting_list; /* list of cluster_accounting_rec_t *'s */
-	char *backup;
+	char *control_host;
+	uint32_t control_port;
 	char *name;
-	char *primary;
 } acct_cluster_rec_t;
 
 typedef struct {
diff --git a/src/common/slurmdbd_defs.c b/src/common/slurmdbd_defs.c
index 5ba03f392f7..fb4e7c710a3 100644
--- a/src/common/slurmdbd_defs.c
+++ b/src/common/slurmdbd_defs.c
@@ -1921,6 +1921,7 @@ void inline
 slurmdbd_pack_node_state_msg(dbd_node_state_msg_t *msg, Buf buffer)
 {
 	packstr(msg->cluster_name, buffer);
+	pack32(msg->cpu_count, buffer);
 	packstr(msg->hostlist, buffer);
 	packstr(msg->reason, buffer);
 	pack16(msg->new_state, buffer);
@@ -1936,6 +1937,7 @@ slurmdbd_unpack_node_state_msg(dbd_node_state_msg_t **msg, Buf buffer)
 	msg_ptr = xmalloc(sizeof(dbd_node_state_msg_t));
 	*msg = msg_ptr;
 	safe_unpackstr_xmalloc(&msg_ptr->cluster_name, &uint32_tmp, buffer);
+	safe_unpack32(&msg_ptr->cpu_count, buffer);
 	safe_unpackstr_xmalloc(&msg_ptr->hostlist, &uint32_tmp, buffer);
 	safe_unpackstr_xmalloc(&msg_ptr->reason,   &uint32_tmp, buffer);
 	safe_unpack16(&msg_ptr->new_state, buffer);
diff --git a/src/common/slurmdbd_defs.h b/src/common/slurmdbd_defs.h
index 16964c59fcc..c08512a4033 100644
--- a/src/common/slurmdbd_defs.h
+++ b/src/common/slurmdbd_defs.h
@@ -220,6 +220,7 @@ typedef struct {
 #define DBD_NODE_STATE_UP    2
 typedef struct dbd_node_state_msg {
 	char *cluster_name;	/* name of cluster */
+	uint32_t cpu_count;     /* number of cpus on node */
 	time_t event_time;	/* time of transition */
 	char *hostlist;		/* name of hosts */
 	uint16_t new_state;	/* new state of host, see DBD_NODE_STATE_* */
diff --git a/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c b/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c
index 0fbfe7c6b27..4d994c9c9cd 100644
--- a/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c
+++ b/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c
@@ -92,7 +92,7 @@ char *cluster_day_table = "cluster_day_usage_table";
 char *cluster_hour_table = "cluster_hour_usage_table";
 char *cluster_month_table = "cluster_month_usage_table";
 char *cluster_table = "cluster_table";
-char *event_table = "event_table";
+char *event_table = "cluster_event_table";
 char *job_table = "job_table";
 char *step_table = "step_table";
 char *txn_table = "txn_table";
@@ -145,7 +145,7 @@ static int _mysql_acct_check_tables(MYSQL *acct_mysql_db)
 	storage_field_t acct_coord_table_fields[] = {
 		{ "deleted", "tinyint default 0" },
 		{ "acct", "tinytext not null" },
-		{ "name", "tinytext not null" },
+		{ "user", "tinytext not null" },
 		{ NULL, NULL}		
 	};
 
@@ -196,8 +196,8 @@ static int _mysql_acct_check_tables(MYSQL *acct_mysql_db)
 		{ "mod_time", "int unsigned default 0 not null" },
 		{ "deleted", "tinyint default 0" },
 		{ "name", "tinytext not null" },
-		{ "primary_node", "tinytext not null" },
-		{ "backup_node", "tinytext not null" },
+		{ "control_host", "tinytext not null" },
+		{ "control_port", "mediumint not null" },
 		{ NULL, NULL}		
 	};
 
@@ -218,6 +218,7 @@ static int _mysql_acct_check_tables(MYSQL *acct_mysql_db)
 	storage_field_t event_table_fields[] = {
 		{ "node_name", "tinytext default '' not null" },
 		{ "cluster", "tinytext not null" },
+		{ "cpu_count", "int not null" },
 		{ "period_start", "int unsigned not null" },
 		{ "period_end", "int unsigned default 0 not null" },
 		{ "reason", "tinytext not null" },
@@ -308,7 +309,7 @@ static int _mysql_acct_check_tables(MYSQL *acct_mysql_db)
 
 	if(mysql_db_create_table(acct_mysql_db, acct_coord_table,
 				 acct_coord_table_fields,
-				 ", primary key (acct(20), name(20)))")
+				 ", primary key (acct(20), user(20)))")
 	   == SLURM_ERROR)
 		return SLURM_ERROR;
 
@@ -444,7 +445,7 @@ extern int init ( void )
 	mysql_get_db_connection(&acct_mysql_db, mysql_db_name, mysql_db_info);
 		
 	rc = _mysql_acct_check_tables(acct_mysql_db);
-	
+
 	mysql_close(acct_mysql_db);
 	acct_mysql_db = NULL;
 #endif		
@@ -502,117 +503,863 @@ extern int acct_storage_p_close_connection(MYSQL *acct_mysql_db)
 
 extern int acct_storage_p_add_users(MYSQL *acct_mysql_db, List user_list)
 {
-	return SLURM_SUCCESS;
+#ifdef HAVE_MYSQL
+	ListIterator itr = NULL;
+	int rc = SLURM_SUCCESS;
+	acct_user_rec_t *object = NULL;
+	char *cols = NULL, *vals = NULL, *query = NULL;
+
+	itr = list_iterator_create(user_list);
+	while((object = list_next(itr))) {
+		if(!object->name || !object->default_acct) {
+			error("We need a user name and "
+			      "default acct to add.");
+			rc = SLURM_ERROR;
+			continue;
+		}
+		xstrcat(cols, "name, default_acct");
+		xstrfmtcat(vals, "'%s', '%s'", 
+			   object->name, object->default_acct); 
+		if(object->expedite != ACCT_EXPEDITE_NOTSET) {
+			xstrcat(cols, ", expedite");
+			xstrfmtcat(vals, ", %u", object->expedite); 		
+		}
+
+		if(object->admin_level != ACCT_ADMIN_NOTSET) {
+			xstrcat(cols, ", admin_level");
+			xstrfmtcat(vals, ", %u", object->admin_level);
+		}
+
+		query = xstrdup_printf("insert into %s (%s) values (%s)",
+				       user_table, cols, vals);
+		xfree(cols);
+		xfree(vals);
+		rc = mysql_db_query(acct_mysql_db, query);
+		xfree(query);
+		if(rc != SLURM_SUCCESS) {
+			error("Couldn't add user %s", object->name);
+		}
+	}
+	list_iterator_destroy(itr);
+
+	return rc;
+#else
+	return SLURM_ERROR;
+#endif
 }
 
 extern int acct_storage_p_add_coord(MYSQL *acct_mysql_db, 
 				    char *acct, acct_user_cond_t *user_q)
 {
+#ifdef HAVE_MYSQL
 	return SLURM_SUCCESS;
+#else
+	return SLURM_ERROR;
+#endif
 }
 
 extern int acct_storage_p_add_accts(MYSQL *acct_mysql_db, List acct_list)
 {
+#ifdef HAVE_MYSQL
 	return SLURM_SUCCESS;
+#else
+	return SLURM_ERROR;
+#endif
 }
 
 extern int acct_storage_p_add_clusters(MYSQL *acct_mysql_db, List cluster_list)
 {
+#ifdef HAVE_MYSQL
 	return SLURM_SUCCESS;
+#else
+	return SLURM_ERROR;
+#endif
 }
 
 extern int acct_storage_p_add_associations(MYSQL *acct_mysql_db, 
 					   List association_list)
 {
-	return SLURM_SUCCESS;
+#ifdef HAVE_MYSQL
+	ListIterator itr = NULL;
+	int rc = SLURM_SUCCESS;
+	acct_association_rec_t *object = NULL;
+	char *cols = NULL, *vals = NULL, *query = NULL;
+	char *parent = NULL;
+
+	itr = list_iterator_create(association_list);
+	while((object = list_next(itr))) {
+		if(!object->cluster || !object->acct) {
+			error("We need a association cluster and "
+			      "acct to add one.");
+			rc = SLURM_ERROR;
+			continue;
+		}
+		xstrcat(cols, "cluster, acct");
+		xstrfmtcat(vals, "'%s', '%s'", 
+			   object->cluster, object->acct); 
+		if(object->user) {
+			xstrcat(cols, ", user");
+			xstrfmtcat(vals, ", '%s'", object->user); 		
+		}
+
+		if(object->parent_acct) {
+			parent = xstrdup(object->parent_acct);
+		} else {
+			parent = xstrdup("root");
+		}
+
+		if(object->partition) {
+			xstrcat(cols, ", partition");
+			xstrfmtcat(vals, ", '%s'", object->partition);
+		}
+
+		if(object->fairshare) {
+			xstrcat(cols, ", fairshare");
+			xstrfmtcat(vals, ", %u", object->fairshare);
+		}
+
+		if(object->max_jobs) {
+			xstrcat(cols, ", max_jobs");
+			xstrfmtcat(vals, ", %u", object->max_jobs);
+		}
+
+		if(object->max_nodes_per_job) {
+			xstrcat(cols, ", max_nodes_per_job");
+			xstrfmtcat(vals, ", %u", object->max_nodes_per_job);
+		}
+
+		if(object->max_wall_duration_per_job) {
+			xstrcat(cols, ", max_wall_duration_per_job");
+			xstrfmtcat(vals, ", %u",
+				   object->max_wall_duration_per_job);
+		}
+
+		if(object->max_cpu_secs_per_job) {
+			xstrcat(cols, ", max_cpu_seconds_per_job");
+			xstrfmtcat(vals, ", %u", object->max_cpu_secs_per_job);
+		}
+		query = xstrdup_printf("SELECT @myRight := rgt FROM %s"
+				       "WHERE acct = '%s' and cluster = '%s' "
+				       "and user = '';"
+				       "UPDATE %s SET rgt = rgt + 2 "
+				       "WHERE rgt > @myRight;"
+				       "UPDATE %s SET lft = lft + 2 "
+				       "WHERE lft > @myRight;"
+				       "insert into %s (%s, lft, rgt) "
+				       "values (%s, @myRight + 1, "
+				       "@myRight + 2);",
+				       assoc_table, parent, object->cluster,
+				       assoc_table, assoc_table,
+				       assoc_table, cols, vals);
+		xfree(cols);
+		xfree(vals);
+		xfree(parent);
+		rc = mysql_db_query(acct_mysql_db, query);
+		xfree(query);
+		if(rc != SLURM_SUCCESS) {
+			error("Couldn't add assoc");
+		}
+	}
+	list_iterator_destroy(itr);
+
+	return rc;
+#else
+	return SLURM_ERROR;
+#endif
 }
 
 extern int acct_storage_p_modify_users(MYSQL *acct_mysql_db, 
 				       acct_user_cond_t *user_q,
 				       acct_user_rec_t *user)
 {
+#ifdef HAVE_MYSQL
 	return SLURM_SUCCESS;
+#else
+	return SLURM_ERROR;
+#endif
 }
 
 extern int acct_storage_p_modify_user_admin_level(MYSQL *acct_mysql_db, 
 						  acct_user_cond_t *user_q)
 {
+#ifdef HAVE_MYSQL
 	return SLURM_SUCCESS;
+#else
+	return SLURM_ERROR;
+#endif
 }
 
 extern int acct_storage_p_modify_accts(MYSQL *acct_mysql_db, 
 				       acct_account_cond_t *acct_q,
 				       acct_account_rec_t *acct)
 {
+#ifdef HAVE_MYSQL
 	return SLURM_SUCCESS;
+#else
+	return SLURM_ERROR;
+#endif
 }
 
 extern int acct_storage_p_modify_clusters(MYSQL *acct_mysql_db, 
 					  acct_cluster_cond_t *cluster_q,
 					  acct_cluster_rec_t *cluster)
 {
+#ifdef HAVE_MYSQL
 	return SLURM_SUCCESS;
+#else
+	return SLURM_ERROR;
+#endif
 }
 
 extern int acct_storage_p_modify_associations(MYSQL *acct_mysql_db, 
 					      acct_association_cond_t *assoc_q,
 					      acct_association_rec_t *assoc)
 {
+#ifdef HAVE_MYSQL
 	return SLURM_SUCCESS;
+#else
+	return SLURM_ERROR;
+#endif
 }
 
 extern int acct_storage_p_remove_users(MYSQL *acct_mysql_db, 
 				       acct_user_cond_t *user_q)
 {
+#ifdef HAVE_MYSQL
 	return SLURM_SUCCESS;
+#else
+	return SLURM_ERROR;
+#endif
 }
 
 extern int acct_storage_p_remove_coord(MYSQL *acct_mysql_db, 
 				       char *acct, acct_user_cond_t *user_q)
 {
+#ifdef HAVE_MYSQL
 	return SLURM_SUCCESS;
+#else
+	return SLURM_ERROR;
+#endif
 }
 
 extern int acct_storage_p_remove_accts(MYSQL *acct_mysql_db, 
 				       acct_account_cond_t *acct_q)
 {
+#ifdef HAVE_MYSQL
 	return SLURM_SUCCESS;
+#else
+	return SLURM_ERROR;
+#endif
 }
 
 extern int acct_storage_p_remove_clusters(MYSQL *acct_mysql_db, 
 					  acct_account_cond_t *cluster_q)
 {
+#ifdef HAVE_MYSQL
 	return SLURM_SUCCESS;
+#else
+	return SLURM_ERROR;
+#endif
 }
 
 extern int acct_storage_p_remove_associations(MYSQL *acct_mysql_db, 
 					      acct_association_cond_t *assoc_q)
 {
+#ifdef HAVE_MYSQL
 	return SLURM_SUCCESS;
+#else
+	return SLURM_ERROR;
+#endif
 }
 
 extern List acct_storage_p_get_users(MYSQL *acct_mysql_db, 
 				     acct_user_cond_t *user_q)
 {
+#ifdef HAVE_MYSQL
+	char *query = NULL;	
+	char *extra = NULL;	
+	char *tmp = NULL;	
+	List user_list = NULL;
+	ListIterator itr = NULL;
+	char *object = NULL;
+	int set = 0;
+	int i=0;
+	MYSQL_RES *result = NULL, *coord_result = NULL;
+	MYSQL_ROW row, coord_row;
+
+	/* if this changes you will need to edit the corresponding enum */
+	char *user_req_inx[] = {
+		"name",
+		"default_acct",
+		"expedite",
+		"admin_level"
+	};
+	enum {
+		USER_REQ_NAME,
+		USER_REQ_DA,
+		USER_REQ_EX,
+		USER_REQ_AL,
+		USER_REQ_COUNT
+	};
+
+	if(!user_q) 
+		goto empty;
+
+	if(user_q->user_list && list_count(user_q->user_list)) {
+		set = 0;
+		if(extra)
+			xstrcat(extra, " && (");
+		else
+			xstrcat(extra, " where (");
+		itr = list_iterator_create(user_q->user_list);
+		while((object = list_next(itr))) {
+			if(set) 
+				xstrcat(extra, " || ");
+			xstrfmtcat(extra, "name='%s'", object);
+			set = 1;
+		}
+		list_iterator_destroy(itr);
+		xstrcat(extra, ")");
+	}
+
+	if(user_q->def_acct_list && list_count(user_q->def_acct_list)) {
+		set = 0;
+		if(extra)
+			xstrcat(extra, " && (");
+		else
+			xstrcat(extra, " where (");
+		itr = list_iterator_create(user_q->def_acct_list);
+		while((object = list_next(itr))) {
+			if(set) 
+				xstrcat(extra, " || ");
+			xstrfmtcat(extra, "default_acct='%s'", object);
+			set = 1;
+		}
+		list_iterator_destroy(itr);
+		xstrcat(extra, ")");
+	}
+	
+	if(user_q->expedite != ACCT_EXPEDITE_NOTSET) {
+		if(extra)
+			xstrfmtcat(extra, " && expedite=%u", user_q->expedite);
+		else
+			xstrfmtcat(extra, " where expedite=%u",
+				   user_q->expedite);
+			
+	}
+
+	if(user_q->expedite != ACCT_ADMIN_NOTSET) {
+		if(extra)
+			xstrfmtcat(extra, " && admin_level=%u",
+				   user_q->admin_level);
+		else
+			xstrfmtcat(extra, " where admin_level=%u",
+				   user_q->admin_level);
+	}
+empty:
+
+	xfree(tmp);
+	xstrfmtcat(tmp, "%s", user_req_inx[i]);
+	for(i=1; i<USER_REQ_COUNT; i++) {
+		xstrfmtcat(tmp, ", %s", user_req_inx[i]);
+	}
+
+	query = xstrdup_printf("select %s from %s", tmp, user_table);
+	xfree(tmp);
+
+	if(extra) {
+		xstrcat(query, extra);
+		xfree(extra);
+	}
+
+	//info("query = %s", query);
+	if(!(result = mysql_db_query_ret(acct_mysql_db, query))) {
+		xfree(query);
+		return NULL;
+	}
+	xfree(query);
+
+	user_list = list_create(destroy_acct_user_rec);
+
+	while((row = mysql_fetch_row(result))) {
+		acct_user_rec_t *user = xmalloc(sizeof(acct_user_rec_t));
+		struct passwd *passwd_ptr = NULL;
+		list_append(user_list, user);
+
+		user->name =  xstrdup(row[USER_REQ_NAME]);
+		user->default_acct = xstrdup(row[USER_REQ_DA]);
+		user->admin_level = atoi(row[USER_REQ_AL]);
+		user->expedite = atoi(row[USER_REQ_EX]);
+
+		passwd_ptr = getpwnam(user->name);
+		if(passwd_ptr) 
+			user->uid = passwd_ptr->pw_uid;
+		
+		user->coord_accts = list_create(destroy_acct_coord_rec);
+		query = xstrdup_printf("select acct from %s where user='%s'",
+				       acct_coord_table, user->name);
+
+		if(!(coord_result = mysql_db_query_ret(acct_mysql_db, query))) {
+			xfree(query);
+			continue;
+		}
+		xfree(query);
+		
+		while((coord_row = mysql_fetch_row(coord_result))) {
+			acct_coord_rec_t *coord =
+				xmalloc(sizeof(acct_coord_rec_t));
+			list_append(user->coord_accts, coord);
+			coord->acct_name = xstrdup(coord_row[0]);
+			coord->sub_acct = 0;
+		}
+		mysql_free_result(coord_result);
+		/* FIX ME: ADD SUB projects here from assoc list lft
+		 * rgt */
+
+	}
+	mysql_free_result(result);
+
+	return user_list;
+#else
 	return NULL;
+#endif
 }
 
 extern List acct_storage_p_get_accts(MYSQL *acct_mysql_db, 
 				     acct_account_cond_t *acct_q)
 {
+#ifdef HAVE_MYSQL
+	char *query = NULL;	
+	char *extra = NULL;	
+	char *tmp = NULL;	
+	List acct_list = NULL;
+	ListIterator itr = NULL;
+	char *object = NULL;
+	int set = 0;
+	int i=0;
+	MYSQL_RES *result = NULL, *coord_result = NULL;
+	MYSQL_ROW row, coord_row;
+
+	/* if this changes you will need to edit the corresponding enum */
+	char *acct_req_inx[] = {
+		"name",
+		"description",
+		"expedite",
+		"organization"
+	};
+	enum {
+		ACCT_REQ_NAME,
+		ACCT_REQ_DESC,
+		ACCT_REQ_EX,
+		ACCT_REQ_ORG,
+		ACCT_REQ_COUNT
+	};
+
+	if(!acct_q) 
+		goto empty;
+
+	if(acct_q->acct_list && list_count(acct_q->acct_list)) {
+		set = 0;
+		if(extra)
+			xstrcat(extra, " && (");
+		else
+			xstrcat(extra, " where (");
+		itr = list_iterator_create(acct_q->acct_list);
+		while((object = list_next(itr))) {
+			if(set) 
+				xstrcat(extra, " || ");
+			xstrfmtcat(extra, "name='%s'", object);
+			set = 1;
+		}
+		list_iterator_destroy(itr);
+		xstrcat(extra, ")");
+	}
+
+	if(acct_q->description_list && list_count(acct_q->description_list)) {
+		set = 0;
+		if(extra)
+			xstrcat(extra, " && (");
+		else
+			xstrcat(extra, " where (");
+		itr = list_iterator_create(acct_q->description_list);
+		while((object = list_next(itr))) {
+			if(set) 
+				xstrcat(extra, " || ");
+			xstrfmtcat(extra, "description='%s'", object);
+			set = 1;
+		}
+		list_iterator_destroy(itr);
+		xstrcat(extra, ")");
+	}
+	
+	if(acct_q->organization_list && list_count(acct_q->organization_list)) {
+		set = 0;
+		if(extra)
+			xstrcat(extra, " && (");
+		else
+			xstrcat(extra, " where (");
+		itr = list_iterator_create(acct_q->organization_list);
+		while((object = list_next(itr))) {
+			if(set) 
+				xstrcat(extra, " || ");
+			xstrfmtcat(extra, "organization='%s'", object);
+			set = 1;
+		}
+		list_iterator_destroy(itr);
+		xstrcat(extra, ")");
+	}
+	
+	if(acct_q->expedite != ACCT_EXPEDITE_NOTSET) {
+		if(extra)
+			xstrfmtcat(extra, " && expedite=%u", acct_q->expedite);
+		else
+			xstrfmtcat(extra, " where expedite=%u",
+				   acct_q->expedite);
+			
+	}
+
+empty:
+
+	xfree(tmp);
+	xstrfmtcat(tmp, "%s", acct_req_inx[i]);
+	for(i=1; i<ACCT_REQ_COUNT; i++) {
+		xstrfmtcat(tmp, ", %s", acct_req_inx[i]);
+	}
+
+	query = xstrdup_printf("select %s from %s", tmp, acct_table);
+	xfree(tmp);
+
+	if(extra) {
+		xstrcat(query, extra);
+		xfree(extra);
+	}
+
+	//info("query = %s", query);
+	if(!(result = mysql_db_query_ret(acct_mysql_db, query))) {
+		xfree(query);
+		return NULL;
+	}
+	xfree(query);
+
+	acct_list = list_create(destroy_acct_account_rec);
+
+	while((row = mysql_fetch_row(result))) {
+		acct_account_rec_t *acct = xmalloc(sizeof(acct_account_rec_t));
+		list_append(acct_list, acct);
+
+		acct->name =  xstrdup(row[ACCT_REQ_NAME]);
+		acct->description = xstrdup(row[ACCT_REQ_DESC]);
+		acct->organization = xstrdup(row[ACCT_REQ_ORG]);
+		acct->expedite = atoi(row[ACCT_REQ_EX]);
+
+		acct->coordinators = list_create(slurm_destroy_char);
+		query = xstrdup_printf("select user from %s where acct='%s'",
+				       acct_coord_table, acct->name);
+
+		if(!(coord_result = mysql_db_query_ret(acct_mysql_db, query))) {
+			xfree(query);
+			continue;
+		}
+		xfree(query);
+		
+		while((coord_row = mysql_fetch_row(coord_result))) {
+			object = xstrdup(coord_row[0]);
+			list_append(acct->coordinators, object);
+		}
+		mysql_free_result(coord_result);
+	}
+	mysql_free_result(result);
+
+	return acct_list;
+#else
 	return NULL;
+#endif
 }
 
 extern List acct_storage_p_get_clusters(MYSQL *acct_mysql_db, 
-					acct_account_cond_t *cluster_q)
+					acct_cluster_cond_t *cluster_q)
 {
+#ifdef HAVE_MYSQL
+	char *query = NULL;	
+	char *extra = NULL;	
+	char *tmp = NULL;	
+	List cluster_list = NULL;
+	ListIterator itr = NULL;
+	char *object = NULL;
+	int set = 0;
+	int i=0;
+	MYSQL_RES *result = NULL;
+	MYSQL_ROW row;
+
+	/* if this changes you will need to edit the corresponding enum */
+	char *cluster_req_inx[] = {
+		"name",
+		"control_host",
+		"control_port"
+	};
+	enum {
+		CLUSTER_REQ_NAME,
+		CLUSTER_REQ_CH,
+		CLUSTER_REQ_CP,
+		CLUSTER_REQ_COUNT
+	};
+
+	if(!cluster_q) 
+		goto empty;
+
+	if(cluster_q->cluster_list && list_count(cluster_q->cluster_list)) {
+		set = 0;
+		if(extra)
+			xstrcat(extra, " && (");
+		else
+			xstrcat(extra, " where (");
+		itr = list_iterator_create(cluster_q->cluster_list);
+		while((object = list_next(itr))) {
+			if(set) 
+				xstrcat(extra, " || ");
+			xstrfmtcat(extra, "name='%s'", object);
+			set = 1;
+		}
+		list_iterator_destroy(itr);
+		xstrcat(extra, ")");
+	}
+
+empty:
+
+	xfree(tmp);
+	xstrfmtcat(tmp, "%s", cluster_req_inx[i]);
+	for(i=1; i<CLUSTER_REQ_COUNT; i++) {
+		xstrfmtcat(tmp, ", %s", cluster_req_inx[i]);
+	}
+
+	query = xstrdup_printf("select %s from %s", tmp, cluster_table);
+	xfree(tmp);
+
+	if(extra) {
+		xstrcat(query, extra);
+		xfree(extra);
+	}
+
+	//info("query = %s", query);
+	if(!(result = mysql_db_query_ret(acct_mysql_db, query))) {
+		xfree(query);
+		return NULL;
+	}
+	xfree(query);
+
+	cluster_list = list_create(destroy_acct_cluster_rec);
+
+	while((row = mysql_fetch_row(result))) {
+		acct_cluster_rec_t *cluster =
+			xmalloc(sizeof(acct_cluster_rec_t));
+		list_append(cluster_list, cluster);
+
+		cluster->name =  xstrdup(row[CLUSTER_REQ_NAME]);
+		cluster->control_host = xstrdup(row[CLUSTER_REQ_CH]);
+		cluster->control_port = atoi(row[CLUSTER_REQ_CP]);
+	}
+	mysql_free_result(result);
+
+	return cluster_list;
+#else
 	return NULL;
+#endif
 }
 
 extern List acct_storage_p_get_associations(MYSQL *acct_mysql_db, 
 					    acct_association_cond_t *assoc_q)
 {
+#ifdef HAVE_MYSQL
+	char *query = NULL;	
+	char *extra = NULL;	
+	char *tmp = NULL;	
+	List assoc_list = NULL;
+	ListIterator itr = NULL;
+	char *object = NULL;
+	int set = 0;
+	int i=0;
+	MYSQL_RES *result = NULL;
+	MYSQL_ROW row;
+
+	/* if this changes you will need to edit the corresponding enum */
+	char *assoc_req_inx[] = {
+		"id",
+		"user",
+		"acct",
+		"cluster",
+		"partition",
+		"parent",
+		"fairshare",
+		"max_jobs",
+		"max_nodes_per_job",
+		"max_wall_duration_per_job",
+		"max_cpu_seconds_per_job",
+	};
+	enum {
+		ASSOC_REQ_ID,
+		ASSOC_REQ_USER,
+		ASSOC_REQ_ACCT,
+		ASSOC_REQ_CLUSTER,
+		ASSOC_REQ_PART,
+		ASSOC_REQ_PARENT,
+		ASSOC_REQ_FS,
+		ASSOC_REQ_MJ,
+		ASSOC_REQ_MNPJ,
+		ASSOC_REQ_MWPJ,
+		ASSOC_REQ_MCPJ,
+		ASSOC_REQ_COUNT
+	};
+
+	if(!assoc_q) 
+		goto empty;
+
+	if(assoc_q->acct_list && list_count(assoc_q->acct_list)) {
+		set = 0;
+		if(extra)
+			xstrcat(extra, " && (");
+		else
+			xstrcat(extra, " where (");
+		itr = list_iterator_create(assoc_q->acct_list);
+		while((object = list_next(itr))) {
+			if(set) 
+				xstrcat(extra, " || ");
+			xstrfmtcat(extra, "acct='%s'", object);
+			set = 1;
+		}
+		list_iterator_destroy(itr);
+		xstrcat(extra, ")");
+	}
+
+	if(assoc_q->cluster_list && list_count(assoc_q->cluster_list)) {
+		set = 0;
+		if(extra)
+			xstrcat(extra, " && (");
+		else
+			xstrcat(extra, " where (");
+		itr = list_iterator_create(assoc_q->cluster_list);
+		while((object = list_next(itr))) {
+			if(set) 
+				xstrcat(extra, " || ");
+			xstrfmtcat(extra, "cluster='%s'", object);
+			set = 1;
+		}
+		list_iterator_destroy(itr);
+		xstrcat(extra, ")");
+	}
+
+	if(assoc_q->user_list && list_count(assoc_q->user_list)) {
+		set = 0;
+		if(extra)
+			xstrcat(extra, " && (");
+		else
+			xstrcat(extra, " where (");
+		itr = list_iterator_create(assoc_q->user_list);
+		while((object = list_next(itr))) {
+			if(set) 
+				xstrcat(extra, " || ");
+			xstrfmtcat(extra, "user='%s'", object);
+			set = 1;
+		}
+		list_iterator_destroy(itr);
+		xstrcat(extra, ")");
+	}
+
+	if(assoc_q->id_list && list_count(assoc_q->id_list)) {
+		set = 0;
+		if(extra)
+			xstrcat(extra, " && (");
+		else
+			xstrcat(extra, " where (");
+		itr = list_iterator_create(assoc_q->id_list);
+		while((object = list_next(itr))) {
+			if(set) 
+				xstrcat(extra, " || ");
+			xstrfmtcat(extra, "id=%s", object);
+			set = 1;
+		}
+		list_iterator_destroy(itr);
+		xstrcat(extra, ")");
+	}
+	
+	if(assoc_q->lft) {
+		if(extra)
+			xstrfmtcat(extra, " && lft=%u", assoc_q->lft);
+		else
+			xstrfmtcat(extra, " where lft=%u",
+				   assoc_q->lft);			
+	}
+
+	if(assoc_q->rgt) {
+		if(extra)
+			xstrfmtcat(extra, " && rgt=%u", assoc_q->rgt);
+		else
+			xstrfmtcat(extra, " where rgt=%u",
+				   assoc_q->rgt);			
+	}
+
+	if(assoc_q->parent) {
+		if(extra)
+			xstrfmtcat(extra, " && parent=%u", assoc_q->parent);
+		else
+			xstrfmtcat(extra, " where parent=%u",
+				   assoc_q->parent);			
+	}
+
+	if(assoc_q->parent_acct) {
+		if(extra)
+			xstrfmtcat(extra, " && parent_acct='%s'",
+				   assoc_q->parent_acct);
+		else
+			xstrfmtcat(extra, " where parent_acct='%s'",
+				   assoc_q->parent_acct);			
+	}
+empty:
+	xfree(tmp);
+	xstrfmtcat(tmp, "%s", assoc_req_inx[i]);
+	for(i=1; i<ASSOC_REQ_COUNT; i++) {
+		xstrfmtcat(tmp, ", %s", assoc_req_inx[i]);
+	}
+
+	query = xstrdup_printf("select %s from %s", tmp, assoc_table);
+	xfree(tmp);
+
+	if(extra) {
+		xstrcat(query, extra);
+		xfree(extra);
+	}
+
+	//info("query = %s", query);
+	if(!(result = mysql_db_query_ret(acct_mysql_db, query))) {
+		xfree(query);
+		return NULL;
+	}
+	xfree(query);
+
+	assoc_list = list_create(destroy_acct_association_rec);
+
+	while((row = mysql_fetch_row(result))) {
+		acct_association_rec_t *assoc =
+			xmalloc(sizeof(acct_association_rec_t));
+		list_append(assoc_list, assoc);
+
+		assoc->id =  atoi(row[ASSOC_REQ_ID]);
+		assoc->user = xstrdup(row[ASSOC_REQ_USER]);
+		assoc->acct = xstrdup(row[ASSOC_REQ_ACCT]);
+		assoc->cluster = xstrdup(row[ASSOC_REQ_CLUSTER]);
+		assoc->partition = xstrdup(row[ASSOC_REQ_PART]);
+		assoc->parent = atoi(row[ASSOC_REQ_PARENT]);
+		assoc->fairshare = atoi(row[ASSOC_REQ_FS]);
+		assoc->max_jobs = atoi(row[ASSOC_REQ_MJ]);
+		assoc->max_nodes_per_job = atoi(row[ASSOC_REQ_MNPJ]);
+		assoc->max_wall_duration_per_job = atoi(row[ASSOC_REQ_MWPJ]);
+		assoc->max_cpu_secs_per_job = atoi(row[ASSOC_REQ_MCPJ]);
+	}
+	mysql_free_result(result);
+
+	return assoc_list;
+#else
 	return NULL;
+#endif
 }
 
 extern int acct_storage_p_get_usage(MYSQL *acct_mysql_db,
@@ -620,18 +1367,26 @@ extern int acct_storage_p_get_usage(MYSQL *acct_mysql_db,
 				    acct_association_rec_t *acct_assoc,
 				    time_t start, time_t end)
 {
+#ifdef HAVE_MYSQL
 	int rc = SLURM_SUCCESS;
 
 	return rc;
+#else
+	return SLURM_ERROR;
+#endif
 }
 
 extern int acct_storage_p_roll_usage(MYSQL *acct_mysql_db, 
 				     acct_usage_type_t type,
 				     time_t start)
 {
+#ifdef HAVE_MYSQL
 	int rc = SLURM_SUCCESS;
 
 	return rc;
+#else
+	return SLURM_ERROR;
+#endif
 }
 
 extern int clusteracct_storage_p_node_down(MYSQL *acct_mysql_db, 
@@ -639,34 +1394,64 @@ extern int clusteracct_storage_p_node_down(MYSQL *acct_mysql_db,
 					   struct node_record *node_ptr,
 					   time_t event_time, char *reason)
 {
-/* 	uint16_t cpus; */
-/* 	int rc = SLURM_ERROR; */
-/* 	char *query = NULL; */
-/* 	char tmp_buff[50]; */
-/* 	char *my_reason; */
-
-/* 	if (slurmctld_conf.fast_schedule && !slurmdbd_conf) */
-/* 		cpus = node_ptr->config_ptr->cpus; */
-/* 	else */
-/* 		cpus = node_ptr->cpus; */
-
-/* 	if (reason) */
-/* 		my_reason = reason; */
-/* 	else */
-/* 		my_reason = node_ptr->reason; */
+#ifdef HAVE_MYSQL
+	uint16_t cpus;
+	int rc = SLURM_SUCCESS;
+	char *query = NULL;
+	char *my_reason;
+
+	if (slurmctld_conf.fast_schedule && !slurmdbd_conf)
+		cpus = node_ptr->config_ptr->cpus;
+	else
+		cpus = node_ptr->cpus;
+
+	if (reason)
+		my_reason = reason;
+	else
+		my_reason = node_ptr->reason;
 	
-/* 	query = xstrdup_printf(""); */
+	query = xstrdup_printf(
+		"update %s set period_end=%d where cluster='%s' "
+		"and period_end=0 and node_name='%s'",
+		event_table, (event_time-1), cluster, node_ptr->name);
+	rc = mysql_db_query(acct_mysql_db, query);
+	xfree(query);
 
+	debug2("inserting %s(%s) with %u cpus", node_ptr->name, cluster, cpus);
 
-	return SLURM_SUCCESS;
+	query = xstrdup_printf(
+		"insert into %s "
+		"(node_name, cluster, cpu_count, period_start, reason) "
+		"values ('%s', '%s', %u, %d, '%s')",
+		event_table, node_ptr->name, cluster, 
+		cpus, event_time, my_reason);
+	rc = mysql_db_query(acct_mysql_db, query);
+	xfree(query);
+
+	return rc;
+#else
+	return SLURM_ERROR;
+#endif
 }
 extern int clusteracct_storage_p_node_up(MYSQL *acct_mysql_db, 
 					 char *cluster,
 					 struct node_record *node_ptr,
 					 time_t event_time)
 {
-	
-	return SLURM_SUCCESS;
+#ifdef HAVE_MYSQL
+	char* query;
+	int rc = SLURM_SUCCESS;
+
+	query = xstrdup_printf(
+		"update %s set period_end=%d where cluster='%s' "
+		"and period_end=0 and node_name='%s'",
+		event_table, (event_time-1), cluster, node_ptr->name);
+	rc = mysql_db_query(acct_mysql_db, query);
+	xfree(query);
+	return rc;
+#else
+	return SLURM_ERROR;
+#endif
 }
 
 extern int clusteracct_storage_p_register_ctld(char *cluster,
@@ -680,15 +1465,78 @@ extern int clusteracct_storage_p_cluster_procs(MYSQL *acct_mysql_db,
 					       uint32_t procs,
 					       time_t event_time)
 {
-	return SLURM_SUCCESS;
+#ifdef HAVE_MYSQL
+	static uint32_t last_procs = -1;
+	char* query;
+	int rc = SLURM_SUCCESS;
+	MYSQL_RES *result = NULL;
+	MYSQL_ROW row;
+
+	if (procs == last_procs) {
+		debug3("we have the same procs as before no need to "
+		       "update the database.");
+		return SLURM_SUCCESS;
+	}
+	last_procs = procs;
+
+	/* Record the processor count */
+	query = xstrdup_printf(
+		"select cpu_count from %s where cluster='%s' "
+		"and period_end=0 and node_name=''",
+		event_table, cluster);
+	if(!(result = mysql_db_query_ret(acct_mysql_db, query))) {
+		xfree(query);
+		return SLURM_ERROR;
+	}
+	xfree(query);
+
+	/* we only are checking the first one here */
+	if(!(row = mysql_fetch_row(result))) {
+		debug("We don't have an entry for this machine %s"
+		      "most likely a first time running.", cluster);
+		goto add_it;
+	}
+
+	if(atoi(row[0]) == procs) {
+		debug("%s hasn't changed since last entry", cluster);
+		goto end_it;
+	}
+	debug("%s has changed from %s cpus to %u", cluster, row[0], procs);   
+
+	query = xstrdup_printf(
+		"update %s set period_end=%d where cluster='%s' "
+		"and period_end=0 and node_name=''",
+		event_table, (event_time-1), cluster);
+	rc = mysql_db_query(acct_mysql_db, query);
+	xfree(query);
+	if(rc != SLURM_SUCCESS)
+		goto end_it;
+add_it:
+	query = xstrdup_printf(
+		"insert into %s (cluster, cpu_count, period_start) "
+		"values ('%s', %u, %d)",
+		event_table, cluster, procs, event_time);
+	rc = mysql_db_query(acct_mysql_db, query);
+	xfree(query);
+
+end_it:
+	mysql_free_result(result);
+	return rc;
+#else
+	return SLURM_ERROR;
+#endif
 }
 
 extern int clusteracct_storage_p_get_usage(
 	MYSQL *acct_mysql_db, acct_usage_type_t type, 
 	acct_cluster_rec_t *cluster_rec, time_t start, time_t end)
 {
+#ifdef HAVE_MYSQL
 
 	return SLURM_SUCCESS;
+#else
+	return SLURM_ERROR;
+#endif
 }
 
 /* 
diff --git a/src/plugins/accounting_storage/mysql/mysql_jobacct_process.c b/src/plugins/accounting_storage/mysql/mysql_jobacct_process.c
index 0ee63e964f4..c0ef4449fe6 100644
--- a/src/plugins/accounting_storage/mysql/mysql_jobacct_process.c
+++ b/src/plugins/accounting_storage/mysql/mysql_jobacct_process.c
@@ -95,7 +95,7 @@ extern List mysql_jobacct_process_get_jobs(MYSQL *acct_mysql_db,
 		"t1.alloc_cpus",
 		"t1.nodelist",
 		"t1.kill_requid",
-		"t1.qos",
+		"t1.qos"
 	};
 
 	/* if this changes you will need to edit the corresponding 
@@ -130,7 +130,7 @@ extern List mysql_jobacct_process_get_jobs(MYSQL *acct_mysql_db,
 		"t1.min_cpu",
 		"t1.min_cpu_task",
 		"t1.min_cpu_node",
-		"t1.ave_cpu",
+		"t1.ave_cpu"
 	};
 
 	enum {
@@ -193,7 +193,10 @@ extern List mysql_jobacct_process_get_jobs(MYSQL *acct_mysql_db,
 
 	if(selected_steps && list_count(selected_steps)) {
 		set = 0;
-		xstrcat(extra, " && (");
+		if(extra)
+			xstrcat(extra, " && (");
+		else
+			xstrcat(extra, " where (");
 		itr = list_iterator_create(selected_steps);
 		while((selected_step = list_next(itr))) {
 			if(set) 
@@ -210,7 +213,10 @@ extern List mysql_jobacct_process_get_jobs(MYSQL *acct_mysql_db,
 
 	if(selected_parts && list_count(selected_parts)) {
 		set = 0;
-		xstrcat(extra, " && (");
+		if(extra)
+			xstrcat(extra, " && (");
+		else
+			xstrcat(extra, " where (");
 		itr = list_iterator_create(selected_parts);
 		while((selected_part = list_next(itr))) {
 			if(set) 
@@ -241,8 +247,7 @@ extern List mysql_jobacct_process_get_jobs(MYSQL *acct_mysql_db,
 	}
 
 	//info("query = %s", query);
-	if(!(result =
-	     mysql_db_query_ret(acct_mysql_db, query))) {
+	if(!(result = mysql_db_query_ret(acct_mysql_db, query))) {
 		xfree(query);
 		list_destroy(job_list);
 		return NULL;
@@ -257,8 +262,7 @@ extern List mysql_jobacct_process_get_jobs(MYSQL *acct_mysql_db,
 
 		job->alloc_cpus = atoi(row[JOB_REQ_ALLOC_CPUS]);
 		account_rec.id = job->associd = atoi(row[JOB_REQ_ASSOCID]);
-		
-		acct_storage_p_get_assoc_id(acct_mysql_db, &account_rec);
+		assoc_mgr_fill_in_assoc(acct_mysql_db, &account_rec, 0);
 		if(account_rec.cluster) {
 			if(params->opt_cluster &&
 			   strcmp(params->opt_cluster, account_rec.cluster)) {
diff --git a/src/plugins/accounting_storage/mysql/mysql_jobacct_process.h b/src/plugins/accounting_storage/mysql/mysql_jobacct_process.h
index 50f76493915..f77fb8e0e58 100644
--- a/src/plugins/accounting_storage/mysql/mysql_jobacct_process.h
+++ b/src/plugins/accounting_storage/mysql/mysql_jobacct_process.h
@@ -43,7 +43,10 @@
 #ifndef _HAVE_MYSQL_JOBACCT_PROCESS_H
 #define _HAVE_MYSQL_JOBACCT_PROCESS_H
 
+#include <sys/types.h>
+#include <pwd.h>
 #include <stdlib.h>
+#include "src/common/assoc_mgr.h"
 #include "src/common/jobacct_common.h"
 #include "src/slurmdbd/read_config.h"
 #include "src/slurmctld/slurmctld.h"
diff --git a/src/plugins/accounting_storage/pgsql/accounting_storage_pgsql.c b/src/plugins/accounting_storage/pgsql/accounting_storage_pgsql.c
index 2ebcd473508..6b7cbfad955 100644
--- a/src/plugins/accounting_storage/pgsql/accounting_storage_pgsql.c
+++ b/src/plugins/accounting_storage/pgsql/accounting_storage_pgsql.c
@@ -89,7 +89,7 @@ char *cluster_day_table = "cluster_day_usage_table";
 char *cluster_hour_table = "cluster_hour_usage_table";
 char *cluster_month_table = "cluster_month_usage_table";
 char *cluster_table = "cluster_table";
-char *event_table = "event_table";
+char *event_table = "cluster_event_table";
 char *job_table = "job_table";
 char *step_table = "step_table";
 char *txn_table = "txn_table";
@@ -145,7 +145,7 @@ static int _pgsql_acct_check_tables(PGconn *acct_pgsql_db,
 	storage_field_t acct_coord_table_fields[] = {
 		{ "deleted", "smallint default 0" },
 		{ "acct", "text not null" },
-		{ "name", "text not null" },
+		{ "user", "text not null" },
 		{ NULL, NULL}		
 	};
 
@@ -196,8 +196,8 @@ static int _pgsql_acct_check_tables(PGconn *acct_pgsql_db,
 		{ "mod_time", "bigint default 0" },
 		{ "deleted", "smallint default 0" },
 		{ "name", "text not null" },
-		{ "primary_node", "text not null" },
-		{ "backup_node", "text not null" },
+		{ "control_host", "tinytext not null" },
+		{ "control_port", "int not null" },
 		{ NULL, NULL}		
 	};
 
@@ -218,6 +218,7 @@ static int _pgsql_acct_check_tables(PGconn *acct_pgsql_db,
 	storage_field_t event_table_fields[] = {
 		{ "node_name", "text default '' not null" },
 		{ "cluster", "text not null" },
+		{ "cpu_count", "int not null" },
 		{ "period_start", "bigint unsigned not null" },
 		{ "period_end", "bigint default 0 not null" },
 		{ "reason", "text not null" },
@@ -378,7 +379,7 @@ static int _pgsql_acct_check_tables(PGconn *acct_pgsql_db,
 		if(pgsql_db_create_table(acct_pgsql_db, 
 					 acct_coord_table, 
 					 acct_coord_table_fields,
-					 ", primary key (acct(20), name(20)))")
+					 ", primary key (acct(20), user(20)))")
 		   == SLURM_ERROR)
 			return SLURM_ERROR;
 	} else {
@@ -836,14 +837,64 @@ extern int clusteracct_storage_p_node_down(PGconn *acct_pgsql_db,
 					   struct node_record *node_ptr,
 					   time_t event_time, char *reason)
 {
+#ifdef HAVE_PGSQL
+	uint16_t cpus;
+	int rc = SLURM_ERROR;
+	char *query = NULL;
+	char *my_reason;
+
+	if (slurmctld_conf.fast_schedule && !slurmdbd_conf)
+		cpus = node_ptr->config_ptr->cpus;
+	else
+		cpus = node_ptr->cpus;
+
+	if (reason)
+		my_reason = reason;
+	else
+		my_reason = node_ptr->reason;
+	
+	query = xstrdup_printf(
+		"update %s set period_end=%d where cluster='%s' "
+		"and period_end=0 and node_name='%s'",
+		event_table, (event_time-1), cluster, node_ptr->name);
+	rc = pgsql_db_query(acct_pgsql_db, query);
+	xfree(query);
+
+	debug2("inserting %s(%s) with %u cpus", node_ptr->name, cluster, cpus);
+
+	query = xstrdup_printf(
+		"insert into %s "
+		"(node_name, cluster, cpu_count, period_start, reason) "
+		"values ('%s', '%s', %u, %d, '%s')",
+		event_table, node_ptr->name, cluster, 
+		cpus, event_time, my_reason);
+	rc = pgsql_db_query(acct_pgsql_db, query);
+	xfree(query);
+
 	return SLURM_SUCCESS;
+#else
+	return SLURM_ERROR;
+#endif
 }
 extern int clusteracct_storage_p_node_up(PGconn *acct_pgsql_db,
 					 char *cluster,
 					 struct node_record *node_ptr,
 					 time_t event_time)
 {
-	return SLURM_SUCCESS;
+#ifdef HAVE_PGSQL
+	char* query;
+	int rc = SLURM_ERROR;
+
+	query = xstrdup_printf(
+		"update %s set period_end=%d where cluster='%s' "
+		"and period_end=0 and node_name='%s'",
+		event_table, (event_time-1), cluster, node_ptr->name);
+	rc = pgsql_db_query(acct_pgsql_db, query);
+	xfree(query);
+	return rc;
+#else
+	return SLURM_ERROR;
+#endif
 }
 
 extern int clusteracct_storage_p_register_ctld(char *cluster,
@@ -857,7 +908,71 @@ extern int clusteracct_storage_p_cluster_procs(PGconn *acct_pgsql_db,
 					       uint32_t procs,
 					       time_t event_time)
 {
-	return SLURM_SUCCESS;
+#ifdef HAVE_PGSQL
+	static uint32_t last_procs = -1;
+	char* query;
+	int rc = SLURM_ERROR;
+	PGresult *result = NULL;
+	int got_procs = 0;
+
+	if (procs == last_procs) {
+		debug3("we have the same procs as before no need to "
+		       "update the database.");
+		return SLURM_SUCCESS;
+	}
+	last_procs = procs;
+
+	/* Record the processor count */
+#if _DEBUG
+	slurm_make_time_str(&event_time, tmp_buff, sizeof(tmp_buff));
+	info("cluster_acct_procs: %s has %u total CPUs at %s", 
+	     cluster, procs, tmp_buff);
+#endif
+	query = xstrdup_printf(
+		"select cpu_count from %s where cluster='%s' "
+		"and period_end=0 and node_name=''",
+		event_table, cluster);
+	if(!(result = pgsql_db_query_ret(acct_pgsql_db, query))) {
+		xfree(query);
+		return SLURM_ERROR;
+	}
+	xfree(query);
+
+	/* we only are checking the first one here */
+	if(!PQntuples(result)) {
+		debug("We don't have an entry for this machine %s"
+		      "most likely a first time running.", cluster);
+		goto add_it;
+	}
+	got_procs = atoi(PQgetvalue(result, 0, 0));
+	if(got_procs == procs) {
+		debug("%s hasn't changed since last entry", cluster);
+		goto end_it;
+	}
+	debug("%s has changed from %d cpus to %u", cluster, got_procs, procs);
+
+	query = xstrdup_printf(
+		"update %s set period_end=%u where cluster='%s' "
+		"and period_end=0 and node_name=''",
+		event_table, (event_time-1), cluster);
+	rc = pgsql_db_query(acct_pgsql_db, query);
+	xfree(query);
+	if(rc != SLURM_SUCCESS)
+		goto end_it;
+add_it:
+	query = xstrdup_printf(
+		"insert into %s (cluster, cpu_count, period_start) "
+		"values ('%s', %u, %d)",
+		event_table, cluster, procs, event_time);
+	rc = pgsql_db_query(acct_pgsql_db, query);
+	xfree(query);
+
+end_it:
+	PQclear(result);
+	return rc;
+#else
+	return SLURM_ERROR;
+#endif
 }
 
 extern int clusteracct_storage_p_get_usage(
diff --git a/src/plugins/accounting_storage/pgsql/pgsql_jobacct_process.h b/src/plugins/accounting_storage/pgsql/pgsql_jobacct_process.h
index 8620cb7acb5..86afcc84d3e 100644
--- a/src/plugins/accounting_storage/pgsql/pgsql_jobacct_process.h
+++ b/src/plugins/accounting_storage/pgsql/pgsql_jobacct_process.h
@@ -43,6 +43,8 @@
 #ifndef _HAVE_PGSQL_JOBACCT_PROCESS_H
 #define _HAVE_PGSQL_JOBACCT_PROCESS_H
 
+#include <sys/types.h>
+#include <pwd.h>
 #include <stdlib.h>
 #include "src/common/jobacct_common.h"
 #include "src/slurmdbd/read_config.h"
diff --git a/src/plugins/accounting_storage/slurmdbd/accounting_storage_slurmdbd.c b/src/plugins/accounting_storage/slurmdbd/accounting_storage_slurmdbd.c
index f4879bbde07..76574b74958 100644
--- a/src/plugins/accounting_storage/slurmdbd/accounting_storage_slurmdbd.c
+++ b/src/plugins/accounting_storage/slurmdbd/accounting_storage_slurmdbd.c
@@ -625,12 +625,25 @@ extern int clusteracct_storage_p_node_down(void *db_conn,
 {
 	slurmdbd_msg_t msg;
 	dbd_node_state_msg_t req;
+	uint16_t cpus;
+	char *my_reason;
+
+	if (slurmctld_conf.fast_schedule)
+		cpus = node_ptr->config_ptr->cpus;
+	else
+		cpus = node_ptr->cpus;
+
+	if (reason)
+		my_reason = reason;
+	else
+		my_reason = node_ptr->reason;
 
 	req.cluster_name = cluster;
+	req.cpu_count = cpus;
 	req.hostlist   = node_ptr->name;
 	req.new_state  = DBD_NODE_STATE_DOWN;
 	req.event_time = event_time;
-	req.reason     = reason;
+	req.reason     = my_reason;
 	msg.msg_type   = DBD_NODE_STATE;
 	msg.data       = &req;
 
diff --git a/src/sacctmgr/cluster_functions.c b/src/sacctmgr/cluster_functions.c
index d2357e81245..5e529ea8f19 100644
--- a/src/sacctmgr/cluster_functions.c
+++ b/src/sacctmgr/cluster_functions.c
@@ -76,13 +76,7 @@ static int _set_rec(int *start, int argc, char *argv[],
 	int set = 0;
 
 	for (i=(*start); i<argc; i++) {
-		if (strncasecmp (argv[i], "Primary=", 8) == 0) {		
-			cluster->primary = xstrdup(argv[i]+8);
-			set = 1;
-		} else if (strncasecmp (argv[i], "Backup=", 7) == 0) {		
-			cluster->backup = xstrdup(argv[i]+7);
-			set = 1;
-		} else if (strncasecmp (argv[i], "FairShare=", 10) == 0) {
+		if (strncasecmp (argv[i], "FairShare=", 10) == 0) {
 			assoc->fairshare = atoi(argv[i]+10);
 			set = 1;
 		} else if (strncasecmp (argv[i], "MaxJobs=", 8) == 0) {
@@ -101,7 +95,7 @@ static int _set_rec(int *start, int argc, char *argv[],
 			i--;
 			break;
 		} else {
-			printf(" error: Valid options are 'Primary='\n");
+			printf(" error: Valid options are\n");
 		}
 	}
 	(*start) = i;
@@ -160,16 +154,7 @@ static void _update_existing(acct_cluster_cond_t *cluster_cond,
 				sacctmgr_remove_from_list(sacctmgr_cluster_list,
 							  cluster);
 			} else {
-				if(new_cluster->primary) {
-					xfree(cluster->primary);
-					cluster->primary =
-						xstrdup(new_cluster->primary);
-				}
-				if(new_cluster->backup) {
-					xfree(cluster->backup);
-					cluster->backup =
-						xstrdup(new_cluster->backup);
-				}				
+								
 			}
 
 			if(!(assoc = sacctmgr_find_association(
@@ -224,10 +209,6 @@ extern int sacctmgr_add_cluster(int argc, char *argv[])
 				cluster->name = xstrdup(argv[i]+5);
 				assoc->cluster = xstrdup(argv[i]+5);
 			}
-		} else if (strncasecmp (argv[i], "Backup=", 7) == 0) {
-			cluster->backup = xstrdup(argv[i]+7);
-		} else if (strncasecmp (argv[i], "Primary=", 8) == 0) {
-			cluster->primary = xstrdup(argv[i]+8);
 		} else if (strncasecmp (argv[i], "FairShare=", 10) == 0) {
 			assoc->fairshare = atoi(argv[i]+10);
 			limit_set = 1;
@@ -267,10 +248,6 @@ extern int sacctmgr_add_cluster(int argc, char *argv[])
 
 	printf(" Adding Cluster(s)\n");
 	printf("  Name           = %s\n", cluster->name);
-	if(cluster->primary)
-		printf("  Primary Node  = %s", cluster->primary);
-	if(cluster->backup)
-		printf("  Backup Node   = %s", cluster->backup);
 
 	printf(" User Defaults =\n");
 
@@ -357,17 +334,17 @@ extern int sacctmgr_list_cluster(int argc, char *argv[])
 		return SLURM_ERROR;
 	
 	itr = list_iterator_create(cluster_list);
-	printf("%-15s %-15s %-15s\n%-15s %-15s %-15s\n",
-	       "Name", "Primary Node", "Backup Node",
+	printf("%-15s %-15s %-5s\n%-15s %-15s %-5s\n",
+	       "Name", "Control Host", "Port",
 	       "---------------",
 	       "---------------",
-	       "---------------");
+	       "-----");
 	
 	while((cluster = list_next(itr))) {
-		printf("%-15.15s %-15.15s %-15.15s\n",
+		printf("%-15.15s %-15.15s %-5u\n",
 		       cluster->name,
-		       cluster->primary,
-		       cluster->backup);
+		       cluster->control_host,
+		       cluster->control_port);
 	}
 
 	printf("\n");
@@ -433,10 +410,6 @@ extern int sacctmgr_modify_cluster(int argc, char *argv[])
 	list_push(assoc_cond->acct_list, "template_account");
 
 	printf(" Setting\n");
-	if(cluster->primary)
-		printf("  Primary Node  = %s\n", cluster->primary);
-	if(cluster->backup)
-		printf("  Backup Node   = %s\n", cluster->backup);
 	if(rec_set) 
 		printf(" User Defaults =\n");
 	if(assoc->fairshare)
diff --git a/src/slurmdbd/proc_req.c b/src/slurmdbd/proc_req.c
index 5753f614d7b..bb1967366b4 100644
--- a/src/slurmdbd/proc_req.c
+++ b/src/slurmdbd/proc_req.c
@@ -1211,6 +1211,7 @@ static int _node_state(void *db_conn,
 	       node_state_msg->reason, 
 	       node_state_msg->event_time);
 	node_ptr.name = node_state_msg->hostlist;
+	node_ptr.cpus = node_state_msg->cpu_count;
 
 	slurmctld_conf.fast_schedule = 0;
 
-- 
GitLab