/** * * @brief update all node partitions of all queues on the server * @note Call update_all_nodepart() after all nodes have been processed * by update_node_on_end/update_node_on_run * * @param[in] policy - policy info * @param[in] sinfo - server info * @param[in] flags - flags to modify behavior * NO_ALLPART - do not update the metadata in the allpart. * There are circumstances (e.g., calendaring) where * the allpart provides limited use and will constantly * be updated. It is best to just skip it. * * @return nothing * */ void update_all_nodepart(status *policy, server_info *sinfo, unsigned int flags) { queue_info *qinfo; int i; if (sinfo == NULL || sinfo->queues == NULL) return; if(sinfo->allpart == NULL) return; if (sinfo->node_group_enable && sinfo->node_group_key != NULL) { node_partition_update_array(policy, sinfo->nodepart); qsort(sinfo->nodepart, sinfo->num_parts, sizeof(node_partition *), cmp_placement_sets); } /* Update and resort the placement sets on the queues */ for (i = 0; sinfo->queues[i] != NULL; i++) { qinfo = sinfo->queues[i]; if (sinfo->node_group_enable && qinfo->node_group_key != NULL) { node_partition_update_array(policy, qinfo->nodepart); qsort(qinfo->nodepart, qinfo->num_parts, sizeof(node_partition *), cmp_placement_sets); } if ((flags & NO_ALLPART) == 0) { if(qinfo->allpart != NULL && qinfo->allpart->res == NULL) node_partition_update(policy, qinfo->allpart); } } /* Update and resort the hostsets */ node_partition_update_array(policy, sinfo->hostsets); if (policy->node_sort[0].res_name != NULL && conf.node_sort_unused && sinfo->hostsets != NULL) { /* Resort the nodes in host sets to correctly reflect unused resources */ qsort(sinfo->hostsets, sinfo->num_hostsets, sizeof(node_partition*), multi_nodepart_sort); } if ((flags & NO_ALLPART) == 0) node_partition_update(policy, sinfo->allpart); sinfo->pset_metadata_stale = 0; }
/** * * @brief update all node partitions of all queues on the server * @note Call update_all_nodepart() after all nodes have been processed * by update_node_on_end/update_node_on_run * * @param[in] policy - policy info * @param[in] sinfo - server info * @param[in] resresv- the job that was just run * * @return nothing * */ void update_all_nodepart(status *policy, server_info *sinfo, resource_resv *resresv) { queue_info *qinfo; int update_allpart = 1; int i; if (sinfo == NULL || sinfo->queues == NULL) return; if(sinfo->allpart == NULL) return; if (resresv != NULL && resresv ->is_job) { if (resresv->job != NULL) { queue_info *job_queue; job_queue = resresv->job->queue; if (job_queue->has_nodes) { update_allpart = 0; node_partition_update(policy, job_queue->allpart); } } } if (update_allpart || sinfo->allpart->res == NULL) node_partition_update(policy, sinfo->allpart); node_partition_update_array(policy, sinfo->hostsets); if (policy->node_sort[0].res_name != NULL && conf.node_sort_unused && sinfo->hostsets != NULL) { /* Resort the nodes in host sets to correctly reflect unused resources */ qsort(sinfo->hostsets, sinfo->num_hostsets, sizeof(node_partition*), multi_nodepart_sort); } for (i = 0; sinfo->queues[i] != NULL; i++) { qinfo = sinfo->queues[i]; if (qinfo->node_group_key) { node_partition_update_array(policy, qinfo->nodepart); qsort(qinfo->nodepart, qinfo->num_parts, sizeof(node_partition *), cmp_placement_sets); } if(qinfo->allpart != NULL && qinfo->allpart->res == NULL) node_partition_update(policy, qinfo->allpart); } }
/** * @brief * create_specific_nodepart - create a node partition with specific * nodes, rather than from a placement * set resource=value * * @param[in] policy - policy info * @param[in] name - the name of the node partition * @param[in] nodes - the nodes to create the placement set with * * @return node_partition * - the node partition * @NULL : on error */ node_partition * create_specific_nodepart(status *policy, char *name, node_info **nodes) { node_partition *np; int i, j; int cnt; if (name == NULL || nodes == NULL) return NULL; np = new_node_partition(); if (np == NULL) return NULL; cnt = count_array((void **) nodes); np->name = string_dup(name); np->def = NULL; np->res_val = string_dup("none"); np->rank = get_sched_rank(); np->ninfo_arr = malloc((cnt + 1) * sizeof(node_info*)); if (np->ninfo_arr == NULL) { log_err(errno, __func__, MEM_ERR_MSG); free_node_partition(np); return NULL; } j = 0; for (i = 0; i < cnt; i++) { if (!nodes[i]->is_stale) { np->ninfo_arr[j] = nodes[i]; j++; } } np->tot_nodes = j; np->ninfo_arr[np->tot_nodes] = NULL; if (node_partition_update(policy, np) == 0) { free_node_partition(np); return NULL; } return np; }
/** * @brief * update metadata for an entire array of node partitions * * @param[in] policy - policy info * @param[in] nodepart - partition array to update * @param[in] ninfo_arr - nodes being updated (may be NULL) * * @return int * @retval 1 : on all success * @retval 0 : on any failure * * @note * This is not an atomic operation -- this means that if this * function fails, some node partitions may have been updated and * others not. * */ int node_partition_update_array(status *policy, node_partition **nodepart) { int i; int cur_rc = 0; int rc = 1; if (policy == NULL || nodepart == NULL) return 0; for (i = 0; nodepart[i] != NULL; i++) { cur_rc = node_partition_update(policy, nodepart[i]); if (cur_rc == 0) rc = 0; update_buckets_for_node_array(nodepart[i]->bkts, nodepart[i]->ninfo_arr); } return rc; }
/** * @brief * update metadata for an entire array of node partitions * * @param[in] policy - policy info * @param[in] nodepart - partition array to update * * @return int * @retval 1 : on all success * @retval 0 : on any failure * * @note * This is not an atomic operation -- this means that if this * function fails, some node partitions may have been updated and * others not. * */ int node_partition_update_array(status *policy, node_partition **nodepart) { int i; int cur_rc = 0; int rc = 1; if (nodepart == NULL) return 0; for (i = 0; nodepart[i] != NULL; i++) { cur_rc = node_partition_update(policy, nodepart[i]); if (cur_rc == 0) rc = 0; } return rc; }