/* * _build_sinfo_data - make a sinfo_data entry for each unique node * configuration and add it to the sinfo_list for later printing. * sinfo_list IN/OUT - list of unique sinfo_data records to report * partition_msg IN - partition info message * node_msg IN - node info message * RET zero or error code */ static int _build_sinfo_data(List sinfo_list, partition_info_msg_t *partition_msg, node_info_msg_t *node_msg) { pthread_attr_t attr_sinfo; pthread_t thread_sinfo; build_part_info_t *build_struct_ptr; node_info_t *node_ptr = NULL; partition_info_t *part_ptr = NULL; int j; g_node_scaling = node_msg->node_scaling; /* by default every partition is shown, even if no nodes */ if ((!params.node_flag) && params.match_flags.partition_flag) { part_ptr = partition_msg->partition_array; for (j=0; j<partition_msg->record_count; j++, part_ptr++) { if ((!params.partition) || (_strcmp(params.partition, part_ptr->name) == 0)) { list_append(sinfo_list, _create_sinfo( part_ptr, (uint16_t) j, NULL, node_msg->node_scaling)); } } } if (params.filtering) { for (j = 0; j < node_msg->record_count; j++) { node_ptr = &(node_msg->node_array[j]); if (node_ptr->name && _filter_out(node_ptr)) xfree(node_ptr->name); } } /* make sinfo_list entries for every node in every partition */ for (j=0; j<partition_msg->record_count; j++, part_ptr++) { part_ptr = &(partition_msg->partition_array[j]); if (params.filtering && params.partition && _strcmp(part_ptr->name, params.partition)) continue; if (node_msg->record_count == 1) { /* node_name_single */ int pos = -1; uint16_t subgrp_size = 0; hostlist_t hl; node_ptr = &(node_msg->node_array[0]); if ((node_ptr->name == NULL) || (part_ptr->nodes == NULL)) continue; hl = hostlist_create(part_ptr->nodes); pos = hostlist_find(hl, node_msg->node_array[0].name); hostlist_destroy(hl); if (pos < 0) continue; if (select_g_select_nodeinfo_get( node_ptr->select_nodeinfo, SELECT_NODEDATA_SUBGRP_SIZE, 0, &subgrp_size) == SLURM_SUCCESS && subgrp_size) { _handle_subgrps(sinfo_list, (uint16_t) j, part_ptr, node_ptr, node_msg-> node_scaling); } else { _insert_node_ptr(sinfo_list, (uint16_t) j, part_ptr, node_ptr, node_msg-> node_scaling); } continue; } /* Process each partition using a separate thread */ build_struct_ptr = xmalloc(sizeof(build_part_info_t)); build_struct_ptr->node_msg = node_msg; build_struct_ptr->part_num = (uint16_t) j; build_struct_ptr->part_ptr = part_ptr; build_struct_ptr->sinfo_list = sinfo_list; slurm_mutex_lock(&sinfo_cnt_mutex); sinfo_cnt++; slurm_mutex_unlock(&sinfo_cnt_mutex); slurm_attr_init(&attr_sinfo); if (pthread_attr_setdetachstate (&attr_sinfo, PTHREAD_CREATE_DETACHED)) error("pthread_attr_setdetachstate error %m"); while (pthread_create(&thread_sinfo, &attr_sinfo, _build_part_info, (void *) build_struct_ptr)) { error("pthread_create error %m"); usleep(10000); /* sleep and retry */ } slurm_attr_destroy(&attr_sinfo); } slurm_mutex_lock(&sinfo_cnt_mutex); while (sinfo_cnt) { pthread_cond_wait(&sinfo_cnt_cond, &sinfo_cnt_mutex); } slurm_mutex_unlock(&sinfo_cnt_mutex); _sort_hostlist(sinfo_list); return SLURM_SUCCESS; }
static int _handle_subgrps(List sinfo_list, uint16_t part_num, partition_info_t *part_ptr, node_info_t *node_ptr, uint32_t node_scaling) { uint16_t size; int *node_state; int i=0, state_cnt = 2; ListIterator iterator = NULL; enum node_states state[] = { NODE_STATE_ALLOCATED, NODE_STATE_ERROR }; /* If we ever update the hostlist stuff to support this stuff * then we can use this to tack on the end of the node name * the subgrp stuff. On bluegene systems this would be nice * to see the ionodes in certain states. * When asking for nodes that are reserved, we need to return * all states of those nodes. */ if (params.state_list) iterator = list_iterator_create(params.state_list); for(i=0; i<state_cnt; i++) { if (iterator) { node_info_t tmp_node, *tmp_node_ptr = &tmp_node; while ((node_state = list_next(iterator))) { tmp_node_ptr->node_state = *node_state; if ((((state[i] == NODE_STATE_ALLOCATED) && IS_NODE_DRAINING(tmp_node_ptr)) || (*node_state == NODE_STATE_DRAIN)) || (*node_state == state[i]) || (*node_state == NODE_STATE_RES)) break; } list_iterator_reset(iterator); if (!node_state) continue; } if (select_g_select_nodeinfo_get(node_ptr->select_nodeinfo, SELECT_NODEDATA_SUBCNT, state[i], &size) == SLURM_SUCCESS && size) { node_scaling -= size; node_ptr->node_state &= NODE_STATE_FLAGS; node_ptr->node_state |= state[i]; _insert_node_ptr(sinfo_list, part_num, part_ptr, node_ptr, size); } } /* now handle the idle */ if (iterator) { while ((node_state = list_next(iterator))) { node_info_t tmp_node, *tmp_node_ptr = &tmp_node; tmp_node_ptr->node_state = *node_state; if (((*node_state == NODE_STATE_DRAIN) || IS_NODE_DRAINED(tmp_node_ptr)) || (*node_state == NODE_STATE_IDLE) || (*node_state == NODE_STATE_RES)) break; } list_iterator_destroy(iterator); if (!node_state) return SLURM_SUCCESS; } node_ptr->node_state &= NODE_STATE_FLAGS; node_ptr->node_state |= NODE_STATE_IDLE; if ((int)node_scaling > 0) _insert_node_ptr(sinfo_list, part_num, part_ptr, node_ptr, node_scaling); return SLURM_SUCCESS; }
/* Build information about a partition using one pthread per partition */ void *_build_part_info(void *args) { build_part_info_t *build_struct_ptr; List sinfo_list; partition_info_t *part_ptr; node_info_msg_t *node_msg; node_info_t *node_ptr = NULL; uint16_t part_num; int j = 0; if (_serial_part_data()) slurm_mutex_lock(&sinfo_list_mutex); build_struct_ptr = (build_part_info_t *) args; sinfo_list = build_struct_ptr->sinfo_list; part_num = build_struct_ptr->part_num; part_ptr = build_struct_ptr->part_ptr; node_msg = build_struct_ptr->node_msg; while (part_ptr->node_inx[j] >= 0) { int i = 0; uint16_t subgrp_size = 0; for (i = part_ptr->node_inx[j]; i <= part_ptr->node_inx[j+1]; i++) { if (i >= node_msg->record_count) { /* If info for single node name is loaded */ break; } node_ptr = &(node_msg->node_array[i]); if (node_ptr->name == NULL) continue; if (select_g_select_nodeinfo_get( node_ptr->select_nodeinfo, SELECT_NODEDATA_SUBGRP_SIZE, 0, &subgrp_size) == SLURM_SUCCESS && subgrp_size) { _handle_subgrps(sinfo_list, part_num, part_ptr, node_ptr, node_msg->node_scaling); } else { _insert_node_ptr(sinfo_list, part_num, part_ptr, node_ptr, node_msg->node_scaling); } } j += 2; } xfree(args); if (_serial_part_data()) slurm_mutex_unlock(&sinfo_list_mutex); slurm_mutex_lock(&sinfo_cnt_mutex); if (sinfo_cnt > 0) { sinfo_cnt--; } else { error("sinfo_cnt underflow"); sinfo_cnt = 0; } pthread_cond_broadcast(&sinfo_cnt_cond); slurm_mutex_unlock(&sinfo_cnt_mutex); return NULL; }
/* * _build_sinfo_data - make a sinfo_data entry for each unique node * configuration and add it to the sinfo_list for later printing. * sinfo_list IN/OUT - list of unique sinfo_data records to report * partition_msg IN - partition info message * node_msg IN - node info message * RET zero or error code */ static int _build_sinfo_data(List sinfo_list, partition_info_msg_t *partition_msg, node_info_msg_t *node_msg) { node_info_t *node_ptr = NULL; partition_info_t *part_ptr = NULL; int j, j2; g_node_scaling = node_msg->node_scaling; /* by default every partition is shown, even if no nodes */ if ((!params.node_flag) && params.match_flags.partition_flag) { part_ptr = partition_msg->partition_array; for (j=0; j<partition_msg->record_count; j++, part_ptr++) { if ((!params.partition) || (_strcmp(params.partition, part_ptr->name) == 0)) { list_append(sinfo_list, _create_sinfo( part_ptr, (uint16_t) j, NULL, node_msg->node_scaling)); } } } /* make sinfo_list entries for every node in every partition */ for (j=0; j<partition_msg->record_count; j++, part_ptr++) { part_ptr = &(partition_msg->partition_array[j]); if (params.filtering && params.partition && _strcmp(part_ptr->name, params.partition)) continue; j2 = 0; while (part_ptr->node_inx[j2] >= 0) { int i2 = 0; uint16_t subgrp_size = 0; for (i2 = part_ptr->node_inx[j2]; i2 <= part_ptr->node_inx[j2+1]; i2++) { if (i2 >= node_msg->record_count) { /* This can happen if info for single * node name is loaded */ break; } node_ptr = &(node_msg->node_array[i2]); if ((node_ptr->name == NULL) || (params.filtering && _filter_out(node_ptr))) continue; if (select_g_select_nodeinfo_get( node_ptr->select_nodeinfo, SELECT_NODEDATA_SUBGRP_SIZE, 0, &subgrp_size) == SLURM_SUCCESS && subgrp_size) { _handle_subgrps(sinfo_list, (uint16_t) j, part_ptr, node_ptr, node_msg-> node_scaling); } else { _insert_node_ptr(sinfo_list, (uint16_t) j, part_ptr, node_ptr, node_msg-> node_scaling); } } j2 += 2; } } _sort_hostlist(sinfo_list); return SLURM_SUCCESS; }