示例#1
0
文件: simulate.c 项目: altair4/pbspro
/**
 * @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;
}
示例#2
0
/**
 * @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;
}