From 43d9ac737a10083e0c8c90eba3f0873158c41f1d Mon Sep 17 00:00:00 2001
From: Morris Jette <jette@schedmd.com>
Date: Thu, 10 Apr 2014 13:25:59 -0700
Subject: [PATCH] Add and populate gres type data structure

---
 src/common/gres.c | 78 ++++++++++++++++++++++++++++++++++++++++++-----
 src/common/gres.h |  5 +++
 2 files changed, 76 insertions(+), 7 deletions(-)

diff --git a/src/common/gres.c b/src/common/gres.c
index 908551c6754..ff241cfde09 100644
--- a/src/common/gres.c
+++ b/src/common/gres.c
@@ -1202,7 +1202,7 @@ static void _gres_node_list_delete(void *list_element)
 	gres_ptr = (gres_state_t *) list_element;
 	gres_node_ptr = (gres_node_state_t *) gres_ptr->gres_data;
 	FREE_NULL_BITMAP(gres_node_ptr->gres_bit_alloc);
-	for (i=0; i<gres_node_ptr->topo_cnt; i++) {
+	for (i = 0; i < gres_node_ptr->topo_cnt; i++) {
 		FREE_NULL_BITMAP(gres_node_ptr->topo_cpus_bitmap[i]);
 		FREE_NULL_BITMAP(gres_node_ptr->topo_gres_bitmap[i]);
 		xfree(gres_node_ptr->topo_model[i]);
@@ -1212,6 +1212,14 @@ static void _gres_node_list_delete(void *list_element)
 	xfree(gres_node_ptr->topo_gres_cnt_alloc);
 	xfree(gres_node_ptr->topo_gres_cnt_avail);
 	xfree(gres_node_ptr->topo_model);
+	for (i = 0; i < gres_node_ptr->type_cnt; i++) {
+		xfree(gres_node_ptr->type_cnt_alloc[i]);
+		xfree(gres_node_ptr->type_cnt_avail[i]);
+		xfree(gres_node_ptr->type_model[i]);
+	}
+	xfree(gres_node_ptr->type_cnt_alloc);
+	xfree(gres_node_ptr->type_cnt_avail);
+	xfree(gres_node_ptr->type_model);
 	xfree(gres_node_ptr);
 	xfree(gres_ptr);
 }
@@ -1231,8 +1239,10 @@ static void _get_gres_cnt(gres_node_state_t *gres_data, char *orig_config,
 			  char *gres_name, char *gres_name_colon,
 			  int gres_name_colon_len)
 {
-	char *node_gres_config, *tok, *num, *last_num = NULL, *last_tok = NULL;
+	char *node_gres_config, *tok, *last_tok = NULL;
+	char *type, *num, *last_num = NULL;
 	uint32_t gres_config_cnt = 0, tmp_gres_cnt = 0;
+	int i;
 
 	xassert(gres_data);
 	if (orig_config == NULL) {
@@ -1240,6 +1250,10 @@ static void _get_gres_cnt(gres_node_state_t *gres_data, char *orig_config,
 		return;
 	}
 
+	for (i = 0; i < gres_data->type_cnt; i++) {
+		gres_data->type_cnt_avail[i] = 0;
+	}
+
 	node_gres_config = xstrdup(orig_config);
 	tok = strtok_r(node_gres_config, ",", &last_tok);
 	while (tok) {
@@ -1248,13 +1262,13 @@ static void _get_gres_cnt(gres_node_state_t *gres_data, char *orig_config,
 			break;
 		}
 		if (!strncmp(tok, gres_name_colon, gres_name_colon_len)) {
+			type = strchr(tok, ':');
 			num = strrchr(tok, ':');
 			if (!num) {
 				error("Bad GRES configuration: %s", tok);
 				break;
 			}
-			num++;
-			tmp_gres_cnt = strtol(num, &last_num, 10);
+			tmp_gres_cnt = strtol(num + 1, &last_num, 10);
 			if (last_num[0] == '\0')
 				;
 			else if ((last_num[0] == 'k') || (last_num[0] == 'K'))
@@ -1264,6 +1278,38 @@ static void _get_gres_cnt(gres_node_state_t *gres_data, char *orig_config,
 			else if ((last_num[0] == 'g') || (last_num[0] == 'G'))
 				tmp_gres_cnt *= (1024 * 1024 * 1024);
 			gres_config_cnt += tmp_gres_cnt;
+			if (type != num) {
+				num[0] = '\0';
+				type++;
+				for (i = 0; i < gres_data->type_cnt; i++) {
+					if (strcmp(gres_data->type_model[i],
+						   type))
+						continue;
+					gres_data->type_cnt_avail[i] +=
+						tmp_gres_cnt;
+					break;
+				}
+				if (i >= gres_data->type_cnt) {
+					gres_data->type_cnt++;
+					gres_data->type_cnt_alloc =
+						xrealloc(gres_data->
+							 type_cnt_alloc,
+							 sizeof(uint32_t) *
+							 gres_data->type_cnt);
+					gres_data->type_cnt_avail =
+						xrealloc(gres_data->
+							 type_cnt_avail,
+							 sizeof(uint32_t) *
+							 gres_data->type_cnt);
+					gres_data->type_model =
+						xrealloc(gres_data->type_model,
+							 sizeof(char *) *
+							 gres_data->type_cnt);
+					gres_data->type_cnt_avail[i] +=
+						tmp_gres_cnt;
+					gres_data->type_model[i] = xstrdup(type);
+				}
+			}
 		}
 		tok = strtok_r(NULL, ",", &last_tok);
 	}
@@ -1717,7 +1763,6 @@ static int _node_reconfig(char *node_name, char *orig_config, char **new_config,
 	if (gres_ptr->gres_data == NULL)
 		gres_ptr->gres_data = _build_gres_node_state();
 	gres_data = gres_ptr->gres_data;
-
 	_get_gres_cnt(gres_data, orig_config,
 		      context_ptr->gres_name,
 		      context_ptr->gres_name_colon,
@@ -1969,7 +2014,7 @@ static void *_node_state_dup(void *gres_data)
 	new_gres->topo_gres_cnt_avail = xmalloc(gres_ptr->topo_cnt *
 						sizeof(uint32_t));
 	new_gres->topo_model = xmalloc(gres_ptr->topo_cnt * sizeof(char *));
-	for (i=0; i<gres_ptr->topo_cnt; i++) {
+	for (i = 0; i < gres_ptr->topo_cnt; i++) {
 		if (gres_ptr->topo_cpus_bitmap[i]) {
 			new_gres->topo_cpus_bitmap[i] =
 				bit_copy(gres_ptr->topo_cpus_bitmap[i]);
@@ -1982,6 +2027,18 @@ static void *_node_state_dup(void *gres_data)
 			gres_ptr->topo_gres_cnt_avail[i];
 		new_gres->topo_model[i] = xstrdup(gres_ptr->topo_model[i]);
 	}
+
+	new_gres->type_cnt       = gres_ptr->type_cnt;
+	new_gres->type_cnt_alloc = xmalloc(gres_ptr->type_cnt *
+					   sizeof(uint32_t));
+	new_gres->type_cnt_avail = xmalloc(gres_ptr->type_cnt *
+					   sizeof(uint32_t));
+	new_gres->type_model = xmalloc(gres_ptr->type_cnt * sizeof(char *));
+	for (i = 0; i < gres_ptr->type_cnt; i++) {
+		new_gres->type_cnt_alloc[i] = gres_ptr->type_cnt_alloc[i];
+		new_gres->type_cnt_avail[i] = gres_ptr->type_cnt_avail[i];
+		new_gres->type_model[i] = xstrdup(gres_ptr->type_model[i]);
+	}
 	return new_gres;
 }
 
@@ -2116,7 +2173,7 @@ static void _node_state_log(void *gres_data, char *node_name, char *gres_name)
 	} else {
 		info("  gres_bit_alloc:NULL");
 	}
-	for (i=0; i<gres_node_ptr->topo_cnt; i++) {
+	for (i = 0; i < gres_node_ptr->topo_cnt; i++) {
 		if (gres_node_ptr->topo_cpus_bitmap[i]) {
 			bit_fmt(tmp_str, sizeof(tmp_str),
 				gres_node_ptr->topo_cpus_bitmap[i]);
@@ -2135,6 +2192,13 @@ static void _node_state_log(void *gres_data, char *node_name, char *gres_name)
 		     gres_node_ptr->topo_gres_cnt_avail[i]);
 		info("  type[%d]:%s", i, gres_node_ptr->topo_model[i]);
 	}
+	for (i = 0; i < gres_node_ptr->type_cnt; i++) {
+		info("  type_cnt_alloc[%d]:%u", i,
+		     gres_node_ptr->type_cnt_alloc[i]);
+		info("  type_cnt_avail[%d]:%u", i,
+		     gres_node_ptr->type_cnt_avail[i]);
+		info("  type[%d]:%s", i, gres_node_ptr->type_model[i]);
+	}
 }
 
 /*
diff --git a/src/common/gres.h b/src/common/gres.h
index 0b48798cd17..0368f9b5efc 100644
--- a/src/common/gres.h
+++ b/src/common/gres.h
@@ -99,6 +99,11 @@ typedef struct gres_node_state {
 	uint32_t *topo_gres_cnt_alloc;
 	uint32_t *topo_gres_cnt_avail;
 	char **topo_model;	/* Type of this gres (e.g. model name) */
+
+	uint16_t type_cnt;
+	char **type_model;	/* Type of this gres (e.g. model name) */
+	uint32_t *type_cnt_alloc;
+	uint32_t *type_cnt_avail;
 } gres_node_state_t;
 
 /* Gres job state as used by slurmctld daemon */
-- 
GitLab