Пример #1
0
/**
 * @brief
 * 	Displays the occurrences in a two-column format:
 * 	the first column corresponds to the occurrence date and time
 * 	the second column corresponds to the reserved execvnode
 *
 * @par	NOTE: This is currently only used by pbs_rstat and only
 * 	for testing purpose, it is not used in production environment.
 *
 * @param[in] rrule - The recurrence rule considered
 * @param[in] dtstart - The date start of the recurrence
 * @param[in] seq_execvnodes - The condensed form of execvnodes/occurrence
 * @param[in] tz - The timezone associated to the recurrence rule
 * @param[in] ridx - The index of the occurrence from which to start displaying information
 * @param[in] count - The total number of occurrences considered
 *
 */
void
display_occurrences(char *rrule, time_t dtstart, char *seq_execvnodes, char *tz, int ridx, int count)
{

#ifdef LIBICAL
	char **short_xc;
	char **tofree;
	char *tt_str;
	time_t next = 0;
	int i = 1;

	if (tz == NULL || rrule == NULL)
		return;

	if (get_num_occurrences(rrule, dtstart, tz) == 0)
		return;

	short_xc = (char **) unroll_execvnode_seq(seq_execvnodes, &tofree);

	printf("Occurrence Dates\t Occurrence Execvnode:\n");
	for (; ridx <= count && next != -1; ridx++) {
		next = get_occurrence(rrule, dtstart, tz, i);
		i++;
		tt_str = ctime(&next);
		/* ctime adds a carriage return at the end, strip it */
		tt_str[strlen(tt_str)-1] = '\0';
		printf("%2s %2s\n", tt_str, short_xc[ridx-1]);
	}
	free_execvnode_seq(tofree);
	free(short_xc);
#endif
}
Пример #2
0
/**
 * @brief
 *	display the number of occurences and occurences.
 *
 * @param[in] rrule - The recurrence rule considered
 * @param[in] dtstart - The date start of the recurrence
 * @param[in] tz - The timezone associated to the recurrence rule
 *
 */
void
test_it(char *rrule, time_t dtstart, char *tz)
{
	int no;
	time_t next;
	int i;

	no = get_num_occurrences(rrule, dtstart, tz);
	printf("Number of occurrences = %d\n", no);
	next = dtstart;
	for (i=0; i < no; i++) {
		next = get_occurrence(rrule, dtstart, tz, i+1);
		printf("Next occurrence on %s", ctime(&next));
	}
	return;
}
Пример #3
0
/**
 * @brief Service the Modify Reservation Request from client such as pbs_ralter.
 *
 *	This request atomically modifies one or more of a reservation's attributes.
 *	An error is returned to the client if the user does not have permission
 *	to perform the modification, the attribute is read-only, the reservation is
 *	running and the attribute is only modifiable when the reservation is not
 *	running or is empty.
 *
 * @param[in] preq - pointer to batch request from client
 */
void
req_modifyReservation(struct batch_request *preq)
{
	char		*rid = NULL;
	svrattrl	*psatl = NULL;
	attribute_def	*pdef = NULL;
	int		rc = 0;
	int		bad = 0;
	char		buf[PBS_MAXUSER + PBS_MAXHOSTNAME + 32] = {0};
	int		sock;
	int		resc_access_perm_save = 0;
	int		send_to_scheduler = 0;
	int		log_len = 0;
	char		*fmt = "%a %b %d %H:%M:%S %Y";
	int		is_standing = 0;
	int		next_occr_start = 0;
	extern char	*msg_stdg_resv_occr_conflict;
	resc_resv	*presv;

	if (preq == NULL)
		return;

	sock = preq->rq_conn;

	presv = chk_rescResv_request(preq->rq_ind.rq_modify.rq_objname, preq);
	/* Note: on failure, chk_rescResv_request invokes req_reject
	 * appropriate reply is sent and batch_request is freed.
	 */
	if (presv == NULL)
		return;

	rid = preq->rq_ind.rq_modify.rq_objname;
	if ((presv = find_resv(rid)) == NULL) {
		/* Not on "all_resvs" list try "new_resvs" list */
		presv = (resc_resv *)GET_NEXT(svr_newresvs);
		while (presv) {
			if (!strcmp(presv->ri_qs.ri_resvID, rid))
				break;
			presv = (resc_resv *)GET_NEXT(presv->ri_allresvs);
		}
	}

	if (presv == NULL) {
		req_reject(PBSE_UNKRESVID, 0, preq);
		return;
	}

	is_standing = presv->ri_wattr[RESV_ATR_resv_standing].at_val.at_long;
	if (is_standing)
		next_occr_start = get_occurrence(presv->ri_wattr[RESV_ATR_resv_rrule].at_val.at_str,
					presv->ri_wattr[RESV_ATR_start].at_val.at_long,
					presv->ri_wattr[RESV_ATR_resv_timezone].at_val.at_str, 2);

	resc_access_perm_save = resc_access_perm;
	psatl = (svrattrl *)GET_NEXT(preq->rq_ind.rq_modify.rq_attr);
	presv->ri_alter_flags = 0;
	while (psatl) {
		long temp = 0;
		char *end = NULL;
		int index;

		/* identify the attribute by name */
		index = find_attr(resv_attr_def, psatl->al_name, RESV_ATR_LAST);
		if (index < 0) {
			/* didn`t recognize the name */
			reply_badattr(PBSE_NOATTR, 1, psatl, preq);
			return;
		}
		pdef = &resv_attr_def[index];

		/* Does attribute's definition flags indicate that
		 * we have sufficient permission to write the attribute?
		 */

		resc_access_perm = resc_access_perm_save; /* reset */
		if (psatl->al_flags & ATR_VFLAG_HOOK) {
			resc_access_perm = ATR_DFLAG_USWR | \
					    ATR_DFLAG_OPWR | \
					    ATR_DFLAG_MGWR | \
				            ATR_DFLAG_SvWR | \
					    ATR_DFLAG_Creat;
		}
		if ((pdef->at_flags & resc_access_perm) == 0) {
			reply_badattr(PBSE_ATTRRO, 1, psatl, preq);
			return;
		}

		switch (index) {
			case RESV_ATR_start:
				if ((presv->ri_wattr[RESV_ATR_state].at_val.at_long != RESV_RUNNING) ||
					!(presv->ri_qp->qu_numjobs)) {
					temp = strtol(psatl->al_value, &end, 10);
					if ((temp > time(NULL)) &&
						(temp != presv->ri_wattr[RESV_ATR_start].at_val.at_long)) {
						if (!is_standing || (temp < next_occr_start)) {
							send_to_scheduler = RESV_START_TIME_MODIFIED;
							presv->ri_alter_stime = presv->ri_wattr[RESV_ATR_start].at_val.at_long;
							presv->ri_alter_flags |= RESV_START_TIME_MODIFIED;
						} else {
							snprintf(log_buffer, sizeof(log_buffer), "%s", msg_stdg_resv_occr_conflict);
							log_event(PBSEVENT_RESV, PBS_EVENTCLASS_RESV, LOG_INFO,
								preq->rq_ind.rq_modify.rq_objname, log_buffer);
							req_reject(PBSE_STDG_RESV_OCCR_CONFLICT, 0, preq);
							return;
						}
					} else {
						req_reject(PBSE_BADTSPEC, 0, preq);
						return;
					}
				} else {
					if (presv->ri_qp->qu_numjobs)
						req_reject(PBSE_RESV_NOT_EMPTY, 0, preq);
					else
						req_reject(PBSE_BADTSPEC, 0, preq);
					return;
				}
				break;
			case RESV_ATR_end:
				temp = strtol(psatl->al_value, &end, 10);
				if (temp == presv->ri_wattr[RESV_ATR_end].at_val.at_long) {
					req_reject(PBSE_BADTSPEC, 0, preq);
					return;
				}
				if (!is_standing || temp < next_occr_start) {
					send_to_scheduler = RESV_END_TIME_MODIFIED;
					presv->ri_alter_etime = presv->ri_wattr[RESV_ATR_end].at_val.at_long;
					presv->ri_alter_flags |= RESV_END_TIME_MODIFIED;
				} else {
					snprintf(log_buffer, sizeof(log_buffer), "%s", msg_stdg_resv_occr_conflict);
					log_event(PBSEVENT_RESV, PBS_EVENTCLASS_RESV, LOG_INFO,
						preq->rq_ind.rq_modify.rq_objname, log_buffer);
					req_reject(PBSE_STDG_RESV_OCCR_CONFLICT, 0, preq);
					return;
				}
				break;
			default:
				break;
		}

		/* decode attribute */
		rc = pdef->at_decode(&presv->ri_wattr[index],
			psatl->al_name, psatl->al_resc, psatl->al_value);

		if (rc != 0) {
			reply_badattr(rc, 1, psatl, preq);
			return;
		}

		psatl = (svrattrl *)GET_NEXT(psatl->al_link);
	}
	resc_access_perm = resc_access_perm_save; /* restore perm */

	if (send_to_scheduler) {
		presv->ri_alter_state = presv->ri_wattr[RESV_ATR_state].at_val.at_long;
		resv_setResvState(presv, RESV_BEING_ALTERED, presv->ri_qs.ri_substate);
		/*"start", "end","duration", and "wall"; derive and check */
		if (start_end_dur_wall(presv, RESC_RESV_OBJECT)) {
			req_reject(PBSE_BADTSPEC, 0, preq);
			resv_revert_alter_times(presv);
			return;
		}
		presv->ri_wattr[RESV_ATR_resource].at_flags |= ATR_VFLAG_SET | ATR_VFLAG_MODIFY | ATR_VFLAG_MODCACHE;
	}
	bad = 0;
	psatl = (svrattrl *)GET_NEXT(preq->rq_ind.rq_modify.rq_attr);
	if (psatl)
		rc = modify_resv_attr(presv, psatl, preq->rq_perm, &bad);

	if (send_to_scheduler)
		set_scheduler_flag(SCH_SCHEDULE_RESV_RECONFIRM, dflt_scheduler);

	(void)sprintf(log_buffer, "Attempting to modify reservation");
	if (presv->ri_alter_flags & RESV_START_TIME_MODIFIED) {
		strftime(buf, sizeof(buf), fmt, localtime((time_t *) &presv->ri_wattr[RESV_ATR_start].at_val.at_long));
		log_len = strlen(log_buffer);
		snprintf(log_buffer + log_len, sizeof(log_buffer) - log_len," start=%s", buf);
	}
	if (presv->ri_alter_flags & RESV_END_TIME_MODIFIED) {
		strftime(buf, sizeof(buf), fmt, localtime((time_t *) &presv->ri_wattr[RESV_ATR_end].at_val.at_long));
		log_len = strlen(log_buffer);
		snprintf(log_buffer + log_len, sizeof(log_buffer) - log_len," end=%s", buf);
	}
	log_event(PBSEVENT_RESV, PBS_EVENTCLASS_RESV, LOG_INFO, preq->rq_ind.rq_modify.rq_objname, log_buffer);

	if ((presv->ri_wattr[RESV_ATR_interactive].at_flags &
		ATR_VFLAG_SET) == 0) {
		char buf1[PBS_MAXUSER + PBS_MAXHOSTNAME + 32] = {0};
		/*Not "interactive" so don't wait on scheduler, reply now*/

		sprintf(buf, "%s ALTER REQUESTED",  presv->ri_qs.ri_resvID);
		sprintf(buf1, "requestor=%s@%s", preq->rq_user, preq->rq_host);

		if ((rc = reply_text(preq, PBSE_NONE, buf))) {
			/* reply failed,  close connection; DON'T purge resv */
			close_client(sock);
			return;
		}
	} else {
		/*Don't reply back until scheduler decides*/
		long dt;
		presv->ri_brp = preq;
		dt = presv->ri_wattr[RESV_ATR_interactive].at_val.at_long;
		/*reply with id and state no decision in +dt secs*/
		(void)gen_future_reply(presv, dt);
		(void)snprintf(buf, sizeof(buf), "requestor=%s@%s Interactive=%ld",
			preq->rq_user, preq->rq_host, dt);
	}
}
Пример #4
0
/**
 * @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);
						}
					}
				}
			}
		}
	}
}