/** * @brief * dup_node_partition - duplicate a node_partition structure * * @param[in] onp - the node_partition structure to duplicate * @param[in] nsinfo - server for the new node partiton (the nodes are needed) * * @return duplicated node_partition * @retval NULL : on error * */ node_partition * dup_node_partition(node_partition *onp, server_info *nsinfo) { node_partition *nnp; if (onp == NULL) return NULL; if ((nnp = new_node_partition()) == NULL) return NULL; if (onp->name != NULL) nnp->name = string_dup(onp->name); if (onp->def != NULL) nnp->def = onp->def; if (onp->res_val != NULL) nnp->res_val = string_dup(onp->res_val); nnp->ok_break = onp->ok_break; nnp->excl = onp->excl; nnp->tot_nodes = onp->tot_nodes; nnp->free_nodes = onp->free_nodes; nnp->res = dup_resource_list(onp->res); #ifdef NAS /* localmod 049 */ nnp->ninfo_arr = copy_node_ptr_array(onp->ninfo_arr, nsinfo->nodes, nsinfo); #else nnp->ninfo_arr = copy_node_ptr_array(onp->ninfo_arr, nsinfo->nodes); #endif nnp->bkts = dup_node_bucket_array(onp->bkts, nsinfo); nnp->rank = onp->rank; /* validity check */ if (onp->name == NULL || onp->res_val == NULL || nnp->res == NULL || nnp->ninfo_arr == NULL) { free_node_partition(nnp); return NULL; } return nnp; }
/** * @brief * simulate the minimum amount of a resource list * for an event list until a point in time. The * comparison we are simulating the minimum for is * (resources_available.foo - resources_assigned.foo) * The minimum is simulated by holding resources_available * constant and maximizing the resources_assigned value * * @note * This function only simulates START and END events. If at some * point in the future we start simulating events such as * qmgr -c 's s resources_available.ncpus + =5' this function will * will have to be revisited. * * @param[in] reslist - resource list to simulate * @param[in] end - end time * @param[in] calendar - calendar to simulate * @param[in] incl_arr - only use events for resresvs in this array (can be NULL) * @param[in] exclude - job/resv to ignore (possibly NULL) * * @return static pointer to amount of resources available during * @retval the entire length from now to end * @retval NULL : on error * * @par MT-safe: No */ schd_resource * simulate_resmin(schd_resource *reslist, time_t end, event_list *calendar, resource_resv **incl_arr, resource_resv *exclude) { static schd_resource *retres = NULL; /* return pointer */ schd_resource *cur_res; schd_resource *cur_resmin; resource_req *req; schd_resource *res; schd_resource *resmin = NULL; timed_event *te; resource_resv *resresv; unsigned int event_mask = (TIMED_RUN_EVENT | TIMED_END_EVENT); if (reslist == NULL) return NULL; /* if there is no calendar, then there is nothing to do */ if (calendar == NULL) return reslist; /* If there are no run events in the calendar between now and the end time * then there is nothing to do. Nothing will reduce resources (only increase) */ if (exists_run_event(calendar, end) == 0) return reslist; if (retres != NULL) { free_resource_list(retres); retres = NULL; } if ((res = dup_resource_list(reslist)) == NULL) return NULL; if ((resmin = dup_resource_list(reslist)) == NULL) { free_resource_list(res); return NULL; } te = get_next_event(calendar); for (te = find_init_timed_event(te, IGNORE_DISABLED_EVENTS, event_mask); te != NULL && (end == 0 || te->event_time < end); te = find_next_timed_event(te, IGNORE_DISABLED_EVENTS, event_mask)) { resresv = (resource_resv*) te->event_ptr; if (incl_arr == NULL || find_resource_resv_by_rank(incl_arr, resresv->rank) !=NULL) { if (resresv != exclude) { req = resresv->resreq; for (; req != NULL; req = req->next) { if (req->type.is_consumable) { cur_res = find_alloc_resource(res, req->def); if (cur_res == NULL) { free_resource_list(res); free_resource_list(resmin); return NULL; } if (te->event_type == TIMED_RUN_EVENT) cur_res->assigned += req->amount; else cur_res->assigned -= req->amount; cur_resmin = find_alloc_resource(resmin, req->def); if (cur_resmin == NULL) { free_resource_list(res); free_resource_list(resmin); return NULL; } if (cur_res->assigned > cur_resmin->assigned) cur_resmin->assigned = cur_res->assigned; } } } } } free_resource_list(res); retres = resmin; return retres; }
/** * @brief * dup_queue_info - duplicate a queue_info structure * * @param[in] oqinfo - the queue_info to copy * @param[in] nsinfo - the server which owns the duplicated queue * * @return duplicated queue_info struct * @retval NULL : on error * */ queue_info * dup_queue_info(queue_info *oqinfo, server_info *nsinfo) { queue_info *nqinfo; if ((nqinfo = new_queue_info(0)) == NULL) return NULL; nqinfo->name = string_dup(oqinfo->name); nqinfo->server = nsinfo; nqinfo->is_started = oqinfo->is_started; nqinfo->is_exec = oqinfo->is_exec; nqinfo->is_route = oqinfo->is_route; nqinfo->is_ok_to_run = oqinfo->is_ok_to_run; nqinfo->is_ded_queue = oqinfo->is_ded_queue; nqinfo->is_prime_queue = oqinfo->is_prime_queue; nqinfo->is_nonprime_queue = oqinfo->is_nonprime_queue; nqinfo->has_nodes = oqinfo->has_nodes; nqinfo->has_soft_limit = oqinfo->has_soft_limit; nqinfo->has_hard_limit = oqinfo->has_hard_limit; nqinfo->is_peer_queue = oqinfo->is_peer_queue; nqinfo->has_resav_limit = oqinfo->has_resav_limit; nqinfo->sc = oqinfo->sc; nqinfo->liminfo = lim_dup_liminfo(oqinfo->liminfo); nqinfo->priority = oqinfo->priority; nqinfo->num_parts = oqinfo->num_parts; nqinfo->num_topjobs = oqinfo->num_topjobs; nqinfo->backfill_depth = oqinfo->backfill_depth; #ifdef NAS /* localmod 046 */ nqinfo->max_starve = oqinfo->max_starve; /* localmod 034 */ nqinfo->max_borrow = oqinfo->max_borrow; /* localmod 038 */ nqinfo->is_topjob_set_aside = oqinfo->is_topjob_set_aside; /* localmod 040 */ nqinfo->ignore_nodect_sort = oqinfo->ignore_nodect_sort; #endif nqinfo->qres = dup_resource_list(oqinfo->qres); nqinfo->alljobcounts = dup_counts_list(oqinfo->alljobcounts); nqinfo->group_counts = dup_counts_list(oqinfo->group_counts); nqinfo->project_counts = dup_counts_list(oqinfo->project_counts); nqinfo->user_counts = dup_counts_list(oqinfo->user_counts); nqinfo->total_alljobcounts = dup_counts_list(oqinfo->total_alljobcounts); nqinfo->total_group_counts = dup_counts_list(oqinfo->total_group_counts); nqinfo->total_project_counts = dup_counts_list(oqinfo->total_project_counts); nqinfo->total_user_counts = dup_counts_list(oqinfo->total_user_counts); nqinfo->nodepart = dup_node_partition_array(oqinfo->nodepart, nsinfo); nqinfo->allpart = dup_node_partition(oqinfo->allpart, nsinfo); nqinfo->node_group_key = dup_string_array(oqinfo->node_group_key); if (oqinfo->resv != NULL) { nqinfo->resv = find_resource_resv_by_rank(nsinfo->resvs, oqinfo->resv->rank); /* just incase we we didn't set the reservation cross pointer */ if (nqinfo->resv != NULL && nqinfo->resv->resv != NULL) nqinfo->resv->resv->resv_queue = nqinfo; } nqinfo->jobs = dup_resource_resv_array(oqinfo->jobs, nqinfo->server, nqinfo); if (nqinfo->jobs != NULL) nqinfo->running_jobs = resource_resv_filter(nqinfo->jobs, nqinfo->sc.total, check_run_job, NULL, 0); if (oqinfo->nodes != NULL) nqinfo->nodes = node_filter(nsinfo->nodes, nsinfo->num_nodes, node_queue_cmp, (void *) nqinfo->name, 0); if (oqinfo->nodes_in_partition != NULL) nqinfo->nodes_in_partition = node_filter(nsinfo->nodes, nsinfo->num_nodes, node_partition_cmp, (void *) oqinfo->partition, 0); if (oqinfo->partition != NULL) { nqinfo->partition = string_dup(oqinfo->partition); if (nqinfo->partition == NULL) { free_queue_info(nqinfo); return NULL; } } return nqinfo; }