/** * @brief * Create new resource_req with given data * * @param[in] name - name of resource * @param[in] value - value of resource * * @return newly created resource_req * @retval NULL : Fail */ resource_req * create_resource_req(char *name, char *value) { resource_req *resreq = NULL; resdef *rdef; if (name == NULL) return NULL; rdef = find_resdef(allres, name); if (rdef != NULL) { if ((resreq = new_resource_req()) != NULL) { resreq->def = rdef; resreq->name = rdef->name; resreq->type = rdef->type; if (value != NULL) { if (set_resource_req(resreq, value) != 1) { schdlog(PBSEVENT_DEBUG, PBS_EVENTCLASS_SCHED, LOG_DEBUG, name, "Bad requested resource data"); return NULL; } } } } else { schdlog(PBSEVENT_DEBUG, PBS_EVENTCLASS_SCHED, LOG_DEBUG, name, "Resource definition does not exist, resource may be invalid"); return NULL; } return resreq; }
/** * @brief * compare_res_to_str - compare a resource structure of type string to * a character array string * * @param[in] res - the resource * @param[in] str - the string * @param[in] cmpflag - case sensitive or insensitive comparison * * @return int * @retval 1 : if they match * @retval 0 : if they don't or res is not a string or error * */ int compare_res_to_str(schd_resource *res, char *str , enum resval_cmpflag cmpflag) { int i; if (res == NULL || str == NULL) return 0; if (res->str_avail == NULL) return 0; for (i = 0; res->str_avail[i] != NULL; i++) { if (cmpflag == CMP_CASE) { if (!strcmp(res->str_avail[i], str)) return 1; } else if (cmpflag == CMP_CASELESS) { if (!strcasecmp(res->str_avail[i], str)) return 1; } else { schdlog(PBSEVENT_DEBUG3, PBS_EVENTCLASS_JOB, LOG_NOTICE, res->name, "Incorrect flag for comparison."); return 0; } } /* if we got here, we didn't match the string */ return 0; }
/** * @brief * find_event_ptr - find the correct event pointer for the duplicated * event based on event type * * @param[in] ote - old event * @param[in] nsinfo - "new" universe * * @return event_ptr in new universe * @retval NULL : on error */ event_ptr_t * find_event_ptr(timed_event *ote, server_info *nsinfo) { resource_resv *oep; /* old event_ptr in resresv form */ event_ptr_t *event_ptr = NULL; char logbuf[MAX_LOG_SIZE]; if (ote == NULL || nsinfo == NULL) return NULL; switch (ote->event_type) { case TIMED_RUN_EVENT: case TIMED_END_EVENT: oep = (resource_resv *) ote->event_ptr; event_ptr = find_resource_resv_by_time(nsinfo->all_resresv, oep->name, oep->start); if (event_ptr == NULL) { schdlog(PBSEVENT_SCHED, PBS_EVENTCLASS_SCHED, LOG_WARNING, ote->name, "Event can't be found in new server to be duplicated."); event_ptr = NULL; } break; case TIMED_POLICY_EVENT: case TIMED_DED_START_EVENT: case TIMED_DED_END_EVENT: event_ptr = nsinfo->policy; break; case TIMED_NODE_DOWN_EVENT: case TIMED_NODE_UP_EVENT: event_ptr = find_node_info(nsinfo->nodes, ((node_info*)(ote->event_ptr))->name); break; default: snprintf(logbuf, MAX_LOG_SIZE, "Unknown event type: %d", #ifdef NAS /* localmod 005 */ (int)ote->event_type); #else ote->event_type); #endif /* localmod 005 */ schdlog(PBSEVENT_SCHED, PBS_EVENTCLASS_SCHED, LOG_WARNING, __func__, logbuf); } return event_ptr; }
/** * @brief * determine_event_name - determine a timed events name based off of * event type and sets it * * @param[in] te - the event * * @par Side Effects * te -> name is set to static data or data owned by other entities. * It should not be freed. * * @return int * @retval 1 : if the name was successfully set * @retval 0 : if not */ int determine_event_name(timed_event *te) { char *name; char logbuf[MAX_LOG_SIZE]; if (te == NULL) return 0; switch (te->event_type) { case TIMED_RUN_EVENT: case TIMED_END_EVENT: te->name = ((resource_resv*) te->event_ptr)->name; break; case TIMED_POLICY_EVENT: name = policy_change_to_str(te); if (name != NULL) te->name = name; else te->name = "policy change"; break; case TIMED_DED_START_EVENT: te->name = "dedtime_start"; break; case TIMED_DED_END_EVENT: te->name = "dedtime_end"; break; case TIMED_NODE_UP_EVENT: case TIMED_NODE_DOWN_EVENT: te->name = ((node_info*) te->event_ptr)->name; break; default: #ifdef NAS /* localmod 005 */ snprintf(logbuf, MAX_LOG_SIZE, "Unknown event type: %d", (int)te->event_type); #else snprintf(logbuf, MAX_LOG_SIZE, "Unknown event type: %d", te->event_type); #endif /* localmod 005 */ schdlog(PBSEVENT_SCHED, PBS_EVENTCLASS_SCHED, LOG_WARNING, __func__, logbuf); return 0; } return 1; }
/** * @brief * count_states - count the jobs in each state and set the state counts * * @param[in] jobs - array of jobs * @param[out] sc - state count structure passed by reference * * @return nothing * */ void count_states(resource_resv **jobs, state_count *sc) { int i; if (jobs != NULL) { for (i = 0; jobs[i] != NULL; i++) { if (jobs[i]->job != NULL) { if (jobs[i]->job->is_queued) sc->queued++; else if (jobs[i]->job->is_running) sc->running++; else if (jobs[i]->job->is_transit) sc->transit++; else if (jobs[i]->job->is_exiting) sc->exiting++; else if (jobs[i]->job->is_held) sc->held++; else if (jobs[i]->job->is_waiting) sc->waiting++; else if (jobs[i]->job->is_suspended) sc->suspended++; else if (jobs[i]->job->is_userbusy) sc->userbusy++; else if (jobs[i]->job->is_begin) sc->begin++; else if (jobs[i]->job->is_expired) sc->expired++; else { sc->invalid++; schdlog(PBSEVENT_JOB, PBS_EVENTCLASS_JOB, LOG_INFO, jobs[i]->name, "Job in unknown state"); } } } } sc->total = sc->queued + sc->running + sc->transit + sc->exiting + sc->held + sc->waiting + sc->suspended + sc->userbusy + sc->begin + sc->expired + sc->invalid; }
int dedtime_change(status *policy, void *arg) { char *event_arg; if (policy == NULL || arg == NULL) return 0; event_arg = (char *)arg; if (strcmp(event_arg, DEDTIME_START) == 0) policy->is_ded_time = 1; else if (strcmp(event_arg, DEDTIME_END) == 0) policy->is_ded_time = 0; else { schdlog(PBSEVENT_SCHED, PBS_EVENTCLASS_SCHED, LOG_WARNING, __func__, "unknown dedicated time change"); return 0; } return 1; }
/** * @brief * dup_event_list() - evevnt_list copy constructor * * @param[in] oelist - event list to copy * @param[in] nsinfo - new universe * * @return duplicated event_list * */ event_list * dup_event_list(event_list *oelist, server_info *nsinfo) { event_list *nelist; if (oelist == NULL || nsinfo == NULL) return NULL; nelist = new_event_list(); if (nelist == NULL) return NULL; nelist->eol = oelist->eol; nelist->current_time = &nsinfo->server_time; if (oelist->events != NULL) { nelist->events = dup_timed_event_list(oelist->events, nsinfo); if (nelist->events == NULL) { free_event_list(nelist); return NULL; } } if (oelist->next_event != NULL) { nelist->next_event = find_timed_event(nelist->events, oelist->next_event->name, oelist->next_event->event_type, oelist->next_event->event_time); if (nelist->next_event == NULL) { schdlog(PBSEVENT_SCHED, PBS_EVENTCLASS_SCHED, LOG_WARNING, oelist->next_event->name, "can't find next event in duplicated list"); free_event_list(nelist); return NULL; } } return nelist; }
/** * @brief * takes a timed_event and performs any actions * required by the event to be completed. * * @param[in] policy - status * @param[in] event - the event to perform * * @return int * @retval 1 : success * @retval 0 : failure */ int perform_event(status *policy, timed_event *event) { char logbuf[MAX_LOG_SIZE]; char logbuf2[MAX_LOG_SIZE]; char timebuf[128]; resource_resv *resresv; int ret = 1; if (event == NULL || event->event_ptr == NULL) return 0; sprintf(timebuf, "%s", ctime(&event->event_time)); /* ctime() puts a \n at the end of the line, nuke it*/ timebuf[strlen(timebuf) - 1] = '\0'; switch (event->event_type) { case TIMED_END_EVENT: /* event_ptr type: (resource_resv *) */ resresv = (resource_resv *) event->event_ptr; update_universe_on_end(policy, resresv, "X"); sprintf(logbuf, "%s end point", resresv->is_job ? "job":"reservation"); break; case TIMED_RUN_EVENT: /* event_ptr type: (resource_resv *) */ resresv = (resource_resv *) event->event_ptr; if (sim_run_update_resresv(policy, resresv, NULL, RURR_NO_FLAGS) <= 0) { schdlog(PBSEVENT_SCHED, PBS_EVENTCLASS_JOB, LOG_INFO, event->name, "Simulation: Event failed to be run"); ret = 0; } else { sprintf(logbuf, "%s start point", resresv->is_job ? "job": "reservation"); } break; case TIMED_POLICY_EVENT: strcpy(logbuf, "Policy change"); break; case TIMED_DED_START_EVENT: strcpy(logbuf, "Dedtime Start"); break; case TIMED_DED_END_EVENT: strcpy(logbuf, "Dedtime End"); break; case TIMED_NODE_UP_EVENT: strcpy(logbuf, "Node Up"); break; case TIMED_NODE_DOWN_EVENT: strcpy(logbuf, "Node Down"); break; default: schdlog(PBSEVENT_SCHED, PBS_EVENTCLASS_JOB, LOG_INFO, event->name, "Simulation: Unknown event type"); ret = 0; } if (event->event_func != NULL) event->event_func(event->event_ptr, event->event_func_arg); if (ret) { snprintf(logbuf2, MAX_LOG_SIZE, "Simulation: %s [%s]", logbuf, timebuf); schdlog(PBSEVENT_DEBUG3, PBS_EVENTCLASS_JOB, LOG_DEBUG, event->name, logbuf2); } return ret; }
/** * @brief * create the placement sets for the server and queues * * @param[in] policy - policy info * @param[in] sinfo - the server * * @return int * @retval 1 : success * @retval 0 : failure */ int create_placement_sets(status *policy, server_info *sinfo) { int i; int is_success = 1; char *resstr[] = {"host", NULL}; int num; sinfo->allpart = create_specific_nodepart(policy, "all", sinfo->unassoc_nodes); if (sinfo->has_multi_vnode) { sinfo->hostsets = create_node_partitions(policy, sinfo->nodes, resstr, policy->only_explicit_psets ? NO_FLAGS : NP_CREATE_REST, &num); if (sinfo->hostsets != NULL) { sinfo->num_hostsets = num; for (i = 0; sinfo->nodes[i] != NULL; i++) { schd_resource *hostres; char hostbuf[256]; hostres = find_resource(sinfo->nodes[i]->res, getallres(RES_HOST)); if (hostres != NULL) { snprintf(hostbuf, sizeof(hostbuf), "host=%s", hostres->str_avail[0]); sinfo->nodes[i]->hostset = find_node_partition(sinfo->hostsets, hostbuf); } else { snprintf(hostbuf, sizeof(hostbuf), "host=\"\""); sinfo->nodes[i]->hostset = find_node_partition(sinfo->hostsets, hostbuf); } } } else { schdlog(PBSEVENT_DEBUG, PBS_EVENTCLASS_SERVER, LOG_DEBUG, "", "Failed to create host sets for server"); is_success = 0; } } if (sinfo->node_group_enable && sinfo->node_group_key != NULL) { sinfo->nodepart = create_node_partitions(policy, sinfo->unassoc_nodes, sinfo->node_group_key, policy->only_explicit_psets ? NO_FLAGS : NP_CREATE_REST, &sinfo->num_parts); if (sinfo->nodepart != NULL) { qsort(sinfo->nodepart, sinfo->num_parts, sizeof(node_partition *), cmp_placement_sets); } else { schdlog(PBSEVENT_DEBUG, PBS_EVENTCLASS_SERVER, LOG_DEBUG, "", "Failed to create node partitions for server"); is_success = 0; } } for (i = 0; sinfo->queues[i] != NULL; i++) { node_info **ngroup_nodes; char **ngkey; queue_info *qinfo = sinfo->queues[i]; if (qinfo->has_nodes) qinfo->allpart = create_specific_nodepart(policy, "all", qinfo->nodes); if (sinfo->node_group_enable && (qinfo->has_nodes || qinfo->node_group_key)) { if (qinfo->has_nodes) ngroup_nodes = qinfo->nodes; else ngroup_nodes = sinfo->unassoc_nodes; if(qinfo->node_group_key) ngkey = qinfo->node_group_key; else ngkey = sinfo->node_group_key; qinfo->nodepart = create_node_partitions(policy, ngroup_nodes, ngkey, policy->only_explicit_psets ? NO_FLAGS : NP_CREATE_REST, &(qinfo->num_parts)); if (qinfo->nodepart != NULL) { qsort(qinfo->nodepart, qinfo->num_parts, sizeof(node_partition *), cmp_placement_sets); } else { schdlog(PBSEVENT_DEBUG, PBS_EVENTCLASS_QUEUE, LOG_DEBUG, qinfo->name, "Failed to create node partitions for queue."); is_success = 0; } } } return is_success; }
/** * @brief * update_resresv_on_end - update a resource_resv structure when * it ends * * @param[out] resresv - the resresv to update * @param[in] job_state - the new state if resresv is a job * * @return nothing * */ void update_resresv_on_end(resource_resv *resresv, char *job_state) { queue_info *resv_queue; resource_resv *next_occr = NULL; time_t next_occr_time; char logbuf[MAX_LOG_SIZE]; int ret; int i; if (resresv == NULL) return; /* now that it isn't running, it might be runnable again */ resresv->can_not_run = 0; /* unless of course it's a job and its queue is in an ineligible state */ if (resresv->is_job && resresv->job != NULL && !resresv->job->queue->is_ok_to_run) resresv->can_not_run = 1; /* no longer running... clear start and end times */ resresv->start = UNSPECIFIED; resresv->end = UNSPECIFIED; if (resresv->is_job && resresv->job != NULL) { set_job_state(job_state, resresv->job); if (resresv->job->is_suspended) { #ifndef NAS /* localmod 005 */ int i; #endif /* localmod 005 */ nspec **ns = resresv->nspec_arr; resresv->job->is_susp_sched = 1; for (i = 0; ns[i] != NULL; i++) ns[i]->ninfo->num_susp_jobs++; } resresv->job->is_provisioning = 0; /* free resources allocated to job since it's now been requeued */ if (resresv->job->is_queued && !resresv->job->is_checkpointed) { free(resresv->ninfo_arr); resresv->ninfo_arr = NULL; free_nspecs(resresv->nspec_arr); resresv->nspec_arr = NULL; free_resource_req_list(resresv->job->resused); resresv->job->resused = NULL; if (resresv->nodepart_name != NULL) { free(resresv->nodepart_name); resresv->nodepart_name = NULL; } free_selspec(resresv->execselect); resresv->execselect = NULL; } } else if (resresv->is_resv && resresv->resv !=NULL) { resresv->resv->resv_state = RESV_DELETED; resv_queue = find_queue_info(resresv->server->queues, resresv->resv->queuename); if (resv_queue != NULL) { resv_queue->is_started = 0; ret = is_ok_to_run_queue(resresv->server->policy, resv_queue); if (ret == SUCCESS) resv_queue->is_ok_to_run = 1; else resv_queue->is_ok_to_run = 0; if (resresv->resv->is_standing) { /* This occurrence is over, move resv pointers of all jobs that are * left to next occurrence if one exists */ if (resresv->resv->resv_idx < resresv->resv->count) { next_occr_time = get_occurrence(resresv->resv->rrule, resresv->resv->req_start, resresv->resv->timezone, 2); if (next_occr_time >= 0) { next_occr = find_resource_resv_by_time(resresv->server->resvs, resresv->name, next_occr_time); if (next_occr != NULL) { if (resv_queue->jobs != NULL) { for (i = 0; resv_queue->jobs[i] != NULL; i++) { if (in_runnable_state(resv_queue->jobs[i])) resv_queue->jobs[i]->job->resv = next_occr; } } } else { snprintf(logbuf, MAX_LOG_SIZE, "Can't find occurrence of standing reservation at time %ld", next_occr_time); schdlog(PBSEVENT_DEBUG, PBS_EVENTCLASS_SERVER, LOG_DEBUG, resresv->name, logbuf); } } } } } } }