diff --git a/src/common/assoc_mgr.c b/src/common/assoc_mgr.c
index a2a437a15a592e60ea9cfe3c713bc1ed7aadee97..f2e7a0a26dd75d35853691b2399b5ae80cb06173 100644
--- a/src/common/assoc_mgr.c
+++ b/src/common/assoc_mgr.c
@@ -824,6 +824,53 @@ extern int assoc_mgr_fini(char *state_save_location)
 	return SLURM_SUCCESS;
 }
 
+extern int assoc_mgr_get_user_assocs(void *db_conn,
+				     acct_association_rec_t *assoc,
+				     int enforce, 
+				     List assoc_list)
+{
+	ListIterator itr = NULL;
+	acct_association_rec_t *found_assoc = NULL;
+	int set = 1;
+
+	xassert(assoc);
+	xassert(assoc->uid != (uint32_t)NO_VAL);
+	xassert(assoc_list);
+
+	if(!assoc_mgr_association_list) {
+		if(_get_assoc_mgr_association_list(db_conn, enforce) 
+		   == SLURM_ERROR)
+			return SLURM_ERROR;
+	}
+
+	if((!assoc_mgr_association_list
+	    || !list_count(assoc_mgr_association_list))
+	   && !(enforce & ACCOUNTING_ENFORCE_ASSOCS)) 
+		return SLURM_SUCCESS;
+
+	slurm_mutex_lock(&assoc_mgr_association_lock);
+	itr = list_iterator_create(assoc_mgr_association_list);
+	while((found_assoc = list_next(itr))) {
+		if(assoc->uid != found_assoc->uid) {
+			debug4("not the right user %u != %u",
+			       assoc->uid, found_assoc->uid);
+			continue;
+		}
+
+		list_append(assoc_list, found_assoc);
+		set = 1;
+	}
+	list_iterator_destroy(itr);
+	slurm_mutex_unlock(&assoc_mgr_association_lock);
+
+	if(set)
+		return SLURM_SUCCESS;
+	else {
+		debug("user %u does not have any associations", assoc->uid);
+		return SLURM_ERROR;
+	}
+}
+
 extern int assoc_mgr_fill_in_assoc(void *db_conn, acct_association_rec_t *assoc,
 				   int enforce, 
 				   acct_association_rec_t **assoc_pptr)
diff --git a/src/common/assoc_mgr.h b/src/common/assoc_mgr.h
index fc86956716fd645f5c89471d45aded384bf982e1..d81d78dc6a7ea18c58552c9eaf2b6e2ec435d8cb 100644
--- a/src/common/assoc_mgr.h
+++ b/src/common/assoc_mgr.h
@@ -76,17 +76,21 @@ extern pthread_mutex_t assoc_mgr_wckey_lock;
 
 /* 
  * get info from the storage 
- * IN/OUT:  user - acct_user_rec_t with the name set of the user.
- *                 "default_account" will be filled in on
- *                 successful return DO NOT FREE.
- * IN/OUT: user_pptr - if non-NULL then return a pointer to the 
- *		       acct_user record in cache on success
- *                     DO NOT FREE.
- * RET: SLURM_SUCCESS on success SLURM_ERROR else
+ * IN:  assoc - acct_association_rec_t with at least cluster and
+ *		    account set for account association.  To get user
+ *		    association set user, and optional partition.
+ *		    Sets "id" field with the association ID.
+ * IN: enforce - return an error if no such association exists
+ * IN/OUT: assoc_list - contains a list of assoc_rec ptrs to
+ *                      associations this user has in the list.  This
+ *                      list should be created with list_create(NULL)
+ *                      since we are putting pointers to memory used elsewhere.
+ * RET: SLURM_SUCCESS on success, else SLURM_ERROR
  */
-extern int assoc_mgr_fill_in_user(void *db_conn, acct_user_rec_t *user,
-				  int enforce,
-				  acct_user_rec_t **user_pptr);
+extern int assoc_mgr_get_user_assocs(void *db_conn,
+				     acct_association_rec_t *assoc,
+				     int enforce, 
+				     List assoc_list);
 
 /* 
  * get info from the storage 
@@ -105,6 +109,19 @@ extern int assoc_mgr_fill_in_assoc(void *db_conn,
 				   int enforce,
 				   acct_association_rec_t **assoc_pptr);
 
+/* 
+ * get info from the storage 
+ * IN/OUT:  user - acct_user_rec_t with the name set of the user.
+ *                 "default_account" will be filled in on
+ *                 successful return DO NOT FREE.
+ * IN/OUT: user_pptr - if non-NULL then return a pointer to the 
+ *		       acct_user record in cache on success
+ *                     DO NOT FREE.
+ * RET: SLURM_SUCCESS on success SLURM_ERROR else
+ */
+extern int assoc_mgr_fill_in_user(void *db_conn, acct_user_rec_t *user,
+				  int enforce,
+				  acct_user_rec_t **user_pptr);
 
 /* 
  * get info from the storage 
diff --git a/src/common/slurm_accounting_storage.c b/src/common/slurm_accounting_storage.c
index 27f9c64056e3220cb63574276ded68775e902a00..499641588daea397312b503bbe0b38d4172fa09f 100644
--- a/src/common/slurm_accounting_storage.c
+++ b/src/common/slurm_accounting_storage.c
@@ -757,6 +757,7 @@ extern void destroy_acct_reservation_rec(void *object)
 {
 	acct_reservation_rec_t *acct_resv = (acct_reservation_rec_t *)object;
 	if(acct_resv) {
+		xfree(acct_resv->assocs);
 		xfree(acct_resv->cluster);
 		xfree(acct_resv->nodes);
 		xfree(acct_resv);
@@ -5665,6 +5666,7 @@ extern void pack_acct_reservation_rec(void *in, uint16_t rpc_version,
 	acct_reservation_rec_t *object = (acct_reservation_rec_t *)in;
 
 	if(!object) {
+		packnull(buffer);
 		packnull(buffer);
 		pack32((uint32_t)NO_VAL, buffer);
 		pack16((uint16_t)NO_VAL, buffer);
@@ -5676,6 +5678,7 @@ extern void pack_acct_reservation_rec(void *in, uint16_t rpc_version,
 		return;
 	}
 	
+	packstr(object->assocs, buffer);
 	packstr(object->cluster, buffer);
 	pack32(object->cpus, buffer);
 	pack16(object->flags, buffer);
@@ -5695,6 +5698,7 @@ extern int unpack_acct_reservation_rec(void **object, uint16_t rpc_version,
 
 	*object = object_ptr;
 
+	safe_unpackstr_xmalloc(&object_ptr->assocs, &uint32_tmp, buffer);
 	safe_unpackstr_xmalloc(&object_ptr->cluster, &uint32_tmp, buffer);
 	safe_unpack32(&object_ptr->cpus, buffer);
 	safe_unpack16(&object_ptr->flags, buffer);
diff --git a/src/common/slurm_accounting_storage.h b/src/common/slurm_accounting_storage.h
index ce73450580a57edd9a3966f2781a3ab3e8b532fe..970b33562eafb549c550874a2e16dec99c6fa8e5 100644
--- a/src/common/slurm_accounting_storage.h
+++ b/src/common/slurm_accounting_storage.h
@@ -349,6 +349,7 @@ typedef struct {
 } acct_qos_cond_t;
 
 typedef struct {
+	char *assocs; /* comma seperated list of associations */
 	char *cluster; /* cluster reservation is for */
 	uint32_t cpus; /* how many cpus are in reservation */
 	uint16_t flags; /* flags for reservation. */
diff --git a/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c b/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c
index f800efbc18c321168f3182178ff02fd5ca19aa4c..692e1cef6c905bf084fc6cbd0975535eafbce7e5 100644
--- a/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c
+++ b/src/plugins/accounting_storage/mysql/accounting_storage_mysql.c
@@ -878,6 +878,12 @@ static int _setup_resv_limits(acct_reservation_rec_t *resv,
 {	
 	/* strip off the action item from the flags */
 
+	if(resv->assocs) {
+		xstrcat(*cols, ", assoclist");
+		xstrfmtcat(*vals, ", \"%s\"", resv->assocs);
+		xstrfmtcat(*extra, ", assoclist=\"%s\"", resv->assocs);
+	}
+
 	if(resv->cpus != (uint32_t)NO_VAL) {
 		xstrcat(*cols, ", cpus");
 		xstrfmtcat(*vals, ", %u", resv->cpus);
@@ -2667,8 +2673,9 @@ static int _mysql_acct_check_tables(MYSQL *db_conn)
 		{ "cluster", "text not null" },
 		{ "deleted", "tinyint default 0" },
 		{ "cpus", "mediumint unsigned not null" },
+		{ "assoclist", "text not null default ''" },
 		{ "nodelist", "text not null default ''" },
-		{ "start", "int unsigned default 0 not null" },
+		{ "start", "int unsigned default 0 not null"},
 		{ "end", "int unsigned default 0 not null" },
 		{ "flags", "smallint default 0 not null" },
 		{ NULL, NULL}		
@@ -4553,7 +4560,6 @@ extern int acct_storage_p_add_reservation(mysql_conn_t *mysql_conn,
 	if((rc = mysql_db_query(mysql_conn->db_conn, query)
 	    == SLURM_SUCCESS))
 		rc = mysql_clear_results(mysql_conn->db_conn);
-
 	
 	xfree(query);
 	xfree(cols);
@@ -5850,6 +5856,7 @@ extern int acct_storage_p_modify_reservation(mysql_conn_t *mysql_conn,
 	int i;
 	int set = 0;
 	char *resv_req_inx[] = {
+		"assoclist",
 		"start",
 		"end",
 		"cpus",
@@ -5857,6 +5864,7 @@ extern int acct_storage_p_modify_reservation(mysql_conn_t *mysql_conn,
 		"flags"
 	};
 	enum {
+		RESV_ASSOCS,
 		RESV_START,
 		RESV_END,
 		RESV_CPU,
@@ -5944,20 +5952,30 @@ try_again:
 	
 	/* check differences here */
 		
-	if(resv->cpus == (uint32_t)NO_VAL) {
-		resv->cpus = atoi(row[RESV_CPU]);
+	if(!resv->assocs 
+	   && row[RESV_ASSOCS] && row[RESV_ASSOCS][0])
+		// if this changes we just update the
+		// record, no need to create a new one since
+		// this doesn't really effect the
+		// reservation accounting wise
+		resv->assocs = xstrdup(row[RESV_ASSOCS]);
+
+	if(resv->cpus != (uint32_t)NO_VAL) 
 		set = 1;
-	}
+	else 
+		resv->cpus = atoi(row[RESV_CPU]);
+
 		
-	if(resv->flags == (uint16_t)NO_VAL) {
-		resv->flags = atoi(row[RESV_FLAGS]);
+	if(resv->flags == (uint16_t)NO_VAL) 
 		set = 1;
-	}
+	else
+		resv->flags = atoi(row[RESV_FLAGS]);
+
 		
-	if(!resv->nodes) {
-		resv->nodes = xstrdup(row[RESV_NODES]);
+	if(resv->nodes) 
 		set = 1;
-	}
+	else if(row[RESV_NODES] && row[RESV_NODES][0])
+		resv->nodes = xstrdup(row[RESV_NODES]);
 		
 	if(!resv->time_end)
 		resv->time_end = atoi(row[RESV_END]);
@@ -5991,9 +6009,9 @@ try_again:
 				       resv->id, start,
 				       resv->cluster);
 		xstrfmtcat(query,
-			   "insert into %s (id, cluster, %s) "
-			   "values (%u, '%s', %s) "
-			   "on duplicate key update deleted=0, %s;",
+			   "insert into %s (id, cluster%s) "
+			   "values (%u, '%s'%s) "
+			   "on duplicate key update deleted=0%s;",
 			   resv_table, cols, resv->id, resv->cluster,
 			   vals, extra);
 	}
diff --git a/src/plugins/accounting_storage/mysql/mysql_jobacct_process.h b/src/plugins/accounting_storage/mysql/mysql_jobacct_process.h
index 12d7a4c4529233d3a39d5d64ff076bf85a4af0bd..2e1b55edc4cf1cc0d186950aafd62b8efae0f250 100644
--- a/src/plugins/accounting_storage/mysql/mysql_jobacct_process.h
+++ b/src/plugins/accounting_storage/mysql/mysql_jobacct_process.h
@@ -56,11 +56,29 @@
 #ifdef HAVE_MYSQL
 
 //extern int acct_db_init;
-
+extern char *acct_coord_table;
+extern char *acct_table;
+extern char *assoc_day_table;
+extern char *assoc_hour_table;
+extern char *assoc_month_table;
 extern char *assoc_table;
+extern char *cluster_day_table;
+extern char *cluster_hour_table;
+extern char *cluster_month_table;
+extern char *cluster_table;
+extern char *event_table;
 extern char *job_table;
+extern char *last_ran_table;
+extern char *qos_table;
+extern char *resv_table;
 extern char *step_table;
+extern char *txn_table;
+extern char *user_table;
 extern char *suspend_table;
+extern char *wckey_day_table;
+extern char *wckey_hour_table;
+extern char *wckey_month_table;
+extern char *wckey_table;
 
 extern int setup_job_cond_limits(acct_job_cond_t *job_cond, char **extra);
 
diff --git a/src/plugins/accounting_storage/mysql/mysql_rollup.c b/src/plugins/accounting_storage/mysql/mysql_rollup.c
index 0e5d1f1d5e6c82592389506edf88cafb2856268d..4a3ca46bd552a88d04db4c4adec29a6f4ddd032c 100644
--- a/src/plugins/accounting_storage/mysql/mysql_rollup.c
+++ b/src/plugins/accounting_storage/mysql/mysql_rollup.c
@@ -51,6 +51,7 @@ typedef struct {
 
 typedef struct {
 	char *name;
+	int id; /*only needed for reservations */
 	uint64_t total_time;
 	uint64_t a_cpu;
 	int cpu_count;
@@ -62,7 +63,18 @@ typedef struct {
 	time_t end;
 } local_cluster_usage_t;
 
-extern void _destroy_local_id_usage(void *object)
+typedef struct {
+	uint64_t a_cpu;
+	char *cluster;
+	int id;
+	List local_assocs; /* list of assocs to spread unused time
+			      over of type local_id_usage_t */
+	uint64_t total_time;
+	time_t start;
+	time_t end;
+} local_resv_usage_t;
+
+static void _destroy_local_id_usage(void *object)
 {
 	local_id_usage_t *a_usage = (local_id_usage_t *)object;
 	if(a_usage) {
@@ -70,7 +82,7 @@ extern void _destroy_local_id_usage(void *object)
 	}
 }
 
-extern void _destroy_local_cluster_usage(void *object)
+static void _destroy_local_cluster_usage(void *object)
 {
 	local_cluster_usage_t *c_usage = (local_cluster_usage_t *)object;
 	if(c_usage) {
@@ -79,6 +91,17 @@ extern void _destroy_local_cluster_usage(void *object)
 	}
 }
 
+static void _destroy_local_resv_usage(void *object)
+{
+	local_resv_usage_t *r_usage = (local_resv_usage_t *)object;
+	if(r_usage) {
+		xfree(r_usage->cluster);
+		if(r_usage->local_assocs)
+			list_destroy(r_usage->local_assocs);
+		xfree(r_usage);
+	}
+}
+
 extern int mysql_hourly_rollup(mysql_conn_t *mysql_conn,
 			       time_t start, time_t end)
 {
@@ -94,11 +117,12 @@ extern int mysql_hourly_rollup(mysql_conn_t *mysql_conn,
 	ListIterator a_itr = NULL;
 	ListIterator c_itr = NULL;
 	ListIterator w_itr = NULL;
+	ListIterator r_itr = NULL;
 	List assoc_usage_list = list_create(_destroy_local_id_usage);
 	List cluster_usage_list = list_create(_destroy_local_cluster_usage);
 	List wckey_usage_list = list_create(_destroy_local_id_usage);
+	List resv_usage_list = list_create(_destroy_local_resv_usage);
 	uint16_t track_wckey = slurm_get_track_wckey();
-	local_cluster_usage_t *last_c_usage = NULL;
 
 	char *event_req_inx[] = {
 		"node_name",
@@ -116,6 +140,7 @@ extern int mysql_hourly_rollup(mysql_conn_t *mysql_conn,
 		EVENT_REQ_END,
 		EVENT_REQ_COUNT
 	};
+
 	char *job_req_inx[] = {
 		"id",
 		"jobid",
@@ -127,7 +152,9 @@ extern int mysql_hourly_rollup(mysql_conn_t *mysql_conn,
 		"end",
 		"suspended",
 		"alloc_cpus",
-		"req_cpus"
+		"req_cpus",
+		"resvid"
+	   
 	};
 	char *job_str = NULL;
 	enum {
@@ -142,8 +169,10 @@ extern int mysql_hourly_rollup(mysql_conn_t *mysql_conn,
 		JOB_REQ_SUSPENDED,
 		JOB_REQ_ACPU,
 		JOB_REQ_RCPU,
+		JOB_REQ_RESVID,
 		JOB_REQ_COUNT
 	};
+
 	char *suspend_req_inx[] = {
 		"start",
 		"end"
@@ -155,6 +184,25 @@ extern int mysql_hourly_rollup(mysql_conn_t *mysql_conn,
 		SUSPEND_REQ_COUNT
 	};
 
+	char *resv_req_inx[] = {
+		"id",
+		"cluster",
+		"assoclist",
+		"cpus",
+		"start",
+		"end"
+	};
+	char *resv_str = NULL;
+	enum {
+		RESV_REQ_ID,
+		RESV_REQ_CLUSTER,
+		RESV_REQ_ASSOCS,
+		RESV_REQ_CPU,
+		RESV_REQ_START,
+		RESV_REQ_END,
+		RESV_REQ_COUNT
+	};
+
 	i=0;
 	xstrfmtcat(event_str, "%s", event_req_inx[i]);
 	for(i=1; i<EVENT_REQ_COUNT; i++) {
@@ -173,21 +221,28 @@ extern int mysql_hourly_rollup(mysql_conn_t *mysql_conn,
 		xstrfmtcat(suspend_str, ", %s", suspend_req_inx[i]);
 	}
 
+	i=0;
+	xstrfmtcat(resv_str, "%s", resv_req_inx[i]);
+	for(i=1; i<RESV_REQ_COUNT; i++) {
+		xstrfmtcat(resv_str, ", %s", resv_req_inx[i]);
+	}
+
 /* 	info("begin start %s", ctime(&curr_start)); */
 /* 	info("begin end %s", ctime(&curr_end)); */
 	a_itr = list_iterator_create(assoc_usage_list);
 	c_itr = list_iterator_create(cluster_usage_list);
 	w_itr = list_iterator_create(wckey_usage_list);
+	r_itr = list_iterator_create(resv_usage_list);
 	while(curr_start < end) {
+		local_cluster_usage_t *last_c_usage = NULL;
 		int last_id = -1;
 		int last_wckeyid = -1;
 		int seconds = 0;
 		local_cluster_usage_t *c_usage = NULL;
+		local_resv_usage_t *r_usage = NULL;
 		local_id_usage_t *a_usage = NULL;
 		local_id_usage_t *w_usage = NULL;
 
-		last_c_usage = NULL;
-
 		debug3("curr hour is now %d-%d", curr_start, curr_end);
 /* 		info("start %s", ctime(&curr_start)); */
 /* 		info("end %s", ctime(&curr_end)); */
@@ -301,6 +356,54 @@ extern int mysql_hourly_rollup(mysql_conn_t *mysql_conn,
 		}
 		mysql_free_result(result);
 
+		// now get the reservations during this time
+		query = xstrdup_printf("select %s from %s where "
+				       "(start < %d && end >= %d) "
+				       "order by cluster, start",
+				       resv_str, resv_table,
+				       curr_end, curr_start);
+
+		debug3("%d(%d) query\n%s", mysql_conn->conn, __LINE__, query);
+		if(!(result = mysql_db_query_ret(
+			     mysql_conn->db_conn, query, 0))) {
+			xfree(query);
+			return SLURM_ERROR;
+		}
+		xfree(query);
+		
+		while((row = mysql_fetch_row(result))) {
+			int row_start = atoi(row[RESV_REQ_START]);
+			int row_end = atoi(row[RESV_REQ_END]);
+			int row_cpu = atoi(row[RESV_REQ_CPU]);
+		
+			if(row_start < curr_start)
+				row_start = curr_start;
+		
+			if(!row_end || row_end > curr_end) 
+				row_end = curr_end;
+
+			/* Don't worry about it if the time is less
+			 * than 1 second.
+			 */
+			if((row_end - row_start) < 1)
+				continue;
+
+			r_usage = xmalloc(sizeof(local_resv_usage_t));
+			r_usage->id = atoi(row[RESV_REQ_ID]);
+
+			r_usage->local_assocs = list_create(slurm_destroy_char);
+			slurm_addto_char_list(r_usage->local_assocs, 
+					      row[RESV_REQ_ASSOCS]);
+
+			r_usage->cluster = xstrdup(row[RESV_REQ_CLUSTER]);
+			r_usage->total_time = (row_end - row_start) * row_cpu;
+			r_usage->start = row_start;
+			r_usage->end = row_end;
+			list_append(resv_usage_list, r_usage);
+		}
+		mysql_free_result(result);
+
+		/* now get the jobs during this time */
 		query = xstrdup_printf("select %s from %s where "
 				       "(eligible < %d && (end >= %d "
 				       "|| end = 0)) "
@@ -320,6 +423,7 @@ extern int mysql_hourly_rollup(mysql_conn_t *mysql_conn,
 			int job_id = atoi(row[JOB_REQ_JOBID]);
 			int assoc_id = atoi(row[JOB_REQ_ASSOCID]);
 			int wckey_id = atoi(row[JOB_REQ_WCKEYID]);
+			int resv_id = atoi(row[JOB_REQ_RESVID]);
 			int row_eligible = atoi(row[JOB_REQ_ELG]);
 			int row_start = atoi(row[JOB_REQ_START]);
 			int row_end = atoi(row[JOB_REQ_END]);
@@ -338,7 +442,7 @@ extern int mysql_hourly_rollup(mysql_conn_t *mysql_conn,
 
 			if(!row_start || ((row_end - row_start) < 1)) 
 				goto calc_cluster;
-
+			
 			seconds = (row_end - row_start);
 
 			if(row[JOB_REQ_SUSPENDED]) {
@@ -379,7 +483,7 @@ extern int mysql_hourly_rollup(mysql_conn_t *mysql_conn,
 
 					if((local_end - local_start) < 1)
 						continue;
-					
+
 					seconds -= (local_end - local_start);
 				}
 				mysql_free_result(result2);
@@ -388,14 +492,14 @@ extern int mysql_hourly_rollup(mysql_conn_t *mysql_conn,
 				debug4("This job (%u) was suspended "
 				       "the entire hour", job_id);
 				continue;
-			}
+			} 
 
 			if(last_id != assoc_id) {
 				a_usage = xmalloc(sizeof(local_id_usage_t));
 				a_usage->id = assoc_id;
 				list_append(assoc_usage_list, a_usage);
 				last_id = assoc_id;
-			}
+			} 
 			
 			a_usage->a_cpu += seconds * row_acpu;
 
@@ -425,6 +529,32 @@ extern int mysql_hourly_rollup(mysql_conn_t *mysql_conn,
 			if(!row[JOB_REQ_CLUSTER] || !row[JOB_REQ_CLUSTER][0]) 
 				continue;
 			
+			/* first figure out the reservation */
+			if(resv_id) {
+				list_iterator_reset(r_itr);
+				while((r_usage = list_next(r_itr))) {
+					if((r_usage->id == resv_id)
+					   && !strcmp(r_usage->cluster,
+						      row[JOB_REQ_CLUSTER])) {
+						int temp_end = row_end;
+						int temp_start = row_start;
+						if(r_usage->start > temp_start)
+							temp_start =
+								r_usage->start;
+						if(r_usage->end < temp_end)
+							temp_end = r_usage->end;
+						
+						if((temp_end - temp_start) 
+						   > 0) {
+							r_usage->a_cpu += 
+								(temp_end 
+								 - temp_start)
+								* row_acpu;
+						}
+					}
+				}
+			}
+
 			if(last_c_usage && !strcmp(last_c_usage->name,
 						   row[JOB_REQ_CLUSTER])) {
 				c_usage = last_c_usage;
@@ -471,7 +601,8 @@ extern int mysql_hourly_rollup(mysql_conn_t *mysql_conn,
 					row_end = c_usage->end;
 				
 				if((row_end - row_start) > 0) {
-					seconds = (row_end - row_start);
+					seconds = (row_end - row_start)
+						* row_rcpu;
 					
 /* 					info("%d assoc %d reserved " */
 /* 					     "(%d)(%d-%d) * %d = %d " */
@@ -483,12 +614,76 @@ extern int mysql_hourly_rollup(mysql_conn_t *mysql_conn,
 /* 					     row_rcpu, */
 /* 					     seconds * row_rcpu, */
 /* 					     row_rcpu); */
-					c_usage->r_cpu += seconds * row_rcpu;
+					c_usage->r_cpu += seconds;
 				}
 			}
 		}
 		mysql_free_result(result);
 
+		/* now figure out how much more to add to the cluster
+		   from the reservations
+		*/
+		list_iterator_reset(r_itr);
+		while((r_usage = list_next(r_itr))) {
+			int64_t idle = r_usage->total_time - r_usage->a_cpu;
+			char *assoc = NULL;
+			ListIterator tmp_itr = NULL;
+
+			if(idle <= 0)
+				continue;
+			/* Since this reservation was added to the
+			   cluster and only certain people could run
+			   there we will use this as allocated time on
+			   the system.
+			*/
+			if(last_c_usage && !strcmp(last_c_usage->name,
+						   r_usage->cluster)) {
+				c_usage = last_c_usage;
+			} else {
+				list_iterator_reset(c_itr);
+				while((c_usage = list_next(c_itr))) {
+					if(!strcmp(c_usage->name,
+						   r_usage->cluster)) {
+						last_c_usage = c_usage;
+						break;
+					}
+				}				
+			}
+			c_usage->a_cpu += idle;
+			info("adding this much %ll to cluster %s",
+			     idle, c_usage->name);
+			/* now divide that time by the number of
+			   associations in the reservation and add
+			   them to each association */
+			seconds = idle / list_count(r_usage->local_assocs);
+			info("got %d for seconds for %d assocs", seconds,
+			     list_count(r_usage->local_assocs));
+			tmp_itr = list_iterator_create(r_usage->local_assocs);
+			while((assoc = list_next(tmp_itr))) {
+				int associd = atoi(assoc);
+				if(last_id != associd) {
+					list_iterator_reset(a_itr);
+					while((a_usage = list_next(a_itr))) {
+						if(!a_usage->id == associd) {
+							last_id = a_usage->id;
+							break;
+						}
+					}
+				}
+
+				if(!a_usage) {
+					a_usage = xmalloc(
+						sizeof(local_id_usage_t));
+					a_usage->id = associd;
+					list_append(assoc_usage_list, a_usage);
+					last_id = associd;
+				} 
+				
+				a_usage->a_cpu += seconds;
+			}
+			list_iterator_destroy(tmp_itr);
+		}
+
 		/* Now put the lists into the usage tables */
 		list_iterator_reset(c_itr);
 		while((c_usage = list_next(c_itr))) {
@@ -673,13 +868,17 @@ end_it:
 	xfree(suspend_str);	
 	xfree(event_str);	
 	xfree(job_str);
+	xfree(resv_str);
 	list_iterator_destroy(a_itr);
 	list_iterator_destroy(c_itr);
 	list_iterator_destroy(w_itr);
+	list_iterator_destroy(r_itr);
 		
 	list_destroy(assoc_usage_list);
 	list_destroy(cluster_usage_list);
 	list_destroy(wckey_usage_list);
+	list_destroy(resv_usage_list);
+
 /* 	info("stop start %s", ctime(&curr_start)); */
 /* 	info("stop end %s", ctime(&curr_end)); */
 	return rc;
diff --git a/src/plugins/accounting_storage/mysql/mysql_rollup.h b/src/plugins/accounting_storage/mysql/mysql_rollup.h
index c10e1fcfd02af1a24def8a19340493ab5f35dd7e..25ac36fd05b61317148a992c884d3550389eadb7 100644
--- a/src/plugins/accounting_storage/mysql/mysql_rollup.h
+++ b/src/plugins/accounting_storage/mysql/mysql_rollup.h
@@ -44,25 +44,14 @@
 #include "mysql_jobacct_process.h"
 
 #ifdef HAVE_MYSQL
-extern char *assoc_table;
-extern char *assoc_day_table;
-extern char *assoc_hour_table;
-extern char *assoc_month_table;
-extern char *cluster_day_table;
-extern char *cluster_hour_table;
-extern char *cluster_month_table;
-extern char *event_table;
-extern char *suspend_table;
-extern char *wckey_day_table;
-extern char *wckey_hour_table;
-extern char *wckey_month_table;
 
 extern int mysql_hourly_rollup(mysql_conn_t *mysql_conn,
 			       time_t start, time_t end);
 extern int mysql_daily_rollup(mysql_conn_t *mysql_conn,
 			      time_t start, time_t end, uint16_t archive_data);
 extern int mysql_monthly_rollup(mysql_conn_t *mysql_conn,
-			       time_t start, time_t end, uint16_t archive_data);
+				time_t start, time_t end,
+				uint16_t archive_data);
 
 #endif
 
diff --git a/src/slurmctld/reservation.c b/src/slurmctld/reservation.c
index 85fa71d72ad2bf8dada747d46ab32a39313c2fce..a409fcb926ebf70886b29d332a7ec2878d1c1e0c 100644
--- a/src/slurmctld/reservation.c
+++ b/src/slurmctld/reservation.c
@@ -97,25 +97,27 @@ static void _generate_resv_id(void);
 static void _generate_resv_name(reserve_request_msg_t *resv_ptr);
 static bool _is_account_valid(char *account);
 static bool _is_resv_used(slurmctld_resv_t *resv_ptr);
-static void _pack_resv(struct slurmctld_resv *resv_ptr, Buf buffer,
+static void _pack_resv(slurmctld_resv_t *resv_ptr, Buf buffer,
 		       bool internal);
 static int  _resize_resv(slurmctld_resv_t *resv_ptr, uint32_t node_cnt);
 static bool _resv_overlap(time_t start_time, time_t end_time, 
 			  uint16_t flags, bitstr_t *node_bitmap,
-			  struct slurmctld_resv *this_resv_ptr);
+			  slurmctld_resv_t *this_resv_ptr);
 static int  _select_nodes(reserve_request_msg_t *resv_desc_ptr, 
 			  struct part_record **part_ptr,
 			  bitstr_t **resv_bitmap);
-static void _set_cpu_cnt(struct slurmctld_resv *resv_ptr);
+static int  _set_assoc_list(slurmctld_resv_t *resv_ptr);
+static void _set_cpu_cnt(slurmctld_resv_t *resv_ptr);
 static void _swap_resv(slurmctld_resv_t *resv_backup, 
 		       slurmctld_resv_t *resv_ptr);
-static int  _post_resv_create(struct slurmctld_resv *resv_ptr);
-static int  _post_resv_delete(struct slurmctld_resv *resv_ptr);
-static int  _post_resv_update(struct slurmctld_resv *resv_ptr);
+static int  _post_resv_create(slurmctld_resv_t *resv_ptr);
+static int  _post_resv_delete(slurmctld_resv_t *resv_ptr);
+static int  _post_resv_update(slurmctld_resv_t *resv_ptr,
+			      slurmctld_resv_t *old_resv_ptr);
 
-static int  _update_account_list(struct slurmctld_resv *resv_ptr, 
+static int  _update_account_list(slurmctld_resv_t *resv_ptr, 
 				 char *accounts);
-static int  _update_uid_list(struct slurmctld_resv *resv_ptr, char *users);
+static int  _update_uid_list(slurmctld_resv_t *resv_ptr, char *users);
 static void _validate_all_reservations(void);
 static int  _valid_job_access_resv(struct job_record *job_ptr,
 				   slurmctld_resv_t *resv_ptr);
@@ -189,6 +191,7 @@ static void _del_resv_rec(void *x)
 		for (i=0; i<resv_ptr->account_cnt; i++)
 			xfree(resv_ptr->account_list[i]);
 		xfree(resv_ptr->account_list);
+		xfree(resv_ptr->assoc_list);
 		xfree(resv_ptr->features);
 		xfree(resv_ptr->name);
 		if (resv_ptr->node_bitmap)
@@ -311,13 +314,112 @@ static bool _is_account_valid(char *account)
 	return true;
 }
 
+static int _append_assoc_list(List assoc_list, acct_association_rec_t *assoc)
+{
+	int rc = ESLURM_INVALID_BANK_ACCOUNT;
+	acct_association_rec_t *assoc_ptr = NULL;
+	if (assoc_mgr_fill_in_assoc(
+		    acct_db_conn, assoc,
+		    accounting_enforce, 
+		    &assoc_ptr)) {
+		if(accounting_enforce & ACCOUNTING_ENFORCE_ASSOCS) {
+			error("No association for user %u and account %s",
+			      assoc->uid, assoc->acct);
+		} else {
+			verbose("No association for user %u and account %s",
+				assoc->uid, assoc->acct);
+			rc = SLURM_SUCCESS;
+		}
+		
+	} 
+	if(assoc_ptr) {
+		info("got here");
+		list_append(assoc_list, assoc_ptr);
+		rc = SLURM_SUCCESS;
+	}
+
+	return rc;
+}
+/* Set a association list based upon accounts and users */
+static int _set_assoc_list(slurmctld_resv_t *resv_ptr)
+{
+	int rc = SLURM_SUCCESS, i = 0, j = 0;
+	List assoc_list = NULL;
+	acct_association_rec_t assoc, *assoc_ptr = NULL;
+
+	/* no need to do this if we can't ;) */
+	if(!association_based_accounting)
+		return rc;
+
+	assoc_list = list_create(NULL);
+
+	memset(&assoc, 0, sizeof(acct_association_rec_t));
+
+	if(resv_ptr->user_cnt) {
+		for(i=0; i < resv_ptr->user_cnt; i++) {
+			assoc.uid = (uint32_t)resv_ptr->user_list[i];
+			
+			if(resv_ptr->account_cnt) {
+				for(j=0; j < resv_ptr->account_cnt; j++) {
+					assoc.acct = resv_ptr->account_list[j];
+					if((rc = _append_assoc_list(
+						    assoc_list, &assoc))
+					   != SLURM_SUCCESS) {
+						goto end_it;
+					}
+				}	
+			} else {
+				if((rc = assoc_mgr_get_user_assocs(
+					    acct_db_conn, &assoc,
+					    accounting_enforce, assoc_list))
+				   != SLURM_SUCCESS) {
+					rc = ESLURM_INVALID_BANK_ACCOUNT;
+					goto end_it;
+				}
+			}
+		}
+	} else if(resv_ptr->account_cnt) {
+		assoc.uid = (uint32_t)NO_VAL;
+		for(i=0; i < resv_ptr->account_cnt; i++) {
+			assoc.acct = resv_ptr->account_list[j];
+			if((rc = _append_assoc_list(assoc_list, &assoc))
+			   != SLURM_SUCCESS) {
+				goto end_it;
+			}
+		}	
+	} else if(accounting_enforce & ACCOUNTING_ENFORCE_ASSOCS) {
+		error("We need at least 1 user or 1 account to "
+		      "create a reservtion.");
+		rc = SLURM_ERROR;
+	}
+	
+	if(list_count(assoc_list)) {
+		ListIterator itr = list_iterator_create(assoc_list);
+		xfree(resv_ptr->assoc_list);	/* clear for modify */
+		while((assoc_ptr = list_next(itr))) {
+			if(resv_ptr->assoc_list)
+				xstrfmtcat(resv_ptr->assoc_list, ",%u", 
+					   assoc_ptr->id);
+			else
+				xstrfmtcat(resv_ptr->assoc_list, "%u",
+					   assoc_ptr->id);
+		}
+		list_iterator_destroy(itr);
+	}
+
+end_it:
+	list_destroy(assoc_list);
+	return rc;
+}
+
 /* Post reservation create */
-static int _post_resv_create(struct slurmctld_resv *resv_ptr)
+static int _post_resv_create(slurmctld_resv_t *resv_ptr)
 {
 	int rc = SLURM_SUCCESS;
 	acct_reservation_rec_t resv;
 	memset(&resv, 0, sizeof(acct_reservation_rec_t));
 	
+	resv.assocs = resv_ptr->assoc_list;
 	resv.cluster = slurmctld_cluster_name;
 	resv.cpus = resv_ptr->cpu_cnt;
 	resv.flags = resv_ptr->flags;
@@ -332,7 +434,7 @@ static int _post_resv_create(struct slurmctld_resv *resv_ptr)
 }
 
 /* Note that a reservation has been deleted */
-static int _post_resv_delete(struct slurmctld_resv *resv_ptr)
+static int _post_resv_delete(slurmctld_resv_t *resv_ptr)
 {
 	int rc = SLURM_SUCCESS;
 	acct_reservation_rec_t resv;
@@ -351,21 +453,50 @@ static int _post_resv_delete(struct slurmctld_resv *resv_ptr)
 }
 
 /* Note that a reservation has been updated */
-static int _post_resv_update(struct slurmctld_resv *resv_ptr)
+static int _post_resv_update(slurmctld_resv_t *resv_ptr,
+			     slurmctld_resv_t *old_resv_ptr)
 {
 	int rc = SLURM_SUCCESS;
 	acct_reservation_rec_t resv;
 	memset(&resv, 0, sizeof(acct_reservation_rec_t));
-
+	
 	resv.cluster = slurmctld_cluster_name;
-	resv.cpus = resv_ptr->cpu_cnt;
-	resv.flags = resv_ptr->flags;
 	resv.id = resv_ptr->resv_id;
-	resv.nodes = resv_ptr->node_list;
 	resv.time_end = resv_ptr->end_time;
 	resv.time_start = resv_ptr->start_time;
 	resv.time_start_prev = resv_ptr->start_time_prev;
+	
+	if(!old_resv_ptr) {
+		resv.assocs = resv_ptr->assoc_list;
+		resv.cpus = resv_ptr->cpu_cnt;
+		resv.flags = resv_ptr->flags;
+		resv.nodes = resv_ptr->node_list;
+	} else {
+		if(old_resv_ptr->assoc_list && resv_ptr->assoc_list) {
+			if(strcmp(old_resv_ptr->assoc_list,
+				  resv_ptr->assoc_list))
+				resv.assocs = resv_ptr->assoc_list;
+		} else if(resv_ptr->assoc_list)
+			resv.assocs = resv_ptr->assoc_list;
+
+		if(old_resv_ptr->cpu_cnt != resv_ptr->cpu_cnt) 
+			resv.cpus = resv_ptr->cpu_cnt;
+		else 
+			resv.cpus = (uint32_t)NO_VAL;
+
+		if(old_resv_ptr->flags != resv_ptr->flags) 
+			resv.flags = resv_ptr->flags;
+		else 
+			resv.flags = (uint16_t)NO_VAL;
+
+		if(old_resv_ptr->node_list && resv_ptr->node_list) {
+			if(strcmp(old_resv_ptr->node_list,
+				  resv_ptr->node_list))
+				resv.nodes = resv_ptr->node_list;
+		} else if(resv_ptr->node_list)
+			resv.nodes = resv_ptr->node_list;
 
+	}
 	rc = acct_storage_g_modify_reservation(acct_db_conn, &resv);
 
 	return rc;
@@ -426,7 +557,7 @@ static int _build_account_list(char *accounts, int *account_cnt,
  * IN accounts     - a list of account names, to set, add, or remove
  * RETURN 0 on success
  */
-static int  _update_account_list(struct slurmctld_resv *resv_ptr, 
+static int  _update_account_list(slurmctld_resv_t *resv_ptr, 
 				 char *accounts)
 {
 	char *last = NULL, *ac_cpy, *tok;
@@ -618,7 +749,7 @@ static int _build_uid_list(char *users, int *user_cnt, uid_t **user_list)
  * IN users        - a list of user names, to set, add, or remove
  * RETURN 0 on success
  */
-static int _update_uid_list(struct slurmctld_resv *resv_ptr, char *users)
+static int _update_uid_list(slurmctld_resv_t *resv_ptr, char *users)
 {
 	char *last = NULL, *u_cpy = NULL, *tmp = NULL, *tok;
 	int u_cnt = 0, i, j, k;
@@ -766,7 +897,7 @@ static int _update_uid_list(struct slurmctld_resv *resv_ptr, char *users)
  *	to _unpack_reserve_info_members() in common/slurm_protocol_pack.c
  *	plus load_all_resv_state() below.
  */
-static void _pack_resv(struct slurmctld_resv *resv_ptr, Buf buffer, 
+static void _pack_resv(slurmctld_resv_t *resv_ptr, Buf buffer, 
 		       bool internal)
 {
 	packstr(resv_ptr->accounts,	buffer);
@@ -781,9 +912,10 @@ static void _pack_resv(struct slurmctld_resv *resv_ptr, Buf buffer,
 	packstr(resv_ptr->users,	buffer);
 
 	if (internal) {
-		pack32(resv_ptr->cpu_cnt,		buffer);
+		packstr(resv_ptr->assoc_list,	buffer);
+		pack32(resv_ptr->cpu_cnt,	buffer);
+		pack32(resv_ptr->resv_id,	buffer);
 		pack_time(resv_ptr->start_time_prev,	buffer);
-		pack32(resv_ptr->resv_id,		buffer);
 	}
 }
 
@@ -794,7 +926,7 @@ static void _pack_resv(struct slurmctld_resv *resv_ptr, Buf buffer,
  */
 static bool _resv_overlap(time_t start_time, time_t end_time, 
 			  uint16_t flags, bitstr_t *node_bitmap,
-			  struct slurmctld_resv *this_resv_ptr)
+			  slurmctld_resv_t *this_resv_ptr)
 {
 	ListIterator iter;
 	slurmctld_resv_t *resv_ptr;
@@ -846,7 +978,7 @@ static bool _resv_overlap(time_t start_time, time_t end_time,
 
 /* Set a reservation's CPU count. Requires that the reservation's
  *	node_bitmap be set. */
-static void _set_cpu_cnt(struct slurmctld_resv *resv_ptr)
+static void _set_cpu_cnt(slurmctld_resv_t *resv_ptr)
 {
 	int i;
 	uint32_t cpu_cnt = 0;
@@ -1018,6 +1150,8 @@ extern int create_resv(reserve_request_msg_t *resv_desc_ptr)
 	resv_ptr->user_list	= user_list;
 	resv_desc_ptr->users 	= NULL;		/* Nothing left to free */
 	_set_cpu_cnt(resv_ptr);
+	if((rc = _set_assoc_list(resv_ptr)) != SLURM_SUCCESS)
+		goto bad_parse;
 
 	/* This needs to be done after all other setup is done. */
 	_post_resv_create(resv_ptr);
@@ -1201,6 +1335,8 @@ extern int update_resv(reserve_request_msg_t *resv_desc_ptr)
 		goto update_failure;
 	}
 	_set_cpu_cnt(resv_ptr);
+	if((error_code = _set_assoc_list(resv_ptr)) != SLURM_SUCCESS)
+		goto update_failure;
 
 	slurm_make_time_str(&resv_ptr->start_time, start_time, 
 			    sizeof(start_time));
@@ -1210,8 +1346,8 @@ extern int update_resv(reserve_request_msg_t *resv_desc_ptr)
 	     resv_ptr->name, resv_ptr->accounts, resv_ptr->users, 
 	     resv_ptr->node_list, start_time, end_time);
 
+	_post_resv_update(resv_ptr, resv_backup);
 	_del_resv_rec(resv_backup);
-	_post_resv_update(resv_ptr);
 	last_resv_update = now;
 	schedule_resv_save();
 	return error_code;
@@ -1518,6 +1654,7 @@ static void _validate_all_reservations(void)
 			_clear_job_resv(resv_ptr);
 			list_delete_item(iter);
 		} else {
+			_set_assoc_list(resv_ptr);
 			tmp = strrchr(resv_ptr->name, '_');
 			if (tmp) {
 				res_num = atoi(tmp + 1);
@@ -1651,9 +1788,11 @@ extern int load_all_resv_state(int recover)
 		safe_unpackstr_xmalloc(&resv_ptr->users,&uint32_tmp, buffer);
 
 		/* Fields saved for internal use only (save state) */
+		safe_unpackstr_xmalloc(&resv_ptr->assoc_list,	
+				       &uint32_tmp,	buffer);
 		safe_unpack32(&resv_ptr->cpu_cnt,	buffer);
 		safe_unpack32(&resv_ptr->resv_id,	buffer);
-		safe_unpack_time(&resv_ptr->start_time_prev,	buffer);
+		safe_unpack_time(&resv_ptr->start_time_prev, buffer);
 
 		list_append(resv_list, resv_ptr);
 		info("Recovered state of reservation %s", resv_ptr->name);
@@ -2119,7 +2258,7 @@ extern void fini_job_resv_check(void)
 			resv_ptr->start_time_prev = resv_ptr->start_time;
 			resv_ptr->start_time += 24 * 60 * 60;
 			resv_ptr->end_time   += 24 * 60 * 60;
-			_post_resv_update(resv_ptr);
+			_post_resv_update(resv_ptr, NULL);
 			last_resv_update = now;
 			schedule_resv_save();
 			continue;
@@ -2131,7 +2270,7 @@ extern void fini_job_resv_check(void)
 			resv_ptr->start_time_prev = resv_ptr->start_time;
 			resv_ptr->start_time += 7 * 24 * 60 * 60;
 			resv_ptr->end_time   += 7 * 24 * 60 * 60;
-			_post_resv_update(resv_ptr);
+			_post_resv_update(resv_ptr, NULL);
 			last_resv_update = now;
 			schedule_resv_save();
 			continue;
diff --git a/src/slurmctld/slurmctld.h b/src/slurmctld/slurmctld.h
index 68a4296d47358cdcb8a61b971886b78fd8a15f12..d518d5d32a50fcbf16762f8744a95ca2fecc4e1b 100644
--- a/src/slurmctld/slurmctld.h
+++ b/src/slurmctld/slurmctld.h
@@ -310,6 +310,7 @@ typedef struct slurmctld_resv {
 	char *accounts;		/* names of accounts permitted to use	*/
 	int account_cnt;	/* count of accounts permitted to use	*/
 	char **account_list;	/* list of accounts permitted to use	*/
+	char *assoc_list;	/* list of associations			*/
 	uint32_t cpu_cnt;	/* number of reserved CPUs		*/
 	time_t end_time;	/* end time of reservation		*/
 	char *features;		/* required node features		*/