/** * @brief * calculate the run time of a resresv through simulation of * future calendar events * * @param[in] name - the name of the resresv to find the start time of * @param[in] sinfo - the pbs environment * NOTE: sinfo will be modified, it should be a copy * @param[in] flags - some flags to control the function * SIM_RUN_JOB - simulate running the resresv * * @return int * @retval time_t of when the job will run * @retval 0 : can not determine when job will run * @retval 1 : on error * */ time_t calc_run_time(char *name, server_info *sinfo, int flags) { time_t event_time = (time_t) 0; /* time of the simulated event */ event_list *calendar; /* calendar we are simulating in */ resource_resv *resresv; /* the resource resv to find star time for */ /* the value returned from simulate_events(). Init to TIMED_END_EVENT to * force the initial check to see if the job can run */ unsigned int ret = TIMED_END_EVENT; schd_error *err = NULL; timed_event *te_start; timed_event *te_end; int desc; nspec **ns = NULL; if (name == NULL || sinfo == NULL) return (time_t) -1; event_time = sinfo->server_time; calendar = sinfo->calendar; resresv = find_resource_resv(sinfo->all_resresv, name); if (!is_resource_resv_valid(resresv, NULL)) return (time_t) -1; err = new_schd_error(); if(err == NULL) return (time_t) 0; do { /* policy is used from sinfo instead of being passed into calc_run_time() * because it's being simulated/updated in simulate_events() */ desc = describe_simret(ret); if (desc > 0 || (desc == 0 && policy_change_info(sinfo, resresv))) { clear_schd_error(err); if (resresv->is_job) ns = is_ok_to_run(sinfo->policy, -1, sinfo, resresv->job->queue, resresv, IGNORE_EQUIV_CLASS, err); else ns = is_ok_to_run(sinfo->policy, -1, sinfo, NULL, resresv, IGNORE_EQUIV_CLASS, err); } if (ns == NULL) /* event can not run */ ret = simulate_events(sinfo->policy, sinfo, SIM_NEXT_EVENT, &(sinfo->opt_backfill_fuzzy_time), &event_time); #ifdef NAS /* localmod 030 */ if (check_for_cycle_interrupt(0)) { break; } #endif /* localmod 030 */ } while (ns == NULL && !(ret & (TIMED_NOEVENT|TIMED_ERROR))); #ifdef NAS /* localmod 030 */ if (check_for_cycle_interrupt(0) || (ret & TIMED_ERROR)) { #else if ((ret & TIMED_ERROR)) { #endif /* localmod 030 */ free_schd_error(err); if (ns != NULL) free_nspecs(ns); return -1; } /* we can't run the job, but there are no timed events left to process */ if (ns == NULL && (ret & TIMED_NOEVENT)) { schdlogerr(PBSEVENT_SCHED, PBS_EVENTCLASS_SCHED, LOG_WARNING, resresv->name, "Can't find start time estimate", err); free_schd_error(err); return 0; } /* err is no longer needed, we've reported it. */ free_schd_error(err); err = NULL; if (resresv->is_job) resresv->job->est_start_time = event_time; resresv->start = event_time; resresv->end = event_time + resresv->duration; te_start = create_event(TIMED_RUN_EVENT, resresv->start, (event_ptr_t *) resresv, NULL, NULL); if (te_start == NULL) { if (ns != NULL) free_nspecs(ns); return -1; } te_end = create_event(TIMED_END_EVENT, resresv->end, (event_ptr_t *) resresv, NULL, NULL); if (te_end == NULL) { if (ns != NULL) free_nspecs(ns); free_timed_event(te_start); return -1; } add_event(calendar, te_start); add_event(calendar, te_end); if (flags & SIM_RUN_JOB) sim_run_update_resresv(sinfo->policy, resresv, ns, RURR_NO_FLAGS); else free_nspecs(ns); return event_time; } /** * @brief * create an event_list from running jobs and confirmed resvs * * @param[in] sinfo - server universe to act upon * * @return event_list */ event_list * create_event_list(server_info *sinfo) { event_list *elist; elist = new_event_list(); if (elist == NULL) return NULL; elist->events = create_events(sinfo); elist->next_event = elist->events; elist->current_time = &sinfo->server_time; add_dedtime_events(elist, sinfo->policy); return elist; }
/** * @brief * dup_resource_resv - duplicate a resource resv structure * * @param[in] oresresv - res resv to duplicate * @param[in] nsinfo - new server info for resource_resv * @param[in] nqinfo - new queue info for resource_resv if job (NULL if resv) * * @return newly duplicated resource resv * @retval NULL : on error * */ resource_resv * dup_resource_resv(resource_resv *oresresv, server_info *nsinfo, queue_info *nqinfo) { resource_resv *nresresv; static schd_error *err; if (oresresv == NULL || nsinfo == NULL) return NULL; if (err == NULL) { err = new_schd_error(); if (err == NULL) return NULL; } else clear_schd_error(err); if (!is_resource_resv_valid(oresresv, err)) { schdlogerr(PBSEVENT_DEBUG2, PBS_EVENTCLASS_SCHED, LOG_DEBUG, oresresv->name, "Can't dup resresv", err); return NULL; } nresresv = new_resource_resv(); if (nresresv == NULL) return NULL; nresresv->server = nsinfo; nresresv->name = string_dup(oresresv->name); nresresv->user = string_dup(oresresv->user); nresresv->group = string_dup(oresresv->group); nresresv->project = string_dup(oresresv->project); nresresv->nodepart_name = string_dup(oresresv->nodepart_name); nresresv->select = dup_selspec(oresresv->select); nresresv->execselect = dup_selspec(oresresv->execselect); nresresv->is_invalid = oresresv->is_invalid; nresresv->can_not_fit = oresresv->can_not_fit; nresresv->can_not_run = oresresv->can_not_run; nresresv->can_never_run = oresresv->can_never_run; nresresv->is_peer_ob = oresresv->is_peer_ob; nresresv->is_prov_needed = oresresv->is_prov_needed; nresresv->is_shrink_to_fit = oresresv->is_shrink_to_fit; nresresv->will_use_multinode = oresresv->will_use_multinode; nresresv->ec_index = oresresv->ec_index; nresresv->sch_priority = oresresv->sch_priority; nresresv->rank = oresresv->rank; nresresv->qtime = oresresv->qtime; nresresv->qrank = oresresv->qrank; nresresv->start = oresresv->start; nresresv->end = oresresv->end; nresresv->duration = oresresv->duration; nresresv->hard_duration = oresresv->hard_duration; nresresv->min_duration = oresresv->min_duration; nresresv->resreq = dup_resource_req_list(oresresv->resreq); nresresv->place_spec = dup_place(oresresv->place_spec); nresresv->aoename = string_dup(oresresv->aoename); nresresv->eoename = string_dup(oresresv->eoename); nresresv->node_set_str = dup_string_array(oresresv->node_set_str); nresresv->resresv_ind = oresresv->resresv_ind; #ifdef NAS /* localmod 049 */ nresresv->node_set = copy_node_ptr_array(oresresv->node_set, nsinfo->nodes, nsinfo); #else nresresv->node_set = copy_node_ptr_array(oresresv->node_set, nsinfo->nodes); #endif /* localmod 049 */ if (oresresv->is_job) { nresresv->is_job = 1; nresresv->job = dup_job_info(oresresv->job, nqinfo, nsinfo); if (nresresv->job != NULL) { if (nresresv->job->resv !=NULL) { #ifdef NAS /* localmod 049 */ nresresv->ninfo_arr = copy_node_ptr_array(oresresv->ninfo_arr, nresresv->job->resv->resv->resv_nodes, NULL); nresresv->nspec_arr = dup_nspecs(oresresv->nspec_arr, nresresv->job->resv->ninfo_arr, NULL); #else nresresv->ninfo_arr = copy_node_ptr_array(oresresv->ninfo_arr, nresresv->job->resv->resv->resv_nodes); nresresv->nspec_arr = dup_nspecs(oresresv->nspec_arr, nresresv->job->resv->ninfo_arr); #endif /* localmod 049 */ } else { #ifdef NAS /* localmod 049 */ nresresv->ninfo_arr = copy_node_ptr_array(oresresv->ninfo_arr, nsinfo->nodes, nsinfo); nresresv->nspec_arr = dup_nspecs(oresresv->nspec_arr, nsinfo->nodes, nsinfo); #else nresresv->ninfo_arr = copy_node_ptr_array(oresresv->ninfo_arr, nsinfo->nodes); nresresv->nspec_arr = dup_nspecs(oresresv->nspec_arr, nsinfo->nodes); #endif /* localmod 049 */ } } } else if (oresresv->is_resv) { nresresv->is_resv = 1; nresresv->resv = dup_resv_info(oresresv->resv, nsinfo); #ifdef NAS /* localmod 049 */ nresresv->ninfo_arr = copy_node_ptr_array(oresresv->ninfo_arr, nsinfo->nodes, nsinfo); nresresv->nspec_arr = dup_nspecs(oresresv->nspec_arr, nsinfo->nodes, nsinfo); #else nresresv->ninfo_arr = copy_node_ptr_array(oresresv->ninfo_arr, nsinfo->nodes); nresresv->nspec_arr = dup_nspecs(oresresv->nspec_arr, nsinfo->nodes); #endif /* localmod 049 */ } else { /* error */ free_resource_resv(nresresv); return NULL; } #ifdef NAS /* localmod 034 */ nresresv->share_type = oresresv->share_type; #endif /* localmod 034 */ if (!is_resource_resv_valid(nresresv, err)) { schdlogerr(PBSEVENT_DEBUG2, PBS_EVENTCLASS_SCHED, LOG_DEBUG, oresresv->name, "Failed to dup resresv", err); free_resource_resv(nresresv); return NULL; } return nresresv; }